Skip to content

Commit 414b7dc

Browse files
authored
Add files via upload
1 parent 2b048df commit 414b7dc

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package week01.advanced;
2+
3+
import java.util.Random;
4+
5+
public class OmokWinChecker {
6+
7+
public static void main(String[] args) {
8+
System.out.println("<오목 승리 판정하기>");
9+
// 29단계 (심화): 오목 승리 판정하기
10+
// 문제: 19x19 크기의 2차원 char 배열로 오목판이 주어져 있다고 가정하고,
11+
// 특정 위치에 `[x, y]`에 방금 돌(`'B'` 또는 `'W'`)이 놓였다고 할 때,
12+
// 그 돌로 인해 게임이 끝났는지(정확히 5개가 연속되는지) 판정하는 프로그램을 작성하세요.
13+
// 가로, 세로, 대각선 2종류(총 4방향)를 모두 검사해야 합니다.
14+
// 핵심 사고: 한 점을 기준으로 4개의 방향(가로, 세로, 대각선)으로
15+
// 5개의 돌이 연속되는지를 탐색하는 로직
16+
// 힌트: `다중 배열`, `if문`, 각 방향을 검사하는 `for문` 또는 `while문`
17+
int N = 19;
18+
char EMPTY = '\0', BLACK = 'B', WHITE = 'W';
19+
// 가로, 세로, 왼쪽위오른쪽아래, 왼쪽아래오른쪽위
20+
int[] dr = {0, 1, 1, 1};
21+
int[] dc = {1, 0, 1,-1};
22+
23+
char[][] board = new char[N][N];
24+
Random rnd = new Random();
25+
26+
// 흑돌,백돌 50개씩 랜덤으로 놓기
27+
int bPlaced = 50, wPlaced = 50, bCount=0, wCount=0;
28+
while (bCount < bPlaced) {
29+
int r=rnd.nextInt(N), c=rnd.nextInt(N);
30+
if (board[r][c]==EMPTY){
31+
board[r][c]=BLACK;
32+
bCount++;
33+
}
34+
}
35+
while (wCount < wPlaced) {
36+
int r=rnd.nextInt(N), c=rnd.nextInt(N);
37+
if (board[r][c]==EMPTY){
38+
board[r][c]=WHITE;
39+
wCount++;
40+
}
41+
}
42+
43+
// 흑돌 or 백돌(랜덤) 4연속을 17개 놓기(방향/색 랜덤)
44+
int lineCnt = 17;
45+
int placedLine = 0;
46+
47+
while(placedLine<lineCnt) { // 4연속 17개 만들어지면 빠져나오기
48+
char color = rnd.nextBoolean() ? BLACK : WHITE; // 색 랜덤
49+
int dir = rnd.nextInt(4), dx = dr[dir], dy = dc[dir]; // 방향 랜덤
50+
int sr = rnd.nextInt(N); // 행 랜덤
51+
int sc = rnd.nextInt(N); // 열 랜덤
52+
53+
int er = sr + dx * 3; // 마지막 행(0,1,2,3->총 4개) 시작+이동*3
54+
int ec = sc + dy * 3; // 마지막 열(0,1,2,3->총 4개) 시작+이동*3
55+
if (er >= 0 && er < N && ec >= 0 && ec < N) { // 범위안인지 검사
56+
int step = 0;
57+
while (step < 4) { // 연속 4칸 검사
58+
int r = sr + dx * step; // 현재 행
59+
int c = sc + dy * step; // 현재 열
60+
if (board[r][c] != EMPTY) break; // 하나라도 빈칸이 아니면 실패
61+
step++;
62+
}
63+
if (step == 4) { // 연속 4칸 빈칸 확인되면
64+
step = 0; // 0으로 초기화하고
65+
while (step < 4) { // 빈칸 확인된 4칸 채우기
66+
board[sr + dx * step][sc + dy * step] = color; // 랜덤색 뽑은걸로 하나씩 이동하면서 채우기
67+
step++;
68+
}
69+
placedLine++;
70+
}
71+
}
72+
}
73+
74+
// 마지막 수 놓기(자리,색 랜덤)
75+
char lastColor = rnd.nextBoolean() ? BLACK : WHITE;
76+
int x, y;
77+
while (true) {
78+
x = rnd.nextInt(N);
79+
y = rnd.nextInt(N);
80+
if (board[x][y] == EMPTY) {
81+
board[x][y] = lastColor;
82+
break;
83+
}
84+
}
85+
86+
// 오목판 출력: EMPTY는->'.', 마지막 수->'L'
87+
System.out.println();
88+
for (int i=0;i<N;i++){
89+
for (int j=0;j<N;j++){
90+
if(i==x&&j==y) {
91+
System.out.print("L ");
92+
}
93+
else {
94+
System.out.print(board[i][j] == EMPTY ? '.'+" " : board[i][j]+" ");
95+
}
96+
}
97+
System.out.println();
98+
}
99+
System.out.println();
100+
101+
// 마지막 수 기준으로 승패가 결정났는지 확인
102+
boolean win = false;
103+
for (int i = 0; i < 4; i++) { // 4방향 확인
104+
int dx = dr[i], dy = dc[i];
105+
106+
int fCnt = 0; // 정방향 연속 개수
107+
int r = x + dx, c = y + dy; // 4방향 이동후 행과 열
108+
while (0 <= r && r < N && 0 <= c && c < N && board[r][c] == lastColor) { // 범위안 && 같은색
109+
fCnt++;
110+
r += dx; c += dy; // 한 칸씩 이동
111+
}
112+
113+
int bCnt = 0;// 역방향 연속 개수
114+
r = x - dx; c = y - dy;
115+
while (0 <= r && r < N && 0 <= c && c < N && board[r][c] == lastColor) {
116+
bCnt++;
117+
r -= dx; c -= dy;
118+
}
119+
120+
if (1 + fCnt + bCnt != 5) { // 마지막수+같은색돌(정방향+역방향) -> 5가 아니면 통과해서 다음 i 확인
121+
continue;
122+
}
123+
124+
int ax = x - dx * (bCnt + 1), ay = y - dy * (bCnt + 1); // 시작쪽 바깥 -> 현재-방향*(역방향 이동한 횟수+1), - : (역방향으로 이동)
125+
int bx = x + dx * (fCnt + 1), by = y + dy * (fCnt + 1); // 끝쪽 바깥 (정방향으로 이동)
126+
boolean overStart = (0 <= ax && ax < N && 0 <= ay && ay < N) && board[ax][ay] == lastColor; // 바깥 위치가 범위 안 && 마지막수와 색깥이 같음
127+
boolean overEnd = (0 <= bx && bx < N && 0 <= by && by < N) && board[bx][by] == lastColor;
128+
129+
if (!overStart && !overEnd) { // 6연속 아니면 승리
130+
win = true;
131+
break;
132+
}
133+
}
134+
135+
// 승패 판정 여부
136+
if (win) {
137+
System.out.println(lastColor + "가 (" + x + ", " + y + ")에 두어 승리하였습니다.");
138+
} else {
139+
System.out.println(lastColor + "의 마지막 수 (" + x + ", " + y + ")로 승패가 결정나지 않았습니다.");
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)