예제 #1
0
        /// <summary>Moves all seeds into the respective Kalahs.</summary>
        public Move CollectFinalSeeds(Player firstPlayer, Player secondPlayer)
        {
            Move move = new Move();
            Player currentPlayer = firstPlayer;
            for (int playerIndex = 0; playerIndex < 2; ++playerIndex)
            {
                Pit currentPlayersKalah = GetKalahOfPlayer(currentPlayer);
                int internalIndexOfKalah = GetInternalIndexOfKalah(currentPlayer);

                for (int pitIndex = 0; pitIndex < _numHousesPerPlayer; ++pitIndex)
                {
                    Pit currentPit = GetPitOfPlayer(currentPlayer, pitIndex);

                    if (currentPit.GetNumberofSeeds() > 0)
                    {
                        int currentPitsInternalIndex = GetInternalPitIndex(currentPlayer, pitIndex);
                        move.AddSeedMovement(new SeedMovement(currentPitsInternalIndex, internalIndexOfKalah, currentPit.GetNumberofSeeds()));

                        currentPlayersKalah.AddSeeds(currentPit.GetNumberofSeeds());
                        currentPit.RemoveAllSeeds();
                    }
                }
                currentPlayer = secondPlayer;
            }

            return move;
        }
예제 #2
0
        /// <summary>
        /// Returns the next undo move to be taken together with the player whose turn it is after that move.
        /// The undo move is removed from the internal list of the UndoManager.
        /// </summary>
        /// <param name="undoMove">The move to undo the last move that one of the two players made.</param>
        /// <param name="nextPlayer">The player whose turn it is after the undoMove</param>
        public void GetNextUndoMove(ref Move undoMove, ref Player nextPlayer)
        {
            if (_moveList.Count == 0)
            {
                throw new PSTException("UndoManager.GetNextUndoMove: No move left.");
            }

            // Store the respective first elements of the internal lists in the reference parameters:
            undoMove = _moveList[0];
            nextPlayer = _playerList[0];

            // Remove both entries from the lists:
            _moveList.RemoveAt(0);
            _playerList.RemoveAt(0);
        }
