using System.Collections.Generic;
using System.Text;
using UnityEngine;
public class RenjuForbiddenMoveDetector : ForbiddenDetectorBase
{
// 렌주 룰 금수 감지기 생성
/*private RenjuDoubleFourDetector _doubleFourDetactor = new();
private RenjuDoubleThreeDetector _doubleThreeDetector = new();*/
private RenjuOverlineDetector _overlineDetactor = new();
private DoubleFourCheck _doubleFourDetactor = new(); // DoubleFourCheck
private DoubleThreeCheck _doubleThreeDetector = new(); // DoubleThreeCheck
///
/// 렌주 룰로 금수 리스트를 반환하는 함수
///
/// 현재 보드의 상태
/// 금수 좌표를 담은 리스트
public List RenjuForbiddenMove(Enums.PlayerType[,] board)
{
var forbiddenCount = 0;
List forbiddenMoves = new();
List tempForbiddenMoves = new();
for (int row = 0; row < BoardSize; row++)
{
for (int col = 0; col < BoardSize; col++)
{
// ** 비어 있지 않으면 검사할 필요 없음 **
if (!IsEmptyPosition(board, row, col)) continue;
// 장목 검사
if (_overlineDetactor.IsOverline(board, row, col))
{
forbiddenCount++;
forbiddenMoves.Add(new Vector2Int(row, col));
continue;
}
// 4-4 검사
if (_doubleFourDetactor.IsDoubleFour(board, row, col))
{
forbiddenCount++;
forbiddenMoves.Add(new Vector2Int(row, col));
continue;
}
if(forbiddenCount > 0) continue;
// 3-3 검사
if (_doubleThreeDetector.IsDoubleThree(board, row, col))
{
tempForbiddenMoves.Add(new Vector2Int(row, col));
}
}
}
foreach (var pos in tempForbiddenMoves)
{
board[pos.x, pos.y] = Black;
if (!SimulateDoubleFour(board) && !SimulateOverline(board))
{
forbiddenMoves.Add(new Vector2Int(pos.x, pos.y));
}
board[pos.x, pos.y] = Space;
}
List resultMoves = CheckHasFiveStones(board, forbiddenMoves);
return resultMoves;
}
// 금수 위치에서 5목이 가능할 경우 해당 위치는 금수 표기 X
private List CheckHasFiveStones(Enums.PlayerType[,] board, List forbiddenMoves)
{
// 리스트를 수정하는 동안 오류를 방지하기 위해 뒤에서부터 반복
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))
{
forbiddenMoves.RemoveAt(i);
}
}
return forbiddenMoves;
}
private bool SimulateDoubleFour(Enums.PlayerType[,] board)
{
for (int row = 0; row < BoardSize; row++)
{
for (int col = 0; col < BoardSize; col++)
{
if (board[row, col] != Space) // 보드 초기화 방지용
continue;
if (_doubleFourDetactor.IsDoubleFour(board, row, col))
return true;
}
}
return false;
}
private bool SimulateOverline(Enums.PlayerType[,] board)
{
for (int row = 0; row < BoardSize; row++)
{
for (int col = 0; col < BoardSize; col++)
{
if (board[row, col] != Space) // 보드 초기화 방지용
continue;
if (_overlineDetactor.IsOverline(board, row, col))
{
return true;
}
}
}
return false;
}
/*
///
/// 보드 상태를 시각적으로 출력하는 디버깅 함수
///
/// 현재 보드 상태
/// 보드의 시각적 표현 문자열
private string DebugBoard(Enums.PlayerType[,] board)
{
StringBuilder sb = new StringBuilder();
for (int row = 0; row < BoardSize; row++)
{
for (int col = 0; col < BoardSize; col++)
{
sb.Append(board[row, col] switch
{
Enums.PlayerType.None => "□",
Enums.PlayerType.PlayerA => "●",
Enums.PlayerType.PlayerB => "○",
_ => "?"
});
}
sb.AppendLine(); // 줄바꿈 추가
}
return sb.ToString();
}*/
}