STUDY

[3주차 TIL] KnockOn Bootcamp Pre.Rev : 포켓몬 게임 제작 Project

da1seun9 2024. 12. 22. 00:31

개요

이 프로젝트는 2~3주차 동안 이루어진 포켓몬 게임 제작 프로젝트이다.

요구사항

  1. 각 기능과 구조체는 헤더파일을 이용해 구현해야 함.
  2. 구조체는 꼭 malloc을 이용해 동적 heap메모리로 사용하여야 함. 구조체 멤버는 상관 X
  3. 리눅스 환경 gcc컴파일러를 통해서 컴파일 및 실행이 되어야 함
  4. 추가 점수는 자료구조를 이용할 경우 부여함.

구성

pokemon.txt : 포켓몬 리스트가 들어가 있는 파일
pokemon.h : 포켓몬 게임을 위한 함수가 들어간 헤더파일
pokemon.c : main.c
save.txt : 게임 중간에 저장시 발생하는 파일

pokemon.txt

//pokemon.txt
12
파이리 불 60 80
꼬부기 물 40 120
이상해씨 풀 50 100
브케인 불 50 90
라이코 물 40 120
치코리타 풀 50 100
아차모 불 50 90
물짱이 물 40 120
나무지기 풀 50 100
불꽃숭이 불 50 90
팽도리 물 40 120
모부기 풀 50 101

save.txt

// save.txt
[트레이너 정보]
소유한 포켓몬 수 : 6
지갑 : 1372
몬스터 볼 : 0
물약 개수 : 1
[소유한 포켓몬 리스트]
파이리 fire 불 87 141 0
물짱이 물짱 물 76 132 132
꼬부기 꼬북 물 93 143 143
치코리타 치코 풀 75 140 117
아차모 아차 불 50 90 90
물짱이 물짱 물 47 125 13

메인 함수 코드 구성 로직

  1. 맨처음 포켓몬 리스트를 읽어온다.
  2. initial함수 동작(초기화면 출력)
  3. 이어할지, 새로할지 선택
  4. play하고 만일 포켓몬 마스터가 되었을 때, 새로할지 말지를 반환값으로 결정
  5. 게임 내용 세이브

main.c

#include"pokemon.h"

int main() {
    srand(time(NULL));  // 랜덤 시드 초기화

    Trainer* trainer = (Trainer*)malloc(sizeof(Trainer));
    if (trainer == NULL) {
        perror("메모리 할당 실패");
        exit(EXIT_FAILURE);
    }

    Node* pokemonList = loadPokemonData();
    char a = "";
    while(1){
    initial();
    int gameChoice = open_file();

    if (gameChoice == -1) {
        selectPokemon(trainer);
    }
    else if (gameChoice == 1) {
        loadGame(trainer);
    }

    a = play(trainer, pokemonList);

    // 입력받은 값이 'N'이 아니면 계속 게임 진행
    if (a == 'N' || a == 'n') {
        break;
    }
    // 'Y'가 입력되면 계속 게임 재시작
    else {
        continue;
    }
    // 게임을 진행하고 저장하기
    }
    saveGame(trainer);
    // 메모리 해제
    free(trainer);
    return 0;
}

pokemon.h

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h> // linux는 unistd.h 사용

#define MAX_POKEMON 12 // 100
#define MAX_NAME_LEN 50

typedef struct Pokemonster {
    char name[MAX_NAME_LEN];
    char type[MAX_NAME_LEN];
    char nickname[MAX_NAME_LEN];
    int attack;
    int hp;
    int now_hp;
} Pokemon;

typedef struct Trainer {
    Pokemon ownedPokemon[MAX_POKEMON]; //소유한 포켓몬
    int pokemonCount;
    int wallet;
    int pokeballCount;
    int potionCount;
} Trainer;

typedef struct Node {
    Pokemon data;
    struct Node* next;
} Node;

Node *createNode(const Pokemon *data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (!newNode) {
        perror("메모리 할당 실패");
        exit(EXIT_FAILURE);
    }
    newNode->data = *data;
    newNode->next = NULL;
    return newNode;
}

