#include<bits/stdc++.h>
using namespace std;
namespace work{
const int maxPlayerNumber = 11;
int n,m,top;//玩家数,牌堆中的牌数,目前的牌堆顶
unordered_map<string,int> transCard;//牌型编号
unordered_map<string,int> transRole;//角色编号
vector<int> cardHeap;//牌堆
int prince = 1,enemy,princePos;//反贼数量和主公数量,主公位置
int Sstate = 0;//场上无懈可击状态
struct Player{
int role,state,health,Psum,Wsum;//玩家角色,装备(是否装备上诸葛连弩),体力值,桃的数量,无懈可击的数量
string endState = "ALIVE";//在场状态(死亡判断)
bool usedKill;//是否在出牌阶段使用了‘杀’
list<int> card;//手牌
}P[maxPlayerNumber];
int emo[maxPlayerNumber];//对每个玩家的态度 (1 - 主公,2 - 跳忠,3 - 跳反,4 - 类反)
void init() {
transRole["MP"] = 1;transRole["ZP"] = 2;transRole["FP"] = 3;
transCard["P"] = 1;transCard["K"] = 2;transCard["D"] = 3;transCard["F"] = 4;
transCard["N"] = 5;transCard["W"] = 6;transCard["J"] = 7;transCard["Z"] = 8;
}
void getData() {
//读数据
cin>>n>>m;
string s;
for(int i = 1;i<=n;i++) {
cin>>s;
P[i].role = transRole[s];
P[i].health = 4;
if(s == "MP") princePos = i;
if(P[i].role == 3) enemy++;
for(int j = 1;j<=4;j++) {
cin>>s;
P[i].card.emplace_back(transCard[s]);
if(s == "P") P[i].Psum++;
}
}
emo[princePos] = 1;
for(int i = 1;i<=m;i++) {
cin>>s;
cardHeap.emplace_back(transCard[s]);
}
}
bool Check() {
//判断局面情况
if(!prince) return -1;
if(!enemy) return 1;
return 0;
}
int now = 1;
void getCard(int player){
//摸牌
if(cardHeap[top] == 1) P[player].Psum++;
if(cardHeap[top] == 7) P[player].Wsum++;
P[player].card.emplace_back(cardHeap[top++]);
if(top == m) top = m - 1;
}
void usePeach(int player) {
//被动使用桃
auto it = P[player].card.begin();
for(;it != P[player].card.end() && P[player].health <= 0;it++) {
if(*it == 1) {
//桃数量减少,生命值增加,移除一枚桃
P[player].Psum--;
P[player].health++;
P[player].card.erase(it);
it--;
}
}
}
void Death(int player,int Damage){
//死亡判定 死亡者 伤害来源
if(P[player].role == 1) prince = 0;
else if(P[player].role == 2 && P[Damage].role == 1) {
//主公 - kill -> 忠臣
P[Damage].state = 0;
P[Damage].Psum = 0;
P[Damage].Wsum = 0;
list<int> emp;
swap(emp,P[Damage].card);
}else if(P[player].role == 3) {
// ? - kill -> 反贼
getCard(Damage);getCard(Damage);getCard(Damage);
}
P[player].endState = "DEAD";
}
void getDamage(int player,int given){
//造成伤害
P[player].health--;
//无力回天 -> 判定死亡
if(P[player].health <= 0 && P[player].Psum + P[player].health <= 0) Death(player,given);
else usePeach(player);//使用桃回血
}
bool useDefence(int player) {
//被动使用闪
auto it = P[player].card.begin();
for(;it != P[player].card.end();it++) {
if(*it == 3) {
P[player].card.erase(it);
return true;
}
}
return false;
}
bool useKill(int player) {
//被动使用杀
auto it = P[player].card.begin();
for(;it != P[player].card.end();it++) {
if(*it == 2) {
P[player].card.erase(it);
return true;
}
}
return false;
}
void Kill(int given,int recieve){
//使用杀
P[given].state = 1;
if(useDefence(recieve)) return;
else getDamage(recieve,given);
//主公身份不需要更改
if(P[given].role == 1) return;
//跳忠/主公 + 反贼 -> 跳反
if((emo[recieve] == 1 || emo[recieve] == 2) && P[given].role == 3) emo[given] = 3;
//跳反 + 忠臣 -> 跳忠
if(emo[recieve] == 3 && P[given].role == 2) emo[given] = 2;
}
void useWatertight(int player,int recieve) {
//使用无懈可击
auto it = P[player].card.begin();
for(;it != P[player].card.end();it++) {
if(*it == 7) {
P[player].card.erase(it);
break;
}
}
Sstate ^= 1;
//无懈 + 非主公 + 主公/跳忠 -> 此人跳忠
if(P[player].role != 1 && (emo[recieve] == 1 || emo[recieve] == 2) && Sstate) emo[player] = 2;
P[player].Wsum--;
}
bool askWatertight(int recieve,int given){
//询问无懈可击
int tag = 0;//响应圈数计数器
int now_given = given;//锦囊发起者
for(int i = now_given;;i++) {
if(i == n + 1) i = 1;
if(i == now_given) tag++;
if(tag == 2) break;//询问 1 圈后没人响应
if(P[i].Wsum) continue;
//注意无懈可击使用后,需重新询问全体成员
//未被无懈状态 + 忠臣 + 跳忠/主公
if(!Sstate && P[i].role == 2 && (emo[recieve] == 1 || emo[recieve] == 2)) {
useWatertight(i,recieve);
tag = 0;
now_given = i;
}
//被无懈 + 忠臣 + 跳反
else if(Sstate && P[i].role == 2 && emo[recieve] == 3) {
useWatertight(i,recieve);
tag = 0;
now_given = i;
}
//被无懈 + 主公 + 跳反/类反
else if(Sstate && P[i].role == 1 && (emo[recieve] == 3 || emo[recieve] == 4)) {
useWatertight(i,recieve);
tag = 0;
now_given = i;
}
}
return Sstate;
}
void Fight(int given,int recieve){
//决斗
if(askWatertight(recieve,given)) return;
if(P[given].role == 1 && P[recieve].role == 2) getDamage(recieve,given);
else {
while(useKill(recieve)) swap(given,recieve);
getDamage(recieve,given);
if(P[given].role == 1) return;
if((emo[recieve] == 1 || emo[recieve] == 2) && P[given].role == 3) emo[given] = 3;
if(emo[recieve] == 3 && P[given].role == 2) emo[given] = 2;
}
}
void SavageAssault(int player){
//南蛮入侵
for(int i = player + 1;i != player;i++) {
//每回合使用无懈可击时刷新场上无懈可击状态
Sstate = 0;
if(i == n + 1) i = 1;
//询问无懈可击
if(askWatertight(i,player)) continue;
//判断是否有‘杀’可以响应
if(!useKill(i)) {
//没有杀,扣血
getDamage(i,player);
//如果让主公掉血,被判断为 ‘类反贼’
if(i == princePos) if(!emo[i]) emo[i] = 4;
}
}
}
void ArcheryAttack(int player){
//万箭齐发
for(int i = player + 1;i != player;i++) {
Sstate = 0;
if(i == n + 1) i = 1;
//询问无懈可击
if(askWatertight(i,player)) continue;
//判断是否有‘闪’可以响应
if(!useDefence(i)) {
//没有闪,扣血
getDamage(i,player);
//如果让主公掉血,被判断为 ‘类反贼’
if(i == princePos) if(!emo[i]) emo[i] = 4;
}
}
}
void use(int player,list<int>::iterator it) {
//使用牌
int card = *it;
if(card == 1 && P[player].health < 4) {
P[player].Psum--;
P[player].health++;
P[player].card.erase(it);
}
else if(card == 2 && ((!P[player].usedKill) || (P[player].state))) {
//使用杀时,只有距离为 1 的位置才能使用,如果没有必要使用就跳过
//只有正向的距离是 1,反向距离不用考虑
for(int i = player + 1;i != player;i++){
if(i == n + 1) i = 1;
if(P[i].health < 0) continue;
if(P[player].role == 1 && (emo[i] == 3 || emo[i] == 4)) {
P[player].card.erase(it);
Kill(player,i);
return;
}else if(P[player].role == 2 && emo[i] == 3) {
P[player].card.erase(it);
Kill(player,i);
return;
}else break;
}
} else if(card == 4) {
//使用决斗
for(int i = player + 1;i != player;i++) {
if(i == n + 1) i = 1;
if(P[i].health < 0) continue;
if(P[player].role == 1 && (emo[i] == 3 || emo[i] == 4)) {
P[player].card.erase(it);
Fight(player,i);
return;
}else if(P[player].role == 2 && emo[i] == 3) {
emo[player] = 2;
P[player].card.erase(it);
Fight(player,i);
return;
}
}
Sstate = 0;
}else if(card == 5) {
//使用南蛮入侵
P[player].card.erase(it);
SavageAssault(player);
Sstate = 0;
}else if(card == 6) {
//使用万箭齐发
P[player].card.erase(it);
ArcheryAttack(player);
Sstate = 0;
}else if(card == 8) {
//装备诸葛连弩
P[player].state = 1;
P[player].card.erase(it);
}
}
void use_The_Card(int player){
//遍历手牌
auto it = P[player].card.begin();
for(;it != P[player].card.end();it++) {
int card = *it;
auto it2 = it;
it++;
use(player,it2);
it--;
if(card == 8) it = P[player].card.begin();
Check();
}
}
void PlayerOption(int player){
//玩家操作
getCard(player);getCard(player);
use_The_Card(player);
P[player].usedKill = 0;
}
void solve(){
getData();
while(!Check()){
if(P[now].health > 0) PlayerOption(now);
now++;
if(now == n + 1) now = 1;
}
//结束局面
if(Check() == 1) {
cout<<"MP\n";
for(int i = 1;i<=n;i++) {
if(P[i].endState == "DEAD") cout<<P[i].endState;
else for(auto j:P[i].card) cout<<j<<" ";
cout<<'\n';
}
}else {
cout<<"FP\n";
for(int i = 1;i<=n;i++) {
if(P[i].endState == "DEAD") cout<<P[i].endState;
else for(auto j:P[i].card) cout<<j<<" ";
cout<<'\n';
}
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
work::init();
work::solve();
return 0;
}