/// <summary> /// Removes the piece from the board that is at the specified location and sends it /// back to the player's home /// </summary> /// <param name="location"></param> public void RemovePiece(FieldLocation location) { // Find the piece at the specified location foreach (var item in _pawns) { // If the Area and Position match, the piece is at the specified location if (item.Location.Area == location.Area && item.Location.Position == location.Position) { // Find a free spot in the player's home for (int i = 0; i < _pawns.Length; i++) { // If there are not any pieces that are in position i and that are not at home // (pieces at the start of the board will not be confused for pieces being in the home) // then spot is available if (!_pawns.Any(p => p.Location.Position == i && p.Location.Area == _start)) { // Put the piece back in the player's home item.Location.Area = _start; // Put the piece in the correct position in the player home item.Location.Position = i; return; } } } } }
/// <summary> /// Moves a piece from one location to another if the player has a piece in that location /// </summary> /// <param name="oldLocation"></param> /// <param name="newLocation"></param> public void MovePiece(FieldLocation oldLocation, FieldLocation newLocation) { foreach (var item in _pawns) { // If there is a piece in home and the old location is in the home if ((_starts.Contains(oldLocation.Area) && item.Location.Area == oldLocation.Area) || // otherwise, if piece is in old location (item.Location.Area == oldLocation.Area && item.Location.Position == oldLocation.Position)) { // update the location item.Location.Area = newLocation.Area; item.Location.Position = newLocation.Position; return; } } }
/// <summary> /// Constructor for objects of type pawn /// </summary> /// <param name="color"></param> /// <param name="position"></param> public Pawn(PlayerColor color, int position, Canvas fieldCanvas) { Color = color; i = new Image(); BitmapImage bi = new BitmapImage(); bi.BeginInit(); if (color == PlayerColor.green) { Location = new FieldLocation(FieldArea.GreenHome, position); bi.UriSource = new Uri("pack://application:,,,/Images/green.png"); } else if (color == PlayerColor.yellow) { Location = new FieldLocation(FieldArea.YellowHome, position); bi.UriSource = new Uri("pack://application:,,,/Images/yellow.png"); } else if (color == PlayerColor.blue) { Location = new FieldLocation(FieldArea.BlueHome, position); bi.UriSource = new Uri("pack://application:,,,/Images/blue.png"); } else if (color == PlayerColor.red) { Location = new FieldLocation(FieldArea.RedHome, position); bi.UriSource = new Uri("pack://application:,,,/Images/red.png"); } else { throw new Exception("Invalid color for pawn."); } bi.DecodePixelWidth = 22; bi.EndInit(); i.Source = bi; fieldCanvas.Children.Add(i); }
/// <summary> /// Method that will attempt to move a piece and report the caller whether it was succesful /// </summary> /// <param name="player"></param> /// <param name="location">Current location</param> /// <returns></returns> private bool AttemptMove(Player player, FieldLocation location) { // Calculate the new position var newLocation = player.CalculateMove(location, Die); // If the clicked location does not contain a player piece, return false // Second condition prevents the game from getting stuck when a player only has pawns left // that can move to their initial position in the end zone. if (!player.HasPieceIn(location) && !Equals(location, newLocation)) { return(false); } // Don't move if the player already has a piece in the new location if (player.HasPieceIn(newLocation)) { // unless the new location is a final location if (!newLocation.IsFinal()) { return(false); } } // Move the piece player.MovePiece(location, newLocation); // Remove opponent piece, if needed foreach (var item in _players) { // Only check opponents if (item.Color != player.Color) { item.RemovePiece(newLocation); } } return(true); }
/// <summary> /// Returns whether a player actually has a piece in the location and whether the player /// can move this piece /// </summary> /// <param name="location"></param> /// <returns></returns> public bool HasPieceIn(FieldLocation location) { // If the player has clicked on a home if (location.Area == FieldArea.GreenHome || location.Area == FieldArea.YellowHome || location.Area == FieldArea.BlueHome || location.Area == FieldArea.RedHome) { // ... then only Area needs to match if (_pawns.Any(p => p.Location.Area == location.Area)) { return(true); } } // otherwise, both Area and position will need to match if (_pawns.Any(p => p.Location.Area == location.Area && p.Location.Position == location.Position)) { return(true); } return(false); }
/// <summary> /// Method that is called when the player clicks somewhere in the field. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Field_Click(object sender, RoutedEventArgs e) { // If a player has completed the game, all clicks will be ignored if (_currentPhase == Phase.GameOver) { return; } // Only let the player move his piece after rolling the dice. if (_currentPhase != Phase.ChooseMove) { _statusMessage = $"{ActivePlayerString()}{Environment.NewLine}You cannot move a piece, please roll the die."; StatusBox.Text = _statusMessage; return; } // Get the position of the mouse var mp = Mouse.GetPosition(Application.Current.MainWindow); // Find the location that corresponds to the position of the mouse FieldLocation location = new FieldLocation(mp); // If player can make a move, move if (_players[_activePlayer].HasPieceIn(location) && AttemptMove(_players[_activePlayer], location)) { // Update the screen foreach (var item in _players) { item.Show(FieldCanvas); } // Make sure that the updated screen gets rendered now FieldCanvas.Dispatcher.Invoke(delegate { }, DispatcherPriority.Render); // Check if the game is over if (_players[_activePlayer].HasWon()) { _currentPhase = Phase.GameOver; _statusMessage = $"Congratulations, you have won the game. The {ActivePlayerString()} player is the winner."; StatusBox.Text = _statusMessage; } else // Update the game { _currentPhase = Phase.RollDie; if (Die != 6) { // In two player games, make sure that two players play on opposing sides of the board if (_numberOfPLayers == 2) { _activePlayer = _activePlayer == 0 ? 2 : 0; } else { ++_activePlayer; // move to the next player _activePlayer %= _numberOfPLayers; // move back to the first player, if needed } } _statusMessage = $"{ActivePlayerString()}{Environment.NewLine}Please roll the die to continue."; StatusBox.Text = _statusMessage; } } else { // Notify user of invalid move _statusMessage = $"{ActivePlayerString()}{Environment.NewLine}Invalid move, you cannot move that piece or do not have a piece at that position"; StatusBox.Text = _statusMessage; } }
public FieldLocation(FieldLocation location) { Area = location.Area; Position = location.Position; }
/// <summary> /// Will calculate new position after move /// </summary> /// <param name="location"></param> /// <param name="distance"></param> /// <returns></returns> public FieldLocation CalculateMove(FieldLocation location, int distance) { FieldLocation newLocation = new FieldLocation(location); // Advance the player through the regular area and move to the appropriate finish area if needed if (location.Area == FieldArea.SquareX) { newLocation.Position = location.Position + distance; if (Color == PlayerColor.green && location.Position + distance > 51) { newLocation.Position -= 51; newLocation.Area = FieldArea.GreenFinish; } if (Color == PlayerColor.yellow && newLocation.Position > 12 && location.Position < 13) { newLocation.Position -= 12; newLocation.Area = FieldArea.YellowFinish; } if (Color == PlayerColor.blue && newLocation.Position > 25 && location.Position < 26) { newLocation.Position -= 25; newLocation.Area = FieldArea.BlueFinish; } if (Color == PlayerColor.red && newLocation.Position > 38 && location.Position < 39) { newLocation.Position -= 38; newLocation.Area = FieldArea.RedFinish; } newLocation.Position %= 52; // Only 52 regular positions on the board } // If player is in home else if ((new FieldArea[] { FieldArea.GreenHome, FieldArea.YellowHome, FieldArea.BlueHome, FieldArea.RedHome }).Contains(location.Area)) { newLocation.Area = FieldArea.SquareX; if (Color == PlayerColor.green) { newLocation.Position = distance + 0; } else if (Color == PlayerColor.yellow) { newLocation.Position = distance + 13; } else if (Color == PlayerColor.blue) { newLocation.Position = distance + 26; } else if (Color == PlayerColor.red) { newLocation.Position = distance + 39; } } // Player is in finish area else { newLocation.Position += distance; if (newLocation.Position > 6) { newLocation.Position = 6 - (newLocation.Position - 6); } } return(newLocation); }