我使用C#在Unity中制作了一个功能齐全的国际象棋游戏。现在我想添加AI,对于我使用Stockfish的国际象棋引擎。我在游戏中获得了引擎,但它没有做任何事情,因为它无法与董事会沟通。
要进行通信,我需要每行创建一个FEN字符串,从左上角开始,FEN字符串如下所示:rnbqkbnr / pppppppp / 8/8/8/8 / PPPPPPPP / RNBQKBNR w KQkq - 0 1
小写字母是黑色小块,大写字母是白色小块,数字是黑色空格,w表示白色转弯,KQkq表示可用的铸造, - 表示en passant可用,0 1个移动。
有没有人知道一个教程,或者创建和操作字符串来制作FEN字符串的提示?
我将迄今为止我已经完成的代码粘贴到Stockfish进程,我没有做任何与FEN字符串相关的事情,因为我真的不知道如何启动它。
欢迎任何链接或提示
void RunProcess()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = Application.streamingAssetsPath + "/stockfish_9_x64.exe";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
string output;
process.StandardInput.WriteLine("uci");
process.StandardInput.WriteLine("isready");
process.StandardInput.WriteLine("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
process.StandardInput.WriteLine("go");
process.StandardInput.WriteLine("stop");
process.StandardInput.WriteLine("quit");
do
{
output = process.StandardOutput.ReadLine();
} while (!output.Contains("move"));
UnityEngine.Debug.Log(output);
}
void OnMouseDown()
{
RunProcess();
}
只是为了得到基本的部分,你可以做类似的事情(注意:未经测试):
public enum ChessPieces
{
King, Queen, Rook, // ... etc.
}
public class ChessPiece : MonoBehavior
{
public string FenId { get; }
private readonly Dictionary<ChessPiece, string> FenIds = {
{ ChessPieces.King, "K" },
{ ChessPieces.Queen, "Q" },
// ... etc.
};
// assuming you create the set of pieces programatically, use this constructor
public ChessPiece(ChessPiece piece, ChessColor color)
{
FenId = color == ChessColor.Black
? FenIds[piece].ToLower()
: FenIds[piece].ToUpper();
}
}
然后,假设您将您的电路板存储在一个行数组中,要将布局转储为字符串,我可能会在我的ToString
类上覆盖ChessBoard
(也未测试):
// somewhere in your code set the board up
_chessBoard.Rows.Add(new [] {
new ChessPiece(ChessPieces.Rook, ChessColor.Black),
new ChessPiece(ChessPieces.Knight, ChessColor.Black),
// ... etc.
})
_chessBoard.Rows.Add(new [] { /* next row ... */ });
// ... etc.
// to create your output, put this into the override of ToString:
var output = ""; // should be StringBuilder, but for clarity and since this isn't likely performance limiting...
var rowIndex = 0;
foreach (var row in _chessBoard.Rows)
{
rowIndex++;
var blankSpaces = 0;
foreach(var piece in row)
{
if (piece == null)
{
blankSpaces++;
}
else
{
output += blankSpaces == 0
? piece.FenId
: string.Format("{0}{1}", blankspaces, piece.FenId);
blankSpaces = 0;
}
if (blankSpaces > 0)
{
output += blankSpaces;
}
}
if (rowIndex != 8)
{
output += "/";
}
}
此时,您已经在字符串中获得了基本布局,并且您应该具有添加其他FEN字段的基本思路。
我应该注意到我已经选择了一系列用于存储电路板的阵列。这可能不是最有效的存储机制(即在最好的情况下,你存储50%的空值,这只会随着游戏的进行而增加),但由于我们只讨论了64项,我们可能好吧记忆中。