이런식의 모양을 만들어야한다.
소용돌이 치듯이.
직관적으로 방향에 따라 만들기
배열로 만들기
#include <iostream>
#include <assert.h>
#include <iomanip>
using namespace std;
// 달팽이 문제
// 5~9 사이의 숫자 입력
const int MAX = 100;
int board[MAX][MAX] = {};
int input;
enum Dir
{
RIGHT,
LEFT,
DOWN,
UP,
};
void PrintBoard()
{
for (int x = 0; x < input; ++x)
{
for (int y = 0; y < input; ++y)
{
cout << setfill('0') << setw(2) << board[x][y] << " ";
}
cout << endl;
}
}
bool CanGo(int y, int x)
{
if (y < 0 || y >= input)
return false;
if (x < 0 || x >= input)
return false;
if (board[y][x] != 0)
return false;
return true;
}
void SetBoard()
{
int num = 1;
int dir = RIGHT;
int x = 0;
int y = 0;
while (true)
{
board[y][x] = num;
if (num == input * input)
break;
int nextX, nextY;
switch ( dir )
{
case RIGHT:
nextY = y;
nextX = x + 1;
break;
case LEFT:
nextY = y;
nextX = x - 1;
break;
case DOWN:
nextY = y - 1;
nextX = x;
break;
case UP:
nextY = y + 1;
nextX = x;
break;
}
if (CanGo(nextY, nextX))
{
y = nextY;
x = nextX;
++num;
}
else
{
switch (dir)
{
case RIGHT:
dir = DOWN;
break;
case LEFT:
dir = UP;
break;
case DOWN:
dir = LEFT;
break;
case UP:
dir = RIGHT;
break;
}
}
}
}
int main()
{
cin >> input;
SetBoard();
PrintBoard();
return 0;
}
y, x순서
함수의 선언위치
지역변수 선언 위치
switch ( dir )
{
case RIGHT:
nextY = y;
nextX = x + 1;
break;
case LEFT:
nextY = y;
nextX = x - 1;
break;
case DOWN:
nextY = y - 1;
nextX = x;
break;
case UP:
nextY = y + 1;
nextX = x;
break;
}
지금 이 패턴을 간략화 하는 방법에 대해서 알아보자.
더하는 부분이 계속 반복되는데 이것을
배열로써 줄여줄 수 있다.
enum Dir
{
RIGHT,
DOWN,
LEFT,
UP,
};
// enum에 따라서
int dy[] = { 0, -1, 0, 1};
int dx[] = { 1, 0, -1, 0 };
int nextY = y + dy[dir];
int nextX = x + dx[dir];
// dir에 따라서 차이를 더해 줄 수 있다.
else
{
switch (dir)
{
case RIGHT:
dir = DOWN;
break;
case LEFT:
dir = UP;
break;
case DOWN:
dir = LEFT;
break;
case UP:
dir = RIGHT;
break;
}
}
또한 else의 이부분도 간략화 할 수 있는데
enum Dir
{
RIGHT,
DOWN,
LEFT,
UP,
};
// 문제 자체가 R -> B -> L -> U 이기 때문에
else
{
dir = (dir + 1) % 4;
}
dir에다가 계속 1더해서 % 4 나눈 나머지는 0, 1, 2, 3
이기 때문에 상관없다.
2D 로그라이크 게임을 만들때 가장 많이 활용된다.
C#에서도 했었으니까 기억을 해라.