Sechack
[BOJ/백준] 17081번 - RPG Extreme 본문
반응형
https://www.acmicpc.net/problem/17081
별다른 알고리즘은 필요없다. 코딩 능력만 있으면 누구나 도전해볼만 하다. 하지만 RPG게임의 요소를 직접 구현해야 하는 빡구현 문제라서 오로지 구현만으로 티어가 플래티넘 2인 문제이다. 문제 보고나서 초중딩 시절에 C언어 가지고 이것저것 해본 경험 살려서 하면 금방 풀 것 같았고 플래티넘 2를 날먹할 수 있을것 같았다. 그래서 구현했는데 너무 급하게 구현한 탓인지 테케는 다 맞는데 제출만 하면 seg fault터졌고 지인의 도움을 빌려서 seg fault잡으니까 틀렸습니다가 계속 떴다. 결론은 너무 코딩을 빠르게 해서 여러 군데에서 자잘한 논리적인 실수가 있었던 것이었고 프로그램 구조나 구현 방식 자체에는 문제가 없었다. 아무튼 지인 도움 받아서 자잘한 구현 미스를 잡으니까 풀렸다. 개발 경험 좀 있는 사람들은 쉽게 풀 것 같다.
https://www.acmicpc.net/board/view/96496
seg fault가 터진 시점에 게시판에 올린 질문도 있다.
아래는 전체 소스코드이다.
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#include <tuple>
#include<cassert>
using namespace std;
typedef struct _player {
int x;
int y;
int lv;
int hp;
int maxhp;
int att;
int plusatt;
int def;
int plusdef;
int exp;
int maxexp;
string items[4];
}player;
typedef struct _monster {
bool boss;
int x;
int y;
string name;
int att;
int def;
int hp;
int maxhp;
int exp;
}monster;
typedef struct _item {
int x;
int y;
string attr;
int att;
int def;
}item;
player p;
vector<monster> monlist;
vector<item> itemlist;
int n, m, sx, sy;
char mov(vector<vector<char>>& map, char cmd) {
if (cmd == 'L') {
if (p.x - 1 >= 0 && map[p.y][p.x - 1] != '#') p.x--;
}
else if (cmd == 'R') {
if (p.x + 1 < m && map[p.y][p.x + 1] != '#') p.x++;
}
else if (cmd == 'U') {
if (p.y - 1 >= 0 && map[p.y - 1][p.x] != '#') p.y--;
}
else {
if (p.y + 1 < n && map[p.y + 1][p.x] != '#') p.y++;
}
return map[p.y][p.x];
}
void insitem(string a) {
int c = 0;
while (p.items[c][0]) {
if (p.items[c] == a) return;
c++;
if(c >= 4) break;
}
if(c < 4) p.items[c] = a;
}
void getitem(vector<vector<char>>& map, int x, int y) {
int idx;
for (int i = 0; i < itemlist.size(); i++)
if (itemlist[i].x == x && itemlist[i].y == y) { idx = i; break; }
if (itemlist[idx].attr[0] == 'W') p.plusatt = itemlist[idx].att;
else if (itemlist[idx].attr[0] == 'A') p.plusdef = itemlist[idx].def;
else insitem(itemlist[idx].attr);
map[y][x] = '.';
}
void levelup() {
p.lv++;
p.maxhp += 5;
p.att += 2;
p.def += 2;
p.hp = p.maxhp;
p.maxexp = p.lv * 5;
p.exp = 0;
}
string fight(vector<vector<char>>& map, int x, int y) {
int idx, c = 0;
bool db = false;
bool tp = false;
bool pexp = false;
bool hu = false;
string ret = "\x7f\x7f";
for (int i = 0; i < monlist.size(); i++)
if (monlist[i].x == x && monlist[i].y == y) { idx = i; break; }
for (int i = 0; i < 4; i++) {
if (p.items[i] == "CO") {
db = true;
break;
}
}
for (int i = 0; i < 4; i++) {
if (p.items[i] == "DX") {
tp = true;
break;
}
}
if (monlist[idx].boss) {
for (int i = 0; i < 4; i++) {
if (p.items[i] == "HU") {
p.hp = p.maxhp;
hu = true;
}
}
}
if (tp && db) {
monlist[idx].hp -= max(1, (p.att + p.plusatt) * 3 - monlist[idx].def);
if (monlist[idx].hp <= 0) {
monlist[idx].hp = 0;
map[y][x] = '.';
for (int i = 0; i < 4; i++) {
if (p.items[i] == "HR") {
p.hp = min(p.hp + 3, p.maxhp);
break;
}
}
for (int i = 0; i < 4; i++) {
if (p.items[i] == "EX") {
pexp = true;
break;
}
}
if (pexp) {
p.exp += monlist[idx].exp * 1.2;
if (p.exp >= p.maxexp) levelup();
}
else {
p.exp += monlist[idx].exp;
if (p.exp >= p.maxexp) levelup();
}
}
c++;
}
else if (db) {
monlist[idx].hp -= max(1, (p.att + p.plusatt) * 2 - monlist[idx].def);
if (monlist[idx].hp <= 0) {
monlist[idx].hp = 0;
map[y][x] = '.';
for (int i = 0; i < 4; i++) {
if (p.items[i] == "HR") {
p.hp = min(p.hp + 3, p.maxhp);
break;
}
}
for (int i = 0; i < 4; i++) {
if (p.items[i] == "EX") {
pexp = true;
break;
}
}
if (pexp) {
p.exp += monlist[idx].exp * 1.2;
if (p.exp >= p.maxexp) levelup();
}
else {
p.exp += monlist[idx].exp;
if (p.exp >= p.maxexp) levelup();
}
}
c++;
}
while (monlist[idx].hp && p.hp) {
if (c % 2) {
if (hu) { hu = false; }
else p.hp -= max(1, monlist[idx].att - (p.def + p.plusdef));
if (p.hp <= 0) {
p.hp = 0;
for (int i = 0; i < 4; i++) {
if (p.items[i] == "RE") {
p.x = sx;
p.y = sy;
p.hp = p.maxhp;
monlist[idx].hp = monlist[idx].maxhp;
p.items[i] = "\x00\x00";
return ret;
}
}
}
}
else {
monlist[idx].hp -= max(1, p.att + p.plusatt - monlist[idx].def);
if (monlist[idx].hp <= 0) {
monlist[idx].hp = 0;
map[y][x] = '.';
for (int i = 0; i < 4; i++) {
if (p.items[i] == "HR") {
p.hp = min(p.hp + 3, p.maxhp);
break;
}
}
for (int i = 0; i < 4; i++) {
if (p.items[i] == "EX") {
pexp = true;
break;
}
}
if (pexp) {
p.exp += monlist[idx].exp * 1.2;
if (p.exp >= p.maxexp) levelup();
}
else {
p.exp += monlist[idx].exp;
if (p.exp >= p.maxexp) levelup();
}
}
}
c++;
}
return monlist[idx].name;
}
void infoprint(vector<vector<char>>& map, int turn) {
bool live = true;
if (p.hp <= 0) live = false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (live && (p.y == i && p.x == j)) cout << '@';
else if (map[i][j] == '@') cout << '.';
else cout << map[i][j];
}
cout << "\n";
}
cout << "Passed Turns : " << turn << "\n";
cout << "LV : " << p.lv << "\n";
cout << "HP : " << max(0, p.hp) << '/' << p.maxhp << "\n";
cout << "ATT : " << p.att << '+' << p.plusatt << "\n";
cout << "DEF : " << p.def << '+' << p.plusdef << "\n";
cout << "EXP : " << p.exp << '/' << p.maxexp << "\n";
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL);
p.lv = 1;
p.hp = 20;
p.maxhp = 20;
p.att = 2;
p.def = 2;
p.plusatt = 0;
p.plusdef = 0;
p.exp = 0;
p.maxexp = p.lv * 5;
for (int i = 0; i < 4; i++)
p.items[i] = "\x00\x00";
int mc = 0, ic = 0;
string cmd;
cin >> n >> m;
vector<vector<char>> map(n, vector<char>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
if (map[i][j] == '&' || map[i][j] == 'M') mc++;
else if (map[i][j] == 'B') ic++;
else if (map[i][j] == '@') { p.y = i; p.x = j; sy = i; sx = j; }
}
}
cin >> cmd;
for (int i = 0; i < mc; i++) {
monster now;
cin >> now.y;
cin >> now.x;
cin >> now.name;
cin >> now.att;
cin >> now.def;
cin >> now.hp;
cin >> now.exp;
now.y--;
now.x--;
if (map[now.y][now.x] == 'M') now.boss = true;
else now.boss = false;
now.maxhp = now.hp;
monlist.push_back(now);
}
for (int i = 0; i < ic; i++) {
item now;
cin >> now.y;
cin >> now.x;
cin >> now.attr;
if (now.attr[0] == 'O') cin >> now.attr;
else if (now.attr[0] == 'W') cin >> now.att;
else cin >> now.def;
now.y--;
now.x--;
itemlist.push_back(now);
}
int trapatt = 5;
string monstname = "\x00";
int turn;
for (int i = 0; i < cmd.length(); i++) {
turn = i + 1;
char obj = mov(map, cmd[i]);
if (obj == '^') {
for (int j = 0; j < 4; j++) {
if (p.items[j] == "DX") {
trapatt = 1;
break;
}
}
p.hp = max(0, p.hp - trapatt);
if (p.hp <= 0) {
for (int j = 0; j < 4; j++) {
if (p.items[j] == "RE") {
p.x = sx;
p.y = sy;
p.hp = p.maxhp;
p.items[j] = "\x00\x00";
break;
}
}
if (p.hp <= 0) {
infoprint(map, turn);
cout << "YOU HAVE BEEN KILLED BY SPIKE TRAP..";
return 0;
}
}
}
else if (obj == 'B') getitem(map, p.x, p.y);
else if (obj == '&') {
monstname = fight(map, p.x, p.y);
if (p.hp <= 0) {
infoprint(map, turn);
cout << "YOU HAVE BEEN KILLED BY " << monstname << "..";
return 0;
}
}
else if (obj == 'M') {
monstname = fight(map, p.x, p.y);
if (monstname == "\x7f\x7f") continue;
else if (p.hp <= 0) {
infoprint(map, turn);
cout << "YOU HAVE BEEN KILLED BY " << monstname << "..";
return 0;
}
else {
infoprint(map, turn);
cout << "YOU WIN!";
return 0;
}
}
}
infoprint(map, turn);
cout << "Press any key to continue.";
return 0;
}
반응형
'PS > BOJ' 카테고리의 다른 글
[BOJ/백준] 14502번 - 연구소 (C++) (0) | 2022.07.21 |
---|
Comments