From 5695f2c95d852cd1cdad3b965b4def8e150412ca Mon Sep 17 00:00:00 2001 From: fiore Date: Wed, 19 Mar 2025 17:04:45 +0900 Subject: [PATCH] =?UTF-8?q?DO-31=20Feat:=20=EC=8C=8D=EC=82=BC=EA=B8=88?= =?UTF-8?q?=EC=88=98=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 쌍삼 금수 여부 반환 - 4-3일 경우 금수에서 제외토록 처리 --- .../Script/Renju/RenjuDoubleThreeDetector.cs | 129 +++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/Assets/Script/Renju/RenjuDoubleThreeDetector.cs b/Assets/Script/Renju/RenjuDoubleThreeDetector.cs index 03eab22..327eb39 100644 --- a/Assets/Script/Renju/RenjuDoubleThreeDetector.cs +++ b/Assets/Script/Renju/RenjuDoubleThreeDetector.cs @@ -18,10 +18,23 @@ public class RenjuDoubleThreeDetector: ForbiddenDetectorBase // 쌍삼 검사 bool isDoubleThree = CheckDoubleThree(board, row, col); + // 쌍삼으로 판정된 경우 4-3 상황인지 추가 검사 + if (isDoubleThree) + { + // 4가 만들어지는지 확인 + bool hasFour = CheckForFour(board, row, col); + + // 4-3 상황이면 금수에서 제외 + if (hasFour) + { + isDoubleThree = false; + } + } + // 원래 상태로 되돌림 board[row, col] = Space; - return false; + return isDoubleThree; } /// @@ -290,4 +303,118 @@ public class RenjuDoubleThreeDetector: ForbiddenDetectorBase return true; } + + /// + /// 4가 만들어지는지 확인합니다. + /// + private bool CheckForFour(Enums.PlayerType[,] board, int row, int col) + { + // 4개의 방향 쌍에 대해 검사 + for (int i = 0; i < 4; i++) + { + int dir1 = DirectionPairs[i, 0]; + int dir2 = DirectionPairs[i, 1]; + + // 해당 방향에서 4가 형성되는지 확인 + if (CheckFourInDirection(board, row, col, dir1, dir2)) + { + return true; + } + } + + return false; + } + + /// + /// 특정 방향에서 4가 형성되는지 확인합니다. + /// 떨어져 있는 돌도 고려합니다 (한 칸 또는 두 칸 떨어진 패턴 포함). + /// + private bool CheckFourInDirection(Enums.PlayerType[,] board, int row, int col, int dir1, int dir2) + { + // 각 방향으로 최대 5칸까지의 범위를 검사 (현재 위치 포함 총 11칸) + Enums.PlayerType[] linePattern = ExtractLinePattern(board, row, col, dir1, dir2); + int centerIndex = 5; // 중앙 인덱스 (현재 위치) + + // 모든 가능한 패턴 확인 + return CheckFourOneGap(linePattern, centerIndex); + } + + /// + /// 라인 패턴을 추출합니다. (중복 코드를 방지하기 위한 헬퍼 메서드) + /// + private Enums.PlayerType[] ExtractLinePattern(Enums.PlayerType[,] board, int row, int col, int dir1, int dir2) + { + Enums.PlayerType[] linePattern = new Enums.PlayerType[11]; + int centerIndex = 5; // 중앙 인덱스 (현재 위치) + + // 현재 위치 설정 + linePattern[centerIndex] = Black; + + // dir1 방향으로 패턴 채우기 + for (int i = 1; i <= 5; i++) + { + int newRow = row + Directions[dir1, 0] * i; + int newCol = col + Directions[dir1, 1] * i; + + if (IsInBounds(newRow, newCol)) + { + linePattern[centerIndex + i] = board[newRow, newCol]; + } + else + { + linePattern[centerIndex + i] = Space; // 범위 밖은 빈칸으로 처리 + } + } + + // dir2 방향으로 패턴 채우기 + for (int i = 1; i <= 5; i++) + { + int newRow = row + Directions[dir2, 0] * i; + int newCol = col + Directions[dir2, 1] * i; + + if (IsInBounds(newRow, newCol)) + { + linePattern[centerIndex - i] = board[newRow, newCol]; + } + else + { + linePattern[centerIndex - i] = Space; // 범위 밖은 빈칸으로 처리 + } + } + + return linePattern; + } + + /// + /// 한 칸 떨어진 4 패턴을 확인합니다. + /// + private bool CheckFourOneGap(Enums.PlayerType[] linePattern, int centerIndex) + { + // 윈도우 슬라이딩으로 연속된 5칸을 검사 (한 칸 떨어진 패턴을 위해) + for (int start = 0; start <= 5; start++) + { + // 현재 위치가 이 윈도우에 포함되는지 확인 + bool currentPositionInWindow = (start <= centerIndex && centerIndex < start + 5); + if (!currentPositionInWindow) continue; + + // 윈도우 내의 돌 개수 세기 + int stoneCount = 0; + for (int i = 0; i < 5; i++) + { + if (linePattern[start + i] == Black) + { + stoneCount++; + } + } + + // 정확히 4개의 돌이 있고, 1개의 빈칸이 있으면 4로 판정 + // (현재 위치는 흑으로 이미 설정되어 있음) + if (stoneCount == 4) + { + return true; + } + } + + return false; + } } \ No newline at end of file