脏蜜
俄罗斯轮盘赌:一种残忍的赌博游戏。游戏的道具是一把左轮手枪,游戏规则为:在左轮手枪中的6个弹槽中随意放入一颗或者多颗子弹,在任意旋转转轮之后,关上转轮。游戏的参加者轮流把手枪对着自己,扣动扳机,中枪或者怯场,即为输的一方,坚持到最后的即为胜者。
本实践项目类似轮盘赌,使用线性表的两种结构都可实现(链表更容易理解)。游戏规则:n个参加者排成一个环,每次由主持向左轮手枪中装一颗子弹,并随机转动关上转轮。(可以看做一个随机数m,轮流m个人开枪,第m个人中枪),游戏从第一个人开始,轮流拿枪;中枪这退出赌桌,退出者的下一个人作为第一人开始下一轮游戏。直至最后剩余一个人,即为胜者。(这问题其实是约瑟夫问题的改版,每一轮都将m取随机数,其他规则相同这部分代码重点在于考虑删除头结点的情况以及shotnum的随机取值)
//用循环链表实现代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//循环链表模拟轮盘赌
typedef struct line{
int number;
struct line next;
}line;
line initLine(int n)
{
line* head=(line*)malloc(sizeof(line));
head->number=1;
head->next=NULL;
line* list=head;
for(int i=2;i<=n;i++)
{
line* temp=(line*)malloc(sizeof(line));
temp->number=i;
temp->next=NULL;
list->next=temp;
list=list->next;
}
list->next=head;//循环链表
return head;
}
line* delLine(line* head,int num)
{
line* temp=head;
line* front=NULL;
while(temp->number!=num)
{
front=temp;
temp=temp->next;
}
line* d=temp;
if(temp==head)
{
temp=temp->next;
while(temp!=head)
{
front=temp;
temp=temp->next;//找到链表尾部,重新连城一个环
}
head=head->next;
front->next=head;
}
else
{
front->next=temp->next;
}
free(d);
return head;
}
void display(line* head)
{
line* temp=head;
printf(“现在存活的赌徒有:”);
printf("%d “,temp->number);
temp=temp->next;
while(temp!=head)
{
printf(”%d “,temp->number);
temp=temp->next;
}
printf(”\n");
}
int main()
{
int n,shotnum;
srand((int)time(0));//产生随机数固定代码
scanf("%d",&n);
line head=initLine(n);//创建循环链表
printf(“赌桌上初始有%d 人,分别为:\n”,n);
display(head);
int round=1,outid;//赌局轮数
line temp=head;//从第一个人开始第一轮
while(head->next!=head)//只剩一人时退出
{
printf(“第%d轮从编号为%d的人开始\n”,round,temp->number);
shotnum=rand()%n+1;//表明开枪第shotnum次中枪(1-n)
printf(“shotnum的值为%d\n”,shotnum);
for(int i=1;i<shotnum;i++)//找到中枪者的那个人
{
temp=temp->next;
}
outid=temp->number;
temp=temp->next;
printf(“第%d轮中枪出局的是%d\n”,round,outid);
head=delLine(head,outid);//取返回值,删除第一个节点时head改变
display(head);
round++;
}
return 0;
}