Luogu2482 [SDOI2010]猪国杀 ---- 模拟

时间:2024-06-28 23:04:14

Luogu2482 [SDOI2010]猪国杀

题意

......

https://www.luogu.org/problemnew/show/P2482

总结

首先说一下代码的构思:

首先确定了所有的状态表示(例如游戏中游戏结束,不管有没有用),然后确定了所有属性什么的。

然后构思结构体的表达,并且从全局代码考虑需不需要这样设计(因为这个重构了一次,一开始写的结构体内的表示方法代码量大)

然后在结构体内写函数

然后提前分配好一些会用的全局变量,保存状态

然后先把程序入口输入输出写了

然后按照回合分函数,有一个回合分配函数,有一个出牌函数,每张牌都分了主动和被动两种出牌方式,每个函数都带有返回值(后面删掉了一些)

例如无懈可击的发起方有一个Cal_J函数然后去寻找目标,然后在Pas_J中处理猪的关系

例如给扣血的猪“办手续”,从扣血到死亡判定等等

在这中间打好注释,写好调试函数(例如在我的头文件模板中有Debug多参数函数)同时打好assert防止一些不必要的小地方出错(可以用Debug宏)

然后写一些细节函数,例如献殷勤表敌意

然后就是调节代码顺序,调试代码

一些经验吧......

  1. 提前分配好一些比较好的变量名
  2. 建议先声明函数再定义函数
  3. 打开Dev-C++的代码结构或者自己在草稿纸上写结构
  4. 每次调试之前自己浏览一遍代码并手推一遍样例,特别是修改了之后注意自己修改的地方,不要编译了历史版本
  5. 不要写的十分复杂,能简单写简单写
  6. 善用assert
  7. 善用注释
 //Created By Creeper_LKF