// 포켓몬 리스트 로드하는 함수
Node *loadPokemonData() {
    FILE *file = fopen("pokemon.txt", "r");
    if (!file) {
        perror("파일을 열 수 없습니다");
        exit(EXIT_FAILURE);
    }

    int count;
    fscanf(file, "%d", &count); // 첫 줄에서 포켓몬 개수 읽기

    Node *head = NULL, *tail = NULL;
    for (int i = 0; i < count; i++) {
        Pokemon temp;
        fscanf(file, "%s %s %d %d", temp.name, temp.type, &temp.attack, &temp.hp);

        Node *newNode = createNode(&temp);
        if (head == NULL) {
            head = newNode;
            tail = newNode;
        }
        else {
            tail->next = newNode;
            tail = newNode;
        }
    }

    fclose(file);
    return head;
}

// 초기화면 출력
int initial() {
    printf("===============================");
    printf("\n");
    printf("     KnockOn Pokemon Game      ");
    printf("\n");
    printf("                               ");
    printf("\n");
    printf("     press enter to start      ");
    printf("\n");
    printf("===============================\n");
    while (getchar() != '\n');
    system("clear");
    return 0;
}

// 이어할지, 새로할지 선택
int open_file() {
    int num = 0;
    printf("===============================");
    printf("\n");
    printf("     1. 새로하기   2. 이어하기   ");
    printf("\n");
    printf(">>");
    scanf("%d", &num);
    system("clear");

    FILE* file = fopen("save.txt", "r");
    if ((!file) || (num == 1)) {
        return -1; // 처음부터 시작
    }
    else if (num == 2) {
        return 1;  // 이어하기 처리 필요
    }
    fclose(file);
}

// 랜덤값을 만들어내는 함수
int randomStat(int baseStat, int range) {
    return baseStat + (rand() % (range - baseStat + 1));
}

// wildPokemon을 Trainer의 OwnedPokemon 배열에 추가하는 함수(포켓몬 잡는 함수)
void capturePokemon(Trainer* trainer, Pokemon* wildPokemon) {
    // 배열 크기 확인 (예: OwnedPokemon 배열 크기가 6인 경우)
    if (trainer->pokemonCount < 6) {
        // 소유한 포켓몬 배열에 새 포켓몬 추가
        printf("포켓몬의 별명을 입력하세요: ");
        scanf("%s", wildPokemon->nickname);
        trainer->ownedPokemon[trainer->pokemonCount] = *wildPokemon;

        // 포켓몬 카운트 증가
        trainer->pokemonCount++;
        system("clear");
    }
    else {
        printf("포켓몬 보관함이 가득 찼습니다! 더 이상 포켓몬을 잡을 수 없습니다.\n");
    }
}

// 포켓몬 상성 함수
float calculateDamageMultiplier(const char* attackerType, const char* defenderType) {
    if ((strcmp(attackerType, "불") == 0 && strcmp(defenderType, "풀") == 0) ||
        (strcmp(attackerType, "풀") == 0 && strcmp(defenderType, "물") == 0) ||
        (strcmp(attackerType, "물") == 0 && strcmp(defenderType, "불") == 0)) {
        printf("효과가 굉장했다!\n");
        return 1.5f;
    }
    if ((strcmp(attackerType, "풀") == 0 && strcmp(defenderType, "불") == 0) ||
        (strcmp(attackerType, "불") == 0 && strcmp(defenderType, "물") == 0) ||
        (strcmp(attackerType, "물") == 0 && strcmp(defenderType, "풀") == 0)) {
        printf("효과가 별로인 듯 하다...\n");
        return 0.5f;
    }
    return 1.0f;
}

// 포켓몬 배틀 상태창 출력함수
void printBattleStatus(Pokemon* myPokemon, Pokemon* wildPokemon) {
    printf("==============================\n");
    printf("\t\t%s\n\t\t현재 HP: %d / %d\n", wildPokemon->name, wildPokemon->now_hp, wildPokemon->hp);
    printf("%s\n현재 HP: %d / %d\n", myPokemon->name, myPokemon->now_hp, myPokemon->hp);
    printf("==============================\n");
}

