(C, C++) ๐ŸŽฎ ๊ฒŒ์ž„ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด๋ณด์ž.

Jae Chanยท2022๋…„ 6์›” 16์ผ
1

์‹œ์ž‘ํ•˜๊ธฐ ์•ž์„œ

๋ฉฐ์น  ์ „, ๊ต์ˆ˜๋‹˜๊ป˜์„œ ๊ณผ์ œ๋กœ C์–ธ์–ด๋กœ ๊ตฌํ˜„๋œ ๊ฒŒ์ž„(ํ…ŒํŠธ๋ฆฌ์Šค, ๋ฏธ๋กœ์ฐพ๊ธฐ)์— ๋Œ€ํ•œ
์ฝ”๋“œ ๋ถ„์„ํ•˜๊ธฐ๋ฅผ ๋‚ด์ฃผ์…จ๋Š”๋ฐ, ํ‰์†Œ ๊ฒŒ์ž„ ์ฝ”๋“œ๋Š” ์–ด๋–ค์‹์œผ๋กœ ๊ตฌํ˜„ ๋ผ์žˆ์„๊นŒ
๊ถ๊ธˆํ•˜๊ธฐ๋„ ํ–ˆ๋˜ ๋‚˜์ธ์ง€๋ผ ์ข‹์€ ๊ธฐํšŒ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

์ผ๋‹จ ์ฝ”๋“œ ๋ถ„์„์„ ํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ๋ฅผ ์ฐพ๊ธฐ ์ „,
๋ช‡ ๊ฐ€์ง€ ๊ธฐ์ค€์„ ์ •ํ•˜๊ณ  ๊ทธ ๊ธฐ์ค€์— ๋งŒ์กฑํ•˜๋Š” ์ž๋ฃŒ๋ฅผ ์ฐพ๊ธฐ๋กœ ํ–ˆ๋‹ค.

์ฝ”๋“œ ๋ถ„์„ ์ž๋ฃŒ์˜ ์„ ์ • ๊ธฐ์ค€ ๐Ÿ‘โ€๐Ÿ—จ

  • ๋””์ž์ธ๋ณด๋‹จ ๊ธฐ๋Šฅ์— ์ถฉ์‹คํ•œ ๊ฒƒ.
  • ๋ฒ„๊ทธ ๋ฐœ์ƒ ์šฐ๋ ค๋ฅผ ๊ณ ๋ คํ•ด, ํ•จ์ˆ˜ ๋˜๋Š” ์ฝ”๋“œ์˜ ๊ตฌ์„ฑ์ด ํ•˜๋‚˜๋กœ ๋ญ‰์ณ์žˆ์ง€ ์•Š๋Š” ๊ฒƒ.
  • 2 ๋ฒˆ์งธ์™€ ์—ฐ๊ด€ ๋ผ์žˆ๋Š”๋ฐ ์ถ”ํ›„ ๊ฒŒ์ž„ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณ ๋ คํ•ด ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ์ฒด๊ณ„์ ์œผ๋กœ ๊ตฌ์„ฑ ๋˜์žˆ๋Š” ๊ฒƒ.

์ด 3๊ฐ€์ง€๊ฐ€ ์ถฉ์กฑํ•œ ์ž๋ฃŒ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ๋งŽ์€ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ 
๋‚ด๊ฐ€ ์ฝ”๋“œ ๋ถ„์„์„ ํ•˜๊ธฐ๋กœ ํ•œ ์ž๋ฃŒ๋Š”, kkikkodev GitHub ํ•ด๋‹น ์‚ฌ์ดํŠธ์ด๋‹ค.

์ตœ์ข… ์ถœ๋ ฅ ์‹œ ๐Ÿ‘‰

( ์ถœ์ฒ˜ : Kkikkodev Youtube )

kkikkodev ์ด๋ž€ ๋ถ„์ด ๋งŒ๋“œ์‹  ํ…ŒํŠธ๋ฆฌ์Šค ๊ฒŒ์ž„์˜ ์™„์„ฑ๋ณธ์€ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ๊ธฐ์ค€์— ์ ํ•ฉํ•˜์˜€๋‹ค.
์ „์ฒด์ ์ธ ์ฝ”๋“œ๋ฅผ ๋ดค์„ ๋•Œ,
๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด์‹œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๋•Œ์˜ ๋Œ€์‘์„ ์œ„ํ•œ,
์—…๋ฐ์ดํŠธ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ ํ•  ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด ๊ธฐ๋Šฅ ํ•˜๋‚˜ ํ•˜๋‚˜๋ฅผ ์ตœ๋Œ€ํ•œ ํ•จ์ˆ˜๋กœ ์ชผ๊ฐœ์„œ ๋งŒ๋“œ์…จ๋‹ค.