예제 #3
0
        /// <summary>Selects the given house and distributes the seeds of that house among
        /// the following pits, one seed per pit. Takes into account the direction of sowing, depending on the rules.</summary>
        /// <param name="player">The player whose pit is to be moved</param>
        /// <param name="houseIndexToBeMoved">The index of the house to be moved</param>
        /// <param name="lastSeedFellInOwnKalah">A reference parameter which gets the information whether the
        /// <param name="lastSeedFellIntoEmptyOwnHouse">A reference parameter which gets the information whether the
        /// last seed fell into empty pit that is owned by the player.</param>
        /// <param name="lastSeedsHouse">If "lastSeedFellIntoEmptyOwnHouse" is true, then this reference parameter
        /// gets the index of the house that the last seed fell into. Otherwise "lastSeedsHouse" gets the value -1 (for "undefined").
        /// <exception cref="KalahaException">Index out of range</exception>
        public Move MoveHouse(Player player, int houseIndexToBeMoved,
                                ref bool lastSeedFellIntoOwnKalah,
                                ref bool lastSeedFellIntoEmptyOwnHouse,
                                ref int lastSeedsHouse,
                                bool returnMove)
        {
            if ((houseIndexToBeMoved < 0) || (houseIndexToBeMoved >= _numHousesPerPlayer))
            {
                throw new PSTException("MovePit: houseIndex out of range: " + houseIndexToBeMoved);
            }

            lastSeedFellIntoOwnKalah = false;
            lastSeedFellIntoEmptyOwnHouse = false;
            lastSeedsHouse = -1;

            // Create a move object if this is requested by the caller of the method:
            Move move = null;
            if (returnMove)
            {
                move = new Move();
            }

            // Calculate the array index of the house from which we take the seeds out:
            int internalHouseIndex = houseIndexToBeMoved + (player.GetId() * (_numHousesPerPlayer + 1));

            // Keep the number of seeds to be distributed in mind:
            int numOfSeeds = _pit[internalHouseIndex].GetNumberofSeeds();

            // The distribution of seeds is done in a fast way, using the internal array structure.
            // Find out about the sowing direction: It is clockwise if the rule is simply defined that way or if the rule
            // is set to "Cross-Kalah" and the number of seeds is odd:
            bool sowingDirectionIsClockwise = ((Rules.I.GetDirectionOfSowing() == Rules.DirectionOfSowing.Clockwise) ||
                                               ((Rules.I.GetDirectionOfSowing() == Rules.DirectionOfSowing.CrossKalah) && ((numOfSeeds % 2) == 1)));

            // Empty the pit we start from:
            _pit[internalHouseIndex].RemoveAllSeeds();

            // Distribute the seeds:
            int maybeOneMore = 0;
            Pit kalahOfOpponent = GetKalahOfOpponent(player);
            int loopIndex = 0;
            for (; loopIndex < numOfSeeds+maybeOneMore; ++loopIndex)
            {
                // Depending on the sowing direction, we set the index of the pit that gets a seed accordingly:
                int pitIndex = -1;
                if (sowingDirectionIsClockwise)
                {
                    pitIndex = (internalHouseIndex + 10*_numPitsInTotal - loopIndex - 1) % _numPitsInTotal;
                }
                else
                {
                    pitIndex = (internalHouseIndex + 1 + loopIndex) % _numPitsInTotal;
                }

                if (_pit[pitIndex] != kalahOfOpponent)
                {
                    // This is not the Kalah of the opponent --> Add a seed:
                    _pit[pitIndex].AddASeed();
                    if (returnMove)
                    {
                        // Store this step in the move:
                        move.AddSeedMovement(new SeedMovement(internalHouseIndex, pitIndex, 1));
                    }
                }
                else
                {
                    // This is the opponent's Kalah --> Do not add a seed but instead increase the loop by 1:
                    ++maybeOneMore;
                }
            }

            // Calculate which pit the last seed fell into, depending on the sowing direction:
            int pitOfLastSeed = -1;
            if (sowingDirectionIsClockwise)
            {
                pitOfLastSeed = (internalHouseIndex + 10*_numPitsInTotal - loopIndex) % _numPitsInTotal;
            }
            else
            {
                pitOfLastSeed = (internalHouseIndex + loopIndex) % _numPitsInTotal;
            }

            lastSeedFellIntoOwnKalah = (_pit[pitOfLastSeed] == GetKalahOfPlayer(player));

            if (!lastSeedFellIntoOwnKalah)
            {
                // Check whether the last seed fell into an empty own pit:
                if ((_pit[pitOfLastSeed].GetNumberofSeeds() == 1) && IsPlayersOwnPit(player, pitOfLastSeed))
                {
                    // Yes, it did.
                    lastSeedFellIntoEmptyOwnHouse = true;

                    // We have to calculate the player's pit from the internal pit:
                    lastSeedsHouse = pitOfLastSeed % (_numHousesPerPlayer + 1);
                }
            }

            return move;
        }
예제 #4
0
        /// <param name="player">The player whose Kalah coordinates are requested</param>
        /// <returns>The center coordinate on the "1000-page" of the given player</returns>
        public Point GetTopLeftCornerOfKalah(Player player)
        {
            // Take over the numer of pits in order not to call the method each time:
            int numPits = _gameBoard.GetNumOfHousesPerPlayer();

            // Set the internal index of the first pit in the row:
            int internalStartIndex = ((player.GetPosition() == Player.Position.South) ? 0 : (numPits + 1));

            return (_pit[internalStartIndex + numPits].GetTopLeftCorner());
        }