// 트레이너의 가방 함수
int trainer_bag(Pokemon* myPokemon, Pokemon* wildPokemon, Trainer* trainer) {
    printf("===============================");
    printf("\n");
    printf("1. 몬스터볼 x %d", trainer->pokeballCount);
    printf("\n");
    printf("2. 회복약 x %d", trainer->potionCount);
    printf("\n");
    printf(">> ");
    int choice = 0;
    int catch = 100 * (1 - (double)wildPokemon->now_hp / wildPokemon->hp);  //포획확률
    scanf("%d", &choice);
    if (choice == 1) {
        if (trainer->pokeballCount >= 1) {
            trainer->pokeballCount -= 1;
            printBattleStatus(myPokemon, wildPokemon);
            printf("===============================");
            printf("\n");
            printf("몬스터볼을 %s에게 던졌다!", wildPokemon);
            printf("...\n...\n");
            if (rand() % 100 < catch) {     // catch는 포획확률이고, 랜덤값이 이 범위에 있다면, 해당 포획확률%로 포획
                printf("%s을(를) 잡았다!\n", wildPokemon->name);
                capturePokemon(trainer, wildPokemon);
                return 0;
            }
            else {
                printf("포켓몬이 몬스터볼에서 빠져나왔다!\n");
                return 1;
            }
        }
        else {
            printf("몬스터볼이 없다...!\n");
        }
    }
    else if (choice == 2) {
        if (trainer->potionCount >= 1) {
            trainer->potionCount -= 1;
            if (myPokemon->now_hp < myPokemon->hp) {
                myPokemon->now_hp += (double)myPokemon->hp*0.3;
                printf("===============================");
                printf("\n");
                printf("회복약을 사용하였다!\n");
                printf("%s(은)는 %.0f의 체력을 회복하였다.\n", myPokemon->name, (double)myPokemon->hp*0.3);
                if (myPokemon->now_hp > myPokemon->hp) {
                    myPokemon->now_hp = myPokemon->hp;
                    printBattleStatus(myPokemon, wildPokemon);

                }
            }
            else {
                printf("회복할 체력이 없다...!\n");
                printBattleStatus(myPokemon, wildPokemon);
            }
        }
        else {
            printf("회복약이 없다...!\n");
        }
    }

}

// 포켓몬 교체함수
Pokemon* changePokemon(Pokemon* currentPokemon, Pokemon* wildPokemon, Trainer* trainer) {
    printf("사용할 포켓몬을 선택하세요:\n");
    for (int i = 0; i < trainer->pokemonCount; i++) {
        if (trainer->ownedPokemon[i].now_hp > 0) {
            printf("%d. %s (HP: %d/%d)\n", i + 1, trainer->ownedPokemon[i].name, trainer->ownedPokemon[i].now_hp, trainer->ownedPokemon[i].hp);
        }
    }
    int choice;
    do {
        printf(">> ");
        scanf("%d", &choice);
        choice--;  // 배열 인덱스는 0부터 시작
        if (choice < 0 || choice >= trainer->pokemonCount || trainer->ownedPokemon[choice].now_hp <= 0) {
            printf("잘못된 선택입니다. 다시 선택하세요.\n");
        }
    } while (choice < 0 || choice >= trainer->pokemonCount || trainer->ownedPokemon[choice].now_hp <= 0);

    currentPokemon = &trainer->ownedPokemon[choice];
    printf("'%s'를 전투에 내보냈다!\n", currentPokemon->name);
    printBattleStatus(currentPokemon, wildPokemon);
    return currentPokemon;
}

