1. 程式人生 > >紙牌遊戲----小貓釣魚

紙牌遊戲----小貓釣魚

fine 求解 str 判斷 amp 條件 class example #define

問題描述:

遊戲的規則是這樣的:將一副撲克牌平均分成兩份,每人拿一份。小哼先拿出手中的第一張撲克牌放在桌上,然後小哈也拿出手中的第一張撲克牌,並放在小哼剛打出的撲克牌的上面,就像這樣兩人交替出牌。出牌時,如果某人打出的牌與桌上某張牌的牌面相同,即可將兩張相同的牌及其中間所夾的牌全部取走,並依次放到自己手中牌的末尾。當任意一人手中的牌全部出完時,遊戲結束,對手獲勝。

假如遊戲開始時,小哼手中有6 張牌,順序為2 4 1 2 5 6,小哈手中也有6 張牌,順序為3 1 3 5 6 4,最終誰會獲勝呢?現在你可以拿出紙牌來試一試。接下來請你寫一個程序來自動判斷誰將獲勝。這裏我們做一個約定,小哼和小哈手中牌的牌面只有1~9。

技術分享圖片

分析

小哼或小哈 對應的兩個操作------出牌和贏牌,其中出牌對應於出隊,贏牌對應於入隊

桌子相當於 棧,每打出一張牌就相當於入棧,當有人贏牌時,一次將牌從桌子上拿走,相當於出棧

贏牌規則:如果某人打出的牌與桌子上的某張牌相同,即可將兩張牌及中間的牌全部取走

獲勝規則:當任意一人手中的牌全部出完時,遊戲結束,對手獲勝

首先創建一個結構體用來實現隊列:

typedef struct queue{
    ElementType data[MaxSize];
    int head;
    int tail;
}Queue;

接著創建棧:

typedef struct stack{
    ElementType data[N];
    
int top; }Stack;

註:這裏的N,定義的是10 ,因為桌子上最多有9章不同的牌(一旦有重復的牌就會出棧抽走),又因桌子上的數子為1~9(數組下標為0的不用),故有定義N為10 足夠

接下來定義兩個隊列變量q1和q2, q1用來模擬小哼手中的牌,q2用來模擬小哈手中的牌,定義一個棧變量s模擬桌子上的牌

Queue q1,q2;
Stack s;

再接著初始化隊列和棧

    // 初始化隊列q1和q2為空,此時兩人手裏都沒有牌 
    q1.head = 1; 
    q1.tail = 1;
    q2.head = 1;
    q2.tail = 1;
    
// 初始化棧s為空,最開始桌上沒有牌 s.top= 0;

接下來讀入小哼和小哈最初手上的牌,分兩次讀入,每次讀入六個數,分別插入q1和q2中

  // 先讀入六張牌,分別放在小哼和小哈手上
    for(i=1;i<=6;++i)
    {
        scanf("%d",&q1.data[q1.tail++]);   // 讀入一個數到隊列          
    } 
    for(i=1;i<=6;++i)
    {
        scanf("%d",&q2.data[q2.tail++]);   // 讀入一個數到隊列     
    }

再判斷,小哼和小哈打出來的牌是否可以贏牌(即打出的牌跟桌子上的牌有沒有重復的),這裏需要註意的事用book[N]來標記桌子上的牌數

例如先判斷小哼(或者小哈)的出牌,若小哼的這張牌在桌子上有,那麽就將這張牌出隊,並放在隊尾,最後將桌子上的與此紙牌數相同的 出棧,放到小哼的隊尾,否則,小哼的出隊,放入桌子上(即入棧),並標記此紙牌。具體的代碼如下所示:

while(q1.head<q1.tail && q2.head<q2.tail)
    {
        t = q1.data[q1.head];  // 小哼先出牌 
        if(book[t]==0)  //  表明桌上沒有牌面為t的牌
          {
            //小哼此輪沒有贏牌
            q1.head++; //小哼已經打出一張牌,所以要把打出的牌出隊
            s.top++;   // 進棧 
            s.data[s.top]=t; //再把打出的牌放到桌上,即入棧
            book[t]=1; //標記桌上現在已經有牌面為t的牌  
          } 
          else
          {
              //小哼此輪可以贏牌
            q1.head++;//小哼已經打出一張牌,所以要把打出的牌出隊
            q1.data[q1.tail]=t;//緊接著把打出的牌放到手中牌的末尾
            q1.tail++;
            while(s.data[s.top]!=t) //把桌上可以贏得的牌依次放到手中牌的末尾
            {
                book[s.data[s.top]]=0;//取消標記
                q1.data[q1.tail]=s.data[s.top];//依次放入隊尾
                q1.tail++;
                s.top--; //棧中少了一張牌,所以棧頂要減1
            }
          }
        t=q2.data[q2.head]; //小哈出一張牌
        //判斷小哈當前打出的牌是否能贏牌
        if(book[t]==0) //表明桌上沒有牌面為t的牌
        {
            //小哈此輪沒有贏牌
            q2.head++; //小哈已經打出一張牌,所以要把打出的牌出隊
            s.top++;
            s.data[s.top]=t; //再把打出的牌放到桌上,即入棧
            book[t]=1; //標記桌上現在已經有牌面為t的牌
        }
        else
        {
            //小哈此輪可以贏牌
            q2.head++;//小哈已經打出一張牌,所以要把打出的牌出隊
            q2.data[q2.tail]=t;//緊接著把打出的牌放到手中牌的末尾
            q2.tail++;
            while(s.data[s.top]!=t) //把桌上可以贏得的牌依次放到手中牌的末尾
            {
                book[s.data[s.top]]=0;//取消標記
                q2.data[q2.tail]=s.data[s.top];//依次放入隊尾
                q2.tail++;
                s.top--;
            }
        }
    }

最後一步,輸出誰最終贏得了遊戲,以及遊戲結束後獲勝者手中的牌和桌上的牌如果小哼獲勝了那麽小哈的手中一定沒有牌了(隊列q2 為空),即q2.head==q2.tail,具體輸出如下。

if(q2.head==q2.tail)    // 當任意一人手中的牌全部出完時,遊戲結束,對手獲勝 
    {
        printf("小哼獲勝\n");
        printf("小哼當前手中的牌是");
        for(i=q1.head;i<=q1.tail-1;i++)
            printf(" %d",q1.data[i]);
        if(s.top>0) //如果桌上有牌則依次輸出桌上的牌
        {
            printf("\n桌上的牌是");
            for(i=1;i<=s.top;i++)
                printf(" %d",s.data[i]);
            printf("\n");
        }
        else
            printf("\n桌上已經沒有牌了");
        }
        else
        {
            printf("小哈獲勝\n");
            printf("小哈當前手中的牌是");
            for(i=q2.head;i<=q2.tail-1;i++)
                printf(" %d",q2.data[i]);
            if(s.top>0) //如果桌上有牌則依次輸出桌上的牌
            {
                printf("\n桌上的牌是");
                for(i=1;i<=s.top;i++)
                    printf(" %d",s.data[i]);
                printf("\n");    
            }
            else
                printf("\n桌上已經沒有牌了\n");
    }

