1. 程式人生 > >數據結構16: 撲克牌遊戲

數據結構16: 撲克牌遊戲

隊列 span 是否 head 模擬 沒有 一個數 人在 結果

小時候在剛開始接觸撲克牌的時候,最初學會的撲克遊戲就是類似於“推小車”這樣的無腦遊戲,本節帶領大家使用學過的知識編寫推小車卡牌遊戲。


“推小車”撲克牌遊戲適合 2-3 個人玩,遊戲規則也超級簡單:將一副撲克牌平均分成兩份,每人拿一份,每個人手中的撲克牌全部反面朝上,疊成一摞。遊戲進行時,每個人輪流拿出第一張撲克牌放到桌上,將其排成一豎行。如果打出的牌與桌上某張牌的數字(紅桃 5 和黑桃 5 在此遊戲中相等)相等,即可將兩張相同的牌以及兩張中間所夾的所有的牌全部取走,每次取走的一小摞牌都必須放到自己本摞的下面。

遊戲過程中,一旦有人手中沒有牌,則宣布另一人獲勝,同時遊戲結束。

設計思路

假設模擬兩個人進行該撲克牌遊戲。每個人在遊戲過程中都是不斷地從自己這一摞撲克牌的最上方去取牌,放到桌子上;當發現自己的牌同桌子上的牌相等時,將贏得的牌依次放在自己撲克牌的下方。這是典型的隊列的“先進先出”。

而對於桌子而言,就相當於是一個棧。每次放到桌子上的撲克牌,都相當於進棧;當有相同的撲克牌時,相同的撲克牌連通之間的所有的撲克牌則依次出棧。

所以,模擬該撲克牌遊戲需要同時使用 2 個隊列和 1 個棧。

實現代碼

#include <stdio.h>
#include <stdlib.h>
struct queue {
int data[1000]; int head; int tail; };
struct stack { int data[10]; int top; };
void showCard(struct queue *q, int *book, struct stack *s)
{
int t = (*q).data[(*q).head];   //打出一張牌,即從隊列 q 的隊頭取元素(此時還不往桌子的棧裏放) //判斷取出的這張牌是否會贏牌 if(book[t] == 0)
   {
     // 若不贏牌,只需放到桌子上入棧即可 (*q).head++;  //
由於此時牌已經打出,所以隊列的隊頭需要前進 (*s).top++; (*s).data[(*s).top] = t;   //再把打出的牌放到桌上,即入棧 book[t] = 1;          //標記桌上現在已經有牌面為t的牌 } else
  { (*q).head++;//由於此時已經打出去一張牌,所以隊頭需要 +1 (*q).data[(*q).tail] = t;//將打出的牌放到手中牌的最後(再入隊) (*q).tail++; //把桌子上贏得的牌依次放到手中牌的最後(依次出棧在入隊列的過程) while((*s).data[(*s).top] != t)
     { book[(
*s).data[(*s).top]] = 0;//取消對該牌號的標記 (*q).data[(*q).tail] = (*s).data[(*s).top];//依次放入隊尾 (*q).tail++; (*s).top--; } //最後別忘了將最後一張相等的牌取出放入隊列 book[(*s).data[(*s).top]] = 0; (*q).data[(*q).tail] = (*s).data[(*s).top]; (*q).tail++; (*s).top--; } } int main() { struct queue q1,q2;//兩個隊列,分別模擬兩個人,假設分別為小王和小李 struct stack s;//棧,模擬桌子 int book[14];//為了便於判斷桌子上的牌是否有相同的,增加一個數組用於判斷 int i; //初始化隊列 q1.head = 0;
   q1.tail = 0; q2.head = 0;
   q2.tail = 0; //初始化棧 s.top = -1; //初始化用來標記的數組 for(i=0; i<=13; i++) book[i] = 0; //假設初期每個人手中僅有 6 張牌,每個人擁有的牌都是隨機的,但都在 1-13 之間 for(i=1; i<=6; i++)
  { q1.data[q1.tail]
= rand()%13 + 1; q1.tail++; } for(i=1; i<=6; i++)
   { q2.data[q2.tail]
= rand()%13+1; q2.tail++; } //僅當其中一個人沒有牌時,遊戲結束 while(q1.head < q1.tail && q2.head < q2.tail )
   {
     showCard(&q2, book, &s);  //小李出牌 showCard(&q1, book, &s);  //小王出牌 } //遊戲結束時,輸出最後的贏家以及手中剩余的牌數 if(q2.head == q2.tail)
   { printf(
"小李贏\n"); printf("手中還有:%d 張牌", q1.tail - q1.head); } else
  { printf("小王贏\n"); printf("手中還有:%d 張牌", q2.tail - q2.head); }
return 0; }
運行結果:
小王贏
手中還有:7 張牌

數據結構16: 撲克牌遊戲