大概就所有东西都封装成函数,看起来优美又好写。
恰好两百行!
#include <cstdio>
#include <cstdlib>
#include <list>
int n, m, id[12], yes[12] = {1}, HP[12], FP;
bool arm[12], master[12];
typedef std::list<char>::iterator iter;
std::list<char> D[12], Card;
std::list<int> Player;
char last;
void Draw(int now)
{
if(!Card.empty()){ D[now].push_back(Card.front()); Card.pop_front(); }
else D[now].push_back(last);
}
int find_sum; char find_value;
bool check(const char &value)
{
if(find_sum && value == find_value)
{
--find_sum;
return 1;
}
return 0;
}
void Report()
{
for(int i = 0; i < n; ++i)
if(HP[i] <= 0) puts("DEAD");
else
{
for(iter j = D[i].begin(); j != D[i].end(); ++j) printf("%c ", *j);
puts("");
}
exit(0);
}
void Drop(int a, int b)
{
--HP[b];
if(HP[b] == 0)
{
find_sum = 1; find_value = 'P';
D[b].remove_if(check);
if(!find_sum){ ++HP[b]; return ; }
if(b == 0){ puts("FP"); Report(); }
if(id[b] == 2 && --FP){ Draw(a); Draw(a); Draw(a); }
if(FP == 0){ puts("MP"); Report(); }
if(id[b] == 1 && a == 0){ D[a].clear(); arm[a] = 0; }
}
}
bool Kill(int now, iter h)
{
find_sum = 1; find_value = 'D';
for(int i = 1; i < n; ++i) if(HP[(i + now) % n] > 0)
{
int v = (i + now) % n;
if(now == 0 && master[v]);
else if(!yes[v] || yes[v] == id[now]) return 0;
yes[now] = id[now]; master[now] = 0;
D[now].erase(h); D[v].remove_if(check);
if(find_sum) Drop(now, v);
return 1;
}
return 0;
}
bool Miss(int now, int pos, bool flag = 0)
{
for(int i = 0; i < n; ++i)
{
int v = (i + now) % n;
if(HP[v] > 0 && ((!flag && id[v] == yes[pos]) || (flag && id[v] != yes[now])))
{
find_sum = 1; find_value = 'J';
D[v].remove_if(check);
if(!find_sum)
{
yes[v] = id[v]; master[v] = 0;
return !Miss(v, now, 1);
}
}
}
return 1;
}
bool Fight(int now, iter h)
{
int pos = -1;
if(id[now] == 2){ pos = 0; yes[now] = id[now]; master[now] = 0; }
else
{
for(int i = 1; i < n; ++i)
{
int v = (i + now) % n;
if(HP[v] > 0 && ((yes[v] && yes[v] != id[now]) || (now == 0 && master[v])))
{
yes[now] = id[now]; master[now] = 0;
pos = v; break;
}
}
if(pos == -1) return 0;
}
D[now].erase(h);
if(!Miss(now, pos)) return 1;
int s1 = 0, s2 = 0;
for(iter i = D[now].begin(); i != D[now].end(); ++i) if(*i == 'K') ++s1;
for(iter i = D[pos].begin(); i != D[pos].end(); ++i) if(*i == 'K') ++s2;
if(now == 0 && id[pos] == 1) s2 = 0;
find_value = 'K';
if(s1 >= s2)
{
find_sum = s2; D[now].remove_if(check);
find_sum = s2; D[pos].remove_if(check);
Drop(now, pos);
}
else
{
find_sum = s1; D[now].remove_if(check);
find_sum = s1 + 1; D[pos].remove_if(check);
Drop(pos, now);
}
return 1;
}
void For_All(int pos, char t)
{
for(int i = 1; i < n; ++i)
{
int v = (i + pos) % n;
if(HP[v] > 0 && Miss(pos, v))
{
find_sum = 1; find_value = t == 'N' ? 'K' : 'D';
D[v].remove_if(check);
if(find_sum)
{
if(v == 0 && !yes[pos]) master[pos] = 1;
Drop(pos, v);
}
}
}
}
void Play(int now)
{
if(HP[now] <= 0) return ;
bool flag, used_kill = 1; int pos;
do
{
flag = 0;
for(iter i = D[now].begin(); i != D[now].end(); ++i)
{
if(*i == 'Z'){ arm[now] = true; D[now].erase(i); flag = 1; break; }
if(*i == 'P' && HP[now] < 4){ D[now].erase(i); ++HP[now]; flag = 1; break; }
if(*i == 'N' || *i == 'W'){ D[now].erase(i); For_All(now, *i); flag = 1; break; }
if(*i == 'F' && Fight(now, i)){ flag = 1; break; }
if(*i == 'K' && (used_kill || arm[now]) && Kill(now, i)){ used_kill = 0; flag = 1; break; }
}
}
while(flag && HP[now] > 0);
}
void Game()
{
if(FP == 0){ puts("MP"); Report(); }
std::list<int>::iterator turn = Player.begin(), cur;
while(1)
{
if(HP[*turn] > 0)
{
Draw(*turn); Draw(*turn);
Play(*turn);
}
cur = turn; ++turn;
if(turn == Player.end()) turn = Player.begin();
if(HP[*cur] <= 0) Player.erase(cur);
}
}
void Import()
{
scanf("%d %d", &n, &m);
char str[5];
for(int i = 0; i < n; ++i)
{
scanf("%s", str);
if(str[0] == 'F'){ id[i] = 2; ++FP; }
else id[i] = 1;
for(int j = 0; j < 4; ++j)
{
scanf("%s", str);
D[i].push_back(str[0]);
}
}
for(int i = 0; i < m; ++i)
{
scanf("%s", str);
Card.push_back(str[0]);
}
last = Card.back();
for(int i = 0; i < n; ++i) HP[i] = 4;
for(int i = 0; i < n; ++i) Player.push_back(i);
}
int main()
{
Import(); Game();
return 0;
}