// 배틀함수
void battle(Pokemon* myPokemon, Pokemon* wildPokemon, Trainer* trainer) {
    while (myPokemon->now_hp > 0 && wildPokemon->now_hp > 0) {
        printf("무엇을 해야할까?\n1. 공격 2. 가방열기 3. 도망치기\n>> ");
        int choice;
        scanf("%d", &choice);
        system("clear");
        if (choice == 2) {
            printBattleStatus(myPokemon, wildPokemon);
            int i = trainer_bag(myPokemon, wildPokemon, trainer);
            if (i == 0) { return; }
            else {
                printBattleStatus(myPokemon, wildPokemon);
                continue;
            }
        }
        else if (choice == 3) {
            if (rand() % 100 < (110 * (1 - (double)wildPokemon->now_hp / wildPokemon->hp))) {
                printf("성공적으로 도망쳤다!\n");
                return;
            }
            else {
                printf("지금 도망치긴 힘들 것 같다...\n");
                printBattleStatus(myPokemon, wildPokemon);
                continue;
            }
        }

        int first = rand() % 2;  // 누가 먼저 공격할지 랜덤
        for (int i = 0; i < 2; i++) {
            if (myPokemon->now_hp <= 0 || wildPokemon->now_hp <= 0)
                break;

            Pokemon* attacker = first == i ? myPokemon : wildPokemon;
            Pokemon* defender = first == i ? wildPokemon : myPokemon;

            float multiplier = calculateDamageMultiplier(attacker->type, defender->type);
            int damage = (int)(attacker->attack * multiplier);

            // 크리티컬 확률 20%
            if (rand() % 100 < 20) {
                damage = (int)(damage * 1.5);
                printf("급소에 맞았다!\n");
            }

            defender->now_hp -= damage;
            if (defender->now_hp < 0) defender->now_hp = 0;

            printf("%s가 %d의 데미지를 입혔다!\n", attacker->name, damage);
            printBattleStatus(myPokemon, wildPokemon);
        }
    }

    // 전투 종료 조건
    if (wildPokemon->now_hp <= 0) {
        int reward = randomStat(300, 500);
        trainer->wallet += reward;
        printf("야생의 %s를 물리쳤다! %d원을 얻었다!\n", wildPokemon->name, reward);
    }
    else if (myPokemon->now_hp <= 0) {
        printf("%s가 기절했다...!\n", myPokemon->name);
        if (trainer->pokemonCount <= 1) {
            if (trainer->wallet >= 1000) {
                printf("눈앞이 깜깜해졌다... 1000원을 잃었다.\n");
                trainer->wallet -= 1000;
            }
            else {
                printf("눈앞이 깜깜해졌다... 남은 돈을 다 잃었다.\n");
                trainer->wallet = 0;
            }
        }
        else if (trainer->pokemonCount > 1) {
            int num = 0; //포켓몬들의 체력 합
            for (int i = 0; i < trainer->pokemonCount; i++) {
                num += trainer->ownedPokemon[i].now_hp;
            }
            if (num >= 1) {
                Pokemon* nextPokemon = changePokemon(myPokemon, wildPokemon, trainer);  // 포켓몬 교체
                                                                                        // 교체 후 다시 battle() 호출
                battle(nextPokemon, wildPokemon, trainer);  // 포켓몬 교체 후 전투 재개
                return;  // 다시 battle()이 호출되었으므로 원래의 battle() 실행 흐름 종료
            }
            else if (num == 0) {
                if (trainer->wallet >= 1000) {
                    printf("눈앞이 깜깜해졌다... 1000원을 잃었다.\n");
                    trainer->wallet -= 1000;
                }
                else {
                    printf("눈앞이 깜깜해졌다... 남은 돈을 다 잃었다.\n");
                    trainer->wallet = 0;
                }
            }
        }

    }
}

// 배틀전 함수
void adventure(Trainer* trainer, Node* pokemonList) {
    //sleep(randomStat(1, 5));  // 1~5초 대기

    // 랜덤한 야생 포켓몬 등장
    Node* current = pokemonList;
    int index = rand() % MAX_POKEMON;
    while (index-- && current->next)
        current = current->next;

    Pokemon wildPokemon = current->data;
    wildPokemon.attack = randomStat(wildPokemon.attack, 100);
    wildPokemon.hp = randomStat(wildPokemon.hp, 150);
    wildPokemon.now_hp = wildPokemon.hp;

    printf("앗! 야생의 %s가 나타났다!\n", wildPokemon.name);
    printBattleStatus(&trainer->ownedPokemon[0], &wildPokemon);

    // 전투 시작
    battle(&trainer->ownedPokemon[0], &wildPokemon, trainer);  //battle의 매개변수 myPokemon 포인터가 trainer의 포켓몬 구조체를 가리키기위해 주소 전달
}

// 포켓몬을 리스트에서 내가 선택한 포켓몬을 찾는 함수인데... 중간에 만들면서 필요가 없어졌다.. 왜 넣었지... 
void findpokemon(Node* guide, const char* selectedPokemon, int* attack, int* hp) {
    Node* head = guide;
    while (head != NULL) {
        if (strcmp(head->data.name, selectedPokemon) == 0) {
            *attack = head->data.attack;
            *hp = head->data.hp;
            return;
        }
        head = head->next;
    }
}

