HDU1338/卡片游戏/斗地主/拳王争霸

本文探讨了一种特殊的卡片游戏策略,玩家需要在每轮中选择一张卡片与其他玩家比较,目标是赢得最多轮次。通过将问题转化为两个人的对抗,简化了策略分析。地主的牌面已知并按顺序出牌,其他玩家应选择最大牌对抗,以最大化胜率。文章讨论了两种不同的应对策略,分析了如何在不同情况下做出最优选择。
摘要由CSDN通过智能技术生成

题目:假定包括你一共有M个人在玩一个特殊的卡片游戏,一开始,每个玩家拿N张卡片,卡的点数最多是N*M.而且卡数是互异的,每一轮中,每个玩家选择一张卡和其它玩家比较,谁的点数最大谁就赢得这一轮.然后开始下一轮,在N轮之后,当所有玩家的卡片都选过之后,赢得轮数最多的玩家获胜.给你一开始的卡片,说出你至少赢得多少轮.

这道题让我想起了斗地主/拳王争霸之类的竞技游戏,而且地主的牌面是已知的,其它人联合斗地主,尽他们最大的努力让地主赢的次数最少.

这里有两种思路,前边一种思路比较直观,但是写出来的代码比较汗颜,后一种思路比较优雅,而且写出来的代码也很优雅.先说说最直观的想法.n个人玩n*m张牌,每个人拿m张牌.

首先对地主的牌排序,并且假定地主的出牌顺序就是从小到大的.我们的目标是每次都尽力去赢,当然这并不现实,但是这是最直观的策略.所以,对地主的每一张牌,我们都选择1张比它稍大的牌和(n-2)张小牌去打.这样就可以即保证能赢并且可以保存实力,这是很直观的.但是,万一地主的牌是整副牌最小的,我们也必须打n-1张比它大的牌了.

#include #include #include #include #include #define N 100 int n=0; int Checktoseek(char name[]);//查找 void mainmenu();//菜单 void Register();//登记注册 void Showplayer();//显示当前人物数据 void Showallplayer();//显示所有人物数据 void Chooseopponent();//选择对手 void Chooseplayer(int i);//选择角色 void vs(int i,int j);//PK void Attack(int i,int j);//攻击 void recovery(int i,int j);//防御 void Energy(int i,int j);//能量 struct Kof { char name[20]; int Hp; int AP; int Dp; int Rp; }player[N]; void main() { srand(unsigned(time(NULL))); mainmenu(); } void login() { } void mainmenu() { while(1) { int x; printf("\n"); printf("\n"); printf(" ***************************************************************\n"); printf(" *** ***\n"); printf(" *** ***\n"); printf(" *** 欢迎进入Kof ***\n"); printf(" *** ***\n"); printf(" *** ***\n"); printf(" ***************************************************************\n"); printf("\t\t\t\t\t1----请先注册\n"); printf("\t\t\t\t\t2----查看玩家信息\n"); printf("\t\t\t\t\t3----查看自己信息\n"); printf("\t\t\t\t\t4----选择对手\n"); printf("\t\t\t\t\t5----结束\n"); printf("\n\n请选择菜单:"); scanf("%d",&x); if(x==5) break; switch(x) { case 1:Register();break; case 2:Showallplayer();break; case 3:Showplayer();break; case 4:Chooseopponent();break; } printf("\n\n\n\n\n按任意键继续:"); getch(); system("cls"); } } void Register() { char name[20]; printf("输入名称:"); fflush(stdin); gets(name); if(Checktoseek(name)==-1) { strcpy(player[n].name,name); player[n].Hp=rand()%1000; player[n].AP=rand()%(100+1)+50; player[n].Dp=rand()%(10-5+2)+5; player[n].Rp=rand()%(60+2)+60; n++; printf("人物创建成功\n"); } else { Register(); } } void Showplayer() { char name[20]; printf("角色名:"); fflush(stdin); gets(name); int i=Checktoseek(name); if(i!=-1) { printf("人物名称:%s\n",player[i].name); printf("Hp:%d\n",player[i].Hp); printf("Ap:%d\n",player[i].AP); printf("Dp:%d\n",player[i].Dp); printf("Rp:%d\n",player[i].Rp); } else { printf("请重新输入角色名"); Showplayer(); } } void Showallplayer() { printf("%-10s%-10s%-10s%-10s%-10s\n","Name","Hp","Ap","Dp","Rp"); for(int i=0;i<n;i++) { printf("%-10s%-10d%-10d%-10d%-10d\n",player[i].name,player[i].Hp,player[i].AP,player[i].Dp,player[i].Rp); } } void Chooseopponent() { char name[20]; int i; Showallplayer(); printf("你选择PK谁:"); fflush(stdin); gets(name); i=Checktoseek(name); if(i!=-1) { Chooseplayer(i); } else { printf("你选择PK的人物找不到?\n"); Chooseopponent(); } } int Checktoseek(char name[]) { for(int i=0;i0 && player[j].Hp>0) { printf("第%d局***************\n",count); if(count%2==0) { Attack(i,j); recovery(i,j); Energy(i,j); } else { Attack(j,i); recovery(i,j); Energy(i,j); } count++; _sleep(3344); } if(player[i].Hp>0) { printf("%s Victory \n",player[i].name); } else { printf("%s Winner \n",player[j].name); } printf("******************************\n"); } void Attack(int i,int j) { int x; int s; x=rand()%5; switch(x) { case 0: printf("\n%s发出波动伤害%s\n",player[i].name,player[j].name); s=rand()%100; player[j].Hp-=s; printf("%s受到%d点伤害\n\n",player[j].name,s); break; case 1: printf("\n%s使用连招攻击%s\n",player[i].name,player[j].name); s=rand()%100*2; player[j].Hp-=s; printf("%s受到%d点伤害\n\n",player[j].name,s); break; case 2: printf("\n%s释放超杀技\n",player[i].name); s=(rand()%100)*4; player[j].Hp-=s; printf("%s受到%d点伤害\n\n",player[j].name,s); break; } } void recovery(int i,int j) { int s; int x; s=rand()%3; switch(s) { case 0: printf("\n%s防御%s的攻击\n",player[i].name,player[j].name); x=rand()%(10-5+2)+5; player[i].Dp==x; printf("%s抵挡%d点伤害\n\n",player[i].name,x); break; case 1: printf("\n%s防御%s的攻击\n",player[j].name,player[i].name); x=rand()%(10-5+2)+5; player[j].Dp==x; printf("%s抵挡%d点伤害\n\n",player[j].name,x); break; } } void Energy(int i,int j) { int x; int s; x=rand()%6; switch(x) { case 0: printf("\n%s大怒,使用超必杀技\n",player[i].name); s=(rand()%100)*6; player[j].Hp-=s; printf("%s受到%d点伤害\n\n",player[j].name,s); break; case 1: printf("\n%s大怒,使用超必杀技\n",player[j].name); s=(rand()%100)*6; player[i].Hp-=s; printf("%s受到%d点伤害\n\n",player[i].name,s); break; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Raise

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

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

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

打赏作者

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

抵扣说明:

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

余额充值