阅读国际象棋棋盘后,在Unity中创建FEN字符串

问题描述 投票:0回答:1

我使用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();
}
c# unity3d chess
1个回答
0
投票

只是为了得到基本的部分,你可以做类似的事情(注意:未经测试):

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项,我们可能好吧记忆中。

© www.soinside.com 2019 - 2024. All rights reserved.