ํ•˜์ง€๋งŒ ์ตœ์ข… ์™„์„ฑ๋ณธ์˜ ์ฝ”๋“œ๋Š” ๋„ˆ๋ฌด ํ•ด์„ํ•˜๊ธฐ ์–ด๋ ค์› ๊ณ , ๋‚˜ ๋˜ํ•œ C์–ธ์–ด์— ๋Œ€ํ•œ ์ง€์‹์ด ๊นŠ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ œ์ผ ์ดˆ๊ธฐ ๋ฒ„์ „์ธ TetrisForDesktop 0.1ver ์„ ๋ถ„์„ํ•˜๊ธฐ๋กœ ํ•˜์˜€๊ณ ,
ํ•ด์„ํ•˜๋ฉด์„œ ๋Š๋‚€๊ฑฐ์ง€๋งŒ ์ดˆ๊ธฐ ๋ฒ„์ „ ์กฐ์ฐจ๋„ ๋ถ„์„ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ๋‹ค.

๋‚˜์˜ C์–ธ์–ด์— ๋Œ€ํ•œ ์ง€์‹์€ ํฌ์ธํ„ฐ์—์„œ ๋ฉˆ์ถฐ์žˆ๋Š”๋ฐ
ํ•ด๋‹น ์ฝ”๋“œ๋Š” ๊ตฌ์กฐ์ฒด(Structure)๋‚˜, ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ, ์—ด๊ฑฐํ˜• ์ƒ์ˆ˜(enum) ๋“ฑ์„
์‚ฌ์šฉํ•ด์„œ ๊ตฌ๊ธ€์˜ ํž˜์ด ์•„๋‹ˆ์˜€๋‹ค๋ฉด ๋ถ„์„ํ•˜๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํž˜๋“ค์—ˆ๋‹ค. ๐Ÿ˜ฅ

์ผ๋‹จ ์ตœ๋Œ€ํ•œ ์•„๋Š” ์„ ์—์„œ ๋ถ„์„ํ•˜๋ฉฐ ์ฃผ์„์„ ์ž‘์„ฑํ•˜๊ณ ,
๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์€ ์›น์„œํ•‘์„ ํ•˜๋ฉด์„œ ์ •๋ณด๋ฅผ ์–ป๊ณ  ์ž‘์„ฑํ•˜๋‹ค๋ณด๋‹ˆ
์•„์˜ˆ ์ดํ•ด๊ฐ€ ์•ˆ๋˜๋Š” ์ˆ˜์ค€์€ ์•„๋‹ˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ฐ๋ณด๋‹ค ํ• ๋งŒ ํ–ˆ๋‹ค.

์ฝ”๋“œ ๋ถ„์„ โœ

๋ธ”๋กœ๊ทธ์— ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋„ˆ๋ฌด ๊ธธ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋–ค์‹์œผ๋กœ ๋Œ์•„๊ฐ€๋Š”์ง€ ?
  • ๊ฐ ํ—ค๋”ํŒŒ์ผ ๋ฐ ์†Œ์ŠคํŒŒ์ผ์˜ ๊ธฐ๋Šฅ ๋ฐ ํ•จ์ˆ˜๋“ค์˜ ๊ธฐ๋Šฅ(๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€)

    ๊ฐ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ์ œ GitHub๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. ๐Ÿ‘‰ GitHub

ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋–ค์‹์œผ๋กœ ๋Œ์•„๊ฐ€๋Š”์ง€ ๐Ÿค”

๋จผ์ €, ํ…ŒํŠธ๋ฆฌ์Šค๊ฐ€ ๊ตฌํ˜„๋˜๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด์„ ์•Œ์•„๋ด์•ผ ํ•œ๋‹ค.

  • ํ‚ค๋ณด๋“œ๊ฐ€ ํŠน์ • ํ‚ค๋ฅผ ์ž…๋ ฅ ๋ฐ›์„ ๋•Œ ๋งˆ๋‹ค ๋ธ”๋Ÿญ์ด ์Œ“์—ฌ์•ผ ํ•œ๋‹ค.
  • ๋ธ”๋Ÿญ์ด ํŠน์ • ์กฐ๊ฑด๋“ค์ด ๋งŒ์กฑํ–ˆ์„ ๋•Œ์˜ ๋ถ„๊ธฐ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
    • ๋ธ”๋Ÿญ์ด ๊ฐ€๋กœ์ค„๋กœ ์Œ“์ด๊ฒŒ ๋˜๋ฉด ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ
    • ๋ธ”๋Ÿญ์ด ๊ฒŒ์ž„ํŒ๊ณผ ์ถฉ๋Œํ–ˆ์„๋•Œ ๊ฒŒ์ž„์˜ค๋ฒ„ ๊ธฐ๋Šฅ
  • ๋žœ๋ค์œผ๋กœ ๋‹ค์Œ ๋ธ”๋Ÿญ์ด ๋ฌด์—‡์ธ์ง€ ํ‘œ์‹œํ•ด์ค˜์•ผ ํ•œ๋‹ค.

