<토이프로젝트>/[C++ 게임]

[C++ 게임] 짝 맞추기 게임 (Card Matching)

BlockDMask 2020. 6. 3. 18:00

안녕하세요. BlockDMask 입니다.

오늘은 제가 예에에에전에 C++ 언어로 만든 간단한 짝맞추기 게임을 소개해볼까 합니다.

예전 개발 폴더를 뒤지다 보니 여러 프로그램들이 쏙쏙 나오네요.

몇개의 콘솔 게임들이 있는데 차근차근 정리해보겠습니다.


<목차>

1. 게임 이름 및 설명

2. 게임 플레이 영상(GIF)
3. 게임 소스코드


1. 게임 이름 및 설명


▶ 게임 이름

C++ 짝 맞추기

C++ 카드 매칭 게임


▶ 설명

1) 4x4 사이즈의 2차원 배열에 짝이 있는 임의의 숫자들이 존재합니다.

2) 정답인 2차원 배열(originMap)은 그대로 두고, "?"로 이루어진 2차원 배열을 새로 만듭니다.(questionMap)

3) 사용자의 키보드 화살표 입력을 받아서 커서를 움직이고, 스페이스를 이용해서 카드를 뒤집도록 합니다.

4) 카드는 두번만 뒤집을 수 있고, 뒤집을때 카운트를 세서 두번째 뒤집었을 때 뒤집힌 카드들의 숫자가 일치하는지 확인합니다.

5) 뒤집은 두 카드가 일치하는 경우에는 questionMap에 저장을 하고 숫자로 바꾸어줍니다.

6) 뒤집은 두 카드가 일치하지 않는 경우에는 다시 "?"로 표시해줍니다.

7) 이미 뒤집은 카드를 또다시 뒤집을때는 무시하도록 합니다.

8) 모든 카드를 뒤집어서 맞춘 경우 게임을 완료합니다.


▶ 짝 맞추기 게임 개발에 필요한 지식들

1) 콘솔 게임을 개발하는데 사용하는 공통 함수들 (키 입력 받기, 커서 이동하기 등)은 링크에 존재합니다. [바로가기]

2) 2차원 배열, 클래스, 구조체, 열거형 등



2. 게임 플레이 영상 (GIF)



너무 길어서 중간 맞추는것은 짤랐습니다.



3. 게임 소스 코드


▶ 프로그램 소스

