纸牌游戏——小猫钓鱼(队列、栈)

游戏规则:将一副扑克牌分成两份,每人拿一份,A先拿出一张牌放在桌上,然后B在拿出一张牌放在桌上并放在A的那张牌上面,就这样二人交替出牌。出牌时,如果某人打出的牌与桌上某张牌牌面相同,即可获得两张相同的牌及其中间所夹的牌,并依次放到自己手中的牌的末尾,当任意一人手牌全部出完时,游戏结束,对手胜。

思路:

首先A和B只有两个操作,出牌和赢牌,而出牌和赢牌操作就如同队列,一头出一头进,先进先出,所以定义一个队列的结构体来代表两人的手牌。

//队列
typedef struct queue {
	int q[100];        //手上的牌
	int front, rear;    //队首队尾指针
}queue;

然后桌子就像一个栈,A、B出了牌,就将牌入栈,A、B赢了牌,就将牌出栈,所以定义一个栈的结构体代表桌面。

//栈
typedef struct stack {
	int s[100];    //桌面上的牌
	int top;        //栈顶指针
}stack;

最后每次出了一张牌后就要同桌面上已有的牌进行比较,可以直接用遍历的方式来比较。

整体分析如图:

 所以还需要用出队、入队、出栈、入栈等操作来实现整个过程:

入队、出队:

//入队
void enqueue(queue* q, int data) {
	q->q[q->rear++] = data;
}
//出队,返回的是队首元素
int dequeue(queue* q) {
	return q->q[q->front++];
}

入栈、出栈:

//入栈
void push(stack* s, int data) {
	s->s[s->top++] = data;
}
//出栈,返回的是栈顶元素
int pop(stack* s) {
	return s->s[--s->top];
}

判断相等:

//判断相等
//如果桌面上有相同的牌,就返回这张牌的所在位置
//如果没有就返回-1
//因为出了牌都要入栈,栈顶元素都是刚出的牌,所以直接遍历栈看有没有和当前栈顶元素的值相同的
int judge(stack s) {
	for (int i = 0; i < s.top - 1; i++) {
		if (s.s[i] == s.s[s.top-1])
			return i;
	}
	return -1;
}

完整代码及详情如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//队列
typedef struct queue {
	int q[100];
	int front, rear;
}queue;
//栈
typedef struct stack {
	int s[100];
	int top;
}stack;
//入队
void enqueue(queue* q, int data) {
	q->q[q->rear++] = data;
}
//出队
int dequeue(queue* q) {
	return q->q[q->front++];
}
//入栈
void push(stack* s, int data) {
	s->s[s->top++] = data;
}
//出栈
int pop(stack* s) {
	return s->s[--s->top];
}
//判断相等
int judge(stack s) {
	for (int i = 0; i < s.top - 1; i++) {
		if (s.s[i] == s.s[s.top-1])
			return i;
	}
	return -1;
}

int main(){
    //先创建两个队列一个栈
	stack s;
	queue q1, q2;
    //再给他们初始化
	q1.front = q1.rear = q2.front = q2.rear = s.top = 0;

	int N;
	printf("请输入手牌数量:");
	scanf("%d", &N);
    //手牌初始化,相当于摸牌阶段
	while (q1.rear < N)
		scanf("%d", &q1.q[q1.rear++]);
	while (q2.rear < N)
		scanf("%d", &q2.q[q2.rear++]);

	int j;
	int top;
	while (q1.front < q1.rear && q2.front < q2.rear) {//一个人出完了就结束
		push(&s, dequeue(&q1));//先出队,再入栈
		if ((j = judge(s)) != -1) {
			top = s.top;
			for (j; j < top; j++) {
				enqueue(&q1, pop(&s));//先出栈,再入队
			}
		}
		push(&s, dequeue(&q2));
		if ((j = judge(s)) != -1) {
			top = s.top;
			for (j; j < top; j++) {
				enqueue(&q2, pop(&s));
			}
		}
	}
	if (q1.front == q1.rear) {
		printf("B赢了!剩余手牌是:");
		while (q2.front < q2.rear)
			printf("%d ", q2.q[q2.front++]);
		printf("\n桌面的牌是:");
		for (int i = 0; i < s.top; i++)
			printf("%d ", s.s[i]);
	}
	else {
			printf("A赢了!剩余手牌是:");
			while (q1.front < q1.rear)
				printf("%d ", q1.q[q1.front++]);
			printf("\n桌面的牌是:");
			for (int i = 0; i < s.top; i++)
				printf("%d ", s.s[i]);
	}
	return 0;
}

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多低调

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值