์ด ์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ ์ œ์ผ ํ•ต์‹ฌ๋งŒ ์š”์•ฝํ•ด ๋ดค๋‹ค.

๋‹ค์Œ์€, ํ”„๋กœ๊ทธ๋žจ ์ปดํŒŒ์ผ์‹œ ํ„ฐ๋ฏธ๋„์— ๋งจ ์ฒ˜์Œ ์ถœ๋ ฅ๋˜๋Š” ์ฐฝ์ด๋‹ค.

๋ธ”๋Ÿญ์ด ๋‚ด๋ ค์˜ค๋Š” ์†๋„๋ฅผ ํ”Œ๋ ˆ์ด ์œ ์ €๊ฐ€ ์ˆซ์ž 1 - 10 ์‚ฌ์ด๋กœ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.
'1' ์ด ์ œ์ผ ๋Š๋ฆฐ ์†๋„๋กœ ๋‚ด๋ ค์˜ค๋ฉฐ '10' ์— ๊ฐ€๊นŒ์šด ์ˆซ์ž์ผ ์ˆ˜๋ก ์†๋„๊ฐ€ ๋นจ๋ผ์ง„๋‹ค.

1. ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด ํ•  ๋•Œ, ๊ธฐ๋ณธ์ ์ธ ํ‚ค ์ž…๋ ฅ์ด๋‹ค.

ํ‚ค ์กฐ์ž‘๋ฒ• โŒจ

ํ‚ค ์ž…๋ ฅํ–‰๋™
โฌ†๏ธ๋ธ”๋Ÿญ์„ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ 90๋„ ํšŒ์ „์‹œํ‚จ๋‹ค.
โžก๏ธ๋ธ”๋Ÿญ์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ์นธ ์ด๋™ํ•œ๋‹ค.
โฌ…๏ธ๋ธ”๋Ÿญ์„ ์™ผ์ชฝ์œผ๋กœ ํ•œ์นธ ์ด๋™ํ•œ๋‹ค.
โฌ‡๏ธ๋ธ”๋Ÿญ์„ ์•„๋ž˜์ชฝ์œผ๋กœ ํ•œ์นธ ์ด๋™ํ•œ๋‹ค.
Space Bar๋ธ”๋Ÿญ์„ ์ฆ‰์‹œ ๋งจ ๋ฐ‘์œผ๋กœ ๋‚ด๋ฆฐ๋‹ค.

ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์„ ์ˆ™์ง€ ํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ€์ž.

2. ์†๋„๋ฅผ ์ž…๋ ฅํ•œ ํ›„์— ๋‚˜์˜ค๊ฒŒ ๋˜๋Š” ์ฐฝ์ด๋‹ค.

๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด ๋ฐฉ๋ฒ•

  • ๋ธ”๋Ÿญ์„ ๊ฒŒ์ž„ํŒ์ด ์•ˆ๋„˜์น˜๋„๋ก ์Œ“๋Š”๋‹ค.
  • ๋ธ”๋Ÿญ์€ ๊ฐ€๋กœ์ค„๋กœ ํ•œ ์ค„์ด ์™„์„ฑ๋  ๊ฒฝ์šฐ ์‚ญ์ œ๊ฐ€ ๋œ๋‹ค.
  • ๊ฐ€๋กœ์ค„์„ 3๋ฒˆ ์ง€์šธ๋•Œ๋งˆ๋‹ค ์†๋„๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•œ๋‹ค.
  • ๋ธ”๋Ÿญ์€ ํ•ญ์ƒ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

3.๋ธ”๋Ÿญ์ด ๊ฒŒ์ž„ํŒ์„ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ ํ‘œ์‹œ๋˜๋Š” ์ฐฝ์ด๋‹ค.

๋ธ”๋Ÿญ์ด ๊ฒŒ์ž„ํŒ์„ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ ํ‘œ์‹œ๋˜๋Š” ์ฐฝ์ด๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€ ํ”„๋กœ๊ทธ๋žจ์ด ์–ด๋–ค์‹์œผ๋กœ ๋Œ์•„๊ฐ€๋Š”์ง€๋ฅผ ์•Œ์•„๋ณด์•˜๋‹ค.

๊ฐ ํ—ค๋”ํŒŒ์ผ,์†Œ์ŠคํŒŒ์ผ์˜ ๊ธฐ๋Šฅ ๐Ÿ‘พ

์ด ํ…ŒํŠธ๋ฆฌ์Šค ๊ฒŒ์ž„์€ ์ด 10๊ฐœ์˜ ์ฝ”๋“œํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋˜์žˆ์œผ๋ฉฐ
ํ—ค๋” ํŒŒ์ผ 5๊ฐœ, ์†Œ์Šค ํŒŒ์ผ 5๊ฐœ๋กœ ๊ตฌ์„ฑ๋˜์žˆ๋‹ค.

