Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/TollyH/Shogi
Browse files Browse the repository at this point in the history
  • Loading branch information
TollyH committed Mar 24, 2023
2 parents 5e68508 + 7790f00 commit 78d4ac4
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CustomGame.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,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(), new(), sentePieceDrops, gotePieceDrops, new(), null);
new(), new(), new(), sentePieceDrops, gotePieceDrops, new(), null, null);
Close();
}

Expand Down
2 changes: 2 additions & 0 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<MenuItem Header="New Mini Game (_1 Player - Gote)" Click="NewMiniGameCpuGote_Click"/>
<MenuItem Header="New Mini Game (0 Player - Computer _Only)" Click="NewMiniGameCpuOnly_Click"/>
<Separator/>
<MenuItem Header="_Undo Move" Click="UndoMove_Click"/>
<Separator/>
<MenuItem Header="Custom _Game..." Click="CustomGame_Click"/>
<MenuItem Header="Custom Mini Game..." Click="CustomMiniGame_Click"/>
<Separator/>
Expand Down
16 changes: 16 additions & 0 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,22 @@ private void NotationSetItem_Click(object sender, RoutedEventArgs e)
UpdateGameDisplay();
}

private async void UndoMove_Click(object sender, RoutedEventArgs e)
{
if (game.PreviousGameState is not null
&& ((game.CurrentTurnSente && !senteIsComputer) || (!game.CurrentTurnSente && !goteIsComputer)))
{
game = game.PreviousGameState;
if (senteIsComputer || goteIsComputer)
{
// Reverse two moves if the opponent is computer controlled
game = game.PreviousGameState!;
}
UpdateGameDisplay();
await CheckComputerMove();
}
}

private void GoteDrop_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left && !game.GameOver)
Expand Down
13 changes: 8 additions & 5 deletions ShogiGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class ShogiGame
public List<(string, Point, Point, bool, bool)> Moves { get; }
public List<string> JapaneseMoveText { get; }
public List<string> WesternMoveText { get; }
public ShogiGame? PreviousGameState { get; private set; }
public Dictionary<Type, int> SentePieceDrops { get; }
public Dictionary<Type, int> GotePieceDrops { get; }

Expand Down Expand Up @@ -155,7 +156,7 @@ public ShogiGame(Pieces.Piece?[,] board, bool currentTurnSente, bool gameOver,
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)
string? initialState, ShogiGame? previousGameState)
{
if (board.GetLength(0) is not 9 and not 5 || board.GetLength(1) is not 9 and not 5)
{
Expand Down Expand Up @@ -198,6 +199,7 @@ public ShogiGame(Pieces.Piece?[,] board, bool currentTurnSente, bool gameOver,
BoardCounts = boardCounts;

InitialState = initialState ?? ToString();
PreviousGameState = previousGameState;
}

/// <summary>
Expand All @@ -216,7 +218,7 @@ public ShogiGame Clone()

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);
new Dictionary<Type, int>(GotePieceDrops), new(BoardCounts), InitialState, PreviousGameState?.Clone());
}

/// <summary>
Expand Down Expand Up @@ -348,7 +350,7 @@ public bool IsDropPossible(Type dropType, Point destination)
/// If a piece can be promoted, should it be? <see langword="null"/> means the user should be prompted.
/// </param>
/// <param name="updateMoveText">
/// Whether the move should update the game move text. This should usually be <see langword="true"/>,
/// Whether the move should update the game move text and update <see cref="PreviousGameState"/>. This should usually be <see langword="true"/>,
/// but may be set to <see langword="false"/> for performance optimisations in clone games for analysis.
/// </param>
/// <returns><see langword="true"/> if the move was valid and executed, <see langword="false"/> otherwise</returns>
Expand Down Expand Up @@ -393,11 +395,12 @@ public bool MovePiece(Point source, Point destination, bool forceMove = false, b
}
}

// Used for generating new move text
// Used for generating new move text and move undoing
ShogiGame? oldGame = null;
if (updateMoveText)
{
oldGame = Clone();
PreviousGameState = oldGame;
}

bool pieceMoved = piece.Move(Board, destination, forceMove || source.X == -1);
Expand Down Expand Up @@ -976,7 +979,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(), new(), sentePieceDrops, gotePieceDrops, new(), null);
new(), new(), new(), sentePieceDrops, gotePieceDrops, new(), null, null);
}
}
}

0 comments on commit 78d4ac4

Please sign in to comment.