문제
윷놀이는 한국의 전통놀이중 하나로 윷가락을 가지고 진행하는 놀이이다. 윷놀이는 윷가락 4개와, 내 말 4개, 상대편의 말 4개로 총 말 8개 그리고 윷판 하나를 가지고 진행한다. 윷판은 다음과 같이 29개의 위치가 있고, 각각 이름이 붙어 있다. (사진 1)
사진 1: 윷판. 윷판의 각각의 위치에는 이름이 적혀있다.
사진 2: 가능한 네가지 윷길의 그림.
이 게임의 목표는 네 개의 말을 처음의 위치인 날밭에서 시작해, 윷판을 돌아서 다시 날밭으로 돌아온 이후에 탈출하는 게임이다.
각 사람의 턴은 다음과 같이 이루어진다.
- 윷가락을 네 개 던진다.
- 윷가락의 배치에 따라서 전진할 칸수를 정한다.
- 말을 정해서 전진한다.
윷가락은 앞뒷면이 있어서, 던질 경우에 앞뒷면 중 하나가 보이게 떨어진다. 네 개의 윷 중 앞면의 개수가 전진하는 칸수이다. 단, 모두가 뒷면일 경우에는 5칸 전진하게 된다.
전진하는 방향은 새로운 말일 경우에 날밭에서 시작하는 것으로 생각을 하고 다음의 윷길을 따라 전진한다.
말을 움직일 때는, 기본적으로 (사진 2)의 4번 윷길을 따라서 움직인다. 예를 들면, 윷의 위치에서 두 칸 전진할 경우에 뒷도의 위치로 움직인다. 하지만 특수한 경우에는 1번, 2번 혹은 3번 윷길을 따라서 움직인다. 말이 움직이기 시작할 때 모서리 (뒷밭, 앞밭, 방, 쩔밭, 혹은 날밭)에 시작할 경우에는, 날밭으로 가는 거리가 빠른 곳으로 움직이게 된다.
좀 더 구체적으로는, 말이 움직이기 시작할 때 앞밭에 있던 경우에는, 윷길이 3번 윷길로 바뀐다. 예를 들면, 앞밭에서 한 칸 전진하면 앞모도, 두 칸 전진하면 앞모개의 위치에 있게 된다. 윷의 위치에서 한 칸 전진하는 것을 두 번 진행하면 앞모도의 위치에 있지만, 두 칸 전진하는 것을 한 번 진행하면 뒷도의 위치에 있게 된다.)
또, 말이 움직이기 시작할 때 뒷밭에 있었던 경우에는 2번 윷길을 따르게 되어서, 뒷밭에서 한 칸 전진하면 뒷모도, 두 칸 전진하면 뒷모개의 위치에 있게 된다.
또한, 3번 윷길에 있던 말이 방에서 전진을 시작할 경우에는 1번 윷길을 따르게 된다. 방에서 한 칸 전진하면 사려, 두 칸 전진하면 안찌의 위치에 있게 된다.
이렇게 윷길을 따라 이동한 말은 날밭에 도착한 이후로 말이 한 칸 움직이면 판에서 빠져나가게 되어서 판에 다시 등장하지 않게 된다. 전진을 두 번에 나눠서 하지 않고 한번에 해도 된다. 예를 들면, 날걸에서 2칸을 전진하면 날밭에 도착하고, 한 칸 더 전진하면 빠져나가게 된다. 날걸에서 3칸, 4칸, 5칸을 전진해도 빠져나갈 수 있다.
하지만 이렇게 되면 단지 윷가락을 잘 던져서 잘 빠져나가는 게임이 될 뿐이다. 그래서 윷놀이에는 게임을 재밌게 하고 경쟁요소를 추가할 새로운 규칙들이 추가되었다.
하나는 말을 업는 규칙이다. 같은 위치에 있는 자기 편의 말이 두 개 이상 존재한다면, 그 말 중 하나만 움직이는 것으로 전체 말을 다 움직이게 된다.
다른 하나는 말을 잡는 규칙이다. 상대편의 말이 있는 위치가, 자신의 말의 목적지인 경우에는 상대편의 말을 게임판에서 제거하여 시작하기 전의 위치로 옮긴다. 이 말이 다시 출발하려면 날밭에서 부터 출발하게 된다.
당신은 이 윷놀이 게임의 개발을 맡게 되었다. 당신이 해야할 일은 윷놀이의 각 턴이 주어졌을 때 판의 상태를 출력하는 일이다.
입력
입력의 첫째 줄에는 N이 주어진다. 이 N은, 윷을 던지고 말을 움직인 횟수를 나타낸다.
다음 N개의 줄의 i번째 줄에는, i번째 턴이 어떤 것이었는지가 주어진다. i번째 턴은, 말에 대한 정보와 윷에 대한 정보로 주어진다.
어떤 말인지에 대한 정보는 "ABCDabcd" 문자중 하나로, 각 윷에 대한 정보는 뒷면을 뜻하는 'B' 혹은 앞면을 뜻하는 'F' 문자가 공백으로 구분되지 않고 4개가 이어서 주어지며, 말에 대한 정보와 윷에 대한 정보는 공백 하나로 구분되어 있다.
여기서, 대문자 끼리는 같은 팀의 말을, 소문자 끼리도 같은 팀의 말을 나타내고, 소문자와 대문자는 서로 다른 팀을 의미한다.
출력
기본적인 윷판은 다음 32 × 32 문자열로 주어진다.
..----..----..----..----..----..
.. .. .. .. .. ..
| \ / |
| \ / |
| \ / |
| .. .. |
.. .. .. ..
.. \ / ..
| \ / |
| \ / |
| .. .. |
| .. .. |
.. \ / ..
.. \ / ..
| \ / |
| .. |
| .. |
| / \ |
.. / \ ..
.. / \ ..
| .. .. |
| .. .. |
| / \ |
| / \ |
.. / \ ..
.. .. .. ..
| .. .. |
| / \ |
| / \ |
| / \ |
.. .. .. .. .. ..
..----..----..----..----..----..
이 문자열은 "/\.|-"과 공백, 개행문자로만 이루어진 문자열이다. (따옴표는 포함되지 않는다.) 이 문자열은 윷판을 의미하고, 각 칸은 2 × 2 모양의 '.' 문자로 표현이 되어 있다. 가장 왼쪽 위 부터 행우선으로 칸을 읽으면, 차례로 뒷밭, 뒷윷, 뒷걸, 뒷개, 뒷도, 앞밭(모), 뒷모도, 앞모도, 찌도, 윷, 뒷모개, 앞모개, 찌개, 걸, 방, 찌걸, 개, 속윷, 사려, 찌윷, 도, 속모, 안찌, 쩔밭, 날도, 날개, 날걸, 날윷 그리고 날밭 순이 된다.
여기서, N개의 턴이 진행된 후, 각 말이 어느 칸에 있는 지를 출력하여야 한다. 각 칸에 있는 2 × 2 모양의 '.' 문자로 표현이 된 칸 중 한 칸에 출력한다.
A 혹은 a의 말은 왼쪽 위에, B 혹은 b의 말은 오른쪽 위에, C 혹은 c의 말은 왼쪽 아래에, D 혹은 d의 말은 오른쪽 아래에 위치한 '.' 문자를 대체하여 출력한다.
제한
- 1 ≤ N ≤ 100
- 모든 움직임은 올바르다. 즉 빠져나간 말이 다시 판에 등장하는 경우는 없다.
서브태스크 1 (31점)
이 서브태스크는 다음의 조건을 만족한다.:
- N = 1
- 말은 모서리에 위치하지 않는다.
- 모든 말은 "ABCD"중 하나로 주어진다. (따옴표는 제외한다.)
서브태스크 2 (13점)
이 서브태스크는 다음의 조건을 만족한다.:
- 말을 업는 상황은 일어나지 않는다.
- 말은 모서리에 위치하지 않는다.
- 모든 말은 "ABCD"중 하나로 주어진다. (따옴표는 제외한다.)
서브태스크 3 (10점)
이 서브태스크는 다음의 조건을 만족한다.:
- 말은 모서리에 위치하지 않는다.
- 모든 말은 "ABCD"중 하나로 주어진다. (따옴표는 제외한다.)
서브태스크 4 (27점)
이 서브태스크는 다음의 조건을 만족한다.:
- 모든 말은 "ABCD"중 하나로 주어진다. (따옴표는 제외한다.)
서브태스크 5 (19점)
이 서브태스크는 추가 제한 조건이 없다.
예제 입력 1
4
A BBFB
B BBFB
A BFFB
c FFFB
예제 출력 1
..----..----..----..----..----..
.. .. .. .. .. ..
| \ / |
| \ / |
| \ / |
| .. .. |
.. .. .. ..
.. \ / ..
| \ / |
| \ / |
| .. .. |
| .. .. |
.. \ / ..
.. \ / c.
| \ / |
| .. |
| .. |
| / \ |
.. / \ ..
.. / \ ..
| .. .. |
| .. .. |
| / \ |
| / \ |
.. / \ ..
.. .. .. ..
| .. .. |
| / \ |
| / \ |
| / \ |
.. .. .. .. .. ..
..----..----..----..----..----..
예제 입력 2
21
A FFFB
c FBBF
d FBBB
B BBFB
C BFBF
d FFBF
B BFBF
a BBBF
C BBBB
D FBFF
a FFFB
d FBFF
b FFFF
b BBBB
c BFFF
B BBFB
b BBBF
B FFFF
c BBBB
b BBBF
A FFFF
예제 출력 2
..----..----..----..----..----.B
.. .. cd C. .. ..
| \ / |
| \ / |
| \ / |
| ab .. |
.. .. .. A.
.. \ / ..
| \ / |
| \ / |
| .. .. |
| .. .. |
.. \ / ..
.. \ / ..
| \ / |
| .. |
| .. |
| / \ |
.. / \ ..
.. / \ ..
| .. .. |
| .. .. |
| / \ |
| / \ |
.. / \ ..
.. .. .. ..
| .. .. |
| / \ |
| / \ |
| / \ |
.. .. .. .. .. ..
..----..----..----..----..----..
알고리즘 분류
- 구현
- 시뮬레이션
풀이
8시간동안 맞왜틀 시전하다 다음날 아침에 해결한 문제였다.
기본적으로 무지성 구현문제답게 주어진 조건대로 해결하면 되는데, 본인은 우선 문자열 배열로 말판을 그렸고 외곽 위치는 6의 배수, 안쪽 대각선은 5의 배수로 이루어지도록 좌표를 설정하였다.
그리고 말판의 정보를 담은 구조체 INFO를 선언하여 좌표와 말에 업히거나 말을 업은 말들을 체크해주는 배열, 그리고 말판을 출발했는지의 여부를 따지는 boolean형 변수를 선언해주었으며, 말이 한 팀당 4개씩 총 8개 있으므로 INFO 구조체 2X4 배열을 선언해주었다.
말이 움직일 때, 시작 위치에 따라 다른 경로로 이동하도록 설정해주었다.
1. 말이 방 (15, 15), 뒷밭 (0, 0)에서 출발할 때는 1, 2번 경로로 이동
- 1번 경로는 2번 경로에 포함되는 것이나 다름없기 때문에 하나로 묶어주었다.
2. 말이 앞밭 (0, 30)에서 출발할 때에는 3번 경로로 이동
3. 말이 한 바퀴를 다 돌고 날밭에서 출발하는 경우에는 말판에서 빠져나감(좌표를 (-1, -1)로 설정)
4. 1~3번 경우에 해당하지 않는데 말의 X좌표 또는 Y좌표가 6의 배수 혹은 0인 경우에는 4번 경로로 이동
5. 말이 뒷모도, 뒷모개, 사려, 안찌(즉 X, Y좌표가 5의 배수면서 둘이 서로 같다)인 경우에는 2번 경로로 이동
6. 말이 앞모도, 앞모개, 속윷, 속모(즉 X, Y좌표가 5의 배수면서 둘이 서로 다르다)인 경우에는 3번 경로로 이동
그리고 1~4번 경로는 다음과 같이 구현하였다.
1, 2번 경로 : X, Y좌표를 5씩 증가
3번 경로 : 뒷밭, 뒷모도, 뒷모개, 방, 사려, 안찌에 위치한 경우 X좌표를 +5, Y좌표를 -5씩 증가, 그 외의 경우에는 Y좌표를 6씩 증가
4번 경로 : 오른쪽 변에 위치한 경우 X좌표를 -6씩 증가, 위쪽 변에 위치한 경우 Y좌표를 -6씩 증가, 왼쪽 변에 위치한 경우 X좌표를 6씩 증가, 아래쪽 변에 위치한 경우 Y좌표를 -6씩 증가
공통 : 말의 출발 유무를 나타내는 isStart 변수가 true일 때 말이 날밭 (30, 30)에 위치한 경우 좌표를 (-1, -1)로 설정(말판에서 빠져나감)
말의 좌표를 옮겼다면 이제부터는 같은 편의 말을 업고 적군의 말을 제거해야 한다.
우선 현재 말을 업거나 현재 말에 업혀 있는(관계되어 있는 이라고 표현하겠다.) 말들 역시 좌표를 동일하게 옮겨준다.
그리고 현재 말의 좌표가 (-1, -1)이 아니라면, 그러니까 말판에 아직 존재한다면 현재 말이 위치한 좌표를 가진 적군의 말들을 제거해준다. 제거해줄 때는 좌표가 같은지, 그리고 이미 출발한 상태인지를 따져서 조건에 만족한다면 좌표를 (30, 30), isStart를 false로 초기화시켜주고 잡은 말과 관계되어 있는 말들 간의 링크를 끊는다.(Horse[][].Teammate[] = false)
마지막으로, 현재 말과 같은 좌표에 있는데 아직 관계되어 있는 말이 아닌 경우 전부 관계되도록 만들어준다.
이 모든 과정을 N번 반복한 후, 마지막으로 말판을 출력하는데, 8개의 말판을 전부 탐색하면서 좌표가 (-1, -1)이거나 isStart가 false인 말들을 제외한 모든 말들을 좌표에 따라 말을 말판에 표시해준다.
코드
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define FIRST cin.tie(NULL); cout.tie(NULL); ios::sync_with_stdio(false);
#define MAX 100005
#define LL long long
#define INF 1e9
using namespace std;
struct INFO {
// 모든 말은 말판의 날밭((30, 30))에서 시작
int Y = 30;
int X = 30;
bool Teammate[4] = { false, false, false, false }; // A~D를 업거나 업혀 있으면 true, 아니라면 false
bool isStart = false; // 출발한 상태라면 true, 아니라면 false
};
int N;
INFO Horse[2][4]; // 0팀은 대문자, 1팀은 소문자
string MAP[33] = {
"..----..----..----..----..----..",
".. .. .. .. .. ..",
"| \\ / |",
"| \\ / |",
"| \\ / |",
"| .. .. |",
".. .. .. ..",
".. \\ / ..",
"| \\ / |",
"| \\ / |",
"| .. .. |",
"| .. .. |",
".. \\ / ..",
".. \\ / ..",
"| \\ / |",
"| .. |",
"| .. |",
"| / \\ |",
".. / \\ ..",
".. / \\ ..",
"| .. .. |",
"| .. .. |",
"| / \\ |",
"| / \\ |",
".. / \\ ..",
".. .. .. ..",
"| .. .. |",
"| / \\ |",
"| / \\ |",
"| / \\ |",
".. .. .. .. .. ..",
"..----..----..----..----..----.." }; // 말판을 문자열로 구현
/*
(0, 0) 뒷밭 (0, 6) 뒷윷 (0, 12) 뒷걸 (0, 18) 뒷개 (0, 24) 뒷도 (0, 30) 앞밭(모)
(5, 5) 뒷모도 (5, 25) 앞모도
(6, 0) 찌도 (6, 30) 윷
(10, 10) 뒷모개 (10, 20) 앞모개
(12, 0) 찌개 (6, 30) 걸
(15, 15) 방
(18, 0) 찌걸 (6, 30) 개
(10, 20) 속윷 (20, 20) 사려
(24, 0) 찌윷 (6, 30) 도
(5, 25) 속모 (25, 25) 안찌
(30, 0) 쩔밭 (30, 6) 날도 (30, 12) 날개 (30, 18) 날걸 (30, 24) 날윷 (30, 30) 날밭
*/
void Horse_Move_First_Second(int& Y, int& X, int Team, int Mal, int Cnt) { // 1, 2번 경로(우하향 대각선 방향)
int CurY = Y;
int CurX = X;
int CurCnt = Cnt;
while (CurCnt--) {
if (((CurY == 0) && (CurX == 0)) || ((CurY == 5) && (CurX == 5)) || ((CurY == 10) && (CurX == 10))
|| ((CurY == 15) && (CurX == 15)) || ((CurY == 20) && (CurX == 20)) || ((CurY == 25) && (CurX == 25))) {
// 뒷밭, 뒷모도, 뒷모개, 방, 사려, 안찌에 위치한 경우 우하향으로 한 칸씩 이동
CurY += 5;
CurX += 5;
}
else if ((CurY == 30) && (CurX == 30)) { // 날밭에 위치한 경우 말판에서 말이 빠져나간다.
CurY = -1;
CurX = -1;
break;
}
};
Y = CurY;
X = CurX;
}
void Horse_Move_Third(int& Y, int& X, int Team, int Mal, int Cnt) { // 3번 경로(삼각형)
int CurY = Y;
int CurX = X;
int CurCnt = Cnt;
while (CurCnt--) {
if (((CurY == 0) && (CurX == 30)) || ((CurY == 5) && (CurX == 25)) || ((CurY == 10) && (CurX == 20))
|| ((CurY == 15) && (CurX == 15)) || ((CurY == 20) && (CurX == 10)) || ((CurY == 25) && (CurX == 5))) {
// 뒷밭, 뒷모도, 뒷모개, 방, 사려, 안찌에 위치한 경우 우하향으로 한 칸씩 이동
CurY += 5;
CurX -= 5;
}
else if (((CurY == 30) && (CurX == 0)) || ((CurY == 30) && (CurX == 6))
|| ((CurY == 30) && (CurX == 12)) || ((CurY == 30) && (CurX == 18)) || ((CurY == 30) && (CurX == 24))) {
// 쩔밭, 날도, 날개, 날걸, 날윷에 위치한 경우 오른쪽으로 한 칸씩 이동
CurX += 6;
}
else if ((CurY == 30) && (CurX == 30)) { // 날밭에 위치한 경우 말판에서 말이 빠져나간다.
CurY = -1;
CurX = -1;
break;
}
};
Y = CurY;
X = CurX;
}
void Horse_Move_Fourth(int& Y, int& X, int Team, int Mal, int Cnt) { // 4번 경로(사각형)
int CurY = Y;
int CurX = X;
int CurCnt = Cnt;
while (CurCnt--) {
if (!Horse[Team][Mal].isStart) { // 아직 출발 안 한 경우 출발하면서 도로 이동
Horse[Team][Mal].isStart = true;
CurY -= 6;
}
else {
if (((CurY > 0) && (CurY < 30)) && (CurX == 30)) { // 도, 개, 걸, 윷에 위치한 경우 위로 한 칸씩 이동
CurY -= 6;
}
else if ((CurY == 0) && (CurX > 0)) { // 앞밭(모), 뒷도, 뒷개, 뒷걸, 뒷윷에 위치한 경우 왼쪽으로 한 칸씩 이동
CurX -= 6;
}
else if ((CurY < 30) && (CurX == 0)) { // 뒷밭, 찌도, 찌개, 찌걸, 찌윷에 위치한 경우 아래쪽으로 한 칸씩 이동
CurY += 6;
}
else if (CurY == 30) {
if (CurX < 30) { // 쩔밭, 날도, 날개, 날걸, 날윷에 위치한 경우 오른쪽으로 한 칸씩 이동
CurX += 6;
}
else if (CurX >= 30) { // 날밭에 위치한 경우 말판에서 말이 빠져나간다.
CurY = -1;
CurX = -1;
break;
}
}
}
};
Y = CurY;
X = CurX;
}
void Make_Teammate(int Y, int X, int Team, int Mal) {
for (int i = 0; i < 4; i++) {
if (i == Mal) { // 본인이 본인을 업을 수는 없다.
continue;
}
if ((Horse[Team][i].Y == Y) && (Horse[Team][i].X == X) && (!Horse[Team][Mal].Teammate[i]) && (Horse[Team][i].isStart)) {
// 말판을 출발한 아군 말이 현재 말과 같은 위치에 있는데 아직 업지 않은 경우
Horse[Team][Mal].Teammate[i] = true;
Horse[Team][i].Teammate[Mal] = true;
}
}
}
void Delete_Other_Team_Horse(int Y, int X, int Team) {
if (Team == 0) { // 현재 말이 대문자(0팀)라면
for (int i = 0; i < 4; i++) {
if ((Horse[1][i].Y == Y) && (Horse[1][i].X == X) && (Horse[1][i].isStart)) {
// 말판을 출발한 1팀 말이 현재 말과 같은 위치에 있는 경우 그 말을 잡을 수 있다.
Horse[1][i].Y = 30;
Horse[1][i].X = 30;
Horse[1][i].isStart = false;
// 말판을 출발하기 전으로 되돌린다.
for (int j = 0; j < 4; j++) { // 또한 말이 잡혔으므로, 말이 업고 있거나 말을 업은 말들과 전부 관계를 끊는다.
if (i == j) {
continue;
}
if (Horse[1][i].Teammate[j]) {
Horse[1][i].Teammate[j] = false;
}
}
}
}
}
else if (Team == 1) { // 현재 말이 소문자(1팀)라면
for (int i = 0; i < 4; i++) {
if ((Horse[0][i].Y == Y) && (Horse[0][i].X == X) && (Horse[0][i].isStart)) {
Horse[0][i].Y = 30;
Horse[0][i].X = 30;
Horse[0][i].isStart = false;
for (int j = 0; j < 4; j++) {
if (i == j) {
continue;
}
if (Horse[0][i].Teammate[j]) {
Horse[0][i].Teammate[j] = false;
}
}
}
}
}
}
void Remain_Operation(int Y, int X, int Team, int Mal) {
// N턴에서 움직여 최종적으로 변경된 말의 좌표 다시 초기화
Horse[Team][Mal].Y = Y;
Horse[Team][Mal].X = X;
for (int i = 0; i < 4; i++) { // 말에 업혀 있거나 말을 업은 말들의 좌표 역시 초기화
if (Mal == i) {
continue;
}
if (Horse[Team][Mal].Teammate[i]) {
Horse[Team][i].Y = Y;
Horse[Team][i].X = X;
}
}
if ((Horse[Team][Mal].Y != -1) && (Horse[Team][Mal].X != -1)) { // 말이 말판에서 빠져나가지 않은 경우
Delete_Other_Team_Horse(Horse[Team][Mal].Y, Horse[Team][Mal].X, Team); // 잡을 수 있는 말들을 탐색
Make_Teammate(Horse[Team][Mal].Y, Horse[Team][Mal].X, Team, Mal); // 말이업을 수 있는 말들을 탐색
for (int i = 0; i < 4; i++) { // 마찬가지로 말에 업혀 있거나 말을 업은 말들이 업을 수 있는 말들을 탐색
if (Mal == i) {
continue;
}
if (Horse[Team][Mal].Teammate[i]) {
Make_Teammate(Horse[Team][i].Y, Horse[Team][i].X, Team, i);
}
}
}
}
void Print() {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
int Y = Horse[i][j].Y;
int X = Horse[i][j].X;
if ((!Horse[i][j].isStart) || ((Y == -1) && (X == -1))) {
// 출발하지 않았거나 말판 한 바퀴를 다 돌고 나간 말이라면 MAP에 표시하지 않는다.
continue;
}
if (j == 0) {
MAP[Y][X] = (i == 0) ? 'A' : 'a';
}
if (j == 1) {
MAP[Y][X + 1] = (i == 0) ? 'B' : 'b';
}
if (j == 2) {
MAP[Y + 1][X] = (i == 0) ? 'C' : 'c';
}
if (j == 3) {
MAP[Y + 1][X + 1] = (i == 0) ? 'D' : 'd';
}
}
}
for (int i = 0; i < 32; i++) {
cout << MAP[i] << "\n";
}
cout << "\n";
}
int main() {
FIRST
cin >> N;
for (int i = 0; i < N; i++) {
char Mal;
string Yut;
cin >> Mal >> Yut;
// 말의 현재 좌표 가져오기
int Y, X;
if ((Mal >= 'A') && (Mal <= 'D')) { // 대문자라면 0팀
Y = Horse[0][Mal - 'A'].Y;
X = Horse[0][Mal - 'A'].X;
}
else if ((Mal >= 'a') && (Mal <= 'd')) { // 소문자라면 1팀
Y = Horse[1][Mal - 'a'].Y;
X = Horse[1][Mal - 'a'].X;
}
// 즉 윷의 앞면의 수(F)만큼 전진
int Cnt = 0;
for (int j = 0; j < Yut.size(); j++) {
if (Yut[j] == 'F') {
Cnt++;
}
}
Cnt = (Cnt) ? Cnt : 5; // 모두 뒷면(B)이라면 5칸 전진
// 말 움직이기
if ((Mal >= 'A') && (Mal <= 'D')) { // 말이 대문자라면 0팀
if (((Y == 0) && (X == 0)) || ((Y == 15) && (X == 15))) {
// 말이 뒷밭에서 출발할 때에는 2번 경로로 이동, 방에서 출발할 때에는 1번 경로로 이동
Horse_Move_First_Second(Y, X, 0, Mal - 'A', Cnt);
}
else if ((Y == 0) && (X == 30)) {
// 말이 앞밭에서 출발할 때에는 3번 경로로 이동
Horse_Move_Third(Y, X, 0, Mal - 'A', Cnt);
}
else if ((Y == 30) && (X == 30) && (Horse[0][Mal - 'A'].isStart)) {
// 말이 이미 출발한 상태에서 날밭에서 출발하는 경우에는 말판에서 빠져나가게 된다.
Y = -1;
X = -1;
}
else if ((Y % 6 == 0) || (X % 6 == 0)) {
// 말이 도, 개, 걸, 윷, 뒷도, 뒷개, 뒷걸, 뒷윷, 찌도, 찌개, 찌걸, 찌윷, 쩔밭, 날도, 날개, 날걸, 날윷에서 출발할 때에는 4번 경로로 이동
Horse_Move_Fourth(Y, X, 0, Mal - 'A', Cnt);
}
else {
if (Y == X) { // 말이 뒷모도, 뒷모개, 사려, 안찌에서 출발할 때에는 2번 경로로 이동
Horse_Move_First_Second(Y, X, 0, Mal - 'A', Cnt);
}
else { // 말이 앞모도, 앞모개, 속윷, 속모에서 출발할 때에는 3번 경로로 이동
Horse_Move_Third(Y, X, 0, Mal - 'A', Cnt);
}
}
Remain_Operation(Y, X, 0, Mal - 'A'); // 적팀 말 제거, 아군 말 업기 등 추가 작업
}
else if ((Mal >= 'a') && (Mal <= 'd')) { // 말이 소문자라면 1팀
if (((Y == 0) && (X == 0)) || ((Y == 15) && (X == 15))) {
Horse_Move_First_Second(Y, X, 1, Mal - 'a', Cnt);
}
else if ((Y == 0) && (X == 30)) {
Horse_Move_Third(Y, X, 1, Mal - 'a', Cnt);
}
else if ((Y == 30) && (X == 30) && (Horse[1][Mal - 'a'].isStart)) {
Y = -1;
X = -1;
}
else if ((Y % 6 == 0) || (X % 6 == 0)) {
Horse_Move_Fourth(Y, X, 1, Mal - 'a', Cnt);
}
else {
if (Y == X) {
Horse_Move_First_Second(Y, X, 1, Mal - 'a', Cnt);
}
else {
Horse_Move_Third(Y, X, 1, Mal - 'a', Cnt);
}
}
Remain_Operation(Y, X, 1, Mal - 'a');
}
}
Print();
return 0;
}
'BOJ > Platinum ~ Diamond' 카테고리의 다른 글
[BOJ/Platinum 4] 백준 14868 문명(C++) (0) | 2022.02.13 |
---|---|
[BOJ/Platinum 5] 백준 14632 고급 작품(C++) (0) | 2022.02.04 |
[BOJ/Platinum 5] 백준 20541 앨범정리(C++) (0) | 2022.02.02 |
[BOJ/Platinum 5] 백준 17377 Taxi(C++) (0) | 2022.02.01 |
[BOJ/Platinum 5] 백준 18891 제21대 국회의원 선거(C++) (0) | 2022.01.31 |