/* -Header Files list- */
	 Block.h
     Constant.h 
     TetrisManager.h
     TetrisView.h
     Util.h
/* -Source Files list- */
	Main.c
    Block.c
    TetrisManager.c
    TetrisView.c
    Util.c

์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑ ๋˜์–ด์žˆ๋Š”๋ฐ ํ•˜๋‚˜์”ฉ ๋ฌด์Šจ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ํŒŒ์ผ์ธ์ง€ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž.

block.c , block.h

/* =============================== block.h =============================== */
#ifndef _BLOCK_H
#define _BLOCK_H

typedef struct _point{
	int x;
	int y;
}Point;

#define POSITIONS_SIZE 4

typedef struct _block{
	Point positions[POSITIONS_SIZE][POSITIONS_SIZE];
	int current;
	int next;
	int direction;
}Block;

Block Block_Make(int isFirst, Block block);
Block Block_Move(Block block, int direction);
Point* Block_GetPositions(Block block);
void Block_PrintNext(Block block, int x, int y);

#endif
/* =============================== block.c =============================== */
#include <time.h>
#include <windows.h>
#include <stdio.h>
#include "Block.h"
#include "Util.h"
#include "Constant.h"
#define BLOCK_EXAMPLES_SIZE 6
const static Point blockExamples[BLOCK_EXAMPLES_SIZE][POSITIONS_SIZE][POSITIONS_SIZE] = {...}

static Block _Block_MoveToDown(Block block);
static Block _Block_MoveToLeft(Block block);
static Block _Block_MoveToRight(Block block);
static Block _Block_RotateRight(Block block);

Block Block_Make(int isFirst, Block block) {...}
Block Block_Move(Block block, int direction) {...}
Point* Block_GetPositions(Block block) {...}
void Block_PrintNext(Block block, int x, int y) {...}
static Block _Block_MoveToDown(Block block) {...}
static Block _Block_MoveToLeft(Block block) {...}
static Block _Block_MoveToRight(Block block) {...}
static Block _Block_RotateRight(Block block) {...}

Block.c ์™€ Block.h ํŒŒ์ผ์˜ ๊ธฐ๋Šฅ์€,
๋ธ”๋Ÿญ์˜ ํ˜•ํƒœ๋ฅผ ์ œ์ž‘, ๋ธ”๋Ÿญ์„ ํ…ŒํŠธ๋ฆฌ์Šค ํŒ์—์„œ ์ž…๋ ฅ์— ๋งž๊ฒŒ ์›€์ง์ด๊ฒŒ,
๋ธ”๋Ÿญ์˜ ๋‹ค์Œ ์ถœ๋ ฅ์„ ๋žœ๋คํ•˜๊ฒŒ ๋“ฑ ๋ธ”๋Ÿญ์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ˆˆ ์—ฌ๊ฒจ ๋ณผ์ ์€ ๋‹ค์Œ ๋ถ€๋ถ„์ด๋‹ค.

blockExamples[BLOCK_EXAMPLES_SIZE][POSITIONS_SIZE][POSITIONS_SIZE] = {...} 

ํ•ด๋‹น ๋ถ€๋ถ„์€, ์ถœ๋ ฅ๋  ๋ธ”๋Ÿญ๋“ค์˜ ๋ชจ์–‘์„ ์ƒ์ˆ˜ ๋ฐฐ์—ด(๋ณ€ํ•˜์ง€ ์•Š๋Š”)๋กœ ์„ ์–ธํ–ˆ๋‹ค.
์ฝ”๋“œ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด์„œ, ์ž์„ธํ•œ ๋ถ€๋ถ„์€ ๊นƒํ—ˆ๋ธŒ์— ์˜ฌ๋ฆฐ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๋ ๋“ฏํ•˜๋‹ค.

๋‹ค์Œ์œผ๋กœ block.c,h ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

static Block _Block_MoveToDown(Block block);
static Block _Block_MoveToLeft(Block block);
static Block _Block_MoveToRight(Block block);
static Block _Block_RotateRight(Block block);

์œ„์˜ ํ•จ์ˆ˜๋“ค์€ static ์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋“ค๋กœ Block.cํŒŒ์ผ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ
๊ฐ ๊ธฐ๋Šฅ๋“ค์€ ์œ ์ €๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์— ๋”ฐ๋ผ ๋ธ”๋ก์„ ์›€์ง์ด๊ฒŒ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ–๊ณ ์žˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

Block Block_Make(int isFirst, Block block) {...}
Block Block_Move(Block block, int direction) {...}
Point* Block_GetPositions(Block block) {...}
void Block_PrintNext(Block block, int x, int y) {...}