예제 #5
0
        /// <summary>Logs the board contents for debug purposes.</summary>
        public void LogBoard(Player firstPlayer, Player secondPlayer, Logging.LogLevel logLevel)
        {
            if ((Logging.I.GetLogLevel() & logLevel) == Logging.LogLevel.Off)
            {
                // Small optimization to leave as soon as possible if logging is not active anyway.
                return;
            }

            if (firstPlayer == secondPlayer)
            {
                Logging.I.LogMessage("LogBoard: first and second player are the same: " + firstPlayer + ".\n");
                return;
            }

            // We find out who of the players is south and who is north;
            Player south = null;
            Player north = null;
            if (firstPlayer.GetPosition() == Player.Position.South)
            {
                south = firstPlayer;
                north = secondPlayer;
            }
            else
            {
                south = secondPlayer;
                north = firstPlayer;
            }

            // Now we start building up the log string:
            string logString = ("Game board:\n                ");

            for (int pitIndex = _numHousesPerPlayer - 1; pitIndex >= 0; --pitIndex)
            {
                int numberOfSeeds = GetPitOfPlayer(north, pitIndex).GetNumberofSeeds();
                if (numberOfSeeds < 10) {
                    logString += " ";
                }
                logString += numberOfSeeds + " ";
            }

            logString += "\n              " + GetKalahOfPlayer(north).GetNumberofSeeds();
            for (int index = 0; index < ((3*_numHousesPerPlayer)+3); ++index)
            {
                logString += " ";
            }
            logString += (GetKalahOfPlayer(south).GetNumberofSeeds() + "\n                ");

            for (int pitIndex = 0; pitIndex < _numHousesPerPlayer; ++pitIndex)
            {
                int numberOfSeeds = GetPitOfPlayer(south, pitIndex).GetNumberofSeeds();
                if (numberOfSeeds < 10) {
                    logString += " ";
                }
                logString += numberOfSeeds + " ";
            }

            Logging.I.LogMessage(logString + "\n", logLevel);
        }
예제 #6
0
 /// <returns>The pit with the given number of the given player</returns>
 /// <param name="player">The player whose pit is asked for</param>
 /// <param name="pitIndex">The index of the pit whose internal index is to be returned</param>
 private int GetInternalPitIndex(Player player, int pitIndex)
 {
     if ((pitIndex < 0) || (pitIndex >= _numHousesPerPlayer))
     {
         throw new PSTException("GameBoard.GetInternalPitIndex: pitIndex out of range: " + pitIndex);
     }
     return (pitIndex + (player.GetId() * (_numHousesPerPlayer + 1)));
 }
예제 #7
0
        /// <summary>
        /// Sets the pit with the given index to state "selected" by making visible the according image.
        /// Sets all other pits unselected. Sets all pits unhighlighted.
        /// </summary>
        /// <param name="pitIndexSelected"></param>
        public void SetSelected(int pitIndexSelected, Player currentPlayer)
        {
            int numHouses = GetNumOfHousesPerPlayer();

            if (currentPlayer.GetPosition() == Player.Position.North)
            {
                pitIndexSelected += numHouses + 1;
            }

            for (int pitIndex = 0; pitIndex < numHouses*2+1; ++pitIndex)
            {
                if (pitIndex == numHouses)
                {
                    // Skip the Kalah:
                    continue;
                }

                // Unhighlight the pits in any case:
                UnHighlight(pitIndex);

                if (pitIndex == pitIndexSelected)
                {
                    _pit[pitIndex].SetSelected();
                }
                else
                {
                    _pit[pitIndex].SetUnSelected();
                }
            }
        }
예제 #8
0
        /// <summary>
        /// The given player wins his own pit (given by "ownPitIndex") and the opposite pit. Both pit's contents move into
        /// the player's Kalah.</summary>
        /// <param name="player">The player who wins the pit's contents</param>
        /// <param name="ownPitIndex">The index of the player's pit</param>
        /// <param name="captureOpponentsHouse">A flag whether the seeds in the opponent's house may be captured, too</param>
        /// <param name="returnMove">A flag whether or not to return the move in detail</param>
        /// <returns>The details of this move</returns>
        public Move PlayerWinsHouses(Player player, int ownPitIndex, bool captureOpponentsHouse, bool returnMove)
        {
            Pit ownPit = GetPitOfPlayer(player, ownPitIndex);
            Pit kalahToBeFilled = GetKalahOfPlayer(player);
            int internalKalahIndex = -1;  // Only used when generating a Move
            Move move = null;

            if (returnMove)
            {
                move = new Move();
                internalKalahIndex = GetInternalIndexOfKalah(player);
            }

            if (captureOpponentsHouse)
            {
                // Also the opponent's house shall be captured.
                Pit opponentsPit = GetOppositeHouse(player, ownPitIndex);
                if (returnMove)
                {
                    // Move the opponent's seeds to the player's Kalah:
                    move.AddSeedMovement(new SeedMovement(GetInternalIndexOfOppositeHouse(player, ownPitIndex), internalKalahIndex,
                                         opponentsPit.GetNumberofSeeds()));
                }

                kalahToBeFilled.AddSeeds(opponentsPit.GetNumberofSeeds());
                opponentsPit.RemoveAllSeeds();
            }

            if (returnMove)
            {
                // Move the one seed from the own house into the player's Kalah:
                move.AddSeedMovement(new SeedMovement(GetInternalPitIndex(player, ownPitIndex), internalKalahIndex, 1));
            }

            // Fill the own Kalah with the own seed and remove the own seed from the house:
            kalahToBeFilled.AddSeeds(1);
            ownPit.RemoveAllSeeds();

            return move;
        }