// 초기 포켓몬 선택함수
void selectPokemon(Trainer* trainer) {
    printf("===============================");
    printf("\n");
    printf("어느 포켓몬을 선택하시겠습니까?");
    printf("\n");
    printf("1. 파이리 2. 이상해씨 3. 꼬부기");
    printf("\n");
    printf(">>");
    int choice = 0;
    scanf("%d", &choice);
    system("clear");
    Pokemon selectedPokemon;

    switch (choice) {
    case 1:
        strcpy(selectedPokemon.name, "파이리");
        strcpy(selectedPokemon.type, "불");
        selectedPokemon.attack = randomStat(60, 100);
        selectedPokemon.hp = randomStat(80, 150);
        selectedPokemon.now_hp = selectedPokemon.hp;
        break;
    case 2:
        strcpy(selectedPokemon.name, "이상해씨");
        strcpy(selectedPokemon.type, "풀");
        selectedPokemon.attack = randomStat(50, 100);
        selectedPokemon.hp = randomStat(100, 150);
        selectedPokemon.now_hp = selectedPokemon.hp;
        break;
    case 3:
        strcpy(selectedPokemon.name, "꼬부기");
        strcpy(selectedPokemon.type, "물");
        selectedPokemon.attack = randomStat(40, 100);
        selectedPokemon.hp = randomStat(120, 150);
        selectedPokemon.now_hp = selectedPokemon.hp;
        break;
    default:
        printf("선택지에 없는 포켓몬입니다. 다시 선택해주세요.\n");
        return;
    }

    printf("포켓몬의 별명을 입력하세요: ");
    scanf("%s", selectedPokemon.nickname);
    trainer->pokemonCount = 1;
    trainer->wallet = 10000;
    trainer->pokeballCount = 0;
    trainer->potionCount = 0;
    trainer->ownedPokemon[0] = selectedPokemon;
    system("clear");

    printf("포켓몬 선택 완료! %s(으)로 모험을 시작합니다.\n", trainer->ownedPokemon[0].name);
    printf("현재 지갑: %d원\n", trainer->wallet);
}

//  게임 세이브 함수
void saveGame(const Trainer* trainer) {
    FILE* file = fopen("save.txt", "w");
    if (!file) {
        perror("파일을 열 수 없습니다");
        exit(EXIT_FAILURE);
    }

    fprintf(file, "[트레이너 정보]\n");
    fprintf(file, "소유한 포켓몬 수 : %d\n", trainer->pokemonCount);
    fprintf(file, "지갑 : %d\n", trainer->wallet);
    fprintf(file, "몬스터 볼 : %d\n", trainer->pokeballCount);
    fprintf(file, "물약 개수 : %d\n", trainer->potionCount);

    fprintf(file, "[소유한 포켓몬 리스트]\n");
    for (int i = 0; i < trainer->pokemonCount; i++) {
        fprintf(file, "%s %s %s %d %d %d\n",
            trainer->ownedPokemon[i].name,
            trainer->ownedPokemon[i].nickname,
            trainer->ownedPokemon[i].type,
            trainer->ownedPokemon[i].attack,
            trainer->ownedPokemon[i].hp,
            trainer->ownedPokemon[i].now_hp);
    }
    fclose(file);
}

// 게임 로드함수
void loadGame(Trainer* trainer) {
    FILE* file = fopen("save.txt", "r");
    if (!file) {
        perror("파일을 열 수 없습니다");
        exit(EXIT_FAILURE);
    }

    //트레이너 정보 읽기
    fscanf(file, "[트레이너 정보]\n");
    fscanf(file, "소유한 포켓몬 수 : %d\n", &trainer->pokemonCount);
    fscanf(file, "지갑 : %d\n", &trainer->wallet);
    fscanf(file, "몬스터 볼 : %d\n", &trainer->pokeballCount);
    fscanf(file, "물약 개수 : %d\n", &trainer->potionCount);

    fscanf(file, "[소유한 포켓몬 리스트]\n");
    for (int i = 0; i < trainer->pokemonCount; i++) {
        fscanf(file, "%s %s %s %d %d %d %d\n",
            trainer->ownedPokemon[i].name,
            trainer->ownedPokemon[i].nickname,
            trainer->ownedPokemon[i].type,
            &trainer->ownedPokemon[i].attack,
            &trainer->ownedPokemon[i].hp,
            &trainer->ownedPokemon[i].now_hp);
    }
    fclose(file);
    printf("이어서 게임을 시작합니다. %s(으)로 모험을 시작합니다.\n", trainer->ownedPokemon[0].name);
    printf("현재 지갑: %d원\n", trainer->wallet);
}

// 상점 함수
void shop(Trainer* trainer) {
    int choice, quantity;
    int pokeballPrice = 1000;
    int potionPrice = 500;

    while (1) {
        printf("===============================\n");
        printf("상점                지갑 : %d원\n", trainer->wallet);
        printf("1. 포켓몬볼 (%d원)\n", pokeballPrice);
        printf("2. 상처약 (%d원)\n", potionPrice);
        printf("0. 나가기\n");
        printf("===============================\n");
        printf("무엇을 구매할까요? >> ");
        scanf("%d", &choice);

        if (choice == 0) break;

        printf("몇 개를 구매할까요? >> ");
        scanf("%d", &quantity);

        if (choice == 1 && trainer->wallet >= pokeballPrice * quantity) {
            trainer->wallet -= pokeballPrice * quantity;
            printf("포켓몬볼 %d개를 구매했습니다!\n", quantity);
            trainer->pokeballCount = quantity;
        }
        else if (choice == 2 && trainer->wallet >= potionPrice * quantity) {
            trainer->wallet -= potionPrice * quantity;
            printf("상처약 %d개를 구매했습니다!\n", quantity);
            trainer->potionCount = quantity;
        }
        else {
            printf("돈이 부족하거나 잘못된 입력입니다!\n");
        }
    }
    system("clear");
}

