Stockfish에 FEN을 계속 넘겨줄 때 성능 저하가 심각한가?
✅ FEN 방식이 moves 방식보다 약간 성능 저하가 있지만, 실전에서는 차이가 거의 없음.
✅ Stockfish는 스마트폰에서도 초당 수백만 개의 포지션을 계산할 수 있어서 여전히 인간을 압도함.
✅ 엔진 대 엔진 매치처럼 깊은 탐색(30수 이상)이 필요할 때는 moves 방식이 더 빠름.
/// <summary>
/// 플레이어가 플레이어 턴에 마우스 좌클하면 호출되어 기물 선택, 이동, 삭제를 처리하는 함수
/// </summary>
public void HandleClick(bool whiteTurn)
{
GameObject clickedObject = ClickObject();
if (deleteMode)
{
HandleEnemyPieces(whiteTurn, clickedObject);
return;
}
HandleMyPieces(whiteTurn, clickedObject);
}
private void HandleEnemyPieces(bool whiteTurn, GameObject clickedObject)
{
// 선택한 오브젝트가 없고, 클릭한 오브젝트가 적 기물이라면 삭제
if (clickedObject != null && clickedObject.GetComponent<Piece>().isWhite != whiteTurn)
{
(int, int) clickedGridIdx = board.BoardPosToGridIdx(clickedObject.transform.position);
board.DestroyPieceAt(clickedGridIdx.Item1, clickedGridIdx.Item2);
}
DisableDeleteMode();
}
public void EnableDeleteMode()
{
deleteMode = true;
}
public void DisableDeleteMode()
{
deleteMode = false;
}
FEN의 마지막 두 필드
50수 규칙 카운트 (5번째 필드):
턴 카운트 (6번째 필드):
/// ------------------------------------------------------------------------------------------------------------------------------
/// FEN 관련 함수들
/// ------------------------------------------------------------------------------------------------------------------------------
public string getFENstring()
{
string fen = "";
fen += FEN_Pieces() + " ";
fen += "b "; // FEN string은 AI만 사용하므로, 무조건 b로 기록
fen += FEN_Castling() + " ";
fen += FEN_EnPassant() + " ";
fen += FEN_HalfMoveClock() + " ";
fen += FEN_FullMoveNumber();
return fen;
}
private string FEN_Pieces()
{
string fen_pieces = "";
for (int y = 8; y >= 1; y--)
{
int empty = 0;
for (int x = 1; x <= 8; x++)
{
if (GetPieceAt(x, y) == null)
{
empty++;
}
else
{
if (empty != 0)
{
fen_pieces += empty.ToString();
empty = 0;
}
fen_pieces += GetPieceAt(x, y).GetComponent<Piece>().GetFENchar();
}
}
if (empty != 0)
{
fen_pieces += empty.ToString();
}
if (y != 1)
{
fen_pieces += "/";
}
}
return fen_pieces;
}
private string FEN_Castling()
{
string fen_castling = "";
if (BothFirstMove((1, 1), (5, 1))) fen_castling += "K";
if (BothFirstMove((8, 1), (5, 1))) fen_castling += "Q";
if (BothFirstMove((1, 8), (5, 8))) fen_castling += "k";
if (BothFirstMove((8, 8), (5, 8))) fen_castling += "q";
if (fen_castling == "") fen_castling = "-";
return fen_castling;
}
private bool BothFirstMove((int, int) p1, (int, int) p2)
{
Piece p1_script = GetPieceScriptAt(p1.Item1, p1.Item2);
Piece p2_script = GetPieceScriptAt(p2.Item1, p2.Item2);
if (p1_script == null || p2_script == null) return false;
return p1_script.FirstMove && p2_script.FirstMove;
}
private string FEN_EnPassant()
{
string fen_enpassant = "";
(int ep_x, int ep_y) = moveValidator.blackEnPassantCandidate;
if ((ep_x, ep_y) != (-1, -1)) fen_enpassant = aiManager.GridToUCI(ep_x, ep_y);
else fen_enpassant = "-";
return fen_enpassant;
}
private string FEN_HalfMoveClock()
{
return halfMoveCount.ToString();
}
public void ResetHalfMoveCount()
{
halfMoveCount = 0;
}
public void IncreaseHalfMoveCount()
{
halfMoveCount++;
}
private string FEN_FullMoveNumber()
{
return fullMoveCount.ToString();
}
public void ResetFullMoveCount()
{
fullMoveCount = 1;
}
public void IncreaseFullMoveCount()
{
fullMoveCount++;
}
Board.cs
// 50수 규칙을 위한 카운트
if (destroyed || pieceScript is Pawn) board.ResetHalfMoveCount();
else board.IncreaseHalfMoveCount();
if (!gameManager.whiteTurn) board.IncreaseFullMoveCount(); // 흑 끝나면 전체 턴 수 증가
InputHandler.cs :: MoveTo()
