#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 102
struct MONSTER{
int W,A,cur_H,max_H,E;
string name;
};
struct ITEM{
string cat;
int num;
string eff;
};
map<string,int> mp;
string acc_effect[]={"HR","RE","CO","EX","EX","HU","CU"};
bool finish;
MONSTER monster_arr[MAXN][MAXN];
ITEM item_arr[MAXN][MAXN];
char arr[MAXN][MAXN];
string dirs;
int N,M;
int sx,sy;
int dx[] = {0,0,-1,1};
int dy[] = {-1,1,0,0};
struct STATUS{
int x,y;
int level;
int cur_hp;
int max_hp;
int att;
int w_att;
int def;
int a_def;
int cur_exp,max_exp;
int death;
string death_info;
STATUS(){
level = 1;
cur_hp = max_hp = 20;
att = def = 2;
max_exp = 5;
w_att = a_def = cur_exp =death = 0;
};
bool acc[8];
int acc_cnt;
void check_status(){
// 전투했을시
if (arr[x][y]=='&' || arr[x][y] =='M'){
MONSTER m = monster_arr[x][y];
// 사망한 경우
if (cur_hp<=0){
if (acc[mp["RE"]]){
acc[mp["RE"]]=false;
acc_cnt--;
x = sx;
y = sy;
m.cur_H = m.max_H;
cur_hp = max_hp;
}
else {
cur_hp = 0;
finish = true;
death = 1;
death_info = m.name;
}
}
// 몬스터가 죽은 경우
else{
if (acc[mp["EX"]]) cur_exp +=1.2*m.E;
else cur_exp += m.E;
if (arr[x][y] =='M'){
finish = true;
}
arr[x][y] = '.';
if (acc[mp["HR"]]){
cur_hp = min(cur_hp+3,max_hp);
}
}
}
// 가시함정
else if (arr[x][y] == '^'){
if (cur_hp <=0){
if (acc[mp["RE"]]){
acc[mp["RE"]] = false;
acc_cnt--;
x = sx;
y = sy;
cur_hp = max_hp;
}
else {
cur_hp = 0;
finish = true;
death = 1;
death_info = "SPIKE TRAP";
}
}
}
else if (arr[x][y] =='B') arr[x][y]='.';
// 레벨업 시
if (cur_exp >= max_exp){
level++;
cur_exp = 0;
max_exp = level*5;
max_hp +=5;
att +=2;
def += 2;
cur_hp = max_hp;
}
}
};
STATUS ch;
bool is_range(int x, int y){
return (x>=0 && y>=0 && x <N && y <M);
}
void fight(MONSTER m,int mode){
int idx = 0;
if (mode == 1 && ch.acc[mp["HU"]]) ch.cur_hp = ch.max_hp;
while (!(ch.cur_hp<=0 || m.cur_H <=0)){
if (!idx&& ch.acc[mp["CO"]]){
if (ch.acc[mp["DX"]]) {
m.cur_H-= max(1,(ch.att+ch.w_att)*3-m.A);
}
else m.cur_H -= max(1,(ch.att+ch.w_att)*2-m.A);
}
else{
if (idx%2==0){
m.cur_H -= max(1,(ch.att+ch.w_att)-m.A);
}
else{
if (!(mode==1 && idx==1 && ch.acc[mp["HU"]])) ch.cur_hp -= max(1,(m.W-(ch.def+ch.a_def)));
}
}
idx++;
}
}
void equip(ITEM item){
if (item.cat == "A"){
ch.a_def = item.num;
}
else if (item.cat == "W"){
ch.w_att = item.num;
}
else{
if (ch.acc_cnt>=4 || ch.acc[mp[item.eff]]) return;
ch.acc[mp[item.eff]] = true;
ch.acc_cnt++;
}
}
void go(int dir){
int nx = ch.x + dx[dir];
int ny = ch.y + dy[dir];
if (!is_range(nx,ny)|| arr[nx][ny]=='#') nx = ch.x,ny=ch.y;
// 몬스터 만나는 경우
if (arr[nx][ny]=='&'){
fight(monster_arr[nx][ny],0);
}
// 보스 만나는 경우
else if (arr[nx][ny] =='M'){
fight(monster_arr[nx][ny],1);
}
// 아이템 상자 만나는 경우
else if (arr[nx][ny] == 'B'){
equip(item_arr[nx][ny]);
}
// 가시함정 만나는 경우
else if (arr[nx][ny] == '^'){
if (ch.acc[mp["DX"]]) ch.cur_hp--;
else ch.cur_hp-=5;
}
ch.x = nx;
ch.y = ny;
ch.check_status();
}
int main(){
ios::sync_with_stdio(false);
for (int i = 0 ;i < 7; i++){
mp[acc_effect[i]] = i+1;
}
cin >> N >> M;
int m_cnt = 0;
int b_cnt = 0;
for (int i = 0;i<N ;i++){
cin >> arr[i];
for (int j =0 ; j < M; j++){
if (arr[i][j]=='@'){
ch.x = i;
ch.y = j;
sx = i;
sy = j;
arr[i][j] = '.';
}
else if (arr[i][j] == '&'|| arr[i][j] =='M'){
m_cnt++;
}
else if (arr[i][j] =='B') b_cnt++;
}
}
cin >> dirs;
while (m_cnt--){
int x,y,W,A,H,E;
string name;
cin >> x >> y >> name >> W >> A >> H >> E;
x--;
y--;
monster_arr[x][y]={W,A,H,H,E,name};
}
while (b_cnt--){
int x,y;
string cat;
cin >> x >> y >> cat;
x--;
y--;
if (cat=="W" || cat == "A"){
int num;
cin >> num;
item_arr[x][y]={cat,num,""};
}
else{
string eff;
cin >> eff;
item_arr[x][y]={cat,0,eff};
}
}
int i;
for (i = 0 ; i < dirs.size()&&!finish; i++){
int dir;
if (dirs[i] == 'L') dir = 0;
else if (dirs[i] =='R') dir = 1;
else if (dirs[i] == 'U') dir=2;
else dir = 3;
go(dir);
}
if (!(finish &&ch.death)) arr[ch.x][ch.y] = '@';
for (int j = 0;j< N; j++){
for (int k = 0 ;k<M; k++){
cout << arr[j][k] ;
}
cout <<"\n";
}
cout << "Passed Turns : "<< i <<"\n";
cout << "LV : " << ch.level<<"\n";
cout << "HP : " << ch.cur_hp <<"/"<<ch.max_hp<<"\n";
cout << "ATT : " << ch.att <<"+"<<ch.w_att<<"\n";
cout << "DEF : " << ch.def <<"+" << ch.a_def <<"\n";
cout << "EXP : " << ch.cur_exp <<"/"<<ch.max_exp<<"\n";
if (!finish){
cout << "Press any key to continue.";
}
else{
if (ch.death){
cout << "YOU HAVE BEEN KILLED BY " << ch.death_info <<"..";
}
else{
cout <<"YOU WIN!";
}
}
return 0;
}