최대한 분석 해보시고 이해가 안간다면 댓글로 질문을 달아주세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//Dev. BlockDMask
//Blog. https://blockdmask.tistory.com/
#include<iostream>
#include<Windows.h>
#include<conio.h>
using namespace std;
#define INIT_POS 1
//-----------------------------------------
//콘솔 내부의 특정 위치로 커서를 이동하는 함수.
void GotoXY(int x, int y)
{
    COORD pos;
    pos.X = 2 * x;
    pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
 
//콘솔 창 크기와 제목을 관리하는 함수.
void SetConsoleView()
{
    system("mode con:cols=65 lines=10");
    system("title Card Matching Game. by BlockDmask.");
}
 
//키보드 입력 감지 및 입력된 키보드를 반환하는 함수.
int GetKeyDown()
{
    if (_kbhit() != 0)
    {
        return _getch();
    }
    return 0;
}
//-----------------------------------------
//2차원 배열로 이루어진 맵
const int originMap[4][4= { {1618},
                                {6254},
                                {7254},
                                {8337} };
 
//포지션 구조체
struct Pos
{
    int x;
    int y;
};
 
//키보드 입력을 저장해 놓은 enum
enum KEYBOARD
{
    IS_ARROW = 224,
    UP = 72,
    LEFT = 75,
    RIGHT = 77,
    DOWN = 80,
    SPACE = 32,
};
 
//색상을 저장해놓은 enum
enum COLOR
{
    GREEN = 10,
    MINT,
    RED,
    PINK,
    YELLOW,
    WHITE,
};
cs


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
//게임 매니저 클래스
class GameManager
{
private:
    char questionMap[4][4];    //맞추고 있는 맵.
    Pos player;                //플레이어 커서 위치.
    Pos flipPos[2];            //뒤집은 카드 위치 저장.
    int flipCount;            //뒤집은 카드 개수.
    int spaceCount;            //뒤집은 횟수.
    int matchedCardCount;    //맞춘 카드 개수.
public:
    void StartGame()
    {
        Init();        //게임 초기화
        DrawBack();    //배경 그리기
        
        //게임 루프 시작
        int key = 0;
        while (true)
        {
            key = GetKeyDown();    //키 입력 받는 함수
            if (key == KEYBOARD::IS_ARROW)
            {
                //화살표들.
                MovePos();
            }
            if (key == KEYBOARD::SPACE)
            {
                //스페이스
                FlipCard();
            }
            //draw
            DrawMain();
            Sleep(100);
            CheckCard();
        }
    }
    //맵 초기화
    void Init()
    {
        for (int y = 0; y < 4++y)
        {
            for (int x = 0; x < 4++x)
            {
                questionMap[y][x] = '?';    //물음표로 다 세팅
            }
        }
        player.x = 0;
        player.y = 0;
        flipCount = 0;
        spaceCount = 0;
        matchedCardCount = 0;
    }
    //카드 뒤집는 함수
    void FlipCard()
    {
        if (questionMap[player.y][player.x] != '?'return;
        if (flipCount > 2return;
        flipPos[flipCount].x = player.x;
        flipPos[flipCount].y = player.y;
        questionMap[player.y][player.x] = originMap[player.y][player.x] + '0';
        ++flipCount;
    }
    //커서의 위치 이동
    void MovePos()
    {
        GotoXY(INIT_POS + (player.x * 3), INIT_POS + (player.y * 2+ 1);
        printf("  ");
        //키보드 입력을 받아서, 해당 위치로 이동을 시켜준다.
        switch (_getch())
        {
        case KEYBOARD::LEFT:
            --player.x;
            if (player.x <= 0)
            {
                player.x = 0;
            }
            break;
        case KEYBOARD::RIGHT:
            ++player.x;
            if (player.x >= 3)
            {
                player.x = 3;
            }
            break;
        case KEYBOARD::UP:
            --player.y;
            if (player.y <= 0)
            {
                player.y = 0;
            }
            break;
        case KEYBOARD::DOWN:
            ++player.y;
            if (player.y >= 3)
            {
                player.y = 3;
            }
            break;
        }
    }
    void DrawMain()
    {
        //map draw
        SetTextColor(WHITE);
        char c = '\0';
        for (int y = 0; y < 4++y)
        {
            GotoXY(INIT_POS, INIT_POS + (2 * y));
            for (int x = 0; x < 4++x)
            {
                c = questionMap[y][x];
                if (c != '?')
                {
                    SetTextColor(GREEN);
                }
                printf("[%c]   ", c);
                SetTextColor(WHITE);
            }
        }
        //player draw
        GotoXY(INIT_POS + (player.x * 3), INIT_POS + (player.y * 2+ 1);
        printf(" ^");
        GotoXY(141);
        printf("Count : %d", spaceCount);
    }
    void CheckCard()
    {
        if (flipCount == 2)
        {
            char c = '?';
            if (originMap[flipPos[0].y][flipPos[0].x] == originMap[flipPos[1].y][flipPos[1].x])
            {
                //같을때
                c = originMap[flipPos[0].y][flipPos[0].x] + '0';
                ++matchedCardCount;
            }
            else
            {
                //다를때.
                Sleep(500);
            }
            questionMap[flipPos[0].y][flipPos[0].x] = c;
            questionMap[flipPos[1].y][flipPos[1].x] = c;
            flipCount = 0;
            ++spaceCount;
            if (matchedCardCount >= 8)
            {
                DrawGameClear();
                Sleep(2000);
                system("cls");
                Init();
                DrawBack();
            }
        }
    }
    void DrawBack()
    {
        SetTextColor(WHITE);
        GotoXY(146);
        cout << "https://blockdmask.tistory.com/";
        GotoXY(147);
        cout << "_by. ";
        SetTextColor(PINK);
        cout << "BlockDMask";
        SetTextColor(WHITE);
    }
    void DrawGameClear()
    {
        SetTextColor(YELLOW);
        GotoXY(103);
        cout << "=========================";
        GotoXY(104);
        cout << "======= C L E A R =======";
        GotoXY(105);
        cout << "=========================";
        SetTextColor(WHITE);
    }
    void SetTextColor(int color)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
    }
};
//메인함수
int main(void)
{
    SetConsoleView();
    GameManager* pGameMgr = new GameManager();
    pGameMgr->StartGame();
    delete(pGameMgr);
    return 0;
}
 
cs


이상으로 "C++ 짝 맞추기, 카드 매칭 게임" 포스팅을 마치겠습니다.

소스코드 : https://github.com/BlockDMask/CardMatching_Game/blob/master/main.cpp