본문 바로가기
Programming/C, C++

C++ 슬라이딩 퍼즐 구현

by Dev_카페인 2022. 12. 8.
반응형

[C/C++] 슬라이딩 퍼즐 구현

슬라이드(슬라이딩) 퍼즐 게임

 

퍼즐 규칙

1. N * N 크기의 퍼즐을 만든다.

2. 0 ~ N * N - 1 까지 숫자를 채워 넣는다.

3. 0번을 움직여서 상하좌우로 계속 움직여 섞는다.

4. W, A, S, D 키를 눌러 0번을 제어해 1부터 순차적으로 맞추면 클리어

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>

typedef unsigned int uint;

#define MAX_PUZZLE_SIZE 3
#define SHUFFLE_COUNT 100
#define MAX_ARROW_INDEX 4

enum Arrow
{
	NONE,
	UP,
	DOWN,
	LEFT,
	RIGHT,
};

void SetPuzzle(int arr[][MAX_PUZZLE_SIZE]);
void ShufflePuzzle(int& x, int& y, int arr[][MAX_PUZZLE_SIZE]);
Arrow GetRandomArrow();
Arrow InputMove();
void MovePuzzle(int& x, int& y, Arrow arrow, int arr[][MAX_PUZZLE_SIZE]);
void MovePuzzle(int& x, int& y, int moveX, int moveY, int arr[][MAX_PUZZLE_SIZE]);
bool ResultCheck(int arr[][MAX_PUZZLE_SIZE]);

void DrawSlidePuzzle(int arr[][MAX_PUZZLE_SIZE]);

int main()
{
	srand((uint)time(0));

	int puzzleArray[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];

	int x = 0; 
	int y = 0;

	SetPuzzle(puzzleArray);
	ShufflePuzzle(x, y, puzzleArray);

	while (true)
	{

		if (_kbhit())
		{
			MovePuzzle(x, y, InputMove(), puzzleArray);
			if (ResultCheck(puzzleArray))
				break;
			//printf("%d", InputMove());
		}
		DrawSlidePuzzle(puzzleArray);
		Sleep(200);
		system("cls");
		// 무브
	}
	printf("끝!");

}

void SetPuzzle(int arr[][MAX_PUZZLE_SIZE])
{
	for (int i = 0; i < MAX_PUZZLE_SIZE; i++)
	{
		for (int j = 0; j < MAX_PUZZLE_SIZE; j++)
		{
			arr[i][j] = MAX_PUZZLE_SIZE * i + j;
		}
	}
}

void ShufflePuzzle(int& x, int& y, int arr[][MAX_PUZZLE_SIZE])
{
	for (int i = 0; i < SHUFFLE_COUNT; i++)
	{
		switch (GetRandomArrow())
		{
		case UP :
			MovePuzzle(x, y, x, y - 1, arr);
			break;
		case DOWN :
			MovePuzzle(x, y, x, y + 1, arr);
			break;
		case LEFT :
			MovePuzzle(x, y, x - 1, y, arr);
			break;
		case RIGHT :
			MovePuzzle(x, y, x + 1, y, arr);
			break;
		}
	}
}

Arrow GetRandomArrow()
{
	int arrowIndex = rand() % MAX_ARROW_INDEX + 1;
	return Arrow(arrowIndex);
}

Arrow InputMove()
{
	if (_kbhit())
	{
		int inputNum = _getch();
		switch (inputNum)
		{
		case 'w' :
			return UP;
		case 's':
			return DOWN;
		case 'a':
			return LEFT;
		case 'd':
			return RIGHT;
		default :
			return NONE;
		}
	}
}

void MovePuzzle(int& x, int& y, Arrow arrow, int arr[][MAX_PUZZLE_SIZE])
{
	if (arrow == NONE) return;

	switch (arrow)
	{
	case UP:
		MovePuzzle(x, y, x, y - 1, arr);
		break;
	case DOWN:
		MovePuzzle(x, y, x, y + 1, arr);
		break;
	case LEFT:
		MovePuzzle(x, y, x - 1, y, arr);
		break;
	case RIGHT:
		MovePuzzle(x, y, x + 1, y, arr);
		break;
	}
}
void MovePuzzle(int& x, int& y, int moveX, int moveY, int arr[][MAX_PUZZLE_SIZE])
{
	if (moveX >= 0 && moveX < MAX_PUZZLE_SIZE && moveY >= 0 && moveY < MAX_PUZZLE_SIZE)
	{
		int temp = arr[y][x];
		arr[y][x] = arr[moveY][moveX];
		arr[moveY][moveX] = temp;
		x = moveX;
		y = moveY;
	}
}

bool ResultCheck(int arr[][MAX_PUZZLE_SIZE])
{
	for (int i = 0; i < MAX_PUZZLE_SIZE; i++)
	{
		for (int j = 0; j < MAX_PUZZLE_SIZE; j++)
		{
			if (arr[i][j] != MAX_PUZZLE_SIZE * i + j + 1)
			{
				if (i == MAX_PUZZLE_SIZE - 1 && j == MAX_PUZZLE_SIZE - 1) break;
				return false;
			}
		}
	}
	return true;
}

void DrawSlidePuzzle(int arr[][MAX_PUZZLE_SIZE])
{
	for (int i = 0; i < MAX_PUZZLE_SIZE; i++)
	{
		printf("----------------\n");
		for (int j = 0; j < MAX_PUZZLE_SIZE; j++)
		{
			printf("|");
			printf("%.2d", arr[i][j]);
		}
		printf("|\n");
	}
	printf("----------------\n");
}

반응형

'Programming > C, C++' 카테고리의 다른 글

C++ Windows.h 콘솔창 지우기, Sleep  (0) 2022.12.08
C++ 다차원 배열  (0) 2022.12.08
C++ 빙고 게임 만들기  (0) 2022.12.08
C++ 숫자 야구게임 만들기  (0) 2022.12.07
C++ 지역변수, 전역변수, 정적변수  (0) 2022.12.07