Skip to content

Commit

Permalink
Implement selection of western or japanese notation
Browse files Browse the repository at this point in the history
  • Loading branch information
TollyH committed Feb 28, 2023
1 parent b605bbe commit 8efb000
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 26 deletions.
2 changes: 1 addition & 1 deletion CustomGame.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
4 changes: 4 additions & 0 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
<MenuItem Header="Japanese (_Simplified - 1 Kanji, Black with Red Promotions)" Click="PieceSetItem_Click" IsCheckable="True" Tag="1kanji"/>
<MenuItem Header="_Western (Symbols, Black with Red Promotions)" Click="PieceSetItem_Click" IsCheckable="True" Tag="western"/>
</MenuItem>
<MenuItem x:Name="notationSetItem" Header="_Move Notation">
<MenuItem Header="Japanese" Click="NotationSetItem_Click" IsCheckable="True" Tag="japanese"/>
<MenuItem Header="Western" Click="NotationSetItem_Click" IsCheckable="True" Tag="western"/>
</MenuItem>
<Separator/>
<MenuItem Header="Customise..." Click="CustomiseItem_Click"/>
</MenuItem>
Expand Down
24 changes: 21 additions & 3 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -215,9 +219,12 @@ public void UpdateGameDisplay()
}

movesPanel.Children.Clear();
for (int i = 0; i < game.MoveText.Count; i++)
List<string> 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,
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -27,6 +28,7 @@ public Settings()
FlipBoard = false;
UpdateEvalAfterBot = true;
PieceSet = "1kanji";
Notation = "japanese";

BoardColor = Color.FromRgb(249, 184, 83);
CheckedKingColor = Brushes.Red.Color;
Expand All @@ -41,14 +43,15 @@ 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)
{
FlipBoard = flipBoard;
UpdateEvalAfterBot = updateEvalAfterBot;
PieceSet = pieceSet;
Notation = notation;
BoardColor = boardColor;
CheckedKingColor = checkedKingColor;
SelectedPieceColor = selectedPieceColor;
Expand Down
55 changes: 34 additions & 21 deletions ShogiGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public class ShogiGame
/// (pieceLetter, sourcePosition, destinationPosition, promotionHappened, dropHappened)
/// </summary>
public List<(string, Point, Point, bool, bool)> Moves { get; }
public List<string> MoveText { get; }
public List<string> JapaneseMoveText { get; }
public List<string> WesternMoveText { get; }
public Dictionary<Type, int> SentePieceDrops { get; }
public Dictionary<Type, int> GotePieceDrops { get; }

Expand All @@ -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<string>();
JapaneseMoveText = new List<string>();
WesternMoveText = new List<string>();
SentePieceDrops = new Dictionary<Type, int>()
{
{ typeof(Pieces.GoldGeneral), 0 },
Expand Down Expand Up @@ -136,9 +138,10 @@ public ShogiGame()
/// Create a new instance of a shogi game, setting each game parameter to a non-default value
/// </summary>
public ShogiGame(Pieces.Piece?[,] board, bool currentTurnSente, bool gameOver,
List<(string, Point, Point, bool, bool)> moves, List<string> moveText,
Dictionary<Type, int>? sentePieceDrops, Dictionary<Type, int>? gotePieceDrops,
Dictionary<string, int> boardCounts, string? initialState)
List<(string, Point, Point, bool, bool)> moves, List<string> japaneseMoveText,
List<string> westernMoveText, Dictionary<Type, int>? sentePieceDrops,
Dictionary<Type, int>? gotePieceDrops, Dictionary<string, int> boardCounts,
string? initialState)
{
if (board.GetLength(0) != 9 || board.GetLength(1) != 9)
{
Expand All @@ -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<Type, int>()
{
{ typeof(Pieces.GoldGeneral), 0 },
Expand Down Expand Up @@ -192,9 +196,9 @@ public ShogiGame Clone()
}
}

return new ShogiGame(boardClone, CurrentTurnSente, GameOver, new(Moves), new(MoveText),
new Dictionary<Type, int>(SentePieceDrops), new Dictionary<Type, int>(GotePieceDrops),
new(BoardCounts), InitialState);
return new ShogiGame(boardClone, CurrentTurnSente, GameOver, new(Moves), new(JapaneseMoveText),
new(WesternMoveText), new Dictionary<Type, int>(SentePieceDrops),
new Dictionary<Type, int>(GotePieceDrops), new(BoardCounts), InitialState);
}

/// <summary>
Expand Down Expand Up @@ -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<Pieces.Piece> canReachDest = oldGame!.Board.OfType<Pieces.Piece>().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;
Expand Down Expand Up @@ -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);
}
}
}

0 comments on commit 8efb000

Please sign in to comment.