一、問題描述
俄羅斯輪盤賭是一種殘忍的賭博遊戲。遊戲的道具是一把左輪手槍,其規則也很簡單:在左輪手槍中的6個彈槽中隨意放入一顆或者多顆子彈,在任意旋轉轉輪之後,關上轉輪。遊戲的參加者輪流把手槍對着自己,扣動扳機:中槍或是怯場,即爲輸的一方;堅持到最後的即爲勝者。
遊戲規則:n
個參加者排成一個環,每次由主持向左輪手槍中裝一顆子彈,並隨機轉動關上轉輪,遊戲從第一個人開始,輪流拿槍;中槍者退出賭桌,退出者的下一個人作爲第一人開始下一輪遊戲。直至最後剩餘一個人,即爲勝者。要求:模擬輪盤賭的遊戲規則,找到遊戲的最終勝者。
注:
本例使用循環鏈表實現。
二、代碼實現
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Gambler {
int Number;
struct Gambler *next;
} Gambler;
//按照賭徒人數,初始化循環鏈表
void InitGambler(Gambler **head,int n) {
*head=(Gambler*)malloc(sizeof(Gambler));//頭指針指向首元節點
(*head)->next=NULL;
(*head)->Number=1;
Gambler *list=*head;//指向鏈表尾
for (int i=1; i<n; i++) {
Gambler * body=(Gambler*)malloc(sizeof(Gambler));//申請新節點
body->next=NULL;
body->Number=i+1;
list->next=body;//將新節點鏈接到鏈表尾
list=list->next;//移動list到尾指針
}
list->next=*head;//將鏈表成環
}
//輸出鏈表中所有的結點信息
void Display(Gambler *head) {
Gambler * temp=head;
while (temp->next!=head) {
printf("%d ",temp->Number);
temp=temp->next;
}
printf("%d\n",temp->Number);
}
int main() {
Gambler * head=NULL;
srand((int)time(0));//使用當前時間作爲rand()函數的隨機數的種子
int n,shootNum,round=1;
printf(">>>>俄羅斯輪盤賭遊戲<<<<\n");
printf(">>>遊戲開始>>>輸入賭徒人數:");
scanf("%d",&n);
InitGambler(&head,n);//初始化
Gambler* GamblerNext=head;//用於記錄每輪開始的位置
//僅當鏈表中只含有一個結點時,即頭結點時,退出循環
while (head->next!=head) {
printf(">>第%d輪遊戲開始,初始位置編號%d,",round,GamblerNext->Number);
shootNum=rand()%n+1;
printf("槍在第%d次扣動扳機時會響!\n",shootNum);
Gambler *temp=GamblerNext;
//遍歷循環鏈表,找到將要刪除結點的上一個結點
for(int i=1; i<shootNum-1; i++) {
temp=temp->next;
}
//將要刪除結點從鏈表中刪除,並釋放其佔用空間
printf("編號%d賭徒喪命,剩餘賭徒編號:",temp->next->Number);
Gambler * del=temp->next;
temp->next=temp->next->next;
if (del==head) {
head=head->next;
}
Display(head);
//賦值新一輪開始的位置
GamblerNext=temp->next;
round++;//記錄循環次數
printf("\n");
}
printf(">>---Game over!--->>勝利者是第%d位賭徒!\n",head->Number);
system("pause");//防止生成可執行程序閃退
return 0;
}