-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMove.c
More file actions
149 lines (138 loc) · 7.49 KB
/
Move.c
File metadata and controls
149 lines (138 loc) · 7.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*-----------------------------------------------------------------머릿주석-----------------------------------------------------------------*/
/*이 소스파일은 Move.h에 선언된 변수와 함수들을 사용하고 있다.*/
/*방향키 조작에 대한 함수들과 방향키 조작 후 처리되는 2048게임의 알고리즘들이 같이 포함되어 있다.*/
/*findTarget, slideArray, rotateBoard, moveUp, moveLeft, moveDown, moveRight 함수 사용.*/
/*----------------------------------------------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#include"Move.h"
/*-----------------------------------------------------------------findTarget-----------------------------------------------------------------*/
/*배열을 열로 순회하다가 타겟(합치고자 하는 숫자)이 합칠 숫자가 생기면 타겟의 위치를 반환하기 위함입니다.*/
/*4x4 행렬을 한라인씩 순회 하다가 같은 숫자가 나오면 그 즉시 합치고자 하는 숫자의 위치를 알려주는 역할입니다.*/
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
uint8_t findTarget(uint8_t array[SIZE], uint8_t x, uint8_t stop) {
uint8_t t;
if (x == 0) { // 위치가 1순위이면 계산하지 않는다.
return x;
}
t = x - 1;
while (t--) { // 방향키 입력 방향으로 타겟을 이동시키다가 타겟의 숫자와 타일의 숫자가 같으면 합치기 위함. ex) 2+2 = 4로 만들기 위함입니다.
if (array[t] != 0) {
if (array[t] != array[x]) { // 병합할 수 없을 경우 아래 조건문 실행
return t + 1; // 합칠 숫자를 발견하지 못하면 인덱스를 다음으로 넘깁니다.
}
return t; // 합칠 숫자를 발견하면 타겟의 인덱스를 반환합니다.
}
else {
// 중복 합침을 방지하기 위해서 합친 위치의 인덱스를 저장해놓고 그 인덱스에 도착할 때 아무것도 안하고 멈추기 위함입니다.
if (t == stop) {
return t;
}
}
}
return x; // 타겟을 찾지 못하면 그냥 x 반환
}
/*-----------------------------------------------------------------slideArray-----------------------------------------------------------------*/
/*4x4 행렬을 순회 하다가 같은 숫자가 나오면 합쳐주는 역할입니다.*/
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
bool slideArray(uint8_t array[SIZE]) {
bool success = false;
uint8_t x, t, stop = 0;
for (x = 0; x < SIZE; x++) {
if (array[x] != 0) {
t = findTarget(array, x, stop);
// 대상이 원래 위치가 아닌 경우 이동 또는 병합
if (t != x) {
//만약 목표가 0이라면 배열을 이동 시킨다.
if (array[t] == 0) {
array[t] = array[x];
}
else if (array[t] == array[x]) {
// 병합한다.
array[t]++;
// 점수를 증가 시킨다.
score += (uint32_t)1 << array[t];
// 이중 합병을 피하기 위해 중지한다.
stop = t + 1;
}
array[x] = 0; // 2를 합치고나서 합친 2의 자리를 0으로 초기화
success = true;
}
}
}
return success;
}
/*-----------------------------------------------------------------rotateBoard-----------------------------------------------------------------*/
/*4x4 행렬을 반시계방향으로 90도 돌려줍니다*/
/*함수내에 여러가지 로직을 구현할 때 호출됩니다.(가로,세로를 바꿔 연산하기위해)*/
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
void rotateBoard(uint8_t board[SIZE][SIZE]) {
uint8_t i, j, n = SIZE;
uint8_t tmp;
for (i = 0; i < n / 2; i++) { /* n/2를 쓴 이유(SIZE의 반만큼): 4x4행렬에서
왼쪽 위 2x2행렬을 왼쪽 아래 2x2행렬과 바꾸고
왼쪽 아래 2x2행렬을 오른쪽 아래 2x2행렬로
옮기는 작업이 이 for문 안의 for문에서 수행
해주기 때문에 1루프에 2x2행렬이 2번 작업되기
때문이다.*/
for (j = i; j < n - i - 1; j++) { /*처음 2x2 행렬을 바꾸고난 후 바꾼 행렬
도 한칸씩 밀어주기 위함이다.*/
tmp = board[i][j]; // 이동 시키고 난 자리의 값을 사라지지 않게 하기 위해서 임시 변수에 값을 담아준다.
board[i][j] = board[j][n - i - 1]; //
board[j][n - i - 1] = board[n - i - 1][n - j - 1];
board[n - i - 1][n - j - 1] = board[n - j - 1][i];
board[n - j - 1][i] = tmp;
}
}
}
/*-----------------------------------------------------------------moveUp-----------------------------------------------------------------*/
/*방향키 위를 입력했을 때 보드판 맨 위에서 아래까지 순회하면서 똑같은 숫자끼리 합해주고 합한 숫자 둘중에 하나를 지웁니다.*/
/*4x4 행렬을 위에서 아래로 이동하면서 같은 숫자가 나오면 합쳐주는 함수들 입니다.*/
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
bool moveUp(uint8_t board[SIZE][SIZE]) {
bool success = false;
uint8_t x;
for (x = 0; x < SIZE; x++) {
success |= slideArray(board[x]); /* |=의 사용은 같은 숫자끼리 한번이라도 합치면
true를 출력해서 합침 성공을 알리기 위함입니다.*/
}
return success;
}
/*-----------------------------------------------------------------moveLeft-----------------------------------------------------------------*/
/* 왼쪽으로 이동할 경우 rotateBoard함수를 1번 이용하여 보드를 90도를 돌린뒤 위로 밀고난 후 다시 270도를 돌려서 원상태로 만들어준다. */
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
bool moveLeft(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
return success;
}
/*-----------------------------------------------------------------moveDown-----------------------------------------------------------------*/
/* 아래쪽으로 이동할 경우 rotateBoard함수를 2번 이용하여 보드를 180도를 돌린뒤 위로 밀고난 후 다시 180도를 돌려서 원상태로 만들어준다. */
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
bool moveDown(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
rotateBoard(board);
return success;
}
/*-----------------------------------------------------------------moveRight-----------------------------------------------------------------*/
/* 오른쪽으로 이동할 경우 rotateBoard함수를 3번 이용하여 보드를 270도를 돌린뒤 위로 밀고난 후 다시 90도를 돌려서 원상태로 만들어준다. */
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
bool moveRight(uint8_t board[SIZE][SIZE]) {
bool success;
rotateBoard(board);
rotateBoard(board);
rotateBoard(board);
success = moveUp(board);
rotateBoard(board);
return success;
}