예제 #9
0
 /// <returns>The internal index of the Kalah for the given player</returns>
 /// <param name="player">The player whose Kalah's internal index is asked for</param>
 private int GetInternalIndexOfKalah(Player player)
 {
     return (_numHousesPerPlayer + (player.GetId() * (_numHousesPerPlayer + 1)));
 }
예제 #10
0
        /// <summary>
        /// Restores the stuff that is stored for the players.
        /// If no saved data can be found or an exception occurs, nothing is done and the current settings of the players are kept unchanged.
        /// </summary>
        private void RestorePlayersValues(ref Player southPlayer, ref Player northPlayer)
        {
            // Retrieve the settings from the ApplicationData.Current.RoamingGameStorage:
            ApplicationDataCompositeValue playersGroup_GameStorage = (ApplicationDataCompositeValue)_roamingSettings.Values[_playersStorageName];
            if (playersGroup_GameStorage != null)
            {
                try
                {
                    // We found some settings!
            //DEBUG             Logging.I.LogMessage("GameStorage.RestorePlayersValues: Found saved data.\n");

                    // Restore the human player's names:
                    southPlayer.SetName((string)playersGroup_GameStorage[_playersKey_humanNameSouth]);
                    northPlayer.SetName((string)playersGroup_GameStorage[_playersKey_humanNameNorth]);

                    // Restore the species and the computer's strength:
                    southPlayer.SetSpecies((Player.Species)playersGroup_GameStorage[_playersKey_speciesSouth],
                                           (Player.ComputerStrength)playersGroup_GameStorage[_playersKey_computerStrengthSouth]);
                    northPlayer.SetSpecies((Player.Species)playersGroup_GameStorage[_playersKey_speciesNorth],
                                           (Player.ComputerStrength)playersGroup_GameStorage[_playersKey_computerStrengthNorth]);
                }
                catch (Exception ex)
                {
                    // In the case of not reading the player settings correctly we do nothing:
                    Logging.I.LogMessage("GameStorage.RestorePlayersValues: Exception: " + ex.Message + "\n", Logging.LogLevel.Error);
                }
            }
            else
            {
            //DEBUG         Logging.I.LogMessage("GameStorage.RestorePlayersValues: No saved data found.\n");
            }
        }
예제 #11
0
        /// <summary>
        /// Saves the stuff that is stored in the players' settings.
        /// </summary>
        private void SavePlayersValues(Player southPlayer, Player northPlayer)
        {
            ApplicationDataCompositeValue playersGroup_GameStorage = new ApplicationDataCompositeValue();

            // Save the human player's names:
            playersGroup_GameStorage[_playersKey_humanNameSouth] = southPlayer.GetHumansName();
            playersGroup_GameStorage[_playersKey_humanNameNorth] = northPlayer.GetHumansName();

            // Save the currently set species:
            playersGroup_GameStorage[_playersKey_speciesSouth] = (int)southPlayer.GetSpecies();
            playersGroup_GameStorage[_playersKey_speciesNorth] = (int)northPlayer.GetSpecies();

            // Save the currently set computer's strength:
            playersGroup_GameStorage[_playersKey_computerStrengthSouth] = (int)southPlayer.GetComputerStrength();
            playersGroup_GameStorage[_playersKey_computerStrengthNorth] = (int)northPlayer.GetComputerStrength();

            // Save all stuff at once now:
            _roamingSettings.Values[_playersStorageName] = playersGroup_GameStorage;
        }
예제 #12
0
 /// <summary>
 /// Restores previously saved values in the respective objects. If no saved values could be found, the defaults are set.
 /// </summary>
 public void RestoreSavedValues(ref Player southPlayer, ref Player northPlayer, ref string themeName)
 {
     RestoreThemesValues(ref themeName);
     RestoreSettingsValues();
     RestorePlayersValues(ref southPlayer, ref northPlayer);
     RestoreRulesValues();
 }
