Пример #1
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))));
 }
Пример #2
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)));
 }
Пример #3
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)));
 }
Пример #4
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;
        }
Пример #5
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;
        }
Пример #6
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)));
        }
Пример #7
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))];
 }