造福下后来人
查看原帖
造福下后来人
960410
aru123楼主2023/5/31 20:56

把注释改掉了,可以看整局游戏的出牌、被杀、掉血死亡、摸牌以及跳反跳忠的情况,这样应该会方便您调试一点

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

template <typename T>
inline void read(T &x){
    bool f = 0; x = 0; char c = getchar();
    while(c < '0' || c > '9'){ f = c == '-'; c = getchar();}
    while(c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}
    if(f) x = -x;
}

inline void read(string& s){
    char c = getchar();
    s.clear();
    while(c != EOF && !isblank(c) && c != '\n'){
        s.push_back(c);
        c = getchar();
    }
}

struct card{
    char type;
    card *next, *pre;
    card(char& c, card* pre = nullptr, card* next = nullptr):type(c), next(next), pre(pre){}
};

class Player{
public:
    int Hp = 4, num, hasEnd = 0;
    char type;
    queue<char>* pile;
    bool hasZ = false, hasUsedKill = false, hasShow = false, likelihood = false;
    Player *next = nullptr, *pre = nullptr, *enemy = nullptr, *MP = nullptr;
    card* head_of_cards = nullptr, *nowCard = nullptr;
    card* end_of_cards = nullptr;
    int num_of_ds = 0, num_of_ps = 0, num_of_invunberable = 0, num_of_ks = 0, num_of_fs = 0;
public:
    Player(string& s, int k, Player* pr = nullptr, Player* nxt = nullptr){
        if(pr != nullptr){
            pr->next = this;
            this->pre = pr;
        }
        if(nxt != nullptr){
            nxt->pre = this;
            this->next = nxt;
        }
        type = s[0];
        hasShow = type == 'M';
        num = k;
    }

    void drow(){
        char top = pile->front();
        pile->pop();
        GetCard(top);
        if(pile->empty()){
            pile->emplace(top);
        }
        printf("draw %c\n", top);
    }

    void GetCard(char& c){
        if(c == 'P'){
            num_of_ps ++;
        }
        else if(c == 'J'){
            num_of_invunberable ++;
        }
        else if(c == 'D'){
            num_of_ds ++;
        }
        else if(c == 'K'){
            num_of_ks ++;
        }
        else if(c == 'F'){
            num_of_fs ++;
        }
        if(head_of_cards == nullptr){
            head_of_cards = new card(c);
            end_of_cards = head_of_cards;
        }
        else{
            end_of_cards->next = new card(c, end_of_cards);
            end_of_cards = end_of_cards->next;
        }
    }

    bool CanKill(){
        if((!hasZ && hasUsedKill) || num_of_ks <= 0){
            return false;
        }
        if(type == 'M' && (next->likelihood || (next->hasShow && next->type == 'F'))){
            return true;
        }
        if(type == 'Z' && next->type == 'F' && next->hasShow){
            return true;
        }
        if(type == 'F' && ((next->type == 'Z' && next->hasShow) || next->type == 'M')){
            if(next->type == 'M'){
                hasShow = true;
            }
            return true;
        }
        return false;
    }

    void FindEnemy(){
        enemy = nullptr;
        Player* token = next;
        while(token != this){
            if(type == 'M' && (token->likelihood || (token->hasShow && token->type == 'F'))){
                enemy = token;
                break;
            }
            if(type == 'Z' && token->type == 'F' && token->hasShow){
                enemy = token;
                break;
            }
            if(type == 'F' && token->type == 'M'){
                enemy = token;
                break;
            }
            token = token->next;
        }
    }

    card* FindCard(char type){
        card* token = head_of_cards;
        while(token != nullptr && token -> type != type){
            token = token->next;
        }
        return token;
    }

