完成链表的学习后,作为一个小实践项目实现俄罗斯轮盘赌。
轮盘赌游戏基于单循环链表实现,使用C语言的rand函数生成随机数,注意要不断更新随机数种子。
俄罗斯轮盘赌,想必很多人都听说过,一种残忍的赌博游戏。游戏的道具是一把左轮手枪,
其规则也很简单:在左轮手枪中的 6 个弹槽中随意放入一颗或者多颗子弹,在任意旋转转轮之后,关上转轮。
游戏的参加者轮流把手枪对着自己,扣动扳机:中枪或是怯场,即为输的一方;坚持到最后的即为胜者。
实践项目同轮盘赌类似,游戏规则:n 个参加者排成一个环,每次由主持向左轮手枪中装一颗子弹,并随机转动关上转轮,游戏从第一个人开始,轮流拿枪;中枪者退出赌桌,退出者的下一个人作为第一人开始下一轮游戏。直至最后剩余一个人,即为胜者。要求:模拟轮盘赌的游戏规则,找到游戏的最终胜者。
c语言代码实现:注意这里使用的delete节点函数参数用pos(位置)而不是ele(元素值)比较恰当
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<signal.h> //signal()#include<string.h>#include<sys/stat.h>#include<time.h>#include<stdarg.h>#if 1#define INFO_DEBUG "%d lines in "__FILE__", complie time is "__TIME__" "__DATE__" \n",__LINE__#define ADI_RUN_ERROR1#define ADI_NULL_POINTER -1#define ADI_OK 0#define ADI_PRINT printf("[%s][%d]:",__FUNCTION__,__LINE__);printf#define ADI_ASSERT(c,prt,ret) if(c) {printf(prt);return ret;}#endif/*俄罗斯轮盘赌,想必很多人都听说过,一种残忍的赌博游戏。游戏的道具是一把左轮手枪,其规则也很简单:在左轮手枪中的 6 个弹槽中随意放入一颗或者多颗子弹,在任意旋转转轮之后,关上转轮。游戏的参加者轮流把手枪对着自己,扣动扳机:中枪或是怯场,即为输的一方;坚持到最后的即为胜者。本节实践项目同轮盘赌类似,游戏规则:n 个参加者排成一个环,每次由主持向左轮手枪中装一颗子弹,并随机转动关上转轮,游戏从第一个人开始,轮流拿枪;中枪者退出赌桌,退出者的下一个人作为第一人开始下一轮游戏。直至最后剩余一个人,即为胜者。要求:模拟轮盘赌的游戏规则,找到游戏的最终胜者。*/typedef struct list{int elem;struct list *next;}list;#define PARAM_FAIL -1#define P_NULL -2#define SUCCESS 0#define SIZE_GUN 6 //弹容量6发/*初始化:只创建头结点*/list* initList(){list *head = (list*)malloc(sizeof(list));if(NULL==head) {printf("NULL");return head;}head->next = head;return head;}/*pos从0开始,pos=0为第一个*//*如果循环链表插入操作指定插入位置pos,会麻烦些,如下,如果不指定位置,默认插入到最后,会比较简单*/int insertList(list *list_insert,int elem,int pos){int i=0;if(NULL == list_insert){ADI_PRINT("err NULL\n");return P_NULL;}list *head = list_insert;//取头指针while(i<pos && list_insert != head->next){head = head->next;i++;//i比head快一个,i=1时head指向的是第0个元素}if((list_insert==head->next)&&(i<pos))//已经到链表尾部,但是pos>i,说明指定的插入位置超过了链表的末尾位置{ADI_PRINT("pos = %d, list's last = %d,pos>i,insert err!\n",pos,i);return PARAM_FAIL;}else{list *node = (list*)malloc(sizeof(list));if(NULL==node) {printf("NULL");return P_NULL;}node->next = head->next;node->elem = elem;head->next = node;ADI_PRINT("insert elem = %d\n",elem);}return SUCCESS;}/*pos从0开始,pos=0为第一个*/int replaceList(list *list_insert,int elem,int pos){int i=0;if(NULL == list_insert){ADI_PRINT("err NULL\n");return P_NULL;}list *head = list_insert;//取头指针while(i<pos && list_insert != head->next){head = head->next;i++;//i比head快一个,i=1时head指向的是第0个元素}if(list_insert==head->next)//已经到链表尾部,说明指定的修改位置超过了链表原有大小{ADI_PRINT("pos = %d, list's last = %d,change err!\n",pos,i);return PARAM_FAIL;}else{head->next->elem = elem;ADI_PRINT("change elem = %d,pos = %d\n",elem,pos);}return SUCCESS;}/*指定删除元素的值*//*int delList(list *list_insert,int elem){if(NULL == list_insert){ADI_PRINT("err NULL\n");return P_NULL;}list *head = list_insert;while(list_insert != head->next){if(elem == head->next->elem){list *del = head->next;head->next = head->next->next;free(del);ADI_PRINT("del ele = %d\n",elem);return SUCCESS;}head = head->next;}ADI_PRINT("can not find ele = %d\n",elem);return PARAM_FAIL;}*//*指定删除元素的位置*/int delList(list *list_insert,int pos){if(NULL == list_insert){ADI_PRINT("err NULL\n");return P_NULL;}list *head = list_insert;int i = 0;while(list_insert != head->next){if(pos == i){list *del = head->next;head->next = head->next->next;ADI_PRINT("del pos = %d,ele = %d\n",pos,del->elem);free(del);return SUCCESS;}head = head->next;i++;}ADI_PRINT("can not find pos = %d\n",pos);return PARAM_FAIL;}/*pos为在链表中的位置,ele为待查找的元素*/int findList(list *listFind,int ele,int *pos){if(NULL == listFind){ADI_PRINT("err NULL\n");return P_NULL;}int i = 0;list *head = listFind;while(listFind != head->next){if(ele == head->next->elem){*pos = i;return SUCCESS;}i++;head = head->next;}ADI_PRINT("can not find ele = %d\n",ele);return PARAM_FAIL;}int printList(list *list_prt){if(NULL == list_prt){ADI_PRINT("err NULL\n");return P_NULL;}int i = 0;list *head = list_prt;while(head != list_prt->next){ list_prt = list_prt->next;ADI_PRINT("list[%d] = %d\n",i,list_prt->elem);i++;}return SUCCESS;}/*return 队列的大小*/int sizeList(list *list_size){if(NULL == list_size){ADI_PRINT("err NULL\n");return P_NULL;}int i = 0;list *head = list_size;while(head != list_size->next){ list_size = list_size->next;i++;}return i;}int main(){int ret = 0;int rand_gun = 0;//子弹在弹夹中的位置int kill_id = 0; //本次要被kill的人在队列中的位置list *list_test = initList();if(NULL == list_test){ADI_PRINT("err \n");return P_NULL;}/*初始化一个20人的队列*/for(int i=0;i<20;i++){ret = insertList(list_test,i,i);if(SUCCESS != ret) {ADI_PRINT("insert err\n");return PARAM_FAIL;}}printList(list_test);int size_man = sizeList(list_test);//还活着的人数while(1 != sizeList(list_test))//剩最后一个人{srand((int)time(0));//time函数得到的时间只能精确到秒,循环处理太快,秒没有发生变化,导致随机数都是一样的,所以每次产生随机数要在后面进行sleeprand_gun = rand()%(SIZE_GUN-1);//生成0-5的随机数对应子弹位置,弹容量6发kill_id += rand_gun;if(kill_id >=size_man) {kill_id = kill_id-size_man;}ADI_PRINT("rand_gun = %d,size_man=%d,kill_id = %d\n",rand_gun,size_man,kill_id);ret = delList(list_test,kill_id);sleep(1);size_man--;}ADI_PRINT("FINAL IS %d\n",list_test->next->elem);return SUCCESS;}