OK,每個過程分析完了,一下看看詳細代碼:

  1 #include<stdio.h>
  2 #define MaxSize 1001
  3 #define N 10
  4 #define ElementType int  
  5 
  6 
  7 /*
  8 * brief:小貓釣魚問題,  轉化為棧和隊列的操作來求解 
  9 * input:分別輸入兩組數字,每組數字6個  大小限制在1~9之間
 10 * output:獲勝一方,和桌子上剩余的紙牌
 11 * example:
 12 *     input:    2 4 1 2 5 6
 13 *            3 1 3 5 6 4  
 14 *    output: 小哼win
 15 *            小哼當前手中的牌是 5 6 2 3 1 4 6 5
 16 *            桌上的牌是 2 1 3 4
 17 */
 18 
 19 //  定義一個隊列用來模擬小哼小哈的操作 
 20 typedef struct queue{
 21     ElementType data[MaxSize];
 22     int head;
 23     int tail;
 24 }Queue;
 25 
 26 //  定義棧用來模擬桌子的操作 
 27 typedef struct stack{
 28     ElementType data[N];
 29     int top;    
 30 }Stack;
 31 
 32 
 33 int main()
 34 {
 35     Queue q1,q2;     // q1,q2分別模擬小哼和小哈手中的牌 
 36     Stack s;         // 模擬桌子上的牌 
 37     int i,t;
 38     int book[N];     // 用來標記桌子上出牌的數字(1~9) 
 39      
 40     // 初始化隊列q1和q2為空,此時兩人手裏都沒有牌 
 41     q1.head = 1;     q1.tail = 1;
 42     q2.head = 1;     q2.tail = 1;
 43     // 初始化棧s為空,最開始桌上沒有牌
 44     s.top= 0;
 45     // 初始化用來標記的數組,用來標記哪些牌在桌子上了
 46     for(i=1;i<=9;i++)
 47         book[i] = 0;
 48          
 49     // 先讀入六張牌,分別放在小哼和小哈手上
 50     for(i=1;i<=6;++i)
 51     {
 52         scanf("%d",&q1.data[q1.tail++]);   // 讀入一個數到隊列          
 53     } 
 54     for(i=1;i<=6;++i)
 55     {
 56         scanf("%d",&q2.data[q2.tail++]);   // 讀入一個數到隊列     
 57     }
 58     
 59     while(q1.head<q1.tail && q2.head<q2.tail)
 60     {
 61         t = q1.data[q1.head];  // 小哼先出牌 
 62         if(book[t]==0)  //  表明桌上沒有牌面為t的牌
 63           {
 64             //小哼此輪沒有贏牌
 65             q1.head++; //小哼已經打出一張牌,所以要把打出的牌出隊
 66             s.top++;   // 進棧 
 67             s.data[s.top]=t; //再把打出的牌放到桌上,即入棧
 68             book[t]=1; //標記桌上現在已經有牌面為t的牌  
 69           } 
 70           else
 71           {
 72               //小哼此輪可以贏牌
 73             q1.head++;//小哼已經打出一張牌,所以要把打出的牌出隊
 74             q1.data[q1.tail]=t;//緊接著把打出的牌放到手中牌的末尾
 75             q1.tail++;
 76             while(s.data[s.top]!=t) //把桌上可以贏得的牌依次放到手中牌的末尾
 77             {
 78                 book[s.data[s.top]]=0;//取消標記
 79                 q1.data[q1.tail]=s.data[s.top];//依次放入隊尾
 80                 q1.tail++;
 81                 s.top--; //棧中少了一張牌,所以棧頂要減1
 82             }
 83           }
 84         t=q2.data[q2.head]; //小哈出一張牌
 85         //判斷小哈當前打出的牌是否能贏牌
 86         if(book[t]==0) //表明桌上沒有牌面為t的牌
 87         {
 88             //小哈此輪沒有贏牌
 89             q2.head++; //小哈已經打出一張牌,所以要把打出的牌出隊
 90             s.top++;
 91             s.data[s.top]=t; //再把打出的牌放到桌上,即入棧
 92             book[t]=1; //標記桌上現在已經有牌面為t的牌
 93         }
 94         else
 95         {
 96             //小哈此輪可以贏牌
 97             q2.head++;//小哈已經打出一張牌,所以要把打出的牌出隊
 98             q2.data[q2.tail]=t;//緊接著把打出的牌放到手中牌的末尾
 99             q2.tail++;
100             while(s.data[s.top]!=t) //把桌上可以贏得的牌依次放到手中牌的末尾
101             {
102                 book[s.data[s.top]]=0;//取消標記
103                 q2.data[q2.tail]=s.data[s.top];//依次放入隊尾
104                 q2.tail++;
105                 s.top--;
106             }
107         }
108     }
109 
110     if(q2.head==q2.tail)    // 當任意一人手中的牌全部出完時,遊戲結束,對手獲勝 
111     {
112         printf("小哼獲勝\n");
113         printf("小哼當前手中的牌是");
114         for(i=q1.head;i<=q1.tail-1;i++)
115             printf(" %d",q1.data[i]);
116         if(s.top>0) //如果桌上有牌則依次輸出桌上的牌
117         {
118             printf("\n桌上的牌是");
119             for(i=1;i<=s.top;i++)
120                 printf(" %d",s.data[i]);
121             printf("\n");
122         }
123         else
124             printf("\n桌上已經沒有牌了");
125         }
126         else
127         {
128             printf("小哈獲勝\n");
129             printf("小哈當前手中的牌是");
130             for(i=q2.head;i<=q2.tail-1;i++)
131                 printf(" %d",q2.data[i]);
132             if(s.top>0) //如果桌上有牌則依次輸出桌上的牌
133             {
134                 printf("\n桌上的牌是");
135                 for(i=1;i<=s.top;i++)
136                     printf(" %d",s.data[i]);
137                 printf("\n");    
138             }
139             else
140                 printf("\n桌上已經沒有牌了\n");
141     }
142     return 0;
143 } 

為了程序的魯棒性,需要進一步的測試,優化,暫時先不完善了(提示:需要設置一定的條件)

紙牌遊戲----小貓釣魚