    void UseCard(){
        nowCard = head_of_cards;
        while(nowCard != nullptr && !hasEnd){
            switch (nowCard->type){
                case 'P':
                    if(Hp < 4){
                        Hp ++;
                        num_of_ps --;
                        ExhaustCard(nowCard);
                    }
                    break;
                case 'K':
                    if(CanKill()){
                        num_of_ks --;
                        ExhaustCard(nowCard);
                        Kill();
                    }
                    break;
                case 'F':
                    if(type == 'Z' || type == 'M'){
                        FindEnemy();
                        if(enemy != nullptr){
                            num_of_fs --;
                            ExhaustCard(nowCard);
                            Fight(this, enemy);
                        }
                    }
                    else{
                        num_of_fs --;
                        ExhaustCard(nowCard);
                        Fight(this, MP);
                    }
                    if(Hp <= 0){
                        nowCard = nullptr;
                    }
                    break;
                case 'W':
                    ExhaustCard(nowCard);
                    Arrow();
                    FindEnemy();
                    if((num_of_fs > 0 && enemy != nullptr) || CanKill()){
                        nowCard = head_of_cards;
                        continue;
                    }
                    break;
                case 'N':
                    ExhaustCard(nowCard);
                    Foreign();
                    FindEnemy();
                    if((num_of_fs > 0 && enemy != nullptr) || CanKill()){
                        nowCard = head_of_cards;
                        continue;
                    }
                    break;
                case 'Z':
                    ExhaustCard(nowCard);
                    hasZ = true;
                    if(CanKill()){
                        nowCard = head_of_cards;
                        continue;
                    }
                    break;
                default:
                    break;
            }
            if(head_of_cards == nullptr){
                nowCard = nullptr;
            }
            if(nowCard != nullptr){
                nowCard = nowCard->next;
            }
        }
        enemy = nullptr;
    }
    
    void ExhaustCard(card* c){
        printf("%d %c use %c\n", num, type, c->type);
        if(c == head_of_cards){
            head_of_cards = head_of_cards->next;
        }
        if(c == end_of_cards){
            end_of_cards = end_of_cards->pre;
        }
        if(c->next != nullptr){
            c->next->pre = c->pre;
        }
        if(c->pre != nullptr){
            c->pre->next = c->next;
        }
        if(c->type == 'P'){
            printf("%c now Hp is %d\n", type, Hp);
        }
    }

    void Kill(){
        hasUsedKill = 1;
        printf("%d %c kill %d %c\n", num, type, next->num, next->type);
        this->next->BeKill('K', this, this);
        if(next->type == 'M'){
            hasShow = 1;
        }
    }

    bool BeKill(char type, Player* owner, Player* owner_of_turn){
        if(type == 'K' && num_of_ds > 0){
            num_of_ds --;
            ExhaustCard(FindCard('D'));
            return false;
        }
        else if(type == 'D' && num_of_ks > 0){
            num_of_ks --;
            ExhaustCard(FindCard('K'));
            return false;
        }
        LossHp(owner, owner_of_turn);
        return true;
    }

    void LossHp(Player* killer, Player* owner_of_turn){
        Hp--;
        printf("%d %c loss Hp, now is %d\n", num, type, Hp);
        if(Hp <= 0){
            if(num_of_ps > 0){
                num_of_ps --;
                Hp ++;
                ExhaustCard(FindCard('P'));
            }
            else{
                Dead(killer, owner_of_turn);
            }
        }
    }

    void check(){
        Player* token = this->next;
        int num_of_F = (type == 'F' && Hp > 0);
        while(token != this){
            num_of_F += (token->type == 'F' && token->Hp > 0);
            token = token -> next;
        }
        if(num_of_F == 0){
            hasEnd = 2;
        }
    }

    void Dead(Player* killer, Player* owner_of_turn){
        printf("%d dead, hs is %c, killed by %d\n", this->num, this->type, killer->num);
        if(this->type == 'F'){
            owner_of_turn->check();
            if(owner_of_turn->hasEnd){
                return ;
            }
        }
        if(type == 'F' && this != killer){
            for(int i = 0; i < 3; i++){
                killer->drow();
            }
            if(owner_of_turn == killer && killer->nowCard->next == nullptr){
                killer->nowCard->next = killer->head_of_cards;
            }
        }
        else if(this->type == 'Z' && killer->type == 'M'){
            killer->hasZ = 0;
            killer->num_of_ds = 0;
            killer->num_of_ps = 0;
            killer->num_of_ks = 0;
            killer->num_of_invunberable = 0;
            killer->head_of_cards = nullptr;
            killer->end_of_cards = nullptr;
        }
        else if(this->type == 'M'){
            owner_of_turn->hasEnd = 1;
            return ;
        }
        this->next->pre = this->pre;
        this->pre->next = this->next;
        if(owner_of_turn != this && owner_of_turn->enemy == this){
            owner_of_turn->FindEnemy();
        }
    };