๋‹ค์Œ ํ•จ์ˆ˜๋“ค์€,

๋ธ”๋Ÿญ์„ ์ถœ๋ ฅ ๋ฐ ๋žœ๋ค์œผ๋กœ ์ถœ๋ ฅ, Block Block_Make(int isFirst, Block block)
๋ธ”๋Ÿญ์˜ ์›€์ง์ด๊ฒŒ, Block Block_Move(Block block, int direction)
๋ธ”๋Ÿญ์˜ ์ขŒํ‘œ๋ฅผ ์žก์•„์ฃผ๋Š” ๊ธฐ๋Šฅ์„, Point* Block_GetPositions(Block block)
๋‹ค์Œ ๋ธ”๋Ÿญ์˜ ์ถœ๋ ฅ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅvoid Block_PrintNext(Block block, int x, int y)

์ด๋ผ๊ณ  ๋ณด๋ฉด ๋ ๋“ฏ ํ•˜๋‹ค.


Util.c , Util.h

/* =============================== Util.h =============================== */
#pragma once
#ifndef _UTIL_H
#define _UTIL_H

void CursorUtil_GotoXY(int x, int y);
void CursorUtil_Hide();

#endif
/* =============================== block.c =============================== */
#include <Windows.h>
#include "Util.h"

void CursorUtil_GotoXY(int x, int y) {
	COORD pos = { x, y };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void CursorUtil_Hide() {
	CONSOLE_CURSOR_INFO cursorInfo;
	cursorInfo.dwSize = 1;
	cursorInfo.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

Util.c ์™€ Util.h ํŒŒ์ผ์˜ ๊ธฐ๋Šฅ์€
์ปค์„œ์˜ ์œ„์น˜(ํ„ฐ๋ฏธ๋„์—์„œ์˜ ์ถœ๋ ฅ ์ขŒํ‘œ ์œ„์น˜)๋ฅผ ์–ป๊ณ , ์ปค์„œ๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ–๊ณ ์žˆ๋‹ค.

void CursorUtil_GotoXY(int x, int y) ์˜ ๊ธฐ๋Šฅ์€ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ int x,y ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ SetConsoleCursorPositionํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ปค์„œ๋ฅผ ์ด๋™์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ๊ฐ–๊ณ ์žˆ๋‹ค.

void CursorUtil_Hide()์˜ ๊ธฐ๋Šฅ์€, ํ‘œ์‹œ๋˜๋Š” ์ปค์„œ๋ฅผ ์ˆจ๊ธฐ๋Š” ์—ญํ• ์ด๋ผ๊ณ  ๋ด์•ผํ• ๋“ฏ ํ•˜๋‹ค.


TetrisManager.c , TetrisManager.h

TetrisManager ๋ถ€๋ถ„์€, ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธด ๊ด€๊ณ„๋กœ,
๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š” ํŒŒ์ผ์ธ์ง€๋งŒ ์•Œ์•„๋ณด๊ณ  ๊ฐ€์ž.
์‚ฌ์‹ค์ƒ ์ œ์ผ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๋Š” ํŒŒ์ผ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ ๊ธฐ๋Šฅ์„ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๊ฒŒ์ž„์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ
  • ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด์‹œ ๊ฒŒ์ž„ํŒ์˜ ์ดˆ๊ธฐํ™” ๋ฐ ์ถœ๋ ฅ ๊ธฐ๋Šฅ
  • ๋ธ”๋Ÿญ์ด ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ๋‚ฌ์„๋•Œ์˜ ๋ถ„๊ธฐ์  ์ƒ์„ฑ
    ( ์˜ˆ : ๋ธ”๋Ÿญ์ด ๊ฐ€๋กœ์ค„์„ ์™„์„ฑํ–ˆ์„๋•Œ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ ์™ธ ์—ฌ๋Ÿฌ๊ฐ€์ง€)

    ์ด์™ธ์—๋„ ์ค‘์š”ํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ๋งŽ๋‹ค.

์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š”์ง€ ๋‚ด์šฉ๋งŒ ์•Œ์•„๋ณด์ž.

/* ====================== TetrisManager Function() ======================= */

void TetrisManager_Init(TetrisManager* tetrisManager, int speedLevel); 
int TetrisManager_CheckValidPosition(TetrisManager* tetrisManager, int direction);
void TetrisManager_ChangeBoardByDirection(TetrisManager* tetrisManager, int direction);
void TetrisManager_ChangeBoardByAuto(TetrisManager* tetrisManager);
void TetrisManager_ProcessDirectDown(TetrisManager* tetrisManager);
void TetrisManager_ProcessDeletingLines(TetrisManager* tetrisManager);
int TetrisManager_IsReachedToBottom(TetrisManager* tetrisManager);
int TetrisManager_ProcessReachedCase(TetrisManager* tetrisManager);
void TetrisManager_Sleep(TetrisManager* tetrisManager);
void TetrisManager_Print(TetrisManager* tetrisManager);

static void _TetrisManager_ClearBoard(TetrisManager* tetrisManager);
static void _TetrisManager_ChangeBoardByStatus(TetrisManager* tetrisManager, int status);
static void _TetrisManager_UpSpeedLevel(TetrisManager* tetrisManager);
static void _TetrisManager_SearchLineIndexesToDelete(TetrisManager* tetrisManager, int* indexes, int* count);
static void _TetrisManager_DeleteLines(TetrisManager* tetrisManager, int* indexes, int count);

TetrisView.c , TetrisView.h

/* ============================= TetrisView.h =============================== */
#ifndef _TETRIS_VIEW_H
#define _TETRIS_VIEW_H

#include "TetrisManager.h"

typedef struct _tetrisView{
	TetrisManager tetrisManager;
}TetrisView;

void TetrisView_StartGame(TetrisView* tetrisView);
void TetrisView_ProcessGame(TetrisView* tetrisView, int processType, int direction);
void TetrisView_EndGame(TetrisView* tetrisView);

#endif
/* ============================= TetrisView.c ============================= */
#include ...
#pragma comment(lib, "winmm.lib")
#define TETRIS_BACKGROUND_MUSIC_FILE_NAME " ~~~.wav "

void TetrisView_StartGame(TetrisView* tetrisView) {...}

void TetrisView_ProcessGame(TetrisView* tetrisView, int processType, int direction){...}

void TetrisView_EndGame(TetrisView* tetrisView){...}

TetrisView ํŒŒ์ผ๋“ค์˜ ๊ธฐ๋Šฅ์€ User Interface(UI) ๊ธฐ๋Šฅ ๋ฐ ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด ๊ตฌํ˜„์ด๋ผ๊ณ  ์ƒ๊ฐ๋œ๋‹ค.

์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

#pragma comment(lib, "winmm.lib")
#define TETRIS_BACKGROUND_MUSIC_FILE_NAME " ~~~.wav "

ํ•ด๋‹น ๋ถ€๋ถ„์€ , ์ปดํŒŒ์ผ ์‹œ ๋…ธ๋ž˜๊ฐ€ ๋‚˜์˜ค๋„๋ก ์„ ์–ธํ•œ ๊ฒƒ์ด๋ฉฐ
void TetrisView_StartGame(TetrisView* tetrisView) ํ•จ์ˆ˜์•ˆ์—
๋…ธ๋ž˜๊ฐ€ ํ”Œ๋ ˆ์ด ๋˜๋„๋ก ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์„ ์–ธ ํ•ด์ค€๋“ฏ ํ•˜๋‹ค.

void TetrisView_StartGame(TetrisView* tetrisView);
void TetrisView_ProcessGame(TetrisView* tetrisView, int processType, int direction);
void TetrisView_EndGame(TetrisView* tetrisView);

ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์€ ๊ฐ๊ฐ
๊ฒŒ์ž„์„ ์‹œ์ž‘ํ• ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜ void TetrisView_StartGame()
๊ฒŒ์ž„์ค‘์— ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜ void TetrisView_ProcessGame()
๊ฒŒ์ž„์ด ๋๋‚ฌ์„ ๊ฒฝ์šฐ์— ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜ void TetrisView_EndGame()
๋ฅผ ์˜๋ฏธ ํ•œ๋‹ค.


Constant.h

/* ======== Constant.h ======== */
#ifndef _CONSTANT_H
#define _CONSTANT_H

enum Boolean{
	False, True
};

enum Direction{
	UP, RIGHT, DOWN, LEFT
};

enum ProcessType{
	DIRECTION, DIRECT_DOWN, AUTO
};

enum KeyCode{
	UP_KEY_CODE = 72, LEFT_KEY_CODE = 75, 
	RIGHT_KEY_CODE = 77, DOWN_KEY_CODE = 80, 
	SPACE_BAR_KEY_CODE = 32
};

enum BoardType{
	EMPTY,
	MOVING_BLOCK, FIXED_BLOCK,
	LEFT_WALL, RIGHT_WALL, BOTTOM_WALL, TOP_WALL,
	LEFT_TOP_EDGE, RIGHT_TOP_EDGE, LEFT_BOTTOM_EDGE, RIGHT_BOTTOM_EDGE
};

#define MAX_SPEED_LEVEL 10
#define MIN_SPEED_LEVEL 1

#endif

Constant.h ์ด ํŒŒ์ผ์€ ์•ž์œผ๋กœ ๋ชจ๋“  ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์—ด๊ฑฐํ˜• ์ƒ์ˆ˜๋“ค์˜ ์„ ์–ธ์„
ํ†ต์งธ๋กœ ๋ชจ์•„๋‘” ํŒŒ์ผ์ธ๋ฐ,

๋‚˜๋Š” ์ด ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉฐ C์–ธ์–ด์˜ ๊ณ ์งˆ์ ์ธ ๋ฌธ์ œ๋ฅผ ์•Œ์ˆ˜์žˆ์—ˆ๋˜ ํŒŒ์ผ์ด์˜€๋‹ค.
์ž์„ธํžˆ ๋ณด๋ฉด, enum Boolean ์„ ์–ธ ๋ถ€๋ถ„์€ ๋‹จ์ˆœํžˆ True(=1), False(=0)์„ ์„ ์–ธํ•œ ๊ฒƒ์„ ์•Œ์ˆ˜์žˆ๋‹ค.

๋น„๊ต์  ์ตœ์‹  ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์–ธ์–ด์ธ ํŒŒ์ด์ฌ๊ณผ ๋น„๊ตํ•ด๋ดค์„๋•Œ ์ƒ๋‹นํžˆ ๋ถˆ์นœ์ ˆ ํ•˜๋‹ค๊ณ  ๋Š๋‚„์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋‚˜๋Š” ์ด๋Ÿฐ ์ ์ด ์˜คํžˆ๋ ค C์–ธ์–ด์˜ ๋งค๋ ฅ์ด ์•„๋‹๊นŒ? ๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค๊ธฐ๋„ ํ•œ๋‹ค.


Main.c

#include <...>

int main(int argc, char* argv[]){
	TetrisView tetrisView;
	TetrisView_StartGame(&tetrisView);
	int processType;
	int direction;
	while (True){
		processType = AUTO;
		direction = DOWN;
		if (_kbhit()){
			int key = _getch();
			if (_kbhit()){
				key = _getch();
				switch (key){
				case UP_KEY_CODE:
					processType = DIRECTION;
					direction = UP;
					break;
				case LEFT_KEY_CODE:
					processType = DIRECTION;
					direction = LEFT;
					break;
				case RIGHT_KEY_CODE:
					processType = DIRECTION;
					direction = RIGHT;
					break;
				case DOWN_KEY_CODE:
					processType = DIRECTION;
					direction = DOWN;
					break;
				}
			}
			else{
				switch (key){
				case SPACE_BAR_KEY_CODE:
					processType = DIRECT_DOWN;
				}
			}
		}
		TetrisView_ProcessGame(&tetrisView, processType, direction);
	}
	return 0;
}

์‚ฌ์‹ค์ƒ ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ€๋™๋˜๋Š” ๋ถ€๋ถ„์ธ Main.c ๋ฉ”์ธ ํŒŒ์ผ์ด๋‹ค.
์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์ ์œผ๋กœ ๋ด์•ผํ•  ๋ถ€๋ถ„์€ (_kbhit()) ํ•จ์ˆ˜๊ฐ€ 2๋ฒˆ ํ˜ธ์ถœ๋จ์„ ์•Œ์ˆ˜์žˆ๋Š”๋ฐ,
์™œ ๊ทธ๋Ÿฐ๊ฐ€ ์ดํ•ด๊ฐ€ ์•ˆ๋˜์–ด ์ฐพ์•„๋ณธ ๊ฒฐ๊ณผ,

๋ฐฉํ–ฅํ‚ค๋Š”, ์ž…๋ ฅ ๋ฒ„ํผ์— 2 ๊ฐœ์˜ ๊ฐ’์ด ์—ฐ์†์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 
์ฒซ ๋ฒˆ์งธ๋Š” 0xE0 (= 224), ๊ทธ๋ฆฌ๊ณ  ๋ฐฉํ–ฅํ‚ค์— ๋Œ€ํ•œ ์ •์ˆ˜ ๊ฐ’ ์ด๋ ‡๊ฒŒ 2 ๊ฐœ๊ฐ€ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์—, 
๋‘ ๋ฒˆ ์ž…๋ ฅ๋ฒ„ํผ๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 
16 ๋ผ์ธ์—์„œ _kbhit ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ํ›„ ๋ฐ˜ํ™˜๊ฐ’์ด 0 ์ด ์•„๋‹ˆ๋ฉด, ์ƒ,ํ•˜,์ขŒ,์šฐ ๋ฐฉํ–ฅ ํ‚ค ์ค‘ 
ํ•˜๋‚˜๊ฐ€ ๋ˆŒ๋ ธ๋‹ค๋Š” ๋ง์ด๊ธฐ ๋•Œ๋ฌธ์—, 
switch ~ case ๋ฌธ์—์„œ ๋ถ„๊ธฐํ•˜์—ฌ, ๊ฐ๊ฐ์— ํ•ด๋‹นํ•˜๋Š” processType ๊ณผ direction ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ฆ‰ ๋ฐฉํ–ฅํ‚ค ๊ฐ™์€ ๊ฒฝ์šฐ์—” *์ž…๋ ฅ ๋ฒ„ํผ ์— 2๊ฐœ์˜ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์—,
์ž…๋ ฅ๋ฒ„ํผ๋กœ๋ถ€ํ„ฐ ๋‘๋ฒˆ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ํ™•์ธํ•ด์•ผํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.
์ •๋ง๋กœ C์–ธ์–ด๋Š” ๊น๊นํ•˜๋‹ค.

*์ž…๋ ฅ ๋ฒ„ํผ๋ž€?
scanf_s ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” ๋ฐ”๋กœ ํ”„๋กœ๊ทธ๋žจ์— ์ฝํ˜€์ง€๋Š” ๊ฒƒ์ด ์•„๋‹Œ,
์ž…๋ ฅ ๋ฒ„ํผ์— ์ €์žฅ ๋œ ํ›„, ์ž…๋ ฅ ๋ฒ„ํผ์˜ ๋‚ด์šฉ์ด ํ”„๋กœ๊ทธ๋žจ์— ์ „๋‹ฌ๋˜๋Š” ์ฆ‰ 2๋ฒˆ์˜ ์ „๋‹ฌ์„ ๊ฑฐ์นœ๋‹ค๋Š” ๋œป์ด๋‹ค.


๋งˆ์น˜๋ฉฐ,

์ฝ”๋“œ๋ถ„์„์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฝ”๋“œ์˜ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด๋งŽ์•„
๋ณธ๋ฌธ์—์„œ ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ์ง„ ๋ชปํ–ˆ๊ณ 
์ „์ฒด์ ์ธ ํ”„๋กœ๊ทธ๋žจ์˜ ํ๋ฆ„ ๋ฐ ํ”„๋กœ๊ทธ๋žจ์„ ๋Œ์•„๊ฐ€๊ฒŒํ•˜๋Š” ์ „์ฒด์ ์ธ ํŒŒ์ผ,
๊ฐ ์†Œ์Šค ํŒŒ์ผ ๋ฐ ํ—ค๋”ํŒŒ์ผ์˜ ๊ธฐ๋Šฅ๋“ค์„ ์•„์ฃผ ๊ฐ„๋‹จํ•œ๊ฒŒ ์„ค๋ช…ํ–ˆ๋Š”๋ฐ,
์„ค๋ช…์ด ๋„ˆ๋ฌด ๋ถ€์กฑํ–ˆ๋˜๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ์—ˆ๋‹ค.

๊ฒŒ์ž„ ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•˜๊ณ  ๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ์ฐพ๋Š” ๊ณผ์ •์— ์žˆ์–ด์„œ
๋Š๋ผ๋Š”๊ฒŒ ๋งŽ์•˜๋‹ค. ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ ๋ฝ‘์ž๋ฉด,

1. ํ™•์‹คํžˆ ์ฝ”๋“œ๋Š” ๋ณด๋ฉด์„œ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์ง์ ‘ ๋ถ€๋”ชํ˜€ ๋ด์•ผํ•œ๋‹ค.

2. ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ๊ณ ๋ คํ•˜๊ณ  ์„ค๊ณ„ ํ•ด์•ผํ•  ๋ถ€๋ถ„์ด ๋งค์šฐ ๋งŽ์€๊ฒƒ ๊ฐ™๋‹ค.

3. ๊ฒŒ์ž„ํ•˜๋‹ค๊ฐ€ ๋ฒ„๊ทธ ๋‚ฌ๋‹ค๊ณ  ์š•ํ•˜๋Š”์ง“์ด์•ผ ๋ง๋กœ ์–ด๋ฆฌ์„์€ ์ง“์ด๋‹ค.
์„ธ์ƒ์— ๋ฒ„๊ทธ๊ฐ€ ์—†๋Š” ํ”„๋กœ๊ทธ๋žจ์€ ์—†๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

3๋ฒˆ์€ ๋†๋‹ด ๋ฐ˜ ์ง„๋‹ด ๋ฐ˜์œผ๋กœ ํ•œ์†Œ๋ฆฌ๊ณ  ๐Ÿ˜ต
์ด๋ฒˆ ๊ธฐํšŒ๋กœ ๋งค์šฐ ํฐ ๊ณต๋ถ€๊ฐ€ ๋๊ณ 
๊ฒŒ์ž„์ด๋“  ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์ด๋“  ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐœ๋ฐœํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์กด๊ฒฝํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋“ค์–ด๊ฐ€๋ฉด ๋“ค์–ด๊ฐˆ์ˆ˜๋ก ์‹ฌ์˜คํ•ด์ง€๋Š” ๋Š๋‚Œ์ด๋‹ค.

profile
๐Ÿ‹

0๊ฐœ์˜ ๋Œ“๊ธ€