From 8efb00068c526bf0cd794b5c8b269621731b9651 Mon Sep 17 00:00:00 2001
From: Tolly <34184902+TollyH@users.noreply.github.com>
Date: Tue, 28 Feb 2023 15:22:24 +0000
Subject: [PATCH] Implement selection of western or japanese notation
---
CustomGame.xaml.cs | 2 +-
MainWindow.xaml | 4 ++++
MainWindow.xaml.cs | 24 +++++++++++++++++---
Settings.cs | 5 ++++-
ShogiGame.cs | 55 ++++++++++++++++++++++++++++------------------
5 files changed, 64 insertions(+), 26 deletions(-)
diff --git a/CustomGame.xaml.cs b/CustomGame.xaml.cs
index 31c9db7..f3a570d 100644
--- a/CustomGame.xaml.cs
+++ b/CustomGame.xaml.cs
@@ -115,7 +115,7 @@ private void startButton_Click(object sender, RoutedEventArgs e)
bool currentTurnSente = turnSelectSente.IsChecked ?? false;
GeneratedGame = new ShogiGame(Board, currentTurnSente,
ShogiGame.EndingStates.Contains(BoardAnalysis.DetermineGameState(Board, currentTurnSente)),
- new(), new(), sentePieceDrops, gotePieceDrops, new(), null);
+ new(), new(), new(), sentePieceDrops, gotePieceDrops, new(), null);
Close();
}
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 53accc2..275066f 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -39,6 +39,10 @@
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 5161d29..79d1ee1 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -62,6 +62,10 @@ public MainWindow()
{
item.IsChecked = config.PieceSet == (string)item.Tag;
}
+ foreach (MenuItem item in notationSetItem.Items)
+ {
+ item.IsChecked = config.Notation == (string)item.Tag;
+ }
}
public void UpdateGameDisplay()
@@ -215,9 +219,12 @@ public void UpdateGameDisplay()
}
movesPanel.Children.Clear();
- for (int i = 0; i < game.MoveText.Count; i++)
+ List moves = config.Notation == "western"
+ ? game.WesternMoveText
+ : game.JapaneseMoveText;
+ for (int i = 0; i < moves.Count; i++)
{
- string text = $"{i + 1}. {game.MoveText[i]}";
+ string text = $"{i + 1}. {moves[i]}";
_ = movesPanel.Children.Add(new Label()
{
Content = text,
@@ -495,7 +502,7 @@ private void UpdateEvaluationMeter(BoardAnalysis.PossibleMove? bestMove, bool se
foreach ((System.Drawing.Point source, System.Drawing.Point destination, bool doPromotion) in bestMove.Value.BestLine)
{
_ = moveStringGenerator.MovePiece(source, destination, true, doPromotion);
- convertedBestLine += " " + moveStringGenerator.MoveText[^1];
+ convertedBestLine += " " + moveStringGenerator.JapaneseMoveText[^1];
}
toUpdate.ToolTip = convertedBestLine.Trim();
}
@@ -887,6 +894,17 @@ private void PieceSetItem_Click(object sender, RoutedEventArgs e)
UpdateGameDisplay();
}
+ private void NotationSetItem_Click(object sender, RoutedEventArgs e)
+ {
+ string chosenNotation = (string)((MenuItem)sender).Tag;
+ config.Notation = chosenNotation;
+ foreach (MenuItem item in notationSetItem.Items)
+ {
+ item.IsChecked = chosenNotation == (string)item.Tag;
+ }
+ UpdateGameDisplay();
+ }
+
private void GoteDrop_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left && !game.GameOver)
diff --git a/Settings.cs b/Settings.cs
index 1a20804..d82cf67 100644
--- a/Settings.cs
+++ b/Settings.cs
@@ -10,6 +10,7 @@ public class Settings
public bool FlipBoard { get; set; }
public bool UpdateEvalAfterBot { get; set; }
public string PieceSet { get; set; }
+ public string Notation { get; set; }
public Color BoardColor { get; set; }
public Color CheckedKingColor { get; set; }
@@ -27,6 +28,7 @@ public Settings()
FlipBoard = false;
UpdateEvalAfterBot = true;
PieceSet = "1kanji";
+ Notation = "japanese";
BoardColor = Color.FromRgb(249, 184, 83);
CheckedKingColor = Brushes.Red.Color;
@@ -41,7 +43,7 @@ public Settings()
}
[JsonConstructor]
- public Settings(bool flipBoard, bool updateEvalAfterBot, string pieceSet,
+ public Settings(bool flipBoard, bool updateEvalAfterBot, string pieceSet, string notation,
Color boardColor, Color checkedKingColor, Color selectedPieceColor, Color checkMateHighlightColor,
Color lastMoveSourceColor, Color lastMoveDestinationColor, Color bestMoveSourceColor,
Color bestMoveDestinationColor, Color availableMoveColor, Color availableCaptureColor)
@@ -49,6 +51,7 @@ public Settings(bool flipBoard, bool updateEvalAfterBot, string pieceSet,
FlipBoard = flipBoard;
UpdateEvalAfterBot = updateEvalAfterBot;
PieceSet = pieceSet;
+ Notation = notation;
BoardColor = boardColor;
CheckedKingColor = checkedKingColor;
SelectedPieceColor = selectedPieceColor;
diff --git a/ShogiGame.cs b/ShogiGame.cs
index db555a8..c913642 100644
--- a/ShogiGame.cs
+++ b/ShogiGame.cs
@@ -72,7 +72,8 @@ public class ShogiGame
/// (pieceLetter, sourcePosition, destinationPosition, promotionHappened, dropHappened)
///
public List<(string, Point, Point, bool, bool)> Moves { get; }
- public List MoveText { get; }
+ public List JapaneseMoveText { get; }
+ public List WesternMoveText { get; }
public Dictionary SentePieceDrops { get; }
public Dictionary GotePieceDrops { get; }
@@ -92,7 +93,8 @@ public ShogiGame()
GoteKing = new Pieces.King(new Point(4, 8), false);
Moves = new List<(string, Point, Point, bool, bool)>();
- MoveText = new List();
+ JapaneseMoveText = new List();
+ WesternMoveText = new List();
SentePieceDrops = new Dictionary()
{
{ typeof(Pieces.GoldGeneral), 0 },
@@ -136,9 +138,10 @@ public ShogiGame()
/// Create a new instance of a shogi game, setting each game parameter to a non-default value
///
public ShogiGame(Pieces.Piece?[,] board, bool currentTurnSente, bool gameOver,
- List<(string, Point, Point, bool, bool)> moves, List moveText,
- Dictionary? sentePieceDrops, Dictionary? gotePieceDrops,
- Dictionary boardCounts, string? initialState)
+ List<(string, Point, Point, bool, bool)> moves, List japaneseMoveText,
+ List westernMoveText, Dictionary? sentePieceDrops,
+ Dictionary? gotePieceDrops, Dictionary boardCounts,
+ string? initialState)
{
if (board.GetLength(0) != 9 || board.GetLength(1) != 9)
{
@@ -152,7 +155,8 @@ public ShogiGame(Pieces.Piece?[,] board, bool currentTurnSente, bool gameOver,
CurrentTurnSente = currentTurnSente;
GameOver = gameOver;
Moves = moves;
- MoveText = moveText;
+ JapaneseMoveText = japaneseMoveText;
+ WesternMoveText = westernMoveText;
SentePieceDrops = sentePieceDrops ?? new Dictionary()
{
{ typeof(Pieces.GoldGeneral), 0 },
@@ -192,9 +196,9 @@ public ShogiGame Clone()
}
}
- return new ShogiGame(boardClone, CurrentTurnSente, GameOver, new(Moves), new(MoveText),
- new Dictionary(SentePieceDrops), new Dictionary(GotePieceDrops),
- new(BoardCounts), InitialState);
+ return new ShogiGame(boardClone, CurrentTurnSente, GameOver, new(Moves), new(JapaneseMoveText),
+ new(WesternMoveText), new Dictionary(SentePieceDrops),
+ new Dictionary(GotePieceDrops), new(BoardCounts), InitialState);
}
///
@@ -460,52 +464,61 @@ public bool MovePiece(Point source, Point destination, bool forceMove = false, b
if (updateMoveText)
{
- string newMove = (CurrentTurnSente ? "☖" : "☗")
+ string newJapaneseMove = (CurrentTurnSente ? "☖" : "☗")
+ (Moves.Count > 1 && destination == Moves[^2].Item3 ? "同 " : destination.ToShogiCoordinate())
+ beforePromotion.SymbolLetter;
+ string newWesternMove = beforePromotion.SFENLetter;
// Disambiguate moving piece if two pieces of the same type can reach destination
IEnumerable canReachDest = oldGame!.Board.OfType().Where(
- p => piece.GetType() == p.GetType() && p.Position != source && p.IsSente == piece.IsSente
+ p => beforePromotion.GetType() == p.GetType() && p.Position != source && p.IsSente == beforePromotion.IsSente
&& p.GetValidMoves(oldGame.Board, true).Contains(destination));
if (canReachDest.Any())
{
+ newWesternMove += $"{9 - source.X}{9 - source.Y}";
if (source.X == -1)
{
- newMove += '打';
+ newJapaneseMove += '打';
}
else if (destination.Y > source.Y && !canReachDest.Where(p => destination.Y > p.Position.Y).Any())
{
- newMove += CurrentTurnSente ? '引' : '上';
+ newJapaneseMove += CurrentTurnSente ? '引' : '上';
}
else if (destination.Y < source.Y && !canReachDest.Where(p => destination.Y < p.Position.Y).Any())
{
- newMove += CurrentTurnSente ? '上' : '引';
+ newJapaneseMove += CurrentTurnSente ? '上' : '引';
}
else if (destination.Y == source.Y && !canReachDest.Where(p => destination.Y == p.Position.Y).Any())
{
- newMove += '寄';
+ newJapaneseMove += '寄';
}
else if (destination.X > source.X && !canReachDest.Where(p => destination.X > p.Position.X).Any())
{
- newMove += CurrentTurnSente ? "右" : "左";
+ newJapaneseMove += CurrentTurnSente ? "右" : "左";
}
else if (destination.X < source.X && !canReachDest.Where(p => destination.X < p.Position.X).Any())
{
- newMove += CurrentTurnSente ? "左" : "右";
+ newJapaneseMove += CurrentTurnSente ? "左" : "右";
}
else
{
- newMove += "直";
+ newJapaneseMove += "直";
}
}
+ newWesternMove += source.X == -1 ? '*'
+ : oldGame.Board[destination.X, destination.Y] is not null ? 'x'
+ : '-';
+ newWesternMove += $"{9 - destination.X}{9 - destination.Y}";
+
if (promotionPossible)
{
- newMove += promotionHappened ? "成" : "不成";
+ newJapaneseMove += promotionHappened ? "成" : "不成";
+ newWesternMove += promotionHappened ? '+' : '=';
}
- MoveText.Add(newMove);
+ JapaneseMoveText.Add(newJapaneseMove);
+ WesternMoveText.Add(newWesternMove);
}
return true;
@@ -937,7 +950,7 @@ public static ShogiGame FromShogiForsythEdwards(string forsythEdwards)
// Shogi Forsyth–Edwards doesn't define what the previous moves were, so they moves list starts empty
return new ShogiGame(board, currentTurnSente, EndingStates.Contains(BoardAnalysis.DetermineGameState(board, currentTurnSente)),
- new(), new(), sentePieceDrops, gotePieceDrops, new(), null);
+ new(), new(), new(), sentePieceDrops, gotePieceDrops, new(), null);
}
}
}