题目简述:
这是一道非常善良的凉心模拟题。。。
<身份>:
主猪(主公):MP
忠猪(忠臣):ZP
反猪(反贼):FP
<基本牌>:
杀:K
闪:D
桃:P
<锦囊牌>:
万箭齐发:W
南猪入侵:N
无懈可击:J
决斗:F
<装备牌>:
猪哥连弩:Z
- 以上各牌用法与三国杀相同
<概念>
伤害来源: 杀、南猪入侵、决斗、万箭齐发的伤害来源均是使用该牌的猪
距离: 相邻玩家距离为1,一个角色的死亡会导致一些猪距离的改变(具体规则与三国杀相同)
死亡: 降到0或者更低,并且自己手中没有足够的桃使得自己的体力值回到1
奖励与惩罚:反猪死亡时,最后一个伤害来源处(即使是反猪)立即摸三张牌;忠猪死亡时,如果最后一个伤害来源是主猪,那么主猪所有装备牌、手牌被弃置
结束 : 一旦达成胜利条件,游戏立刻结束,其余不用执行了
弃置: 被弃置的牌以后都不能再用,即与游戏无关
<回合>
摸牌阶段: 放到手牌的最右边
出牌阶段: 可以使用0张到任意张牌,每次使用最靠左的能够使用的牌,如果没有猪哥连弩,每个出牌阶段只能使用一次“杀”来攻击,任何牌被使用后被弃置(武器是装备上)
<行为>
献殷勤:使用无懈可击挡下南猪入侵、万箭齐发、决斗;使用无懈可击抵消表敌意
表敌意:对某个角色使用杀、决斗;使用无懈可击抵消献殷勤
忠猪不会跳反,反猪也不会跳忠;不管是忠猪还是反猪,能够跳必然跳
<注意>
共性:
-
每个角色如果手里有桃且生命值未满,那么必然吃掉;
-
有南猪入侵、万箭齐发、必然使用;
-
有装备必然装上;
-
受到杀时,有闪必然弃置;
-
响应南猪入侵或者万箭齐发时候,有杀/闪必然弃置;
-
不会对未表明身份的猪献殷勤(包括自己)
特性·忠猪:
- 对于每种表敌意的方式,对逆时针方向能够执行到的第一只已经跳反的猪表
- 决斗时,如果对方是主猪,那么不会弃置杀,否则,会不遗余力弃置杀
特性·反猪:
- 对于每种表敌意的方式,如果有机会则对主猪表;否则,对逆时针方向能够执行到的第一只已经跳忠的猪表;
- 决斗时会不遗余力弃置杀;
- 如果有机会对已经跳反的猪献殷勤,那么一定献;
暴力解析:
我们要做的是,按照题目所说的规则,一步一步模拟出这场游戏的结果。
注:这道题的详细解析已放入代码中。
代码最重要:
#include <bits/stdc++.h>
using namespace std;
const int N = 2100;
struct ACF {
int last, next, cardans; // cardans为卡牌数量
char card[N], id; //card为卡牌,id为身份
int life; //当前生命值
bool Zhuge_Repeating_crossbow; //是否装备诸葛连弩
}a[N] = {
};
char king[N], sumcard[N], s[N]; //king 表示主猪眼里的这只猪的身份,'U'表示未表态,'M'表示友好;sumcard表示卡堆中的牌,s只是一个输入道具
bool ed = 0; //判断是否有哪一方胜利,以便退出游戏
int n, m, kkkk = 0;
int fz = 0; //反猪的数目
bool wxkj(int x1,int x2,int x3) {
//【无懈可击】
int i = x1;
while (1) {
if (x3 == 1) {
if (king[x2] == a[i].id || (king[x2] == 'M' && a[i].id == 'Z') || (king[x2] == 'Z' && a[i].id == 'M'))
{
//假如是敌对的那就【无懈可击】掉
// cout<<endl<<"kkk"<<" ";
// if (a[i].life>0)
for (int j=1;j<=a[i].cardans;j++)
if (a[i].card[j] == 'J') {
a[i].card[j]='U';
king[i]=a[i].id;
return !wxkj(i,x1,0);
}
}
}
else {
if (((a[i].id == 'M' || a[i].id == 'Z') && king[x1] == 'F') || (a[i].id == 'F' && (king[x1] == 'M' || king[x1] == 'Z')))
{
// cout<<endl<<"yyy"<<" ";
// if (a[i].life>0)
for (int j=1;j<=a[i].cardans;j++)
if(a[i].card[j] == 'J') {
a[i].card[j]='U';
king[i]=a[i].id;
return !wxkj(i,x1,0);
}
}
}
i = a[i].next;
if (i == x1) break;
//没有人会(可用【无懈可击】抵挡此【无懈可击】那么这张牌就生效
}
return false;
}
void touch_card(int x) {
//摸牌
if (!m) m++; //数据有个Bug,当牌堆没牌时,会持续摸最后一张牌
a[x