halisi7

一个专注技术的组织

0%

小猫钓鱼(纸牌游戏)-c语言

小猫钓鱼(纸牌游戏)-c语言

说明:

星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”。游戏的规则是这样的:
将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,
并放在小哼刚打出的扑克牌的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人手中的牌全部出完时,游戏结束,
对手获胜。
假如游戏开始时,小哼手中有 6 张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6 张牌,顺序
为 3 1 3 5 6 4,最终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来自动判断谁将获胜。
这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9。

分析:

我们先来分析一下这个游戏有哪几种操作。小哼有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,
出牌就是出队,赢牌就是入队。小哈的操作和小哼是一样的。而桌子就是一个栈,每打出一张牌放到桌上就相当于入栈。
当有人赢牌的时候,依次将牌从桌上拿走,这就相当于出栈。那如何解决赢牌的问题呢?赢牌的规则是:如果某人打出的
牌与桌上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。那如何知道桌上已经有哪些牌了呢?最简单的方法就
是枚举桌上的每一张牌,当然也有更好的办法我们待会再说。OK, 小结一下,我们需要两个队列、一个栈来模拟整个游戏。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
struct queue{//定义队列
int data[1000];
int head;
int tail;
};
struct stack//定义栈
{
int data[10];
int top;
};
int main() {
struct queue q1, q2;//模拟小哈和小哼
struct stack s;//模拟桌子上的牌
int i,t;
int book[10];//对桌子上的牌做标记
//初始化值
q1.head = 1; q1.tail = 1;
q2.head = 1; q2.tail = 1;
//初始化栈顶
s.top = 0;
//初始化计数器
for (i = 1; i < 10; i++)
book[i] = 0;
//逐个输入 小哼
printf("请输入小哼手上的6张牌:");
for (i = 1; i <= 6; i++) {
scanf_s("%d", &q1.data[q1.tail]);
q1.tail++;
}
//逐个输入 小哈
printf("请输入小哈手上的6张牌:");
for (i = 1; i <= 6; i++) {
scanf_s("%d", &q2.data[q2.tail]);
q2.tail++;
}
//当队列不为空的时候执行循环
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];//依次放入队尾
s.top--;//栈中少了一张牌,所以栈顶要减1
q1.tail++;
}

}
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];//依次放入队尾
s.top--;
q2.tail++;
}
}

}
if (q2.head == q2.tail) {
printf("小哼WIN!\n");
printf("小哼手里的牌是:");
for (i = q1.head; i < q1.tail; i++) {
printf("%d ", q1.data[i]);
}
if (s.top != 0) {//如果桌上有牌则依次输出桌上的牌
printf("\n桌上的牌是:");
for (i = 1; i <= s.top; i++) {
printf("%d ", s.data[i]);
}
}
else {
printf("桌上已经没牌了!");
}
}
if (q1.head == q1.tail) {
printf("小哈WIN!\n");
printf("小哈手里的牌是:");
for (i = q2.head; i < q2.tail; i++) {
printf("%d ", q1.data[i]);
}
if (s.top != 0) {
printf("\n桌上的牌是:");
for (i = 1; i <= s.top; i++) {
printf("%d ", s.data[i]);
}
}
else {
printf("桌上已经没牌了!");
}
}
getchar(); getchar();
return 0;
}

输入:

1
2
请输入小哼手上的6张牌:2 4 1 2 5 6
请输入小哈手上的6张牌:3 1 3 5 6 4

输出:

1
2
3
小哼WIN!
小哼手里的牌是:5 6 2 3 1 4 6 5
桌上的牌是:2 1 3 4

总结:

队列:<(11条消息) 解密 QQ 号-队列-c语言_halisi7的博客-CSDN博客>

栈:<(11条消息) 回文数(栈)-c语言_halisi7的博客-CSDN博客>

打赏一下作者~ ฅ( ̳• ◡ • ̳)ฅ