From 2ddf2cc1694202ee8b55be99ae8bc9b676ad8273 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 28 Mar 2025 10:44:05 +0900 Subject: [PATCH 1/2] =?UTF-8?q?DO-75=20[Fix]=20=EC=8A=B9=ED=8C=A8=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?=EB=B0=8F=20AI=20=EA=B0=80=EC=A4=91=EC=B9=98=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/AI/AIEvaluator.cs | 27 +++++++++---------- Assets/Script/AI/MiniMaxAIController.cs | 2 +- .../Script/Game/GameUtility/GameWinCheck.cs | 2 +- .../Renju/RenjuForbiddenMoveDetector.cs | 11 +++++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Assets/Script/AI/AIEvaluator.cs b/Assets/Script/AI/AIEvaluator.cs index 255666e..d6e42c2 100644 --- a/Assets/Script/AI/AIEvaluator.cs +++ b/Assets/Script/AI/AIEvaluator.cs @@ -11,9 +11,9 @@ public static class AIEvaluator // AI 패턴 점수 public const float FIVE_IN_A_ROW = 100000f; public const float OPEN_FOUR = 15000f; - public const float HALF_OPEN_FOUR = 5000f; + public const float HALF_OPEN_FOUR = 6000f; public const float CLOSED_FOUR = 500f; - public const float OPEN_THREE = 3000f; + public const float OPEN_THREE = 3500f; public const float HALF_OPEN_THREE = 500f; public const float CLOSED_THREE = 50f; public const float OPEN_TWO = 100f; @@ -23,13 +23,13 @@ public static class AIEvaluator public const float CLOSED_ONE = 1f; // 복합 패턴 점수 - public const float DOUBLE_THREE = 8000f; + public const float DOUBLE_THREE = 9000f; public const float DOUBLE_FOUR = 12000f; - public const float FOUR_THREE = 10000f; + public const float FOUR_THREE = 11000f; // 위치 가중치 기본값 - public const float CENTER_WEIGHT = 1.2f; - public const float EDGE_WEIGHT = 0.8f; + public const float CENTER_WEIGHT = 1.3f; + public const float EDGE_WEIGHT = 0.85f; } private static readonly int[][] Directions = AIConstants.Directions; @@ -51,7 +51,7 @@ public static class AIEvaluator ai4Positions, player4Positions); // 2. 복합 패턴 평가 - score += EvaluateComplexPatterns(aiOpen3Positions, playerOpen3Positions, ai4Positions, player4Positions, aiPlayer); + score += EvaluateComplexPatterns(aiOpen3Positions, playerOpen3Positions, ai4Positions, player4Positions); return score; } @@ -153,8 +153,7 @@ public static class AIEvaluator List<(int row, int col, int[] dir)> aiOpen3Positions, List<(int row, int col, int[] dir)> playerOpen3Positions, List<(int row, int col, int[] dir)> ai4Positions, - List<(int row, int col, int[] dir)> player4Positions, - Enums.PlayerType aiPlayer) + List<(int row, int col, int[] dir)> player4Positions) { float score = 0; @@ -494,12 +493,12 @@ public static class AIEvaluator if (count >= 4) { - normalScore = PatternScore.FIVE_IN_A_ROW / 8.5f; + normalScore = PatternScore.FIVE_IN_A_ROW / 7.5f; } else if (count == 3) { // 일관된 분모 사용 (방어 가중치는 유지) - normalScore = (openEnds == 2) ? PatternScore.OPEN_THREE / 1.3f : + normalScore = (openEnds == 2) ? PatternScore.OPEN_THREE / 1.25f : (openEnds == 1) ? PatternScore.HALF_OPEN_THREE / 3.2f : PatternScore.CLOSED_THREE / 4.2f; } @@ -562,7 +561,7 @@ public static class AIEvaluator if (!AreParallelDirections(openThrees[i].dir, openThrees[j].dir)) { float threeThreeScore = PatternScore.DOUBLE_THREE / 4; // 복합 패턴 가중치 - score += isAI ? threeThreeScore * 1.1f : threeThreeScore * 1.3f; + score += isAI ? threeThreeScore * 1.2f : threeThreeScore * 1.3f; break; } } @@ -579,7 +578,7 @@ public static class AIEvaluator if (!AreParallelDirections(fours[i].dir, fours[j].dir)) { float fourFourScore = PatternScore.DOUBLE_FOUR / 4; - score += isAI ? fourFourScore * 1.2f : fourFourScore * 1.5f; + score += isAI ? fourFourScore * 1.3f : fourFourScore * 1.7f; break; } } @@ -590,7 +589,7 @@ public static class AIEvaluator if (fours.Count > 0 && openThrees.Count > 0) { float fourThreeScore = PatternScore.FOUR_THREE / 4; - score += isAI ? fourThreeScore * 1.1f : fourThreeScore * 1.4f; + score += isAI ? fourThreeScore * 1.1f : fourThreeScore * 1.6f; } return score; diff --git a/Assets/Script/AI/MiniMaxAIController.cs b/Assets/Script/AI/MiniMaxAIController.cs index 062f181..5952707 100644 --- a/Assets/Script/AI/MiniMaxAIController.cs +++ b/Assets/Script/AI/MiniMaxAIController.cs @@ -360,7 +360,7 @@ public static class MiniMaxAIController var (count, _) = CountStones(board, row, col, dir, player, isSavedCache); // 자기 자신 포함하여 5개 이상일 시 true 반환 - if (count + 1 == WIN_COUNT) + if (count + 1 >= WIN_COUNT) return true; } diff --git a/Assets/Script/Game/GameUtility/GameWinCheck.cs b/Assets/Script/Game/GameUtility/GameWinCheck.cs index 2487c7a..a4f8531 100644 --- a/Assets/Script/Game/GameUtility/GameWinCheck.cs +++ b/Assets/Script/Game/GameUtility/GameWinCheck.cs @@ -7,7 +7,7 @@ } // 특정 방향으로 같은 돌 개수와 열린 끝 개수를 계산하는 함수 - private (int count, int openEnds) CountStones( + public static (int count, int openEnds) CountStones( Enums.PlayerType[,] board, int row, int col, int[] direction, Enums.PlayerType player) { int size = board.GetLength(0); diff --git a/Assets/Script/Renju/RenjuForbiddenMoveDetector.cs b/Assets/Script/Renju/RenjuForbiddenMoveDetector.cs index 7e74980..d523480 100644 --- a/Assets/Script/Renju/RenjuForbiddenMoveDetector.cs +++ b/Assets/Script/Renju/RenjuForbiddenMoveDetector.cs @@ -73,16 +73,21 @@ public class RenjuForbiddenMoveDetector : ForbiddenDetectorBase // 금수 위치에서 5목이 가능할 경우 해당 위치는 금수 표기 X private List CheckHasFiveStones(Enums.PlayerType[,] board, List forbiddenMoves) { + int[][] directions = AIConstants.Directions; + // 리스트를 수정하는 동안 오류를 방지하기 위해 뒤에서부터 반복 for (int i = forbiddenMoves.Count - 1; i >= 0; i--) { int row = forbiddenMoves[i].x; int col = forbiddenMoves[i].y; - // 해당 위치에서 승리(5목)이 가능하면 금수 표기 X - if (OmokAI.Instance.CheckGameWin(Enums.PlayerType.PlayerA, board, row, col)) + foreach (var dir in directions) { - forbiddenMoves.RemoveAt(i); + var (count, _) = GameLogic.CountStones(board, row, col, dir, Enums.PlayerType.PlayerA); + + // 해당 위치에서 승리(5목)이 가능하면 금수 표기 X + if (count + 1 == 5) + forbiddenMoves.RemoveAt(i); } } From 2ebc57468187ba21a28fbdb604591939b45bd9a8 Mon Sep 17 00:00:00 2001 From: fiore Date: Fri, 28 Mar 2025 11:14:52 +0900 Subject: [PATCH 2/2] =?UTF-8?q?DO-80=20[feat]=20=EB=AC=B4=EC=8A=B9?= =?UTF-8?q?=EB=B6=80=20=EC=A0=9C=EC=95=88=20=EC=A3=BC=EA=B3=A0=20=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EC=A4=91=20=ED=83=80=EC=9D=B4=EB=A8=B8=20=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=20=EC=A0=95=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Script/Game/GameLogic.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Assets/Script/Game/GameLogic.cs b/Assets/Script/Game/GameLogic.cs index 07b35ff..9882b9d 100644 --- a/Assets/Script/Game/GameLogic.cs +++ b/Assets/Script/Game/GameLogic.cs @@ -138,6 +138,7 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.ReceiveDrawRequest: Debug.Log("상대방의 무승부 요청 들어옴"); + TimerPause(); ExecuteOnMainThread(() => { GameManager.Instance.panelManager.OpenDrawConfirmPanel("무승부 요청을 승낙하시겠습니까?", () => @@ -153,6 +154,7 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.DrawRequestSent: Debug.Log("무승부 요청 전송 완료"); + TimerPause(); break; case Constants.MultiplayManagerState.DrawAccepted: Debug.Log("무승부 요청이 승낙이 들어옴"); @@ -167,6 +169,7 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.DrawRejected: Debug.Log("무승부 요청이 거부가 들어옴"); + TimerUnpause(); ExecuteOnMainThread(() => { GameManager.Instance.panelManager.OpenConfirmPanel("무승부 요청을 거부하였습니다.", () => { }); @@ -174,7 +177,7 @@ public partial class GameLogic : IDisposable break; case Constants.MultiplayManagerState.DrawRejectionConfirmed: Debug.Log("무승부 요청 거부 완료"); - + TimerUnpause(); break; case Constants.MultiplayManagerState.ReceiveTimeout: Debug.Log("상대방이 타임 아웃 됨"); @@ -529,6 +532,12 @@ public partial class GameLogic : IDisposable return AI_NAMIES[index]; } + // 타이머 일시정지 + private void TimerPause() => FioTimer.PauseTimer(); + + // 타이머 일시정지 해제 + private void TimerUnpause() => FioTimer.StartTimer(); + #endregion public void Dispose()