예제 #13
0
 /// <summary>
 /// Saves all settings.
 /// </summary>
 public void Save(Player southPlayer, Player northPlayer, string currentThemeName)
 {
     SaveThemesValues(currentThemeName);
     SaveSettingsValues();
     SavePlayersValues(southPlayer, northPlayer);
     SaveRulesValues();
 }
예제 #14
0
 /// <summary>
 /// Switches the indicator to the player whose turn it is.
 /// </summary>
 /// <param name="currentPlayer">The player whose turn it is</param>
 public void SwitchVisualIndicators(Player currentPlayer)
 {
     if (currentPlayer.GetPosition() == Player.Position.South)
     {
         _visualIndicatorSouth.SwitchOn();
         _visualIndicatorNorth.SwitchOff();
         PlayerNameFieldSouth.Foreground = Application.Current.Resources["GamePageTextOn"] as SolidColorBrush;
         PlayerNameFieldNorth.Foreground = Application.Current.Resources["GamePageTextOff"] as SolidColorBrush;
     }
     else
     {
         _visualIndicatorSouth.SwitchOff();
         _visualIndicatorNorth.SwitchOn();
         PlayerNameFieldSouth.Foreground = Application.Current.Resources["GamePageTextOff"] as SolidColorBrush;
         PlayerNameFieldNorth.Foreground = Application.Current.Resources["GamePageTextOn"] as SolidColorBrush;
     }
 }
예제 #15
0
        /// <summary>
        /// Prints a message to the screen at the center position, using a globalized string taken from the corresponding resource file.
        /// This message does not vanish.
        /// </summary>
        /// <param name="messageKey">The resource key to be used</param>
        /// <param name="relevantPlayer">The player whose turn it is currently</param>
        /// <param name="args">0 or more parameters for the resource key</param>
        public void PrintFixedMsg(String messageKey, Player relevantPlayer, params object[] args)
        {
            string message = KalahaResources.I.GetMsg(messageKey, args);
            FixedMessageFieldCenter.Text = message;

            if ((relevantPlayer.GetPosition() == Player.Position.North) && Presenter.I.TabletModeIsActive())
            {
                // Put the words upside down in order for the current player to be easily readable:

                // Define the angle of the visual indicator:
                FixedMessageFieldCenter.RenderTransformOrigin = new Point(0.5, 0.5);         // Rotate around the center
                RotateTransform myRotateTransform = new RotateTransform();
                // Put the name upside down if we are told to do so:
                myRotateTransform.Angle = 180;
                FixedMessageFieldCenter.RenderTransform = myRotateTransform;
            }
        }
예제 #16
0
        /// <summary>
        /// Prints a message to the screen at the center position, using a globalized string taken from the corresponding resource file.
        /// This message automatically vanishes after a few seconds.
        /// </summary>
        /// <param name="messageKey">The resource key to be used</param>
        /// <param name="relevantPlayer">The player whose turn it is currently</param>
        /// <param name="args">0 or more parameters for the resource key</param>
        public async void PrintFadingMsg(String messageKey, Player relevantPlayer, params object[] args)
        {
            string message = KalahaResources.I.GetMsg(messageKey, args);
            MessageFieldCenter.Text = message;

            // Define the angle of the visual indicator:
            MessageFieldCenter.RenderTransformOrigin = new Point(0.5, 0.5);         // Rotate around the center
            RotateTransform myRotateTransform = new RotateTransform();

            if ((relevantPlayer.GetPosition() == Player.Position.North) && Presenter.I.TabletModeIsActive())
            {
                // Put the name upside down if we are told to do so:
                myRotateTransform.Angle = 180;
            }
            else
            {
                // Leave the name in the "usual" angle:
                myRotateTransform.Angle = 0;
            }

            MessageFieldCenter.RenderTransform = myRotateTransform;

            // Print the actual message to the screen by fading in:
            await MessageFieldCenter.FadeIn(TimeSpan.FromMilliseconds(1500));   // The parameter defines the time that the message is visible

            // ... and out:
            await MessageFieldCenter.FadeOut(TimeSpan.FromMilliseconds(200));
        }
