Luogu2482 [SDOI2010]豬國殺 ---- 模擬

Luogu2482 [SDOI2010]豬國殺

題意

......linux

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

總結

首先說一下代碼的構思:c++

首先肯定了全部的狀態表示(例如遊戲中游戲結束,無論有沒有用),而後肯定了全部屬性什麼的。git

而後構思結構體的表達,而且從全局代碼考慮需不須要這樣設計(由於這個重構了一次,一開始寫的結構體內的表示方法代碼量大)數組

而後在結構體內寫函數dom

而後提早分配好一些會用的全局變量,保存狀態ide

而後先把程序入口輸入輸出寫了函數

而後按照回合分函數,有一個回合分配函數,有一個出牌函數,每張牌都分了主動和被動兩種出牌方式,每一個函數都帶有返回值(後面刪掉了一些)spa

例如無懈可擊的發起方有一個Cal_J函數而後去尋找目標,而後在Pas_J中處理豬的關係設計

例如給扣血的豬「辦手續」,從扣血到死亡斷定等等

在這中間打好註釋,寫好調試函數(例如在個人頭文件模板中有Debug多參數函數)同時打好assert防止一些沒必要要的小地方出錯(能夠用Debug宏)

而後寫一些細節函數,例如獻殷勤表敵意

而後就是調節代碼順序,調試代碼

