/*
심심하기도 하고 이거 하다가 막히는 사람이 있길래 참고하라고 만들어봤음.
대충 만들어서 코드도 좀 더럽고, 버그가 있을 수 있음.
전역변수, 맵 사이즈, 지도 값등을 숫자로 직접 쓴건 간단하게 하려고 그런거고 그건 안쓰는게 좋음
여긴 게임 구현만 해놨고, 조작하는건 없음.
사용법은 ./sokoban [레벨] [명령] 이고 명령은 rlud 에서 골라서 쓰면 됨(right, left, up, down)
예: ./sokoban 1 rulurrrrllldddldrrrdruu
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// 0 빈 공간
// 1 벽
// 2 별
// 3 플레이어
// 4 상자
// 5 별+상자
// 6 플레이어+상자
static const int stages[][8][8] =
{
{
{1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,1},
{1,0,2,0,1,1,1,1},
{1,3,0,0,1,4,1,1},
{1,0,0,0,1,0,1,1},
{1,0,0,0,0,0,1,1},
{1,0,0,0,0,0,1,1},
{1,1,1,1,1,1,1,1}
},
{
{1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,4,1},
{1,0,2,0,1,1,1,1},
{1,3,0,0,1,4,1,1},
{1,0,0,0,1,0,1,1},
{1,0,2,0,0,0,1,1},
{1,0,0,0,0,0,1,1},
{1,1,1,1,1,1,1,1}
},
};
static int current_stage, x, y;
static int stage[8][8];
int set_stage(int level)
{
current_stage = level;
memcpy(stage, &stages[level], sizeof(stage));
for(y = 0; y < 8; y++)
{
for(x = 0; x < 8; x++)
{
if(stage[y][x] == 3)
{
return 0;
}
}
}
return -1;
}
int print_stage(void)
{
int i, j;
//for(i = 0; i < 24; i++)
//putchar(\'\\n\');
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
switch(stage[i][j])
{
case 0: putchar(\' \'); break;
case 1: putchar(\'#\'); break;
case 2: putchar(\'*\'); break;
case 3: putchar(\'$\'); break;
case 4: putchar(\'=\'); break;
case 5: putchar(\'+\'); break;
case 6: putchar(\'?\'); break;
}
}
putchar(10);
}
return 0;
}
int check_stage(void)
{
int i, j;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
if(stage[i][j] == 2)
{
return 0;
}
}
}
return 1;
}
int movep(int dx, int dy)
{
int *p;
int d;
int *crnt, *next, *next2;
int wplayer;
crnt = &stage[y][x]; // 현재 위치
wplayer = *crnt == 6?4:0; // 현재 상태가 플레이어+상자일 경우 플레이어 이동 후 채울 값
if(dx)
{
p = &x; // x값을 변경
d = dx;
next = &stage[y][x+dx]; // 플레이어가 이동할 예정인 자리의 값
next2 = &stage[y][x+dx+dx]; // 플레이어가 이동할 예정인 자리 다음 값 - 별을 움직일때 필요
}
else
{
p = &y;
d = dy;
next = &stage[y+dy][x];
next2 = &stage[y+dy+dy][x];
}
if((d<0)?(*p > 0):(*p < 7)) // 경계 확인
{
switch(*next)
{
case 0: *p += d; *next = 3; *crnt = wplayer; break;
case 1: break;
case 2:
if((d<0)?(*p > 1):(*p < 6)) // 경계 확인
{
switch(*next2)
{
case 0: *p += d; *crnt = wplayer; *next = 3; *next2 = 2;
case 1: case 2: case 3: case 5: case 6: break; // 움직이지 않음
case 4: *p += d; *crnt = wplayer; *next = 3; *next2 = 5;
}
}
break;
case 4: *p += d; *crnt = wplayer; *next = 6; break;
case 5:
if((d<0)?(*p > 1):(*p < 6))
{
switch(*next2)
{
case 0: *p += d; *crnt = wplayer; *next = 6; *next2 = 2;
case 1: case 2: case 3: case 5: case 6: break;
case 4: *p += d; *crnt = wplayer; *next = 6; *next2 = 5;
}
}
break;
}
}
return 0;
}
int move(char *dir)
{
while(*dir)
{
switch(*dir)
{
case \'l\':
movep(-1, 0);
break;
case \'r\':
movep(1, 0);
break;
case \'u\':
movep(0, -1);
break;
case \'d\':
movep(0, 1);
break;
}
dir++;
}
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
set_stage(argv[1]?atoi(argv[1]):0);
move(argv[2]?argv[2]:\"\");
print_stage();
if(check_stage())
{
printf(\"Completed\\n\");
}
return EXIT_SUCCESS;
}
댓글 0