Sechack

[BOJ/백준] 17081번 - RPG Extreme 본문

PS/BOJ

[BOJ/백준] 17081번 - RPG Extreme

Sechack 2022. 8. 3. 22:10
반응형

https://www.acmicpc.net/problem/17081

 

17081번: RPG Extreme

요즘 택희는 RPG 게임을 하고 있다. 던전을 헤쳐나가며 몬스터를 물리치고, 아이템을 모으고, 레벨 업을 하여 보스 몬스터를 물리치는 전형적인 RPG 게임이다. 이 게임은 N×M 2차원 그리드 위에서

www.acmicpc.net

 

별다른 알고리즘은 필요없다. 코딩 능력만 있으면 누구나 도전해볼만 하다. 하지만 RPG게임의 요소를 직접 구현해야 하는 빡구현 문제라서 오로지 구현만으로 티어가 플래티넘 2인 문제이다. 문제 보고나서 초중딩 시절에 C언어 가지고 이것저것 해본 경험 살려서 하면 금방 풀 것 같았고 플래티넘 2를 날먹할 수 있을것 같았다. 그래서 구현했는데 너무 급하게 구현한 탓인지 테케는 다 맞는데 제출만 하면 seg fault터졌고 지인의 도움을 빌려서 seg fault잡으니까 틀렸습니다가 계속 떴다. 결론은 너무 코딩을 빠르게 해서 여러 군데에서 자잘한 논리적인 실수가 있었던 것이었고 프로그램 구조나 구현 방식 자체에는 문제가 없었다. 아무튼 지인 도움 받아서 자잘한 구현 미스를 잡으니까 풀렸다. 개발 경험 좀 있는 사람들은 쉽게 풀 것 같다.

 

https://www.acmicpc.net/board/view/96496

 

글 읽기 - 17081 rpg extreme 제발 살려주세요 ㅠㅠ

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

 

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