zoukankan      html  css  js  c++  java
  • Luogu2482 [SDOI2010]猪国杀 模拟

    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. 善用注释
       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
    我永远爱19491001
  • 相关阅读:
    C# HTTP系列9 GET与POST示例
    [译]Android Studio 3.6 新特性概览
    mysql error 1290 hy000:The MySQL server is running with the --skip-grant-tables option so it cannot execute this statemen' 解决方案
    mysql error 1130 hy000:Host 'localhost' is not allowed to connect to this mysql server 解决方案
    Windows+Apache2.4.10+PHP7.0+MySQL5.6.21安装
    php版本的选择
    PHP,Mysql根据经纬度计算距离并排序
    windows无法启动MySQL服务 错误1067
    PHP MYSQL 搜索周边坐标,并计算两个点之间的距离
    html5获取用户当前的地理位置,即经纬度。
  • 原文地址:https://www.cnblogs.com/CreeperLKF/p/9097332.html
Copyright © 2011-2022 走看看