diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-20 12:00:59 +0000 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-20 12:00:59 +0000 |
| commit | 9aec3f89e7239eded3fd18b5428947143463b213 (patch) | |
| tree | c5495b6212ef33c6470cd5560ab066d0a67309fd /src/BoardWidget.cs | |
| parent | 4b007c2b1f6791ca52e840a15c2edc9c754acf41 (diff) | |
tesselation, should be optionalwinBinary
Diffstat (limited to 'src/BoardWidget.cs')
| -rw-r--r-- | src/BoardWidget.cs | 209 |
1 files changed, 172 insertions, 37 deletions
diff --git a/src/BoardWidget.cs b/src/BoardWidget.cs index 7188a41..456bfe5 100644 --- a/src/BoardWidget.cs +++ b/src/BoardWidget.cs @@ -3,7 +3,9 @@ // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; +using System.Collections.Generic; using System.ComponentModel; +using System.IO; using Crow; using Crow.Drawing; //using vkvg; @@ -13,10 +15,13 @@ namespace vkChess public class BoardWidget : Widget { Picture sprites; + string filePath; + IList<string> moves; + string[,] currentBoard; Piece[,] board; [DefaultValue(null)] - public virtual Piece[,] Board { + public Piece[,] Board { get { return board; } set { if (board == value) { @@ -28,15 +33,84 @@ namespace vkChess RegisterForGraphicUpdate (); } } - public BoardWidget ():base() + public virtual IList<string> Moves { + get => moves; + set { + if (moves == value) + return; + + if (moves is ObservableList<string> ol) { + ol.ListAdd -= Lines_ListAdd; + ol.ListRemove -= Lines_ListRemove; + ol.ListClear -= Lines_ListClear; + } + + moves = value; + + if (moves is ObservableList<string> olNew) { + olNew.ListAdd += Lines_ListAdd; + olNew.ListRemove += Lines_ListRemove; + olNew.ListClear += Lines_ListClear; + } + + NotifyValueChanged ("Moves", moves); + + replayAllMoves (); + + RegisterForGraphicUpdate (); + } + } + public string FilePath { + get => FilePath; + set { + if (filePath == value) + return; + filePath = value; + NotifyValueChangedAuto (filePath); + RegisterForGraphicUpdate (); + + if (string.IsNullOrEmpty (filePath)) + resetCurrentBoard (); + else + loadFromFile (); + } + } + public BoardWidget (): base() { sprites = new SvgPicture ("data/Pieces.svg"); } + static readonly string[,] boardInit = { + {"wr", "wp", "", "", "", "", "bp", "br"}, + {"wk", "wp", "", "", "", "", "bp", "bk"}, + {"wb", "wp", "", "", "", "", "bp", "bb"}, + {"wq", "wp", "", "", "", "", "bp", "bq"}, + {"wK", "wp", "", "", "", "", "bp", "bK"}, + {"wb", "wp", "", "", "", "", "bp", "bb"}, + {"wk", "wp", "", "", "", "", "bp", "bk"}, + {"wr", "wp", "", "", "", "", "bp", "br"} + }; + void Lines_ListAdd (object sender, ListChangedEventArg e) + { + processMove (currentBoard, e.Element.ToString()); + RegisterForRedraw (); + } + void Lines_ListRemove (object sender, ListChangedEventArg e) + { + replayAllMoves (); + RegisterForRedraw (); + } + void Lines_ListClear (object sender, ListClearEventArg e) + { + resetCurrentBoard(); + RegisterForRedraw (); + } protected override void onDraw (Context gr) { base.onDraw (gr); + this.setFontForContext (gr); + /*gr.FontFace = Font.Name; gr.FontSize = (uint)Font.Size;*/ @@ -88,47 +162,108 @@ namespace vkChess } gr.Fill (); - if (board == null) - return; - for (int x = 0; x < 8; x++) { - for (int y = 0; y < 8; y++) { - if (board [x, y] == null) - continue; + if (board != null) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + if (board [x, y] == null) + continue; - string spriteName; - if (board [x, y].Player == ChessColor.White) - spriteName = "w"; - else - spriteName = "b"; + string spriteName; + if (board [x, y].Player == ChessColor.White) + spriteName = "w"; + else + spriteName = "b"; - switch (board[x,y].Type) { - case PieceType.Pawn: - spriteName += "p"; - break; - case PieceType.Rook: - spriteName += "r"; - break; - case PieceType.Knight: - spriteName += "k"; - break; - case PieceType.Bishop: - spriteName += "b"; - break; - case PieceType.King: - spriteName += "K"; - break; - case PieceType.Queen: - spriteName += "q"; - break; + switch (board[x,y].Type) { + case PieceType.Pawn: + spriteName += "p"; + break; + case PieceType.Rook: + spriteName += "r"; + break; + case PieceType.Knight: + spriteName += "k"; + break; + case PieceType.Bishop: + spriteName += "b"; + break; + case PieceType.King: + spriteName += "K"; + break; + case PieceType.Queen: + spriteName += "q"; + break; + } + sprites.Paint (IFace, gr,new Rectangle( + (int)(gridX + x * cellSize), + (int)(gridY + (7 - y) * cellSize), + (int)cellSize, + (int)cellSize),spriteName); + } + } + } else if (moves != null && currentBoard != null) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + if (string.IsNullOrEmpty(currentBoard [x, y])) + continue; + sprites.Paint (IFace, gr,new Rectangle( + (int)(gridX + x * cellSize), + (int)(gridY + (7 - y) * cellSize), + (int)cellSize, + (int)cellSize),currentBoard[x, y]); } - sprites.Paint (IFace, gr,new Rectangle( - (int)(gridX + x * cellSize), - (int)(gridY + (7 - y) * cellSize), - (int)cellSize, - (int)cellSize),spriteName); } } } + void loadFromFile () { + try { + using (Stream stream = new FileStream (filePath, FileMode.Open)) + using (StreamReader sw = new StreamReader (stream)) + Moves = sw.ReadLine ().Split (' '); + } catch (Exception ex) { + Crow.MessageBox.ShowModal (IFace, MessageBox.Type.Error, $"Failed loading {filePath}\n{ex.Message}"); + } + } + void resetCurrentBoard () => currentBoard = boardInit.Clone() as string[,]; + void replayAllMoves () { + resetCurrentBoard (); + if (moves == null) + return; + int i = 0; + + lock (VkChess.movesMutex) { + foreach (string move in moves) { + try { + processMove (currentBoard, move); + } catch { + Console.WriteLine ($"move: {move} i:{i}"); + } + i++; + } + } + } + void processMove (string[,] board, string move) { + ReadOnlySpan<char> m = move.AsSpan(); + Point p0 = VkChess.getChessCell (m.Slice (0, 2)); + Point p1 = VkChess.getChessCell (m.Slice (2, 2)); + + if (board[p0.X, p0.Y][1] == 'p') {//pawn + if (m.Length == 5) //pawnPromotion + board[p0.X, p0.Y] = board[p0.X, p0.Y][0].ToString() + m[4]; + else if (p0.X != p1.X && string.IsNullOrEmpty (board[p1.X, p1.Y]))//prise en passant + board[p0.X, p1.Y] = null; + }else if (board[p0.X, p0.Y][1] == 'K' && Math.Abs(p0.X - p1.X) > 1) {//rook + if (p0.X - p1.X < 0) {//small rock + board[5, p0.Y] = board[7, p0.Y]; + board[7, p0.Y] = null; + } else { //big rock + board[3, p0.Y] = board[0, p0.Y]; + board[0, p0.Y] = null; + } + } + board[p1.X, p1.Y] = board[p0.X, p0.Y]; + board[p0.X, p0.Y] = null; + } } } |