Xiangqi-Core is a comprehensive library designed to facilitate the development of applications related to Xiangqi (Chinese Chess). It provides a robust set of functionalities including move generation, move validation, game state management, etc. Built with flexibility and performance in mind, XiangqiCore aims to be the go-to solution for developers looking to integrate Xiangqi mechanics into their software.
- Fluent API: Provides a fluent API for easy configuration and initialization of game instances.
- Game State Management: Easily manage game states, including piece positions, turn tracking, and game outcome detection.
- Parsing of Move Notations: Supports parsing of move notations in UCCI, Chinese, and English, allowing for versatile game command inputs.
- Move Validation: Validate player moves, ensuring moves adhere to the rules of Xiangqi.
- Utility Functions: A collection of utility functions for piece and board management, including piece movement simulation and position checking.
Xiangqi-Core is available as a NuGet package. You can install it using the NuGet Package Manager or the dotnet CLI.
dotnet add package Xiangqi-Core
To get started with Xiangqi-Core, first import the package into your project:
Here's a simple example of setting up a game board and making a move:
using XiangqiCore.Game;
// Create a new game instance with the help of the XiangqiBuilder
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
// Make a move
game.MakeMove("炮二平五", MoveNotationType.Chinese);
Refer to the tests or documentation below (In progress) for more detailed examples and usage instructions.
The XiangqiBuilder
class is responsible for creating instances of the Xiangqi game with different configurations. It provides a fluent API for easy configuration and initialization of game instances.
Sets the Xiangqi game configuration to the default starting position.
Default Configuration:
- Starting Fen: rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
- Side to move: Red
- Red player: Unknown
- Black player: Unknown
- Game result: Unknown
- Competition:
- GameDate : null
- Round : Unknown
- Name : Unknown
If the above fields are not set when calling the Build
method, these default values will be used by default.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
Sets the starting position according to the provided FEN (Forsyth-Edwards Notation).
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithStartingFen("1r2kabr1/4a4/1c2b1n2/p3p1C1p/2pn2P2/9/P1P1P2cP/N3C1N2/2R6/2BAKABR1 b - - 2 10")
.Build();
Sets the starting position to an empty board by setting the initial FEN to "9/9/9/9/9/9/9/9/9/9 w - - 0 1".
This is useful for setting up custom board configurations with the WithBoardConfig
method below, where you want to set up the board manually without using a FEN.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithEmptyBoard()
.Build();
Builds an instance of the Xiangqi game.
Sets the configuration for the red player. If the Name or Team is not set for the player, the default value will be "Unknown".
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithRedPlayer(player => {
player.Name = "許銀川";
plyaer.Team = "廣東":
})
.Build();
Sets the configuration for the black player. If the Name or Team is not set for the player, the default value will be "Unknown".
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithBlackPlayer(player => player.Name = "趙國榮")
.Build();
Sets the game result for the Xiangqi game. The default value is GameResult.Unknown.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithGameResult(GameResult.RedWin)
.Build();
Sets the configuration for the competition. The competition configuration includes the event name, site, and date. If these fields are not set, the default value of event name and site will be "Unknown", and the default date would be today's date.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithCompetition(competition => {
competition.Event = "World Xiangqi Championship";
competition.Site = "Beijing, China";
competition.Date = "2022-10-01";
})
.Build();
Sets the board configuration for the Xiangqi game using a BoardConfig
class instance.
The SetPiece method is used to set the piece type and color at a specific coordinate on the board.
It will overwrite any existing piece at that coordinate, so it is recommended to call the WithEmptyBoard
method before calling WithBoardConfig
.
using XiangqiCore.Game;
using XiangqiCore.Boards;
XiangqiBuilder builder = new ();
BoardConfig config = new ();
config.AddPiece(new Coordinate(column: 5, row: 5), PieceType.Rook, PieceColor.Red);
config.AddPiece(new Coordinate(column: 5, row: 1), PieceType.King, PieceColor.Red);
config.AddPiece(new Coordinate(column: 4, row: 10), PieceType.King, PieceColor.Black);
XiangqiGame game = builder
.WithEmptyBoard()
.WithBoardConfig(config)
.Build();
Sets the board configuration for the Xiangqi game using the APIs directly from the BoardConfig
class.
using XiangqiCore.Game;
using XiangqiCore.Boards;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithEmptyBoard()
.WithBoardConfig(config => {
config.AddPiece(new Coordinate(column: 5, row: 5), PieceType.Rook, PieceColor.Red);
config.AddPiece(new Coordinate(column: 5, row: 1), PieceType.King, PieceColor.Red);
config.AddPiece(new Coordinate(column: 4, row: 10), PieceType.King, PieceColor.Black);
})
.Build();
Sets the move record for the Xiangqi game.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithMoveRecord("1. 炮二平五 炮8平5")
.Build();
Sets the game name for the Xiangqi game.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithGameName("呂欽專集 第一局 ")
.Build();
Sets the Xiangqi game configuration using a Dpxq game record. The method is used to import a game from dpxq.com. The method is still in beta, and there may be issues with parsing the game record, due to the incosistency in the game record format.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDpxqGameRecord(@"标题: 杭州环境集团队 王天一 和 四川成都懿锦金弈队 武俊强
分类: 全国象棋甲级联赛
赛事: 2023年腾讯棋牌天天象棋全国象棋甲级联赛
轮次: 决赛
布局: E42 对兵互进右马局
红方: 杭州环境集团队 王天一
黑方: 四川成都懿锦金弈队 武俊强
结果: 和棋
日期: 2023.12.10
地点: 重庆丰都
组别: 杭州-四川
台次: 第04台
评论: 中国象棋协会
作者: 张磊
备注: 第3局
记时规则: 5分+3秒
红方用时: 6分
黑方用时: 6分钟
棋局类型: 全局
棋局性质: 超快棋
红方团体: 杭州环境集团队
红方姓名: 王天一
黑方团体: 四川成都懿锦金弈队
黑方姓名: 武俊强
棋谱主人: 东萍公司
棋谱价值: 0
浏览次数: 3086
来源网站: 1791148
第3局
【主变: 和棋】
1. 兵七进一 卒7进1
2. 马八进七 马8进7
3. 马二进一 象3进5
4. 炮八平九 马2进3
5. 车九平八 车1平2
6. 炮二平四 马7进8
7. 炮九进四 车9进1
8. 车八进六 车9平6
9. 仕四进五 炮2退1
10. 炮九平七 卒9进1
11. 相三进五 车6进3
12. 车一平三 马8进9
13. 车八退二 炮2平8
14. 车八进五 马3退2
15. 兵三进一 卒7进1
16. 相五进三 马2进1
17. 炮七平九 车6平1
18. 相三退五 后炮平3
19. 炮九平八 车1平2
20. 炮八平九 车2平1
21. 炮九平八 车1平2
22. 炮八平九 象5进7
23. 车三进三 马9退8
24. 车三进一 炮8平3
25. 马七退九 车2平1
26. 炮九平八 车1平2
27. 炮八平九 车2平1
28. 炮九平八 象7退5
29. 炮八退四 车1进2
30. 炮八平七 马1进2
31. 炮七进五 车1进2
32. 炮七平八 车1平4
33. 相七进九 马2进3
34. 车三平二 车4退4
35. 马一进三 马8退6
36. 车二平四 马6进8
37. 车四进一 车4平6
38. 马三进四 卒5进1
39. 炮八平七 马8进6
40. 炮七退四 炮3进5
41. 马四进二 士4进5
42. 相九退七
棋谱由 http://www.dpxq.com/ 生成")
.Build();
Randomises the board position. If fromFen is set to true, the board will be randomised based on the current FEN. If fromFen is set to false, the board will be randomised based on the board config. If allowCheck is set to false, the randomised position will be checked to ensure that the king is not in check.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.RandomisePosition(fromFen: true, allowCheck: false)
.Build();
Randomises the board position based on the PieceCounts
class.
If allowCheck is set to false, the randomised position will be checked to ensure that the king is not in check.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
PieceCounts pieceCounts = new(
RedPieces: new Dictionary<PieceType, int>()
{
{ PieceType.King, 1 },
{ PieceType.Advisor, 1 },
{ PieceType.Cannon, 1 },
},
BlackPieces: new Dictionary<PieceType, int>()
{
{ PieceType.King, 1 },
{ PieceType.Advisor, 2 },
}
);
XiangqiGame game = builder
.RandomisePosition(pieceCounts, allowCheck: false)
.Build();
The BoardConfig
class is used to set up the board configuration for the Xiangqi game in XiangqiBuilder
without the use of FEN.
It provides a set of APIs for setting up the board configuration.
Sets the piece type and color at a specific coordinate on the board.
using XiangqiCore.Boards;
BoardConfig config = new ();
config.AddPiece(new Coordinate(column: 5, row: 5), PieceType.Rook, PieceColor.Red);
config.AddPiece(new Coordinate(column: 5, row: 1), PieceType.King, PieceColor.Red);
config.AddPiece(new Coordinate(column: 4, row: 10), PieceType.King, PieceColor.Black);
Sets a random piece at a specific coordinate on the board.
using XiangqiCore.Boards;
BoardConfig config = new ();
config.AddRandomPiece(new Coordinate(column: 5, row: 5));
Sets the piece counts for the board configuration. This is for the RandomisePosition
method in the XiangqiBuilder
.
using XiangqiCore.Boards;
BoardConfig config = new ();
PieceCounts pieceCounts = new(
RedPieces: new Dictionary<PieceType, int>()
{
{ PieceType.King, 1 },
{ PieceType.Advisor, 1 },
{ PieceType.Cannon, 1 },
},
BlackPieces: new Dictionary<PieceType, int>()
{
{ PieceType.King, 1 },
{ PieceType.Advisor, 2 },
}
);
config.SetPieceCounts(pieceCounts);
The XiangqiGame
class is the main class that represents a game of Xiangqi.
It provides a set of APIs for managing game states, making moves, and retrieving game information.
Makes a move in the game based on the provided move notation and notation type. Returns a boolean representing if the move is made successfully or not. Currently, the library supports UCCI, Chinese and English move notations.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("h8+7", MoveNotationType.English);
Makes a move in the game based on the starting and destination coordinates. Returns a boolean representing if the move is made successfully or not
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove(new Coordinate(column: 5, row: 2), new Coordinate(column: 5, row: 3));
Exports the move history of the game as a string.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.MakeMove("車9平8", MoveNotationType.Chinese);
string moveHistory = game.ExportMoveHistory();
Console.WriteLine(moveHistory);
// Output:
// 1. 炮二平五 馬8進7
// 2. 馬二進三 車9平8
Exports the game as a PGN string.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithRedPlayer(player => player.Name = "吕钦")
.WithBlackPlayer(player => player.Name = "王嘉良")
.WithCompetition(competition => {
competition.Event = "全国象棋个人锦标赛";
competition.Date = "1987-11-30";
})
.WithMoveRecord(@"
1. 炮二平五 馬8進7 2. 馬二進三 車9平8
3. 馬八進七 卒3進1 4. 炮八平九 馬2進3
5. 車九平八 車1平2 6. 車一進一 象7進5
7. 車一平四 炮2進4 8. 車八進一 士6進5
9. 車八平六 炮2進1 10. 車四進五 卒7進1
11. 車四平三 馬7退6 12. 車三平二 車8進1
13. 兵五進一 炮8平7 14. 車二平三 車8進4
15. 馬三進五 車8平6 16. 車六進五 炮2退1
17. 炮五平二 車6平8 18. 馬五退四 車2進5
19. 仕六進五 車2平5 20. 車六平八 車5平6
21. 車八退三 車6進3 22. 炮二平四 車6平7
23. 兵七進一 卒7進1 24. 兵七進一 車7退2
25. 馬七進六 車7平2 26. 馬六退八 卒5進1
27. 炮四進六 車8退4 28. 車三進一 車8平6
29. 車三退一 車6進4 30. 兵七進一 馬3退2
31. 馬八退六 卒5進1 32. 馬六進七 象5進3
33. 炮九進四 馬6進5 34. 車三平一 卒5平4
35. 馬七退八 車6進1 36. 馬八進九 車6平2
37. 相三進五 象3進1 38. 兵七平六 馬2進3
39. 炮九平八 車2退1 40. 車一進三 士5退6
41. 兵六進一")
.WithGameResult(GameResult.RedWin)
.Build();
string pgnString = game.ExportGameAsPgnString();
Console.WriteLine(pgnString);
// Output:
// [Game "Chinese Chess"]
// [Event "全国象棋个人锦标赛"]
// [Site "Unknown"]
// [Date "1987.11.30"]
// [Red "吕钦"]
// [RedTeam "Unknown"]
// [Black "王嘉良"]
// [BlackTeam "Unknown"]
// [Result "1-0"]
// [FEN "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1"]
// 1. 炮二平五 馬8進7
// 2. 馬二進三 車9平8
// 3. 馬八進七 卒3進1
// 4. 炮八平九 馬2進3
// 5. 車九平八 車1平2
// 6. 車一進一 象7進5
// 7. 車一平四 炮2進4
// 8. 車八進一 士6進5
// 9. 車八平六 炮2進1
// 10. 車四進五 卒7進1
// 11. 車四平三 馬7退6
// 12. 車三平二 車8進1
// 13. 兵五進一 炮8平7
// 14. 車二平三 車8進4
// 15. 馬三進五 車8平6
// 16. 車六進五 炮2退1
// 17. 炮五平二 車6平8
// 18. 馬五退四 車2進5
// 19. 仕六進五 車2平5
// 20. 車六平八 車5平6
// 21. 車八退三 車6進3
// 22. 炮二平四 車6平7
// 23. 兵七進一 卒7進1
// 24. 兵七進一 車7退2
// 25. 馬七進六 車7平2
// 26. 馬六退八 卒5進1
// 27. 炮四進六 車8退4
// 28. 車三進一 車8平6
// 29. 車三退一 車6進4
// 30. 兵七進一 馬3退2
// 31. 馬八退六 卒5進1
// 32. 馬六進七 象5進3
// 33. 炮九進四 馬6進5
// 34. 車三平一 卒5平4
// 35. 馬七退八 車6進1
// 36. 馬八進九 車6平2
// 37. 相三進五 象3進1
// 38. 兵七平六 馬2進3
// 39. 炮九平八 車2退1
// 40. 車一進三 士5退6
// 41. 兵六進一
Exports the game as a PGN file to the specified filePath. If the file name is provided in the file path, please make sure you are using the PGN extension. If not provided, the PGN file would be default to use the GameName in the XiangqiGame class
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithRedPlayer(player => player.Name = "吕钦")
.WithBlackPlayer(player => player.Name = "王嘉良")
.WithCompetition(competition => {
competition.Event = "全国象棋个人锦标赛";
competition.Date = "1987-11-30";
})
.Buil();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.MakeMove("車9平8", MoveNotationType.Chinese);
game.ExportGameAsPgnFile("game.pgn");
GenerateImage(string filePath, int moveCount = 0, bool flipHorizontal = false, bool flipVertical = false)
GenerateImageAsync(string filePath, int moveCount = 0, bool flipHorizontal = false, bool flipVertical = false, CancellationToken cancellationToken = default)
Generates an image of the a board position for a specified move count and saves it to the specified file path. If the image name is provided in the file path, please make sure you are using the JPG extension. If not provided, the image would be default to use the GameName in the XiangqiGame class
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.GenerateImage("C:\Users\User\Downloads", moveCount: 3);
GenerateGif(string filePath, bool flipHorizontal = false, bool flipVertical = false, decimal frameDelayInSecond = 1)
GenerateGifAsync(string filePath, bool flipHorizontal = false, bool flipVertical = false, decimal frameDelayInSecond = 1, CancellationToken cancellationToken = default)
Generates a GIF of the game and saves it to the specified file path. If the image name is provided in the file path, please make sure you are using the GIF extension. If not provided, the image would be default to use the GameName in the XiangqiGame class
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.GenerateGif("C:\Users\User\Downloads", frameDelayInSecond: 2);
Gets the current FEN of the game.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.MakeMove("車9平8", MoveNotationType.Chinese);
string currentFen = game.CurrentFen;
Console.WriteLine(currentFen);
// Output:
// rnbakabr1/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C1N2/9/RNBAKAB1R w - - 4 2
Gets the current board position of the game. It returns a deep copy of the 2D array of Piece
objects representing the board state.
using XiangqiCore.Game;
using XiangqiCore.Extension;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
Piece[,] boardPosition = game.BoardPosition;
Console.WriteLine(boardPosition.GetPieceAtPosition(new Coordinate(column: 5, row: 3)));
// Output:
// XiangqiCore.Pieces.Cannon
Gets the move history of the game as a list of MoveHistoryObject
.
using XiangqiCore.Game;
using XiangqiCore.Move.MoveObjects;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("炮二平五", MoveNotationType.Chinese);
game.MakeMove("馬8進7", MoveNotationType.Chinese);
game.MakeMove("馬二進三", MoveNotationType.Chinese);
game.MakeMove("車9平8", MoveNotationType.Chinese);
IReadOnlyList<MoveHistoryObject> moveHistory = game.MoveHistory;
foreach (MoveHistoryObject move in moveHistory)
Console.WriteLine(move.MoveNotation);
// Output:
// 炮二平五
// 馬8進7
// 馬二進三
// 車9平8
Gets the name of the game. This property can be set in the XiangqiBuilder
using the WithGameName
method.
The default value is {RedPlayerName}{GameResult}{BlackPlayerName}.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game1 = builder
.WithRedPlayer(player => player.Name = "吕钦")
.WithBlackPlayer(player => player.Name = "王嘉良")
.WithGameResult(GameResult.RedWin)
.Build();
XiangqiGame game2 = builder
.WithRedPlayer(player => player.Name = "王天一")
.WithBlackPlayer(player => player.Name = "鄭惟恫")
.WithGameResult(GameResult.Draw)
.Build();
XiangqiGame game3 = builder
.WithRedPlayer(player => player.Name = "胡榮華")
.WithBlackPlayer(player => player.Name = "楊官璘")
.WithGameResult(GameResult.BlackWin)
.Build();
XiangqiGame game4 = builder
.WithRedPlayer(player => player.Name = "胡榮華")
.WithBlackPlayer(player => player.Name = "楊官璘")
.WithGameResult(GameResult.BlackWin)
.WithGameName("1980全國個人賽 胡榮華先负楊官璘")
.Build();
string gameName1 = game1.GameName;
string gameName2 = game2.GameName;
string gameName3 = game3.GameName;
string gameName4 = game3.GameName;
Console.WriteLine(gameName1);
Console.WriteLine(gameName2);
Console.WriteLine(gameName3);
Console.WriteLine(gameName4);
// Output:
// 吕钦先勝王嘉良
// 王天一先和鄭惟恫
// 胡榮華先負楊官璘
// 1980全國個人賽 胡榮華先负楊官璘
Gets the result of the game. This property can be set in the XiangqiBuilder
using the WithGameResult
method.
The default value is GameResult.Unknown.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithGameResult(GameResult.RedWin)
.Build();
GameResult gameResult = game.GameResult;
Console.WriteLine(gameResult);
// Output:
// RedWin
Gets the competition information of the game. This property can be set in the XiangqiBuilder
using the WithCompetition
method.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithCompetition(competition => {
competition.WithName("全国象棋个人锦标赛");
competition.WithGameDate(DateTime.Parse"1987-11-30");
})
.Build();
Competition competition = game.Competition;
Console.WriteLine(competition.Name);
Console.WriteLine(competition.GameDate);
// Output:
// 全国象棋个人锦标赛
// 30/11/1987 00:00:00
Gets the red player information of the game. This property can be set in the XiangqiBuilder
using the WithRedPlayer
method.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithRedPlayer(player => {
player.Name = "吕钦";
player.Team = "广东";
})
.Build();
Player redPlayer = game.RedPlayer;
Console.WriteLine(redPlayer.Name);
Console.WriteLine(redPlayer.Team);
// Output:
// 吕钦
// 广东
Gets the black player information of the game. This property can be set in the XiangqiBuilder
using the WithBlackPlayer
method.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder
.WithDefaultConfiguration()
.WithBlackPlayer(player => {
player.Name = "王嘉良";
player.Team = "黑龍江";
})
.Build();
Player blackPlayer = game.BlackPlayer;
Console.WriteLine(blackPlayer.Name);
Console.WriteLine(blackPlayer.Team);
// Output:
// 王嘉良
// 黑龍江
Gets the side to move in the game. The default value is Side.Red.
using XiangqiCore.Game;
XiangqiBuilder builder = new ();
XiangqiGame game = builder.WithDefaultConfiguration().Build();
Side sideToMove = game.SideToMove;
Console.WriteLine(sideToMove);
// Output:
// Red
A struct representing a coordinate on the Xiangqi board. It has two properties, Column
and Row
, representing the column and row of the coordinate.
Below is a simple diagram of how the coodrinate in XiangqiCore is represented.
The maximum column and row are 9 and 10, respectively.
Black
1 2 3 4 5 6 7 8 9
10 ┌─┬─┬─┬─┬─┬─┬─┬─┐
9 │ │ │ │ │ │ │ │─┤
8 ├─┼─┼─┼─┼─┼─┼─┼─┤
7 │ │ │ │ │ │ │ │─┤
6 ├─┼─┼─┼─┼─┼─┼─┼─┤
5 │ │ │ │ │ │ │ │─┤
4 ├─┼─┼─┼─┼─┼─┼─┼─┤
3 │ │ │ │ │ │ │ │─┤
2 ├─┼─┼─┼─┼─┼─┼─┼─┤
1 │ │ │ │ │ │ │ │─┤
1 2 3 4 5 6 7 8 9
Red
Version 1.4.1 Features:
- Rename the
ExportGameAsPgnFile
toGeneratePgnFile
to follow naming convention - Add
GenerateImageAsync
,GenerateGifAsync
, andGeneratePgnFileAsync
for asynchronous generation of image, GIF, and PGN file
Bug Fixes:
- Fix the position validation for pawns not accounting for the pawns that have not yet crossed the river
Version 1.4.0 Features:
-
Functionality to randomise the board position using the
RandomisePiecePosition
method in theXiangqiBuilder
class. -
Add the overriding behaviour of the
WithBoardConfig
method in theXiangqiBuilder
class. Now it will overwrite the existing FEN/Board Config if it is called multiple times. -
Bug Fixes:
-
Fix the issue where the
WithBoardConfig
method in theXiangqiBuilder
class does not append the game info to the FEN string when initializing the game. -
New extension methods
GetPiecesOfType
to reduce the use of reflection in the process of getting the pieces of a specific type on the board.
Version 1.3.0
Features:
- Functionality to create a GIF from the game.
- Functionality to create an image from a game position.
Version 1.2.1
Features:
- Performance enhancement when building a Xiangqi game from DPXQ or game record
- Default the game date to null if not provided
Bug Fixes:
- Handle the exception when the GameDate format in DPXQ record cannot be parsed
Version 1.2.0
Features:
- Rename the APIs in
XiangqiBuilder
class to prefix withWith
. - Improve the performance of the process for checking for checkmates.
- Add the
WithDpxqGameRecord
method to import a game from dpxq.com. (Beta) - Add the
ExportGameAsPgnFile
method to export the game as a PGN file. ExportMoveHistory
can now accept the MoveNotationType parameter to export the move history in the specified notation. Currently it only supports the transaltion of Chinese/English to UCCI notation. The other translation would be added in the future.- The
MakeMove
method now can also accepts Simplified Chinese notation.
Bug Fixes:
- Fix the issue where the MakeMove method does not handle the edge case that, in some notations, there are two pieces of the same type on the same column and the notation does not mark which piece is moving, as only one of them would be able to perform the move validly.
Contributions to Xiangqi-Core are welcome! If you have suggestions for improvements or bug fixes, please feel free to fork the repository and submit a pull request.
Xiangqi-Core is licensed under the MIT License. See the LICENSE file for more details.
For questions or support, please contact chijason99@gmail.com