맥에서 C로 소코반 게임 만들기
in Devlog on C
맥에서 콘솔로 C게임 만들기
- 맥에서 테트리스라던지, 간단한 콘솔 게임을 만들고 싶었는데 인터넷에 올라와있는 자료들은 대부분 윈도우 os 기준으로 작성되어 있었다.
- gotoxy라던지 키보드 입력을 받는 부분에서 맥에서는 호환이 되지 않았다.
- 맥에서 콘솔게임을 만들어보고 싶어 소코반이라는 콘솔게임을 윈도우에서 구현해 놓은 자료를 참고해서 코드를 변경해 맥에서 구현해 보았다.
참고 출처 : http://cafe.naver.com/clubc/2572
소스 코드 : https://gist.github.com/yunsu3042/6994300d7b74ae8b53c0069c1bec197a
/*
CURHELLO.C
==========
(c) Copyright Paul Griffiths 1999
Email: mail@paulgriffiths.net
"Hello, world!", ncurses style.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>
#include <term.h>
#include <termios.h>
#include <unistd.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
#define ESC 27
#define LEFT 68
#define RIGHT 67
#define UP 65
#define DOWN 66
#define MAXSTAGE 2
void gotoxy(int x, int y)
{
printf("\033[%d;%df", y, x);
fflush(stdout);
}
#define clean() printf("\033[H\033[J")
#define putchxy(x,y,c) {gotoxy(x,y); putchar(c);}
void loadStage(void);
void drawStage(void);
void playerMoveAction(void);
int _getch(void);
BOOL testStageClear(void);
void printInfo(void);
void restart(void);
int _getch(void)
{
int ch;
struct termios buf;
struct termios save;
tcgetattr(0, &save);
buf = save;
buf.c_lflag &= ~(ICANON|ECHO);
buf.c_cc[VMIN] = 1;
buf.c_cc[VTIME] = 0;
tcsetattr(0, TCSAFLUSH, &buf);
ch = getchar();
tcsetattr(0, TCSAFLUSH, &save);
return ch;
}
const char stageData[MAXSTAGE][18][21] =
{
{
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"## O .##",
"## @ O .##",
"## O .##",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################"
},
{
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"##########.##########",
"########## ##########",
"##########O@O.#######",
"########. OO ########",
"########### #########",
"###########.#########",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
"#####################",
}
};
char stage[18][21];
int roundNum;
int roundx, roundy;
int numMove = 0;
int onRestart;
void drawStage()
{
for(int stagey = 0; stagey < 18; stagey++)
{
for(int stagex = 0; stagex < 21; stagex++)
{
putchxy(stagex + 1, stagey, stage[stagey][stagex]);
}
}
putchxy(roundx + 1, roundy,'@');
}
BOOL testStageClear()
{
int cx, cy;
for(cy = 0; cy < 18; cy++)
{
for(cx = 0; cx < 21; cx++)
{
if(stageData[roundNum][cy][cx] == '.' && stage[cy][cx] != 'O')
{
return FALSE;
}
}
}
return TRUE;
}
void loadingStage()
{
int i;
int long_term = 100000;
for(i = 0; i < 45; i++)
{
putchxy(10 + i, 5, '-');
usleep(10000);
}
for(i = 0; i < 45; i++)
{
putchxy(70-i, 10, '-');
usleep(10000);
}
usleep(800000);
gotoxy(35, 7);
printf("소");
usleep(long_term);
gotoxy(38, 7);
printf("코");
usleep(long_term);
gotoxy(41, 7);
printf("반");
usleep(long_term);
putchxy(48, 8, 'M');
usleep(long_term);
putchxy(49, 8, 'a');
usleep(long_term);
putchxy(50, 8, 'd');
usleep(long_term);
putchxy(51, 8, 'e');
usleep(long_term);
putchxy(52, 8, 'b');
usleep(long_term);
putchxy(53, 8, 'y');
usleep(long_term);
gotoxy(58, 8);
printf("Yunsoo");
printf("\n\n\n\n");
usleep(1000000);
}
void playerMoveAction()
{
int dx, dy;
char ch;
ch = _getch();
if(ch == 'r' || ch == 'R')
{
restart();
}
if(ch == 27)
{
ch = _getch();
if(ch == 91)
{
ch = _getch();
switch (ch) {
case RIGHT:
{
dx = 1;
dy = 0;
break;
}
case LEFT:
{
dx = -1;
dy = 0;
break;
}
case UP:
{
dx = 0;
dy = -1;
break;
}
case DOWN:
{
dx = 0;
dy = 1;
break;
}
}
}
}
else return;
if(stage[roundy + dy][roundx + dx] == '#')
{
return ;
}
if(stage[roundy + dy][roundx + dx] == 'O')
{
if(stageData[roundNum][roundy + dy * 2][roundx + dx * 2] == ' ')
{
stage[roundy + dy * 2][roundx + dx * 2] = 'O';
stage[roundy + dy][roundx + dx] = ' ';
}
else if(stageData[roundNum][roundy + dy * 2][roundx + dx * 2] == '#')
{
return ;
}
else if(stageData[roundNum][roundy + dy * 2][roundx + dx * 2] == '.')
{
stage[roundy + dy][roundx + dx] = ' ';
stage[roundy + dy * 2][roundx + dx * 2] = 'O';
}
}
roundx += dx;
roundy += dy;
numMove++;
}
void printInfo()
{
gotoxy(59, 1); printf("┏━━━━━━━━━━━━━━━┓");
gotoxy(59, 2); printf("┃ S O K O B A N ┃");
gotoxy(59, 3); printf("┗━━━━━━━━━━━━━━━┛");
gotoxy(61, 5); printf("스테이지 : %d", MAXSTAGE -1);
gotoxy(61, 7); printf("움직인 횟수 : %d", numMove);
gotoxy(67, 10); printf("UP");
gotoxy(67, 11); printf("↑");
gotoxy(60, 12); printf("LEFT ←");
gotoxy(68, 12); printf("→ RIGHT");
gotoxy(67, 13); printf("↓");
gotoxy(66, 14); printf("DOWN");
gotoxy(61, 16); printf("다시하기 : R");
}
void restart()
{
onRestart = 1;
}
int main()
{
int x,y;
// initscr();
clean();
curs_set(0);
loadingStage();
roundNum = 0;
while(1)
{
numMove = 0;
memcpy(stage, stageData[roundNum], sizeof(stage));
for(y = 0; y < 18; y++)
{
for(x = 0; x < 21; x++)
{
if(stage[y][x] == '@')
{
roundx = x;
roundy = y;
stage[y][x] = ' ';
}
}
}
clean();
while(1)
{
drawStage();
printInfo();
playerMoveAction();
if(onRestart == 1)
{
onRestart = 0;
break;
}
if(testStageClear())
{
clean();
printf("축하합니다.");
gotoxy(29, 5);
printf("%d 스테이지 클리어", roundNum + 1);
gotoxy(34, 8);
printf("다음 스테이지로 이동하겠습니다.");
usleep(1000000);
if(roundNum < MAXSTAGE - 1)
{
roundNum++;
}
break;
}
}
}
return 0;
}