예제 #1
0
        /// <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;
                        }
                    }
                }
            }
        }
예제 #2
0
 /// <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;
         }
     }
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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;
            }
        }
예제 #7
0
 public FieldLocation(FieldLocation location)
 {
     Area     = location.Area;
     Position = location.Position;
 }
예제 #8
0
        /// <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);
        }