#include<stdio.h>
struct card{
int num//
bool ex//真为正面,假为反面
}
void show(struct card a[],int n){// 显示正面朝上的纸牌
int i = 0,j = 0
printf("第%02d次:",n)
for(i = 0i <52i ++){
if(a[i].ex){
j++
printf("%02d ",a[i].num)
if(j == 23){
printf("\n ")
}
}
}
printf("\n\n")
}
void main()
{
int i,j
struct card a[52]
for(i = 0i <52i ++){
a[i].num = i+1
a[i].ex = true
}//初始化纸牌
for(i = 2i <53i ++){
for(j = 0j <52j ++){
if((j+1)%i == 0)
a[j].ex = !a[j].ex
}
show(a,i-1)
}
定义一个结构类型表示一张牌,结构包含3个成员,第一个成员char:取值2,3~K,A表示牌名字,第二个成员int:取值2~14表示牌真实大小。第三个成员:结构链表指针。写一个初始化函数,定义52大小的结构数组,成员值初值分别和牌对应,遍历数组并将每个元素的链表指针依次指向下一个元素地址。这样得到一个初始链表。(相当于一盒新牌)所有涉及随机数都用rand函数,洗牌分四份就是循环取随机数m=1~n,n是随循环自减,初值52,直到n变成0。每随一次循环就从初始链表中遍历取出对应第m个节点,并从初始链表中将这个节点断开(既前一个节点指针直接指向后一个节点指针)。每取13张就组成一个新的链表。这样获得4个新链表分别表示4个玩家。最后出牌就是分别遍历自己的链表,利用循环取牌比较结构数值大小。(取出的牌要从链表断开和上面一样,你把取出节点写成独立函数就能反复使用)。这个游戏要保证先手必胜,先手方只需要每次取牌以后让剩余的牌数为5的整数倍+1就可以了,这样对手无论如何都只能拿到最后一张。以下代码VS2019测试通过。#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
// 电脑取牌,返回张数 1~4
int ComputerChoice(int CardsRemain)
// 人取牌,返回张数 1~4
int HumanChoice(int CardsRemain)
// 游戏函数
void Game(int CardsRemain, bool HumanFirst)
void main()
{
int CardsRemain // 剩余张数
bool HumanFirst // 人先拿 或 电脑先拿
char c = '/0' // 先手选择
// 显示游戏规则
printf("游戏规则:\n\n")
printf("54张牌,人和电脑轮流抽,1到4张任选,抽到最后一张牌者败。\n\n")
printf("按任意键继续...\n")
getch()
while (1)
{
CardsRemain = 54
// 确定谁先拿牌
while (1)
{
system("cls")
printf("\n让电脑先拿牌吗?(Y/N)")
c = getch()
if ((c == 'Y') || (c == 'y'))
{
HumanFirst = false
break
}
if ((c == 'N') || (c == 'n'))
{
HumanFirst = true
break
}
}
// 开始游戏
Game(CardsRemain, HumanFirst)
getch()
// 再来一次?
while (1)
{
system("cls")
printf("\n\n不服!再来一次?(Y/N)")
c = getch()
if ((c == 'Y') || (c == 'y'))
break
if ((c == 'N') || (c == 'n'))
return
}
}
}
// 电脑取牌
int ComputerChoice(int CardsRemain)
{
int i
// 拿掉n张,使得剩下张数为 5 的整数倍+1,必胜
switch (CardsRemain % 5)
{
case 1:
while (1) // 拿不到最佳张数,就在 1~4 张之间随机拿, 要确保电脑所拿张数不大于剩余张数
{
i = rand() % 4 + 1
if (i <= CardsRemain)
return i
}
case 0: return 4
default: return (CardsRemain % 5) - 1
}
}
// 人取牌
int HumanChoice(int CardsRemain)
{
int i
while (1)
{
printf("\n请输入要拿掉的张数[1~4]:")
scanf("%d", &i)
if (i >CardsRemain)
continue
if ((i >= 1) &&(i <= 4))
return i
}
}
// 游戏函数
void Game(int CardsRemain, bool HumanFirst)
{
int LastComChoice = 0 // 电脑 上轮拿牌张数
int LastManChoice = 0 // 人 上轮拿牌张数
int Rounds = 0 // 回合数
bool HumansTurn = HumanFirst // 本轮取牌者是 人 还是 电脑。初始值由 HumanFirst 决定
// 初始化随机数
srand(time(0))
system("cls")
// 取牌循环,直到剩下张数为 1
while (CardsRemain >0)
{
if (HumansTurn) // 轮到人拿牌
{
// 想让电脑互P,把这里 HumanChoice 改成 ComputerChoice, 相应输出文字改成电脑1、2就可以了。
LastManChoice = HumanChoice(CardsRemain)
CardsRemain -= LastManChoice
printf("\n你拿走 %d 张,剩 %d 张。\n", LastManChoice, CardsRemain)
if (CardsRemain == 0)
{
printf("\n\n你拿到最后 1 张牌,你输了! 按任意键结束游戏...")
getch()
return
}
}
else // 轮到电脑拿牌
{
LastComChoice = ComputerChoice(CardsRemain)
CardsRemain -= LastComChoice
printf("\n电脑拿走 %d 张,剩 %d 张。\n", LastComChoice, CardsRemain)
if (CardsRemain == 0)
{
printf("\n\n电脑拿到最后 1 张牌,电脑负! 按任意键结束游戏...")
getch()
return
}
}
HumansTurn = !HumansTurn // 更换拿牌者
Rounds++
if ((Rounds % 2) == 0) // 双方各取一次牌为 1 回合
{
if (HumanFirst)
printf("\n第 %d 轮, 人类:%d张 电脑:%d张 剩下:%d张\n", Rounds / 2, LastManChoice, LastComChoice, CardsRemain)
else
printf("\n第 %d 轮, 电脑:%d张 人类:%d张 剩下:%d张\n", Rounds / 2, LastComChoice, LastManChoice, CardsRemain)
printf("--------------------------------------------------\n")
}
}
}