예제 #17
0
 /// <returns>True if the given player has no only empty houses left</returns>
 /// <param name="player">The player whose houses are to be checked</param>
 public bool PlayerOnlyHasEmptyHouses(Player player)
 {
     return (!PlayerStillHasFullHouses(player));
 }
예제 #18
0
 /// <returns>The Kalah of the given player's opponent</returns>
 /// <param name="player">The player whose opponent's Kalah is asked for.</param>
 public Pit GetKalahOfOpponent(Player player)
 {
     return _pit[_numHousesPerPlayer + (((player.GetId()+1)%2) * (_numHousesPerPlayer + 1))];
 }
예제 #19
0
        /// <returns>True if the given player has at least one house that still contains seeds</returns>
        /// <param name="player">The player whose houses are to be checked</param>
        public bool PlayerStillHasFullHouses(Player player)
        {
            int playersId = player.GetId();
            for (int pitIndex = 0; pitIndex < _numHousesPerPlayer; ++pitIndex)
            {
                if (_pit[pitIndex + (playersId * (_numHousesPerPlayer + 1))].GetNumberofSeeds() > 0)
                {
                    return true;
                }
            }

            // We walked through all pits and found no filled one:
            return false;
        }
예제 #20
0
 /// <returns>The Kalah of the given player</returns>
 /// <param name="player">The player whose Kalah is asked for.</param>
 public Pit GetKalahOfPlayer(Player player)
 {
     return _pit[GetInternalIndexOfKalah(player)];
 }
예제 #21
0
        /// <param name="player"></param>
        /// <returns>The sum of all seeds that the given player currently has in their pits</returns>
        public int SumOfAllSeedsOfPlayer(Player player)
        {
            int sum = 0;

            for (int pitIndex = 0; pitIndex < _numHousesPerPlayer; ++pitIndex)
            {
                Pit currentPit = GetPitOfPlayer(player, pitIndex);
                sum += currentPit.GetNumberofSeeds();
            }

            return sum;
        }
예제 #22
0
        /// <summary>
        /// Remembers the given move as a "normal" by the given player.
        /// </summary>
        /// <param name="move">The move to remember</param>
        /// <param name="currentPlayer">The player who made the move</param>
        public void RememberNormalNove(Move move, Player currentPlayer)
        {
            // A "normal" move is quite easy to remember: We store a new list entry with the move's "backward move".

            // Get the move's backward move:
            Move backMove = move.GetBackwardMove();

            // Add the backward move and the current player at the beginnings of the respecive lists:
            _moveList.Insert(0, backMove);
            _playerList.Insert(0, currentPlayer);
        }
예제 #23
0
 /// <returns>The pit that lies on the opposite side of the given pit number and the given player</returns>
 /// <param name="player">The player whose pit is asked for</param>
 /// <param name="houseIndex">The index of the house whose opposite house index is to be returned</param>
 private int GetInternalIndexOfOppositeHouse(Player player, int houseIndex)
 {
     if ((houseIndex < 0) || (houseIndex >= _numHousesPerPlayer))
     {
         throw new PSTException("GameBoard.GetInternalIndexOfOppositePit: houseIndex out of range: " + houseIndex);
     }
     return (2 * _numHousesPerPlayer - (houseIndex + (player.GetId() * (_numHousesPerPlayer + 1))));
 }
예제 #24
0
        /// <summary>
        /// Remembers the given move as a move that has to be added to the last "normal" move of the same player.
        /// This is supposed to be used for capture moves or "final" moves.
        /// </summary>
        /// <param name="move">The move to remember</param>
        /// <param name="currentPlayer">The player who made the move</param>
        public void RememberFollowUpMove(Move move, Player currentPlayer)
        {
            // We need an existing player list:
            if (_playerList.Count == 0)
            {
                throw new PSTException("UndoManager.RememberFollowUpMove: player list is empty.");
            }

            // We need an existing move list:
            if (_moveList.Count == 0)
            {
                throw new PSTException("UndoManager.RememberFollowUpMove: move list is empty.");
            }

            // We can only add a follow-up move for the same player as exists as the first entry in the list of players:
            if (_playerList[0] != currentPlayer)
            {
                throw new PSTException("UndoManager.RememberFollowUpMove: Unexpected player: " + currentPlayer + ". Expected " + _playerList[0] + ".");
            }

            // Get the move's backward move:
            Move backMove = move.GetBackwardMove();

            // Integrate the backward move into the move that is the first in the already existing list of "undo moves":
            _moveList[0].IntegrateMove(backMove);
        }