    void Arrow(){
        Player* token = next;
        while(token != this){
            if(!Invunerable('A', token)){
                if(token->BeKill('K', this, this) && token->type == 'M' && !hasShow){
                    this->likelihood = 1;
                }
                if(hasEnd){
                    return ;
                }
            }
            token = token->next;
        }
    }

    void Foreign(){
        Player* token = next;
        while(token != this){
            if(!Invunerable('N', token)){
                if(token->BeKill('D', this, this) && token->type == 'M' && !hasShow){
                    this->likelihood = 1;
                }
                if(hasEnd){
                    return ;
                }
            }
            token = token->next;
        }
    }

    bool Invunerable(char cType, Player* victim){
        bool res = false;
        Player* token = this;
        auto canUse = [&]()->bool{
            if(token->num_of_invunberable == 0 || !victim->hasShow){
               return false;
            }
            if(cType == 'J'){
                return (this->type == 'F') ^ (token->type == 'F');
            }
            return !((victim->type == 'F') ^ (token->type == 'F'));
        };
        do{
            if(canUse()){
                res = true;
                if(!token->hasShow){
                    printf("%d jumps, he is %c\n", token->num, token->type);
                }
                token->likelihood = 0;
                token->hasShow = 1;
                token->ExhaustCard(token->FindCard('J'));
                token->num_of_invunberable --;
                res ^= token->Invunerable('J', victim);
                break;
            }
            token = token->next;
        }while(token != this);
        return res;
    }

    void Fight(Player* owner, Player* victim){
        owner->hasShow = 1;
        owner->likelihood = 0;
        if(owner->type == 'M' && victim -> type == 'Z'){
            victim->LossHp(owner, owner);
            return ;
        }
        if(!Invunerable('F', victim)){
            while(1){
                if(victim->BeKill('D', owner, owner)){
                    return ;
                }
                if(owner->BeKill('D', victim, owner)){
                    return ;
                }
            }
        }
    }
};

int main(){
    int n, m, k ;
    string p;
    char c;
    cin >> n >> m >> p;
    Player* first = new Player(p, 0), *pre, *now;
    queue<char> pile;
    k = 0;
    while(k < 4){
        c = getchar();
        if(isalpha(c)){
            k++;
            first->GetCard(c);
        }
    }
    pre = first;
    for(int i = 1; i < n; i++){
        cin >> p;
        now = new Player(p, i, pre);
        now->MP = first;
        pre->next = now;
        pre = now;
        k = 0;
        while(k < 4){
            c = getchar();
            if(isalpha(c)){
                k++;
                now->GetCard(c);
            }
        }
    }
    pre->next = first;
    first->pre = pre;
    now = pre;
    k = 0;
    while(k < m){
        c = getchar();
        if(isalpha(c)){
            pile.emplace(c);
            k++;
        }
    }
    Player *token = now;
    do{
        token->pile = &pile;
        token = token->next;
    }while(token != now);
    while(!(now->hasEnd)){
        now = now->next;
        printf("ths turn of %c\n", now->type);
        for(int i = 0; i < 2; i++){
            now->drow();
        }
        now->UseCard();
    }
    if(now->hasEnd == 1){
        printf("FP\n");
    }
    else{
        printf("MP\n");
    }
    token = now;
    vector<string> res(n, string("0"));
    do{
        if(token->Hp > 0){
            card* c = token->head_of_cards;
            res[token->num].clear();
            while(c != nullptr){
                res[token->num].push_back(c->type);
                c = c->next;
            }
        }
        token = token->next;
    }while(token != now);
    for(int i = 0; i < n; i++){
        if(!res[i].empty()){
            if(res[i][0] == '0'){
                printf("DEAD");
            }
            else if(!res[i].empty()){
                int l = res[i].size();
                for(int j = 0; j < l - 1; j++){
                    printf("%c ", res[i][j]);
                }
            printf("%c", res[i][l - 1]);
            }
        }
        if(i != n - 1 || (res[n - 1].empty())){
            printf("\n");
        }
    }
    return 0;
}
2023/5/31 20:56
加载中...