public void PlaceStone(HexCoordinate cord) { if (Winner != Player.None) { throw new Exception("The game is already over"); } if (!validPlacements.Contains(cord)) { throw new Exception("Tried to place a stone in an invalid position!"); } // Update the chain collection switch (ActivePlayer) { case Player.Black: BlackChains.Add(cord); break; case Player.White: WhiteChains.Add(cord); break; } // Place stone Board.PlaceStone(cord, ActivePlayer); lastMoves.Push(cord); // Switch active player ActivePlayer = ActivePlayer.GetOpponent(); // Remove the old placement coordinate if (IsFirstTurn) { validPlacements.Clear(); IsFirstTurn = false; } else { validPlacements.Remove(cord); } // Add new placement coordinates var neighbors = Board.GetNeighbors(cord); for (var i = 0; i < neighbors.Length; i++) { var neighbor = neighbors[i]; // Do not add coordinates where a stone is already placed if (Board[neighbor] != Player.None) { continue; } var neighborCount = CountNeighborStones(neighbor); if (neighborCount >= 2) { validPlacements.Add(neighbor); } } // Check if a player won or if it's a draw Winner = GetWinner(cord); if (Winner != Player.None || validPlacements.Count == 0) { IsGameOver = true; return; } }
public void UndoLastMove() { if (lastMoves.Count == 0) { throw new Exception("Tried to undo the last move, when no last moves are available"); } var lastMove = lastMoves.Pop(); // Remove the stone Board.RemoveStone(lastMove); validPlacements.Add(lastMove); // Switch the active player ActivePlayer = ActivePlayer.GetOpponent(); // Remove enclosed stones if (moveEnclosedStones.ContainsKey(lastMove)) { foreach (var tile in moveEnclosedStones[lastMove]) { EnclosedStones[ActivePlayer].Remove(tile); } moveEnclosedStones.Remove(lastMove); } // Update the chain collection switch (ActivePlayer) { case Player.Black: BlackChains.Remove(lastMove); break; case Player.White: WhiteChains.Remove(lastMove); break; } // Remove now invalid placements if (CanUndo) { var neighbors = Board.GetNeighbors(lastMove); for (var i = 0; i < neighbors.Length; i++) { var neighbor = neighbors[i]; if (Board[neighbor] != Player.None) { continue; } var neighborCount = CountNeighborStones(neighbor); if (neighborCount < 2) { validPlacements.Remove(neighbor); } } } else { // We are at the beginning of the game IsFirstTurn = true; validPlacements.Clear(); foreach (var neighbor in Center.GetNeighborsClockwise()) { validPlacements.Add(neighbor); } } // Remove the winning player Winner = Player.None; IsGameOver = false; }