题目链接:https://www.luogu.com.cn/problem/P2482
总结了几个坑点…
(这种改一改都能当课设交的东西真的有人比赛的时候写得出来吗)
- 使用锦囊牌时可能存在跳反或跳忠(打出无懈可击)的情况,一旦出现了有可能要从头检索是否有可使用的杀或决斗
- 装备诸葛连弩时同理;
- 对别人打出决斗自己可能会死,此时需要中断回合;
- 反猪的决斗一定是对主猪用的;
- 主猪杀了忠猪后,弃牌的时候不要忘了诸葛连弩;
- 同时不要忘了此时遍历的手牌已经没了;
- 但是不能直接中断回合,比如忠猪如果死于万箭齐发,那么在它之后还可能有反猪因此死掉,这种情况下主公会摸三张牌,回合仍可能继续;
- 角色死后不要鞭尸,南蛮入侵、万箭齐发等需要遍历玩家的情况记得跳过死者;
- 一有角色死亡就要记得计算距离;
- 距离是单向的;
- 牌堆如果没牌了会持续抽最后一张牌;
- 无懈可击可以无限连;
- 如果自身没有跳反/忠,那么无懈可击也不会对自己用
- 使用过和决斗和无懈可击的角色身份一定是明确的
- 反猪并不会帮助类反猪,如果忠猪被变成了类反猪被主猪决斗了那就只能挨打掉血
- 由于角色死亡可能导致游戏结束,因此每次有角色死透了都要康康死的是不是主公或最后一个反贼
附上Ac代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Player
{
char card[2005];
int mp_sign[15];
int card_num=0,hp=4,card_cur=0,card_st=1;
bool mp,zp,fp,weapon,expose;
int wx,shan,atk;
int uwx,u_shan;
}player[15];
char card[2005];
int n,cur=0,fst_kill,fst_jd;
bool fp_ep,zp_ep;
void get_card(int i,char ch)//获取卡牌
{
player[i].card[++player[i].card_cur]=ch;
++player[i].card_num;
if(ch=='J')
++player[i].wx;
else if(ch=='D')
++player[i].shan;
}
int z_wx(const int &num,const int &n)//主公一派打出无懈
{
for(int k=num,i=0;i<n;++i,k=k+1>n?1:k+1)
{
if(player[k].zp&&player[k].wx!=0&&player[k].hp>0)//活的忠臣
{
if(!player[k].expose)
player[k].expose=zp_ep=true,player[1].mp_sign[k]=1;
--player[k].card_num,--player[k].wx,++player[k].uwx;
return k;
}
else if(player[k].mp&&player[k].wx!=0)//主公
{
--player[k].card_num,--player[k].wx,++player[k].uwx;
return k;
}
}
return -1;
}
int f_wx(const int &num,const int &n)//反贼一派打出无懈
{
for(int k=num,i=0;i<n;++i,k=k+1>n?1:k+1)
{
if(player[k].fp&&player[k].wx!=0&&player[k].hp>0)//活的反贼
{
if(!player[k].expose)
player[k].expose=fp_ep=true,player[1].mp_sign[k]=-1;
--player[k].card_num,--player[k].wx,++player[k].uwx;
return k;
}
}
return -1;
}
void dying(const int &num,const int &m,const int &j)//濒死状态
{
for(int i=player[j].card_st;i<=player[j].card_cur;++i)
{
if(player[j].card[i]=='P')//自救成功
{
++player[j].hp,--player[j].card_num,player[j].card[i]=0;
return ;
}
}
if(player[j].mp)
return ;
int a=-1;
for(int i=j-1>0?j-1:n;i!=j;i=i-1>0?i-1:n) //角色死亡导致距离改变
{
if(player[i].hp>0)
{
a=i;
break;
}
}
for(int i=j+1>n?1:j+1;i!=j;i=i+1>n?1:i+1)
{
if(player[i].hp>0)
{
player[a].atk=i;
break;
}
}
if(player[j].fp)//反贼死亡,击杀者摸牌
{
cur=min(m,cur+1),get_card(num,card[cur]);
cur=min(m,cur+1),get_card(num,card[cur]);
cur=min(m,cur+1),get_card(num,card[cur]);
return ;
}
if(player[j].zp&&player[num].mp)//主公杀死忠臣失去所有手牌
{
player[num].uwx=player[num].u_shan=0;
player[num].card_num=player[num].wx=player[num].shan=0;
player[num].card_st=player[num].card_cur+1;
player[num].weapon=false,fst_jd=fst_kill=0;
return ;
}
}
bool jd(const int &a,const int &b)决斗判定
{
while(true)
{
bool k_left=false;
for(int j=player[b].card_st;j<=player[b].card_cur;++j)
{
if(player[b].card[j]=='K')
{
player[b].card[j]=0,--player[b].card_num,k_left=true;
break;
}
}
if(k_left)
{
k_left=false;
for(int j=player[a].card_st;j<=player[a].card_cur;++j)
{
if(player[a].card[j