简单游戏场景用户模拟

来源:互联网 发布:入门级显示器知乎 编辑:程序博客网 时间:2024/05/16 14:56

帮朋友写的, 很简单...

还是贴出来, 希望能对看客有所帮助, 也希望看客能对我有所帮助...


谢谢.


#include <stdio.h>#include <stdlib.h>/** * author: selfimpr * blog: http://blog.csdn.net/lgg201 * mail: lgg860911@yahoo.com.cn */struct UserPool {struct User *head;/* 所分配存储空间首指针 */struct User *useable;/* 当前未使用的存储空间首指针 */struct User *free;/* 空闲链表首指针 */intused;/* 内存池中已在线的用户数 */intalloced;/* 分配的内存池大小 */};/* 用户内存池 */struct User {intuid;/* 用户标识 */intfd;/* 文件描述符 */struct Map*map_p;/* 所在地图 */intmap_i;/* 在所在地图用户数组中的下标 */struct User*next;/* 作为内存池空闲链表时的构造指针 */struct UserPool*pool;/* 所在内存池 */intisfree;/* 是否空闲(1表示用户已离线, 空间可重用) */intpool_i;/* 在内存池中的下标 */};/* 用户 */struct Map {struct User**users;/* 用户数组 */intalloced;/* 已分配用户数组大小 */intused;/* 已使用用户数组大小 */};/* 地图 */struct HashTableElement {unsigned intkey;/* 键 */void*value;/* 值 */struct HashTableElement*next;/* 下一个节点 */};/* 哈希表元素 */struct HashTable {struct HashTableElement*elements;/* 存储数据的链表数组 */unsigned intsize;/* 哈希表大小 */};/* 哈希表 *//* 创建哈希表 */struct HashTable *hash_table_create(unsigned int size) {struct HashTable*ht;ht= (struct HashTable *)malloc(sizeof(struct HashTable));if ( ht == NULL ) goto failed;ht->size= size;ht->elements= (struct HashTableElement *)calloc(size, sizeof(struct HashTableElement));if ( ht->elements == NULL )goto failed;return ht;failed:printf("hash_table_create failed\n");if ( ht != NULL ) {if ( ht->elements != NULL )free(ht->elements);free(ht);}return NULL;}/* 向哈希表中写入或更新数据 */int hash_table_add_or_update(struct HashTable *ht, unsigned int k, void *value) {struct HashTableElement*h, *e, *n;h= &(ht->elements[k % ht->size]);e= h->next;if ( e == NULL ) {e= h;goto insert;}do {if ( e->key == k )goto update;elsee= e->next;} while ( e->next != NULL );insert:n= (struct HashTableElement *)calloc(1, sizeof(struct HashTableElement));n->key= k;n->value= value;e->next= n;return (0);update:e->value= value;return (0);}/* 在哈希表中查找数据 */struct HashTableElement *hash_table_find(struct HashTable *ht, unsigned int k) {struct HashTableElement*h, *e;h= &(ht->elements[k % ht->size]);e= h->next;if ( e == NULL )goto failed;do {if ( e->key == k )return e;else e= e->next;} while ( e != NULL );failed:return NULL;}/* 从哈希表中删除数据 */int hash_table_delete(struct HashTable *ht, unsigned int k) {struct HashTableElement*p, *e;p= &(ht->elements[k % ht->size]);e= p->next;if ( e == NULL )goto failed;do {if ( e->key == k ) {p->next= e->next;free(e);return (0);} else {p= e;e= e->next;}} while ( e != NULL );failed:return (-1);}/* 输出哈希表数据 */void hash_table_dump(struct HashTable *ht, char *(*to_string)(void *)) {inti;struct HashTableElement*h, *e;for ( i = 0; i < ht->size; i ++ ) {h= &(ht->elements[i]);e= h->next;while ( e != NULL ) {printf("%d: %s\n", e->key, to_string(e->value));e= e->next;}}}/* 用于哈希表测试用例的字符串转换函数 */char *empty_to_string(void *v) {return (char *)v;}/* 哈希表测试用例 */void hash_table_test() {struct HashTable*ht;ht= hash_table_create((unsigned int)30);hash_table_add_or_update(ht, 1, (void *)"one");hash_table_add_or_update(ht, 2, (void *)"two");hash_table_add_or_update(ht, 3, (void *)"three");hash_table_add_or_update(ht, 4, (void *)"four");hash_table_add_or_update(ht, 1, (void *)"first-one");hash_table_add_or_update(ht, 2, (void *)"second-two");hash_table_add_or_update(ht, 3, (void *)"third-three");hash_table_add_or_update(ht, 4, (void *)"forth-four");hash_table_delete(ht, 3);hash_table_dump(ht, empty_to_string);}/* 地图创建 */struct Map *map_create(int num) {struct Map*map;map= (struct Map *) malloc(sizeof(struct Map));if ( map == NULL )goto failed;map->users= (struct User **) calloc(num, sizeof(struct User *));map->alloced= num;map->used= 0;return map;failed:if ( map != NULL )free(map);return NULL;}/* 用户进入地图 */int map_user_enter(struct Map *map, struct User *user) {inti;for ( i = 0; i < map->alloced; i ++ ) {if ( map->users[i] == NULL ) {map->users[i]= user;user->map_p= map;user->map_i= i;map->used ++;return (0);}}return (-1);}/* 用户离开地图 */int map_user_leave(struct User *user) {user->map_p->users[user->map_i]= NULL;user->map_p->used --;user->map_i= 0;user->map_p= NULL;}/* 创建用户内存池 */struct UserPool *user_pool_create(int size) {struct UserPool*pool;pool= (struct UserPool *)malloc(sizeof(struct UserPool));pool->head= (struct User *)calloc(size, sizeof(struct User));pool->useable= pool->head;pool->free= NULL;pool->alloced= size;pool->used= 0;return (pool);failed:if ( pool != NULL ) {if ( pool->head != NULL ) free(pool->head);free(pool);}return (NULL);}/* 从内存池分配一个用户的空间 */struct User *user_pool_alloc_user(struct UserPool *pool) {struct User*u;/* TODO 此处应该是内存池扩展逻辑, 比较复杂, 未实现 *//* 从空闲链表中分配 */if ( pool->free != NULL ) {u= pool->free;u->isfree= 0;pool->free= pool->free->next;pool->used ++;return u;}/* 从未使用空间中分配 */u= pool->useable;u->pool= pool;u->pool_i= pool->useable - pool->head;pool->useable ++;pool->used ++;return u;}/* 从内存池中释放一个用户 */void user_pool_free_user(struct User *user) {struct UserPool*pool;pool= user->pool;user->isfree= 1;/* 将被释放的空间放入空闲链表 */user->next= pool->free;pool->free= user;/* 更新用户计数 */pool->used --;}struct Map**maps;/* 所有的地图 */struct HashTable*user_ht;/* 用户哈希表 */struct UserPool*user_pool;/* 用户内存池 *//* 地图数量 */int map_num = 1;/* 地图最大人数 */int map_user_num = 10;/* 总人数上限 */int user_num = 100;/* 游戏初始化 */int game_init() {inti;/* 地图初始化 */maps= (struct Map **)calloc(map_num, sizeof(struct Map *));for ( i = 0; i < map_num; i ++ ) {maps[i]= map_create(map_user_num);}/* 用户存储初始化 */user_pool= user_pool_create(user_num);/* 用户哈希表初始化 */user_ht= hash_table_create(user_num);}/* 用户登入 */void user_login(int uid, int fd) {struct User*user;/* 在内存池中为用户分配空间 */user= user_pool_alloc_user(user_pool);/* 初始化用户基本信息 */user->uid= uid;user->fd= fd;/* 用户进入地图 */map_user_enter(maps[0], user);/* 将用户放入哈希表便于查找 */hash_table_add_or_update(user_ht, uid, (void *)user);}/* 用户登出 */void user_logout(int uid) {struct HashTableElement*e;struct User *user;/* 从哈希表中查找用户 */e= (struct HashTableElement *)hash_table_find(user_ht, uid);user= (struct User *)e->value;/* 用户离开地图 */map_user_leave(user);/* 从内存池中释放用户 */user_pool_free_user(user);/* 从哈希表中移除用户 */hash_table_delete(user_ht, uid);}/* 将用户转换为字符串 */char *user_to_string(void *value) {static charbuffer[1024];struct User*user;user= (struct User *)value;sprintf(buffer, "uid: %d, fd: %d, map_p: %p, map_i: %d, pool: %p, pool_i: %d, ptr: %p, next: %p", user->uid, user->fd, user->map_p, user->map_i, user->pool, user->pool_i, user, user->next);return buffer;}int main(int argc, char *argv[]) {/* 初始化游戏 */game_init();inti;struct User *tmp;/* 登入十个用户 */for ( i = 1; i <= 10; i ++ ) user_login(i, i);/* 登出三个用户 */user_logout(2);user_logout(3);user_logout(4);/* 打印在线用户信息 */hash_table_dump(user_ht, user_to_string);/* 打印用户内存池的空闲链表 */printf("\nfree elements:\n");for ( tmp = user_pool->free; tmp != NULL; tmp = tmp->next )printf("%s\n", user_to_string((void *)tmp));}