// 포켓몬 센터 함수
void pokemonCenter(Trainer* trainer) {
    printf("===============================\n");
    printf("모든 포켓몬을 치료하는 중입니다 ... ... ...\n");
    for (int i = 0; i < trainer->pokemonCount; i++) {
        trainer->ownedPokemon[i].now_hp = trainer->ownedPokemon[i].hp; // HP를 다시 원래대로 설정
    }
    printf("포켓몬의 체력이 완전히 회복되었습니다!\n");
    printf("===============================\n");
    while (getchar() != '\n');

}

// 포켓몬 도감 출력함수
void pokedex(Node* pokemonList) {
    printf("===============================\n");
    printf("포켓몬 도감\n");
    printf("이름       | 속성     | 공격력  | 체력\n");
    printf("------------------------------------\n");

    Node* current = pokemonList;
    while (current != NULL) {
        printf("%-10s   | %-8s   | %-7d   | %-5d\n",
            current->data.name,
            current->data.type,
            current->data.attack,
            current->data.hp);
        current = current->next;
    }
    printf("===============================\n");
}

// 게임의 전반적인 플레이를 할 수 있게 설계된 분기 함수
char play(Trainer* trainer, Node* pokemonList) {
    int num = 0;
    int i = 0;
    char a = "";

    while (1) {
        if (trainer->pokemonCount == 6) {
            printf("===============================\n");
            printf("포켓몬 마스터가 되었다!\n");

            for (int i = 0; i < 6; i++) {
                printf("%s %d/%d\n", trainer->ownedPokemon[i].nickname, trainer->ownedPokemon[i].now_hp, trainer->ownedPokemon[i].hp);
            }
            printf("포켓몬 볼 x %d\n", trainer->pokeballCount);
            printf("회복약 x %d\n", trainer->potionCount);
            printf("지갑 %d원\n", trainer->wallet);
            printf("===============================\n");
            printf("게임을 재시작하겠습니까? (Y/N)\n");
            printf(">> ");
            getchar();    //getchar로 엔터 버퍼지우기
            scanf("%c", &a);
            if (a == 'Y' || a == 'y') {
                return a; // Y 입력시 'Y' 반환하여 게임 재시작
            }
            else if (a == 'N' || a == 'n') {
                return a; // N 입력시 'N' 반환하여 게임 종료
            }
            else {
                printf("잘못된 입력입니다. 다시 입력해주세요.\n");
                continue; // 잘못된 입력일 경우 계속해서 묻기
            }
        }
        printf("===============================\n");
        printf("모험을 진행하시겠습니까?\n");
        printf("1. 네  2. 저장  3. 상점  4. 포켓몬센터  5. 포켓몬 도감  6. 종료\n");
        printf(">> ");
        scanf("%d", &num);
        system("clear");

        switch (num) {
        case 1:
            printf("===============================\n");
            if (trainer->ownedPokemon[0].now_hp == 0) {
                printf("포켓몬센터부터 가자...\n");
                pokemonCenter(trainer);
                break;
            }
            printf("===============================\n");
            printf("포켓몬을 탐색하는 중...\n");
            adventure(trainer, pokemonList);
            break;
        case 2:
            saveGame(trainer);
            printf("===============================\n");
            printf("게임이 저장되었습니다!\n");
            break;
        case 3:
            shop(trainer);
            break;
        case 4:
            pokemonCenter(trainer);
            break;
        case 5:
            pokedex(pokemonList);
            break;
        case 6:
            printf("===============================\n");
            printf("게임을 종료합니다.\n");
            return 'n';
        default:
            printf("===============================\n");
            printf("잘못된 입력입니다! 다시 선택해주세요.\n");
        }
    }
}

결과

imageimageimageimageimageimageimageimageimage

코드리뷰는 지속적으로 최신화해서 포스트 수정할 예정이다.

아래 파일은 게임 파일이다.

pokemon
0.03MB

끝.