//Caution::We used "pragma" in the code
#include <cstdio>
#include <cctype>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream> #ifdef __gnu_linux__ #include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h> #endif #if __cplusplus < 201103L #include <stdarg.h> #endif //Algorithm Heads #include <list>
#include <queue>
#include <vector> using namespace std; //FILE_NAME DEFINATION const char file_name[] = "b"; #define NAME_SPACE
#define USING #ifdef NAME_SPACE
namespace LKF{
#endif
#define SF_READ
#define EOF_READ
// #define NEED_FILE
// #define WRITE_ENDL
// #define FAST_WRITE
const size_t MAX_BUF_SIZE = ; #ifdef FAST_WRITE
char outp[MAX_BUF_SIZE], *op = outp;
#endif #ifdef DONLINE_JUDGE
#undef NEED_FILE
#endif #ifdef FAST_WRITE
#ifndef WRITE_ENDL
#define WRITE_ENDL
#endif
#endif extern inline void FILE_OPT(){
#ifdef NEED_FILE
#define FILE_NAME file_name
char IN_FILE[sizeof(FILE_NAME) + ], OUT_FILE[sizeof(FILE_NAME) + ];
strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME);
strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out");
freopen(IN_FILE, "r", stdin);
freopen(OUT_FILE, "w", stdout);
#endif
} #ifdef __gnu_linux__ char *pc; extern inline void Main_Init(){
static bool INITED = false;
if(INITED){
#ifdef FAST_WRITE
fwrite(outp, , op - outp - , stdout);
#endif
fclose(stdin), fclose(stdout);
} else {
FILE_OPT();
pc = (char *) mmap(NULL, lseek(, , SEEK_END), PROT_READ, MAP_PRIVATE, , );
INITED = true;
}
} #else char buf[MAX_BUF_SIZE], *pc = buf; extern inline void Main_Init(){
static bool INITED = false;
if(INITED){
#ifdef FAST_WRITE
fwrite(outp, , op - outp - , stdout);
#endif
fclose(stdin), fclose(stdout);
} else {
FILE_OPT();
fread(buf, , MAX_BUF_SIZE, stdin);
INITED = true;
}
} #endif #ifdef EOF_READ #ifdef SF_READ template<typename T>
static inline void read(T &num){
num = ;
char c, sf = ;
while(isspace(c = *pc++));
if(c == ) sf = -, c = *pc ++;
while(num = num * + c - , isdigit(c = *pc++));
num *= sf;
} static inline int read(){
int num = ;
char c, sf = ;
while(isspace(c = *pc++));
if(c == ) sf = -, c = *pc ++;
while(num = num * + c - , isdigit(c = *pc++));
return num * sf;
} #else template<typename T>
static inline T read(T &num){
num = ;
char c;
while (isspace(c = *pc++));
while (num = num * + c - , isdigit(c = *pc++));
return num;
} static inline int read(){
int num = ;
char c;
while (isspace(c = *pc++));
while (num = num * + c - , isdigit(c = *pc++));
return num;
} #endif #else #ifdef SF_READ template<typename T>
static inline void read(T &num){
num = ;
char c, sf = ;
while((c = *pc++) < );
if(c == ) sf = -, c = *pc ++;
while(num = num * + c - , (c = *pc++) >= );
num *= sf;
} static inline int read(){
int num = ;
char c, sf = ;
while((c = *pc++) < );
if(c == ) sf = -, c = *pc ++;
while(num = num * + c - , (c = *pc++) >= );
return num * sf;
} #else template<typename T>
static inline T read(T &num){
num = ;
char c;
while ((c = *pc++) < );
while (num = num * + c - , (c = *pc++) >= );
return num;
} static inline int read(){
int num = ;
char c;
while ((c = *pc++) < );
while (num = num * + c - , (c = *pc++) >= );
return num;
} #endif #endif #ifdef FAST_WRITE
template <typename T>
inline void Call_Write(char Split, T tar){
char buf[];
int top = ;
if(tar == ) *op ++ = ;
else {
if(tar < ) *op ++ = '-';
while(tar) buf[++top] = tar % , tar /= ;
while(top) *op ++ = buf[top --] ^ ;
}
*op ++ = Split;
}
template <typename T>
inline void Call_Write(T tar){
char buf[];
int top = ;
if(tar == ) *op ++ = ;
else {
if(tar < ) *op ++ = '-';
while(tar) buf[++top] = tar % , tar /= ;
while(top) *op ++ = buf[top --] ^ ;
}
}
#endif #ifdef FAST_WRITE extern inline void write(){
*op ++ = '\n';
} template<typename T>
extern inline void write(T tar){
Call_Write(tar);
#ifdef WRITE_ENDL
write();
#endif
} #if __cplusplus >= 201103L # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter" template<typename T>
extern inline void write(char Split, T tar){
Call_Write(tar);
#ifdef WRITE_ENDL
write();
#endif
} # pragma GCC diagnostic pop
# pragma message "Warning : pragma used" template<typename Head, typename T, typename... Tail>
extern inline void write(char Split, Head head, T mid, Tail... tail){
Call_Write(Split, head);
write(Split, mid, tail...);
} #else template <typename T>
extern inline void write(char Split, T tar){
Call_Write(tar);
#ifdef WRITE_ENDL
write();
#endif
} #endif #else extern inline void write(){
cout << endl;
} template<typename T>
extern inline void write(T tar){
cout << tar;
#ifdef WRITE_ENDL
write();
#endif
} #if __cplusplus >= 201103L template<typename T>
extern inline void write(char Split, T tar){
cout << tar << Split;
} template<typename Head, typename T, typename... Tail>
extern inline void write(char Split, Head head, T mid, Tail... tail){
cout << head;
write(Split, mid, tail...);
} #else template <typename T>
extern inline void write(char Split, T tar){
cout << tar << Split;
#ifdef WRITE_ENDL
write();
#endif
} #endif #endif template <typename T>
extern inline void upmax(T &x, const T &y){
if(x < y) x = y;
}
template <typename T>
extern inline void upmin(T &x, const T &y){
if(x > y) x = y;
} #if __cplusplus >= 201103L template<typename T>
extern inline T max(T tar){
return tar;
} template<typename T>
extern inline T min(T tar){
return tar;
} template <typename Head, typename T, typename... Tail>
extern inline Head max(Head head, T mid, Tail... tail){
Head tmp = max(mid, tail...);
return head > tmp ? head : tmp;
}
template <typename Head, typename T, typename... Tail>
extern inline Head min(Head head, T mid, Tail... tail){
Head tmp = min(mid, tail...);
return head < tmp ? head : tmp;
} #else template <typename T>
extern inline T max(T a, T b){
return a > b ? a : b;
}
template <typename T>
extern inline T min(T a, T b){
return a < b ? a : b;
} #endif template <typename T>
extern inline T abs(T tar){
return tar < ? -tar : tar;
}
template <typename T>
extern inline void swap(T &a, T &b){
int t = a;
a = b;
b = t;
}
#ifdef NAME_SPACE
}
#endif //Algorithm #ifdef NAME_SPACE
namespace LKF{
#endif template <typename T>
struct Queue{
size_t s, t;
T *q;
Queue(){
s = , t = ;
q = NULL;
}
Queue(size_t siz){
q = (T*)malloc(sizeof(T) * siz);
assert(q != NULL);
}
~Queue(){
delete[] q;
}
inline void clear(){
s = , t = ;
}
inline bool empty(){
return s > t;
}
inline size_t size(){
return t - s + ;
}
inline void push(T tar){
q[++t] = tar;
}
inline void pop_front(){
s++;
}
inline void pop_back(){
t++;
}
inline T front(){
return q[s];
}
inline T back(){
return q[t];
}
}; #ifdef NAME_SPACE
}
#endif #ifdef USING #ifdef NAME_SPACE
using LKF::read;
using LKF::Main_Init;
using LKF::write;
using LKF::upmax;
using LKF::upmin;
using LKF::max;
using LKF::min;
using LKF::abs;
// using LKF::swap;
#else
using ::read;
using ::Main_Init;
using ::write;
using ::upmax;
using ::upmin;
using ::max;
using ::min;
using ::abs;
// using ::swap;
#endif #endif //Source Code using namespace std; typedef list<int> CARD; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Debug_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if DEBUG //Caution: Do Not Inline
//Do Not Open In Dev_CPP void Print_Array(int s, int t, int *arr, string Name){
cout << Name << " Begin" << endl;
for(int i = s; i < t; i++) cout << arr[i] << ' ';
cout << Name << " End" << endl;
} void Print_List(CARD::iterator B, CARD::iterator E, string Name){
cout << Name << " Begin" << endl;
for(CARD::iterator it = B; it != E; it++)
cout << *it << ' ';
cout << Name << " End" << endl;
} #endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Read_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//This is SDOI2010 Killer of Pig Kingdom
//This is Release Version inline char get_c(){
char c;
while(!isalpha(c = *LKF::pc ++));
return c;
} //Caution::
//Do not omit parentheses //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Const_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const int MAXN = , MAXM = ;//数组大小
const int GA = , MA = ;//献殷勤,表敌意
const int ING = , MPG = , FPG = ;//游戏状态
const int MP = , ZP = , AP = ;//人物身份类型IDF,主猪,忠猪,反猪(同时表示主猪位置)
const int NN = , NS = , BZ = , BF = ;//表示状态,未跳,类反猪,跳忠,跳反
const int P = , K = , D = ;//基础类:桃,杀,闪
const int F = , N = , W = , J = ;//技能类:决斗,南蛮入侵,万箭齐发,无懈可击
const int Z = ;//装备类:诸葛连弩
const int FAIL = , SUCCEED = , GAME_OVER = ; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Variable_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int n, m, ReM, HP, FZ, Man_Now;
int Heap[MAXM];
int Game_State; struct Pig{
int IDF, Health, IDS;//身份,血量,表态
int HC_CNT[MAXN], Dis[MAXN];//每种牌统计,距离
bool Death, ST_Z, ST_K;//死亡标记,诸葛连弩装备状态,出杀状态
CARD HC;//要求每次访问之前都有相应元素
Pig(){
Death = false;
Health = ;
IDF = ;
HC.clear();
}
inline void Add(int tar){//摸牌
HC.push_back(tar);
HC_CNT[tar]++;
}
inline int Get(){//出牌
int tar = HC.front();
HC.pop_front();
HC_CNT[tar]--;
return tar;
}
inline int Card(int Knd, int Num){//要求严格存在这些牌
CARD::iterator it;
int tim = ;
for(it = HC.begin(); it != HC.end(); it++){
if(*it == Knd){
HC.erase(it);
HC_CNT[Knd]--;
tim++;
}
if(tim == Num) break;
}
#if DEBUG
assert(tim == Num);
#endif
return tim;
}
}pig[MAXN]; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mini_Function__Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inline int CTI(char tar){
switch(tar){
case 'P' : return P;
case 'K' : return K;
case 'D' : return D;
case 'F' : return F;
case 'N' : return N;
case 'W' : return W;
case 'J' : return J;
case 'Z' : return Z;
}
return ;
} inline char ITC(int tar){
static char ret[] = {, 'P', 'K', 'D', 'F', 'N', 'W', 'J', 'Z', };
return ret[tar];
} inline int Deal_Card(){//不早说
if(HP == m) return Heap[m];
return Heap[++HP];
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Declaring_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inline void Input(); inline void Solve(); inline void Output(); inline int New_Round(int); inline void Reset_Dis(); inline int Kill(int, int); inline int DeaD(int, int); inline int Dec_Health(int, int); inline void Gallant(int, int); inline void Malicious(int, int); //被调用出牌 开始 inline int Pas_P(int);
inline int Pas_K(int, int);
inline int Pas_D(int);
inline int Pas_F(int, int);
inline int Pas_N(int);
inline int Pas_W(int);
inline int Pas_J(int, int, int);
inline int Pas_Z(int); //被调用出牌 结束 //主动出牌 开始 inline int Cal_P(int);
inline int Cal_K(int);
inline int Cal_D(int, int);
inline int Cal_F(int);
inline int Cal_N(int);
inline int Cal_W(int);
inline int Cal_J(int, int, int);
inline int Cal_Z(int); //主动出牌 结束 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int main(){
Main_Init();
Input();
Solve();
Output();
return ;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Function_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inline void Input(){
ReM = n = read(), m = read();
for(int i = ; i <= n; i++){
char idf = get_c();
switch(idf){
case 'M' : pig[i].IDF = MP; break;
case 'Z' : pig[i].IDF = ZP; break;
case 'F' : pig[i].IDF = AP, FZ++; break;
}
get_c();
for(int j = ; j <= ; j++) pig[i].Add(CTI(get_c()));
}
for(int i = ; i <= m; i++) Heap[i] = CTI(get_c());
} inline void Solve(){
if(FZ == ){
Game_State = MPG;
return ;
}
Reset_Dis();
while(Game_State == ING){
Man_Now++;
if(Man_Now == n + ) Man_Now = ;
if(pig[Man_Now].Death) continue;
New_Round(Man_Now);
}
} inline void Output(){
write('\n', Game_State == MPG ? "MP" : "FP");
for(int i = ; i <= n; i++){
if(pig[i].Death) write('\n', "DEAD");
else {
CARD::iterator it;
for(it = pig[i].HC.begin(); it != pig[i].HC.end(); it++){
write(' ', ITC(*it));
}
write();
}
}
} inline int New_Round(int Man){//注意:每次都会重新刷新序列(从头开始)
pig[Man].Add(Deal_Card()), pig[Man].Add(Deal_Card());
pig[Man].ST_K = false;
CARD::iterator it;
int ret = , tar = ;
// Print_List(pig[3].HC.begin(), pig[3].HC.end(), "3");
for(it = pig[Man].HC.begin(); !pig[Man].Death && Game_State == ING && it != pig[Man].HC.end(); ){
tar = *it, ret = ;
switch(tar){
case P : ret = Cal_P(Man); break;
case K : if(!pig[Man].ST_K || pig[Man].ST_Z) ret = bool(Cal_K(Man)), pig[Man].ST_K = ret; break;
// case D : ret = Cal_D(Man); break;
case F : ret = Cal_F(Man); break;
case N : ret = Cal_N(Man), ret = ; break;
case W : ret = Cal_W(Man), ret = ; break;
// case J : ret = Cal_J(Man); break;
case Z : ret = Cal_Z(Man), ret = ; break;
}//要求在各函数内完成牌数统计
if(ret == FAIL) it++;
else it = pig[Man].HC.begin();
}
return SUCCEED;
} inline void Reset_Dis(){
for(int i = ; i <= n; i++){
if(pig[i].Death) continue;
pig[i].Dis[i] = ;
for(int j = i - , dis_now = ReM; j >= ; j--){
if(pig[j].Death) pig[i].Dis[j] = ;
else pig[i].Dis[j] = --dis_now;
}
for(int j = i + , dis_now = ; j <= n; j++){
if(pig[j].Death) pig[i].Dis[j] = ;
else pig[i].Dis[j] = ++dis_now;
}
}
} inline int Dead(int dst, int scr){//返回0表示未死亡,返回1表示死亡,返回2表示游戏结束
if(pig[dst].HC_CNT[P] == ) return bool(Kill(dst, scr)) + ;
Pas_P(dst);
return FAIL;
} inline int Kill(int dst, int scr){//返回0表示游戏继续,返回1表示MP胜利(状态MPG),返回2表示AP胜利(状态FPG)
pig[dst].Death = true;
pig[dst].ST_Z = false;
pig[dst].HC.clear();
for(int i = ; i < ; i++) pig[dst].HC_CNT[i] = ;
ReM--;
if(pig[dst].IDF == MP) return Game_State = FPG;
if(pig[dst].IDF == AP){
FZ --;
if(!FZ) return Game_State = MPG;
pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card());
}
if(pig[dst].IDF == ZP && pig[scr].IDF == MP){
pig[scr].ST_Z = false;
pig[scr].HC.clear();
for(int i = ; i < ; i++) pig[scr].HC_CNT[i] = ;
}
Reset_Dis();
return Game_State = ING;
} inline int Dec_Health(int dst, int scr){//返回0表示未死亡,返回1表示已死亡,返回2表示游戏结束
pig[dst].Health --;
if(pig[dst].Health == ) return Dead(dst, scr);
return FAIL;
} inline void Malicious(int dst, int scr){
if(pig[scr].IDF == MP) return ;
#if DEBUG
if(pig[dst].IDF == MP || pig[dst].IDS == BZ){
assert(pig[scr].IDF != ZP);
pig[scr].IDS = BF;
} else if(pig[dst].IDS == BF){
assert(pig[scr].IDF != AP);
pig[scr].IDS = BZ;
}
#endif
#if !DEBUG
if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BF;
else if(pig[dst].IDS == BF) pig[scr].IDS = BZ;
#endif
} inline void Gallant(int dst, int scr){
if(pig[scr].IDF == MP) return ;
#if DEBUG
if(pig[dst].IDF == MP || pig[dst].IDS == BZ){
assert(pig[scr].IDF != AP);
pig[scr].IDS = BZ;
} else if(pig[dst].IDS == BF){
assert(pig[scr].IDF != ZP);
pig[scr].IDS = BF;
}
#endif
#if !DEBUG
if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BZ;
else if(pig[dst].IDS == BF) pig[scr].IDS = BF;
#endif
} inline int Cal_P(int Man){
if(Pas_P(Man)) return SUCCEED;
return FAIL;
} inline int Pas_P(int Man){//要求每次只加1血
if(pig[Man].Health == || pig[Man].HC_CNT[P] == ) return FAIL;
pig[Man].Card(P, );
pig[Man].Health ++;
return SUCCEED;
} inline int Cal_K(int Man){//主动杀部分
if(pig[Man].IDF == MP){
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death || pig[Man].Dis[j] > ) continue;
if(pig[j].IDS == BF || pig[j].IDS == NS){
Pas_K(j, Man);
return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
}
}
return FAIL;
}
if(pig[Man].IDF == ZP){
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death || pig[Man].Dis[j] > ) continue;
if(pig[j].IDS == BF){
Pas_K(j, Man);
return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
}
}
return FAIL;
}
if(pig[Man].IDF == AP){
if(pig[Man].Dis[MP] <= ){
Pas_K(MP, Man);
return Cal_D(MP, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
}
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death || pig[Man].Dis[j] > ) continue;
if(pig[j].IDF == MP || pig[j].IDS == BZ){
Pas_K(j, Man);
return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;
}
}
return FAIL;
}
return FAIL;
} inline int Pas_K(int dst, int scr){//允许对id=0的猪判断身份
if(dst) Malicious(dst, scr);
if(pig[scr].HC_CNT[K] == ) return FAIL;
pig[scr].Card(K, );
return SUCCEED;
} inline int Cal_D(int dst, int scr){
if(Pas_D(dst) == FAIL) return Dec_Health(dst, scr);
return FAIL;
} inline int Pas_D(int dst){//注意要求dst的方向与K不同
if(pig[dst].HC_CNT[D] == ) return FAIL;
pig[dst].Card(D, );
return SUCCEED;
} inline int Cal_F(int Man){//返回是否成功出牌
if(pig[Man].IDF == MP){
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDS == BF || pig[j].IDS == NS){
return Pas_F(j, Man), SUCCEED;
}
}
return FAIL;
}
if(pig[Man].IDF == ZP){
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDS == BF){
return Pas_F(j, Man), SUCCEED;
}
}
return FAIL;
}
if(pig[Man].IDF == AP){//直接表主猪
return Pas_F(MP, Man), SUCCEED;
/*for(int i = 1; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == MP || pig[j].IDS == BZ){
return Pas_F(j, Man);
}
}
return FAIL;*/
}
return FAIL;
} inline int Pas_F(int dst, int scr){//返回scr出杀的数量
Malicious(dst, scr);
pig[scr].Card(F, );
if(Cal_J(dst, scr, GA)) return FAIL;
#if DEBUG
assert(!(pig[dst].IDF == MP && pig[scr].IDF == ZP));
#endif
if(pig[dst].IDF == ZP && pig[scr].IDF == MP) return Dec_Health(dst, scr), ;//主猪与忠猪的故事
int ret = ;
while(true){
if(Pas_K(, dst) == FAIL) return Dec_Health(dst, scr), ret;
if(Pas_K(, scr) == FAIL) return Dec_Health(scr, dst), ret;//WTF???
ret++;
}
} inline int Cal_J(int dst, int scr, int State){//使用无懈可击的发起方(枚举)是对接收方献殷勤还是表敌意,scr用于枚举起点
if(State == GA){//献殷勤,要求同边。注意逻辑不同,这里是枚举发起方,发起方知道自己的身份
if(pig[dst].IDF == MP){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == MP || pig[j].IDF == ZP){
if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
} else if(pig[dst].IDS == BZ){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == ZP || pig[j].IDF == MP){
if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
} else if(pig[dst].IDS == BF){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == AP){
if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
}
} else {
if(pig[dst].IDF == MP){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == AP){
if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
} else if(pig[dst].IDS == BZ){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == AP){
if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
} else if(pig[dst].IDS == BF){
for(int i = ; i < n; i++){
int j = scr + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(pig[j].IDF == MP || pig[j].IDF == ZP){
if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;
}
}
return FAIL;
} else if(pig[dst].IDS == NS){//主猪对类反猪表敌意
if(Pas_J(dst, MP, MA)) return Cal_J(MP, MP, MA) ? FAIL : SUCCEED;
return FAIL;
}
}
return FAIL;
} inline int Pas_J(int dst, int scr, int State){
if(pig[scr].HC_CNT[J] == ) return FAIL;
if(State == GA) Gallant(dst, scr);
else Malicious(dst, scr);
pig[scr].Card(J, );
return SUCCEED;
} inline int Cal_N(int Man){
assert(Pas_N(Man));
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(Cal_J(j, Man, GA) == SUCCEED) continue;
if(Pas_K(, j) == FAIL){
if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER;
if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS;
}
}
return SUCCEED;
} inline int Pas_N(int dst){
if(pig[dst].HC_CNT[N] == ) return FAIL;
pig[dst].Card(N, );
return SUCCEED;
} inline int Cal_W(int Man){
assert(Pas_W(Man));
for(int i = ; i < n; i++){
int j = Man + i;
if(j > n) j = j - n;
if(pig[j].Death) continue;
if(Cal_J(j, Man, GA) == SUCCEED) continue;
if(Pas_D(j) == FAIL){
if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER;
if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS;
}
}
return SUCCEED;
} inline int Pas_W(int dst){
if(pig[dst].HC_CNT[W] == ) return FAIL;
pig[dst].Card(W, );
return SUCCEED;
} inline int Cal_Z(int Man){
return Pas_Z(Man);
} inline int Pas_Z(int dst){
if(pig[dst].HC_CNT[Z] == ) return FAIL;
pig[dst].ST_Z = true;
pig[dst].Card(Z, );
return SUCCEED;
}

Source Code