예제 #25
0
 /// <returns>The house which is located to the opposite of the given pit</returns>
 /// <param name="player">The player whose house is given</param>
 /// <param name="houseIndex">The index of the house whose opposite house is to be returned</param>
 /// <exception cref="PSTException">Index out of range</exception>
 public Pit GetOppositeHouse(Player player, int houseIndex)
 {
     return _pit[GetInternalIndexOfOppositeHouse(player, houseIndex)];
 }
예제 #26
0
        /// <param name="player">The player whose pit coordinates are requested</param>
        /// <param name="pitIndex">The index of the pit. May be between 0 and the number of pits-1.</param>
        /// <returns>The center coordinate on the "1000-page" of the given pit</returns>
        public Point GetTopLeftCornerOfPit(Player player, int pitIndex)
        {
            // Take over the numer of pits in order not to call the method each time:
            int numPits = GetNumOfHousesPerPlayer();

            if (pitIndex >= numPits)
            {
                throw new PSTException("GetCenterOfPit: Unknown pitIndex: " + pitIndex);
            }

            // Set the internal index of the first pit in the row:
            int internalStartIndex = ((player.GetPosition() == Player.Position.South) ? 0 : (numPits + 1));

            return (_pit[internalStartIndex + pitIndex].GetTopLeftCorner());
        }
예제 #27
0
 /// <returns>The pit with the given number of the given player</returns>
 /// <param name="player">The player whose pit is asked for</param>
 /// <param name="pitIndex">The index of the pit to be returned</param>
 /// <exception cref="PSTException">Index out of range</exception>
 public Pit GetPitOfPlayer(Player player, int pitIndex)
 {
     return _pit[GetInternalPitIndex(player, pitIndex)];
 }
예제 #28
0
        /// <returns>True if the given pit is one of the player's pits</returns>
        /// <param name="player">The player whose pit is to be checked</param>
        /// <param name="pitIndex">The pit's index which can have a range from 0 to _numPitsInTotal-1, i.e. the complete array</param>
        public bool IsPlayersOwnPit(Player player, int pitIndex)
        {
            if ((pitIndex < 0) || (pitIndex >= _numPitsInTotal))
            {
                throw new PSTException("PlayerOwnsPit: pitIndex out of range: " + pitIndex);
            }

            return ((pitIndex >= (player.GetId() * (_numHousesPerPlayer + 1))) &&
                    (pitIndex < ((player.GetId() * (_numHousesPerPlayer + 1)) + _numHousesPerPlayer)));
        }
예제 #29
0
        /// <summary>
        /// Returns the recursion depth for the calculation of a move, depending on the computer's strength and the number of houses
        /// </summary>
        /// <param name="compStrength">The computer's strength</param>
        /// <param name="numOfHouses">The number of houses per player (may have values 3 through 7)</param>
        /// <returns></returns>
        public int GetRecursionDepth(Player.ComputerStrength compStrength, int numOfHouses)
        {
            if ((numOfHouses < 3) || (numOfHouses > 7))
            {
                throw new PSTException("Settings.RecursionDepth: Unexpected numOfHouses: " + numOfHouses);
            }

            return _recursionDepth[(int)compStrength, numOfHouses];
        }
예제 #30
0
        /// <summary>Enables the non-empty houses of the given player and disables all of his opponent.</summary>
        /// <param name="player">The player whose turn it is</param>
        public void EnableHousesOfPlayer(Player player)
        {
            int numPits = GetNumOfHousesPerPlayer();
            int startIndexOfPlayer = ((player.GetPosition() == Player.Position.South) ? 0 : numPits + 1);
            int startIndexOfOpponent = ((player.GetPosition() == Player.Position.South) ? numPits + 1 : 0);

            for (int pitIndex = 0; pitIndex < numPits; ++pitIndex)
            {
                if (_pit[pitIndex + startIndexOfPlayer].GetNumberOfSeeds() > 0)
                {
                    _pit[pitIndex + startIndexOfPlayer].EnableTouchField();
                }
                else
                {
                    _pit[pitIndex + startIndexOfPlayer].DisableTouchField();
                }
                _pit[pitIndex + startIndexOfOpponent].DisableTouchField();
            }
        }