一些經驗吧......

  1. 提早分配好一些比較好的變量名
  2. 建議先聲明函數再定義函數
  3. 打開Dev-C++的代碼結構或者本身在草稿紙上寫結構
  4. 每次調試以前本身瀏覽一遍代碼並手推一遍樣例,特別是修改了以後注意本身修改的地方,不要編譯了歷史版本
  5. 不要寫的十分複雜,能簡單寫簡單寫
  6. 善用assert
  7. 善用註釋
 1 //Created By Creeper_LKF  2 //Caution::We used "pragma" in the code
 3 #include <cstdio>
 4 #include <cctype>
 5 #include <cassert>
 6 #include <cstdlib>
 7 #include <cstring>
 8 #include <iostream>
 9 
 10 #ifdef __gnu_linux__  11 
 12 #include <fcntl.h>
 13 #include <unistd.h>
 14 #include <sys/mman.h>
 15 
 16 #endif
 17 
 18 #if __cplusplus < 201103L
 19 
 20 #include <stdarg.h>
 21 
 22 #endif
 23 
 24 //Algorithm Heads
 25 
 26 #include <list>
 27 #include <queue>
 28 #include <vector>
 29 
 30 using namespace std;  31 
 32 //FILE_NAME DEFINATION
 33 
 34 const char file_name[] = "b";  35 
 36 #define NAME_SPACE
 37 #define USING
 38 
 39 #ifdef NAME_SPACE  40 namespace LKF{  41 #endif
 42     #define SF_READ
 43     #define EOF_READ
 44     // #define NEED_FILE  45     // #define WRITE_ENDL  46     // #define FAST_WRITE
 47     const size_t MAX_BUF_SIZE = 50000000;  48 
 49  #ifdef FAST_WRITE  50     char outp[MAX_BUF_SIZE], *op = outp;  51     #endif
 52 
 53  #ifdef DONLINE_JUDGE  54     #undef NEED_FILE
 55     #endif    
 56 
 57  #ifdef FAST_WRITE  58  #ifndef WRITE_ENDL  59     #define WRITE_ENDL
 60     #endif
 61     #endif
 62 
 63     extern inline void FILE_OPT(){  64  #ifdef NEED_FILE  65         #define FILE_NAME file_name
 66         char IN_FILE[sizeof(FILE_NAME) + 5], OUT_FILE[sizeof(FILE_NAME) + 5];  67  strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME);  68         strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out");  69         freopen(IN_FILE, "r", stdin);  70         freopen(OUT_FILE, "w", stdout);  71         #endif      
 72  }  73 
 74  #ifdef __gnu_linux__  75 
 76     char *pc;  77 
 78     extern inline void Main_Init(){  79         static bool INITED = false;  80         if(INITED){  81  #ifdef FAST_WRITE  82             fwrite(outp, 1, op - outp - 1, stdout);  83             #endif
 84  fclose(stdin), fclose(stdout);  85         } else {  86  FILE_OPT();  87             pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0);  88             INITED = true;  89  }  90  }  91 
 92     #else
 93 
 94     char buf[MAX_BUF_SIZE], *pc = buf;  95 
 96     extern inline void Main_Init(){  97         static bool INITED = false;  98         if(INITED){  99  #ifdef FAST_WRITE  100             fwrite(outp, 1, op - outp - 1, stdout);  101             #endif
 102  fclose(stdin), fclose(stdout);  103         } else {  104  FILE_OPT();  105             fread(buf, 1, MAX_BUF_SIZE, stdin);  106             INITED = true;  107  }  108  }  109 
 110     #endif
 111 
 112  #ifdef EOF_READ  113 
 114  #ifdef SF_READ  115 
 116     template<typename T>
 117     static inline void read(T &num){  118         num = 0;  119         char c, sf = 1;  120         while(isspace(c = *pc++));  121         if(c == 45) sf = -1, c = *pc ++;  122         while(num = num * 10 + c - 48, isdigit(c = *pc++));  123         num *= sf;  124  }  125 
 126     static inline int read(){  127         int num = 0;  128         char c, sf = 1;  129         while(isspace(c = *pc++));  130         if(c == 45) sf = -1, c = *pc ++;  131         while(num = num * 10 + c - 48, isdigit(c = *pc++));  132         return num * sf;  133  }  134 
 135     #else
 136 
 137     template<typename T>
 138     static inline T read(T &num){  139         num = 0;  140         char c;  141         while (isspace(c = *pc++));  142         while (num = num * 10 + c - 48, isdigit(c = *pc++));  143         return num;  144  }  145 
 146     static inline int read(){  147         int num = 0;  148         char c;  149         while (isspace(c = *pc++));  150         while (num = num * 10 + c - 48, isdigit(c = *pc++));  151         return num;  152  }  153 
 154     #endif
 155 
 156     #else
 157 
 158  #ifdef SF_READ  159 
 160     template<typename T>
 161     static inline void read(T &num){  162         num = 0;  163         char c, sf = 1;  164         while((c = *pc++) < 45);  165         if(c == 45) sf = -1, c = *pc ++;  166         while(num = num * 10 + c - 48, (c = *pc++) >= 48);  167         num *= sf;  168  }  169 
 170     static inline int read(){  171         int num = 0;  172         char c, sf = 1;  173         while((c = *pc++) < 45);  174         if(c == 45) sf = -1, c = *pc ++;  175         while(num = num * 10 + c - 48, (c = *pc++) >= 48);  176         return num * sf;  177  }  178 
 179     #else
 180 
 181     template<typename T>
 182     static inline T read(T &num){  183         num = 0;  184         char c;  185         while ((c = *pc++) < 48);  186         while (num = num * 10 + c - 48, (c = *pc++) >= 48);  187         return num;  188  }  189 
 190     static inline int read(){  191         int num = 0;  192         char c;  193         while ((c = *pc++) < 48);  194         while (num = num * 10 + c - 48, (c = *pc++) >= 48);  195         return num;  196  }  197 
 198     #endif
 199 
 200     #endif
 201 
 202  #ifdef FAST_WRITE  203     template <typename T>
 204     inline void Call_Write(char Split, T tar){  205         char buf[20];  206         int top = 0;  207         if(tar == 0) *op ++ = 48;  208         else {  209             if(tar < 0) *op ++ = '-';  210             while(tar) buf[++top] = tar % 10, tar /= 10;  211             while(top) *op ++ = buf[top --] ^ 48;  212  }  213         *op ++ = Split;  214  }  215     template <typename T>
 216     inline void Call_Write(T tar){  217         char buf[20];  218         int top = 0;  219         if(tar == 0) *op ++ = 48;  220         else {  221             if(tar < 0) *op ++ = '-';  222             while(tar) buf[++top] = tar % 10, tar /= 10;  223             while(top) *op ++ = buf[top --] ^ 48;  224  }  225  }  226     #endif
 227 
 228  #ifdef FAST_WRITE  229 
 230     extern inline void write(){  231         *op ++ = '\n';  232  }  233 
 234     template<typename T>
 235     extern inline void write(T tar){  236  Call_Write(tar);  237  #ifdef WRITE_ENDL  238  write();  239         #endif
 240  }  241 
 242     #if __cplusplus >= 201103L
 243 
 244  # pragma GCC diagnostic push  245     # pragma GCC diagnostic ignored "-Wunused-parameter"
 246 
 247     template<typename T>
 248     extern inline void write(char Split, T tar){  249  Call_Write(tar);  250  #ifdef WRITE_ENDL  251  write();  252         #endif
 253  }  254 
 255  # pragma GCC diagnostic pop  256     # pragma message "Warning : pragma used"
 257 
 258     template<typename Head, typename T, typename... Tail>
 259     extern inline void write(char Split, Head head, T mid, Tail... tail){  260  Call_Write(Split, head);  261  write(Split, mid, tail...);  262  }  263 
 264     #else
 265 
 266     template <typename T>
 267     extern inline void write(char Split, T tar){  268  Call_Write(tar);  269  #ifdef WRITE_ENDL  270  write();  271         #endif
 272  }  273 
 274     #endif
 275 
 276     #else
 277 
 278     extern inline void write(){  279         cout << endl;  280  }  281 
 282     template<typename T>
 283     extern inline void write(T tar){  284         cout << tar;  285  #ifdef WRITE_ENDL  286  write();  287         #endif
 288  }  289 
 290     #if __cplusplus >= 201103L
 291 
 292     template<typename T>
 293     extern inline void write(char Split, T tar){  294         cout << tar << Split;  295  }  296 
 297     template<typename Head, typename T, typename... Tail>
 298     extern inline void write(char Split, Head head, T mid, Tail... tail){  299         cout << head;  300  write(Split, mid, tail...);  301  }  302 
 303     #else
 304 
 305     template <typename T>
 306     extern inline void write(char Split, T tar){  307         cout << tar << Split;  308  #ifdef WRITE_ENDL  309  write();  310         #endif
 311  }  312 
 313     #endif
 314 
 315     #endif
 316 
 317     template <typename T>
 318     extern inline void upmax(T &x, const T &y){  319         if(x < y) x = y;  320  }  321     template <typename T>
 322     extern inline void upmin(T &x, const T &y){  323         if(x > y) x = y;  324  }  325 
 326     #if __cplusplus >= 201103L
 327 
 328     template<typename T>
 329     extern inline T max(T tar){  330         return tar;  331  }  332 
 333     template<typename T>
 334     extern inline T min(T tar){  335         return tar;  336  }  337 
 338     template <typename Head, typename T, typename... Tail>
 339     extern inline Head max(Head head, T mid, Tail... tail){  340         Head tmp = max(mid, tail...);  341         return head > tmp ? head : tmp;  342  }  343     template <typename Head, typename T, typename... Tail>
 344     extern inline Head min(Head head, T mid, Tail... tail){  345         Head tmp = min(mid, tail...);  346         return head < tmp ? head : tmp;  347  }  348 
 349     #else
 350 
 351     template <typename T>
 352     extern inline T max(T a, T b){  353         return a > b ? a : b;  354  }  355     template <typename T>
 356     extern inline T min(T a, T b){  357         return a < b ? a : b;  358  }  359 
 360     #endif
 361 
 362     template <typename T>
 363     extern inline T abs(T tar){  364         return tar < 0 ? -tar : tar;  365  }  366     template <typename T>
 367     extern inline void swap(T &a, T &b){  368         int t = a;  369         a = b;  370         b = t;  371  }  372 #ifdef NAME_SPACE  373 }  374 #endif
 375 
 376 //Algorithm
 377 
 378 #ifdef NAME_SPACE  379 namespace LKF{  380 #endif
 381 
 382     template <typename T>
 383     struct Queue{  384  size_t s, t;  385         T *q;  386  Queue(){  387             s = 1, t = 0;  388             q = NULL;  389  }  390  Queue(size_t siz){  391             q = (T*)malloc(sizeof(T) * siz);  392             assert(q != NULL);  393  }  394         ~Queue(){  395             delete[] q;  396  }  397         inline void clear(){  398             s = 1, t = 0;  399  }  400         inline bool empty(){  401             return s > t;  402  }  403  inline size_t size(){  404             return t - s + 1;  405  }  406         inline void push(T tar){  407             q[++t] = tar;  408  }  409         inline void pop_front(){  410             s++;  411  }  412         inline void pop_back(){  413             t++;  414  }  415  inline T front(){  416             return q[s];  417  }  418  inline T back(){  419             return q[t];  420  }  421  };  422 
 423 #ifdef NAME_SPACE  424 }  425 #endif
 426 
 427 #ifdef USING  428 
 429 #ifdef NAME_SPACE  430 using LKF::read;  431 using LKF::Main_Init;  432 using LKF::write;  433 using LKF::upmax;  434 using LKF::upmin;  435 using LKF::max;  436 using LKF::min;  437 using LKF::abs;  438 // using LKF::swap;
 439 #else
 440 using ::read;  441 using ::Main_Init;  442 using ::write;  443 using ::upmax;  444 using ::upmin;  445 using ::max;  446 using ::min;  447 using ::abs;  448 // using ::swap;
 449 #endif
 450 
 451 #endif
 452 
 453 //Source Code
 454 
 455 using namespace std;  456 
 457 typedef list<int> CARD;  458 
 459 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Debug_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 460 #if DEBUG
 461 
 462 //Caution: Do Not Inline  463 //Do Not Open In Dev_CPP
 464 
 465 void Print_Array(int s, int t, int *arr, string Name){  466     cout << Name << " Begin" << endl;  467     for(int i = s; i < t; i++) cout << arr[i] << ' ';  468     cout << Name << " End" << endl;  469 }  470 
 471 void Print_List(CARD::iterator B, CARD::iterator E, string Name){  472     cout << Name << " Begin" << endl;  473     for(CARD::iterator it = B; it != E; it++)  474         cout << *it << ' ';  475     cout << Name << " End" << endl;  476 }  477 
 478 
 479 #endif
 480 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Read_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  481 //This is SDOI2010 Killer of Pig Kingdom  482 //This is Release Version
 483 
 484 inline char get_c(){  485     char c;  486     while(!isalpha(c = *LKF::pc ++));  487     return c;  488 }  489 
 490 //Caution::  491 //Do not omit parentheses  492 
 493 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Const_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 494 
 495 const int MAXN = 15, MAXM = 2018;//數組大小
 496 const int GA = 0, MA = 1;//獻殷勤,表敵意
 497 const int ING = 0, MPG = 1, FPG = 2;//遊戲狀態
 498 const int MP = 1, ZP = 2, AP = 3;//人物身份類型IDF,主豬,忠豬,反豬(同時表示主豬位置)
 499 const int NN = 0, NS = 1, BZ = 2, BF = 3;//表示狀態,未跳,類反豬,跳忠,跳反
 500 const int P = 1, K = 2, D = 3;//基礎類:桃,殺,閃
 501 const int F = 4, N = 5, W = 6, J = 7;//技能類:決鬥,南蠻入侵,萬箭齊發,無懈可擊
 502 const int Z = 8;//裝備類:諸葛連弩
 503 const int FAIL = 0, SUCCEED = 1, GAME_OVER = 2;  504 
 505 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Variable_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 506 
 507 int n, m, ReM, HP, FZ, Man_Now;  508 int Heap[MAXM];  509 int Game_State;  510 
 511 struct Pig{  512     int IDF, Health, IDS;//身份,血量,表態
 513     int HC_CNT[MAXN], Dis[MAXN];//每種牌統計,距離
 514     bool Death, ST_Z, ST_K;//死亡標記,諸葛連弩裝備狀態,出殺狀態
 515     CARD HC;//要求每次訪問以前都有相應元素
 516  Pig(){  517         Death = false;  518         Health = 4;  519         IDF = 0;  520  HC.clear();  521  }  522     inline void Add(int tar){//摸牌
 523  HC.push_back(tar);  524         HC_CNT[tar]++;  525  }  526     inline int Get(){//出牌
 527         int tar = HC.front();  528  HC.pop_front();  529         HC_CNT[tar]--;  530         return tar;  531  }  532     inline int Card(int Knd, int Num){//要求嚴格存在這些牌
 533  CARD::iterator it;  534         int tim = 0;  535         for(it = HC.begin(); it != HC.end(); it++){  536             if(*it == Knd){  537  HC.erase(it);  538                 HC_CNT[Knd]--;  539                 tim++;  540  }  541             if(tim == Num) break;  542  }  543         #if DEBUG
 544         assert(tim == Num);  545         #endif
 546         return tim;  547  }  548 }pig[MAXN];  549 
 550 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mini_Function__Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 551 
 552 inline int CTI(char tar){  553     switch(tar){  554         case 'P' : return P;  555         case 'K' : return K;  556         case 'D' : return D;  557         case 'F' : return F;  558         case 'N' : return N;  559         case 'W' : return W;  560         case 'J' : return J;  561         case 'Z' : return Z;  562  }  563     return 0;  564 }  565 
 566 inline char ITC(int tar){  567     static char ret[10] = {0, 'P', 'K', 'D', 'F', 'N', 'W', 'J', 'Z', 0};  568     return ret[tar];  569 }  570 
 571 inline int Deal_Card(){//不早說
 572     if(HP == m) return Heap[m];  573     return Heap[++HP];  574 }  575 
 576 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Declaring_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 577 
 578 inline void Input();  579 
 580 inline void Solve();  581 
 582 inline void Output();  583 
 584 inline int New_Round(int);  585 
 586 inline void Reset_Dis();  587 
 588 inline int Kill(int, int);  589 
 590 inline int DeaD(int, int);  591 
 592 inline int Dec_Health(int, int);  593 
 594 inline void Gallant(int, int);  595 
 596 inline void Malicious(int, int);  597 
 598 //被調用出牌 開始
 599 
 600 inline int Pas_P(int);  601 inline int Pas_K(int, int);  602 inline int Pas_D(int);  603 inline int Pas_F(int, int);  604 inline int Pas_N(int);  605 inline int Pas_W(int);  606 inline int Pas_J(int, int, int);  607 inline int Pas_Z(int);  608 
 609 //被調用出牌 結束  610 
 611 //主動出牌 開始
 612 
 613 inline int Cal_P(int);  614 inline int Cal_K(int);  615 inline int Cal_D(int, int);  616 inline int Cal_F(int);  617 inline int Cal_N(int);  618 inline int Cal_W(int);  619 inline int Cal_J(int, int, int);  620 inline int Cal_Z(int);  621 
 622 //主動出牌 結束  623 
 624 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Main_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 625 
 626 int main(){  627  Main_Init();  628  Input();  629  Solve();  630  Output();  631     return 0;  632 }  633 
 634 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Function_Part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 635 
 636 inline void Input(){  637     ReM = n = read(), m = read();  638     for(int i = 1; i <= n; i++){  639         char idf = get_c();  640         switch(idf){  641             case 'M' : pig[i].IDF = MP; break;  642             case 'Z' : pig[i].IDF = ZP; break;  643             case 'F' : pig[i].IDF = AP, FZ++; break;  644  }  645  get_c();  646         for(int j = 1; j <= 4; j++) pig[i].Add(CTI(get_c()));  647  }  648     for(int i = 1; i <= m; i++) Heap[i] = CTI(get_c());  649 }  650 
 651 inline void Solve(){  652     if(FZ == 0){  653         Game_State = MPG;  654         return ;  655  }  656  Reset_Dis();  657     while(Game_State == ING){  658         Man_Now++;  659         if(Man_Now == n + 1) Man_Now = 1;  660         if(pig[Man_Now].Death) continue;  661  New_Round(Man_Now);  662  }  663 }  664 
 665 inline void Output(){  666     write('\n', Game_State == MPG ? "MP" : "FP");  667     for(int i = 1; i <= n; i++){  668         if(pig[i].Death) write('\n', "DEAD");  669         else {  670  CARD::iterator it;  671             for(it = pig[i].HC.begin(); it != pig[i].HC.end(); it++){  672                 write(' ', ITC(*it));  673  }  674  write();  675  }  676  }  677 }  678 
 679 inline int New_Round(int Man){//注意:每次都會從新刷新序列(從頭開始)
 680  pig[Man].Add(Deal_Card()), pig[Man].Add(Deal_Card());  681     pig[Man].ST_K = false;  682  CARD::iterator it;  683     int ret = 0, tar = 0;  684 // Print_List(pig[3].HC.begin(), pig[3].HC.end(), "3");
 685     for(it = pig[Man].HC.begin(); !pig[Man].Death && Game_State == ING && it != pig[Man].HC.end(); ){  686         tar = *it, ret = 0;  687         switch(tar){  688             case P : ret = Cal_P(Man); break;  689             case K : if(!pig[Man].ST_K || pig[Man].ST_Z) ret = bool(Cal_K(Man)), pig[Man].ST_K = ret; break;  690             // case D : ret = Cal_D(Man); break;
 691             case F : ret = Cal_F(Man); break;  692             case N : ret = Cal_N(Man), ret = 1; break;  693             case W : ret = Cal_W(Man), ret = 1; break;  694             // case J : ret = Cal_J(Man); break;
 695             case Z : ret = Cal_Z(Man), ret = 1; break;  696         }//要求在各函數內完成牌數統計
 697         if(ret == FAIL) it++;  698         else it = pig[Man].HC.begin();  699  }  700     return SUCCEED;  701 }  702 
 703 inline void Reset_Dis(){  704     for(int i = 1; i <= n; i++){  705         if(pig[i].Death) continue;  706         pig[i].Dis[i] = 0;  707         for(int j = i - 1, dis_now = ReM; j >= 1; j--){  708             if(pig[j].Death) pig[i].Dis[j] = 0;  709             else pig[i].Dis[j] = --dis_now;  710  }  711         for(int j = i + 1, dis_now = 0; j <= n; j++){  712             if(pig[j].Death) pig[i].Dis[j] = 0;  713             else pig[i].Dis[j] = ++dis_now;  714  }  715  }  716 }  717 
 718 inline int Dead(int dst, int scr){//返回0表示未死亡,返回1表示死亡,返回2表示遊戲結束
 719     if(pig[dst].HC_CNT[P] == 0) return bool(Kill(dst, scr)) + 1;  720  Pas_P(dst);  721     return FAIL;  722 }  723 
 724 inline int Kill(int dst, int scr){//返回0表示遊戲繼續,返回1表示MP勝利(狀態MPG),返回2表示AP勝利(狀態FPG)
 725     pig[dst].Death = true;  726     pig[dst].ST_Z = false;  727  pig[dst].HC.clear();  728     for(int i = 1; i < 10; i++) pig[dst].HC_CNT[i] = 0;  729     ReM--;  730     if(pig[dst].IDF == MP) return Game_State = FPG;  731     if(pig[dst].IDF == AP){  732         FZ --;  733         if(!FZ) return Game_State = MPG;  734  pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card()), pig[scr].Add(Deal_Card());  735  }  736     if(pig[dst].IDF == ZP && pig[scr].IDF == MP){  737         pig[scr].ST_Z = false;  738  pig[scr].HC.clear();  739         for(int i = 1; i < 10; i++) pig[scr].HC_CNT[i] = 0;  740  }  741  Reset_Dis();  742     return Game_State = ING;  743 }  744 
 745 inline int Dec_Health(int dst, int scr){//返回0表示未死亡,返回1表示已死亡,返回2表示遊戲結束
 746     pig[dst].Health --;  747     if(pig[dst].Health == 0) return Dead(dst, scr);  748     return FAIL;  749 }  750 
 751 inline void Malicious(int dst, int scr){  752     if(pig[scr].IDF == MP) return ;  753     #if DEBUG
 754     if(pig[dst].IDF == MP || pig[dst].IDS == BZ){  755         assert(pig[scr].IDF != ZP);  756         pig[scr].IDS = BF;  757     } else if(pig[dst].IDS == BF){  758         assert(pig[scr].IDF != AP);  759         pig[scr].IDS = BZ;  760  }  761     #endif
 762     #if !DEBUG
 763     if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BF;  764     else if(pig[dst].IDS == BF) pig[scr].IDS = BZ;  765     #endif
 766 }  767 
 768 inline void Gallant(int dst, int scr){  769     if(pig[scr].IDF == MP) return ;  770     #if DEBUG
 771     if(pig[dst].IDF == MP || pig[dst].IDS == BZ){  772         assert(pig[scr].IDF != AP);  773         pig[scr].IDS = BZ;  774     } else if(pig[dst].IDS == BF){  775         assert(pig[scr].IDF != ZP);  776         pig[scr].IDS = BF;  777  }  778     #endif
 779     #if !DEBUG
 780     if(pig[dst].IDF == MP || pig[dst].IDS == BZ) pig[scr].IDS = BZ;  781     else if(pig[dst].IDS == BF) pig[scr].IDS = BF;  782     #endif
 783 }  784 
 785 inline int Cal_P(int Man){  786     if(Pas_P(Man)) return SUCCEED;  787     return FAIL;  788 }  789 
 790 inline int Pas_P(int Man){//要求每次只加1血 
 791     if(pig[Man].Health == 4 || pig[Man].HC_CNT[P] == 0) return FAIL;  792     pig[Man].Card(P, 1);  793     pig[Man].Health ++;  794     return SUCCEED;  795 }  796 
 797 inline int Cal_K(int Man){//主動殺部分
 798     if(pig[Man].IDF == MP){  799         for(int i = 1; i < n; i++){  800             int j = Man + i;  801             if(j > n) j = j - n;  802             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;  803             if(pig[j].IDS == BF || pig[j].IDS == NS){  804  Pas_K(j, Man);  805                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;  806  }  807  }  808         return FAIL;  809  }  810     if(pig[Man].IDF == ZP){  811         for(int i = 1; i < n; i++){  812             int j = Man + i;  813             if(j > n) j = j - n;  814             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;  815             if(pig[j].IDS == BF){  816  Pas_K(j, Man);  817                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;  818  }  819  }  820         return FAIL;  821  }  822     if(pig[Man].IDF == AP){  823         if(pig[Man].Dis[MP] <= 1){  824  Pas_K(MP, Man);  825             return Cal_D(MP, Man) == GAME_OVER ? GAME_OVER : SUCCEED;  826  }  827         for(int i = 1; i < n; i++){  828             int j = Man + i;  829             if(j > n) j = j - n;  830             if(pig[j].Death || pig[Man].Dis[j] > 1) continue;  831             if(pig[j].IDF == MP || pig[j].IDS == BZ){  832  Pas_K(j, Man);  833                 return Cal_D(j, Man) == GAME_OVER ? GAME_OVER : SUCCEED;  834  }  835  }  836         return FAIL;  837  }  838     return FAIL;  839 }  840 
 841 inline int Pas_K(int dst, int scr){//容許對id=0的豬判斷身份
 842     if(dst) Malicious(dst, scr);  843     if(pig[scr].HC_CNT[K] == 0) return FAIL;  844     pig[scr].Card(K, 1);  845     return SUCCEED;  846 }  847 
 848 inline int Cal_D(int dst, int scr){  849     if(Pas_D(dst) == FAIL) return Dec_Health(dst, scr);  850     return FAIL;  851 }  852 
 853 inline int Pas_D(int dst){//注意要求dst的方向與K不一樣
 854     if(pig[dst].HC_CNT[D] == 0) return FAIL;  855     pig[dst].Card(D, 1);  856     return SUCCEED;  857 }  858 
 859 inline int Cal_F(int Man){//返回是否成功出牌
 860     if(pig[Man].IDF == MP){  861         for(int i = 1; i < n; i++){  862             int j = Man + i;  863             if(j > n) j = j - n;  864             if(pig[j].Death) continue;  865             if(pig[j].IDS == BF || pig[j].IDS == NS){  866                 return Pas_F(j, Man), SUCCEED;  867  }  868  }  869         return FAIL;  870  }  871     if(pig[Man].IDF == ZP){  872         for(int i = 1; i < n; i++){  873             int j = Man + i;  874             if(j > n) j = j - n;  875             if(pig[j].Death) continue;  876             if(pig[j].IDS == BF){  877                 return Pas_F(j, Man), SUCCEED;  878  }  879  }  880         return FAIL;  881  }  882     if(pig[Man].IDF == AP){//直接表主豬
 883         return Pas_F(MP, Man), SUCCEED;  884         /*for(int i = 1; i < n; i++){  885  int j = Man + i;  886  if(j > n) j = j - n;  887  if(pig[j].Death) continue;  888  if(pig[j].IDF == MP || pig[j].IDS == BZ){  889  return Pas_F(j, Man);  890  }  891  }  892  return FAIL;*/
 893  }  894     return FAIL;  895 }  896 
 897 inline int Pas_F(int dst, int scr){//返回scr出殺的數量
 898  Malicious(dst, scr);  899     pig[scr].Card(F, 1);  900     if(Cal_J(dst, scr, GA)) return FAIL;  901     #if DEBUG
 902     assert(!(pig[dst].IDF == MP && pig[scr].IDF == ZP));  903     #endif
 904     if(pig[dst].IDF == ZP && pig[scr].IDF == MP) return Dec_Health(dst, scr), 0;//主豬與忠豬的故事
 905     int ret = 0;  906     while(true){  907         if(Pas_K(0, dst) == FAIL) return Dec_Health(dst, scr), ret;  908         if(Pas_K(0, scr) == FAIL) return Dec_Health(scr, dst), ret;//WTF???
 909         ret++;  910  }  911 }  912 
 913 inline int Cal_J(int dst, int scr, int State){//使用無懈可擊的發起方(枚舉)是對接收方獻殷勤仍是表敵意,scr用於枚舉起點
 914     if(State == GA){//獻殷勤,要求同邊。注意邏輯不一樣,這裏是枚舉發起方,發起方知道本身的身份
 915         if(pig[dst].IDF == MP){  916             for(int i = 0; i < n; i++){  917                 int j = scr + i;  918                 if(j > n) j = j - n;  919                 if(pig[j].Death) continue;  920                 if(pig[j].IDF == MP || pig[j].IDF == ZP){  921                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  922  }  923  }  924             return FAIL;  925         } else if(pig[dst].IDS == BZ){  926             for(int i = 0; i < n; i++){  927                 int j = scr + i;  928                 if(j > n) j = j - n;  929                 if(pig[j].Death) continue;  930                 if(pig[j].IDF == ZP || pig[j].IDF == MP){  931                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  932  }  933  }  934             return FAIL;  935         } else if(pig[dst].IDS == BF){  936             for(int i = 0; i < n; i++){  937                 int j = scr + i;  938                 if(j > n) j = j - n;  939                 if(pig[j].Death) continue;  940                 if(pig[j].IDF == AP){  941                     if(Pas_J(dst, j, GA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  942  }  943  }  944             return FAIL;  945  }  946     } else {  947         if(pig[dst].IDF == MP){  948             for(int i = 0; i < n; i++){  949                 int j = scr + i;  950                 if(j > n) j = j - n;  951                 if(pig[j].Death) continue;  952                 if(pig[j].IDF == AP){  953                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  954  }  955  }  956             return FAIL;  957         } else if(pig[dst].IDS == BZ){  958             for(int i = 0; i < n; i++){  959                 int j = scr + i;  960                 if(j > n) j = j - n;  961                 if(pig[j].Death) continue;  962                 if(pig[j].IDF == AP){  963                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  964  }  965  }  966             return FAIL;  967         } else if(pig[dst].IDS == BF){  968             for(int i = 0; i < n; i++){  969                 int j = scr + i;  970                 if(j > n) j = j - n;  971                 if(pig[j].Death) continue;  972                 if(pig[j].IDF == MP || pig[j].IDF == ZP){  973                     if(Pas_J(dst, j, MA)) return Cal_J(j, j, MA) ? FAIL : SUCCEED;  974  }  975  }  976             return FAIL;  977         } else if(pig[dst].IDS == NS){//主豬對類反豬表敵意
 978             if(Pas_J(dst, MP, MA)) return Cal_J(MP, MP, MA) ? FAIL : SUCCEED;  979             return FAIL;  980  }  981  }  982     return FAIL;  983 }  984 
 985 inline int Pas_J(int dst, int scr, int State){  986     if(pig[scr].HC_CNT[J] == 0) return FAIL;  987     if(State == GA) Gallant(dst, scr);  988     else Malicious(dst, scr);  989     pig[scr].Card(J, 1);  990     return SUCCEED;  991 }  992 
 993 inline int Cal_N(int Man){  994  assert(Pas_N(Man));  995     for(int i = 1; i < n; i++){  996         int j = Man + i;  997         if(j > n) j = j - n;  998         if(pig[j].Death) continue;  999         if(Cal_J(j, Man, GA) == SUCCEED) continue; 1000         if(Pas_K(0, j) == FAIL){ 1001             if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER; 1002             if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS; 1003  } 1004  } 1005     return SUCCEED; 1006 } 1007 
1008 inline int Pas_N(int dst){ 1009     if(pig[dst].HC_CNT[N] == 0) return FAIL; 1010     pig[dst].Card(N, 1); 1011     return SUCCEED; 1012 } 1013 
1014 inline int Cal_W(int Man){ 1015  assert(Pas_W(Man)); 1016     for(int i = 1; i < n; i++){ 1017         int j = Man + i; 1018         if(j > n) j = j - n; 1019         if(pig[j].Death) continue; 1020         if(Cal_J(j, Man, GA) == SUCCEED) continue; 1021         if(Pas_D(j) == FAIL){ 1022             if(Dec_Health(j, Man) == GAME_OVER) return GAME_OVER; 1023             if(j == MP && pig[Man].IDS == NN) pig[Man].IDS = NS; 1024  } 1025  } 1026     return SUCCEED; 1027 } 1028 
1029 inline int Pas_W(int dst){ 1030     if(pig[dst].HC_CNT[W] == 0) return FAIL; 1031     pig[dst].Card(W, 1); 1032     return SUCCEED; 1033 } 1034 
1035 inline int Cal_Z(int Man){ 1036     return Pas_Z(Man); 1037 } 1038 
1039 inline int Pas_Z(int dst){ 1040     if(pig[dst].HC_CNT[Z] == 0) return FAIL; 1041     pig[dst].ST_Z = true; 1042     pig[dst].Card(Z, 1); 1043     return SUCCEED; 1044 }
Source Code
相關文章
相關標籤/搜索