Пример #1
0
    /// <summary>
    /// Updates the indicators with the current move options and dice roll from BoardManager.
    /// </summary>
    private void UpdateMoveIndicators()
    {
        BGMoveOptions moveOptions = BackgammonGame.Instance.MoveOptions;
        BGDiceRoll    diceRoll    = BackgammonGame.Instance.DiceRoll;

        UpdateMoveIndicators(moveOptions, diceRoll);
    }
Пример #2
0
    /// <summary>
    /// Initializes a new instance of the <see cref="BGMoveOptions"/> class.
    /// </summary>
    /// <param name="player"></param>
    /// <param name="boardMap"></param>
    /// <param name="diceRoll"></param>
    public BGMoveOptions(BGPlayerID player, BGBoardMap boardMap, BGDiceRoll diceRoll)
    {
        Moves = null;
        Moves = GetMoves(player, boardMap, diceRoll);

        // A player must use both numbers of a roll if possible.
        // If either number can be played but not both, the player must play the larger one.

        if (diceRoll.Roll1 != diceRoll.Roll2 &&
            diceRoll.CanUse(diceRoll.Roll1) &&
            diceRoll.CanUse(diceRoll.Roll2))
        {
            List <BGMove> roll1OnlyMoves = new List <BGMove>();
            List <BGMove> roll2OnlyMoves = new List <BGMove>();
            List <BGMove> bothRollMoves  = new List <BGMove>();

            foreach (BGMove move in Moves)
            {
                BGBoardMap newBoardMap = boardMap.Copy();
                newBoardMap.Use(move);

                BGDiceRoll newDiceRoll = diceRoll.Copy();
                newDiceRoll.Use(move);

                BGMoveOptions newMoveOptions = new BGMoveOptions(player, newBoardMap, newDiceRoll);

                if (move.DiceRoll == diceRoll.Roll1 && newMoveOptions.CanMoveWith(diceRoll.Roll2) ||
                    move.DiceRoll == diceRoll.Roll2 && newMoveOptions.CanMoveWith(diceRoll.Roll1))
                {
                    bothRollMoves.Add(move);
                }
                else if (move.DiceRoll == diceRoll.Roll1 && !newMoveOptions.CanMoveWith(diceRoll.Roll2))
                {
                    roll1OnlyMoves.Add(move);
                }
                else if (move.DiceRoll == diceRoll.Roll2 && !newMoveOptions.CanMoveWith(diceRoll.Roll1))
                {
                    roll2OnlyMoves.Add(move);
                }
            }

            if (bothRollMoves.Count > 0)
            {
                Moves = bothRollMoves;
            }
            else if (diceRoll.Roll1 > diceRoll.Roll2 && roll1OnlyMoves.Count > 0)
            {
                Moves = roll1OnlyMoves;
            }
            else if (diceRoll.Roll2 > diceRoll.Roll1 && roll2OnlyMoves.Count > 0)
            {
                Moves = roll2OnlyMoves;
            }
        }
    }
Пример #3
0
    /// <summary>
    /// Updates the indicators with the specified move options and dice roll.
    /// </summary>
    private void UpdateMoveIndicators(BGMoveOptions moveOptions, BGDiceRoll diceRoll)
    {
        int index = 0;

        SimpleDie[] dice = GetCurrentMoveIndicators();

        for (int roll = 1; roll <= 6; roll++)
        {
            int total = diceRoll.GetTotalRolls(roll);
            int left  = diceRoll.GetRollsLeft(roll);

            for (int current = 0; current < total; current++)
            {
                if (!dice[index].gameObject.activeSelf)
                {
                    dice[index].gameObject.SetActive(true);
                    dice[index].GetComponent <FloatingObject>().CurrentAngle = 0;
                }

                dice[index].Number = roll;

                if (current < total - left)
                {
                    dice[index].GetComponent <Animator>().SetInteger("State", (int)States.Used);
                }
                else if (!moveOptions.CanMoveWith(roll))
                {
                    dice[index].GetComponent <Animator>().SetInteger("State", (int)States.Unavailable);
                }
                else
                {
                    dice[index].GetComponent <Animator>().SetInteger("State", (int)States.Available);
                }

                if (++index >= 4)
                {
                    break;
                }
            }
        }

        for (int i = index; i < 4; i++)
        {
            dice[i].gameObject.SetActive(false);
        }
    }
Пример #4
0
    /// <summary>
    /// Initializes a new instance of the <see cref="BGState"/> class.
    /// </summary>
    /// <param name="boardMap">Board map.</param>
    /// <param name="moveOptions">Move options.</param>
    /// <param name="diceRoll">Dice roll.</param>
    public BGState(BGBoardMap boardMap, BGMoveOptions moveOptions, BGDiceRoll diceRoll)
    {
        BoardMap   = boardMap;
        Moves      = new List <BGMove>();
        NextStates = new Dictionary <BGMove, BGState>();

        foreach (BGMove move in moveOptions.Moves)
        {
            BGBoardMap newBoardMap = boardMap.Copy();
            newBoardMap.Use(move);

            BGDiceRoll newDiceRoll = diceRoll.Copy();
            newDiceRoll.Use(move);

            BGMoveOptions newMoveOptions = new BGMoveOptions(BGPlayerID.Player2, newBoardMap, newDiceRoll);

            Moves.Add(move);
            NextStates[move] = new BGState(newBoardMap, newMoveOptions, newDiceRoll);
        }
    }
Пример #5
0
    /// <summary>
    /// Determines which move to use given the current board map, move options and available dice rolls.
    /// </summary>
    /// <param name="boardMap"></param>
    /// <param name="moveOptions"></param>
    /// <returns></returns>
    public List <BGMove> GetMove(BGBoardMap boardMap, BGMoveOptions moveOptions, BGDiceRoll diceRoll)
    {
        Evaluate(new BGState(boardMap, moveOptions, diceRoll));

        return(m_BestMoves);
    }
Пример #6
0
    /// <summary>
    /// Wait the specified number of seconds for the dice to settle.
    /// </summary>
    /// <param name="seconds"></param>
    /// <returns></returns>
    private IEnumerator WaitDice(float seconds)
    {
        IsLocked = true;

        yield return(new WaitForSeconds(seconds));

        int roll1;
        int roll2;

        if (IsFirstTurn)
        {
            roll1 = Player1.Dice.Die1.Number;
            roll2 = Player2.Dice.Die1.Number;
        }
        else
        {
            roll1 = CurrentPlayer.Dice.Die1.Number;
            roll2 = CurrentPlayer.Dice.Die2.Number;
        }

        if (IsFirstTurn && roll1 == roll2)
        {
            if (IsMurphyRuleEnabled)
            {
                Stakes *= 2;
            }

            ShowAlert("Rerolling dice.");
            RollDice();
        }
        else
        {
            if (IsFirstTurn)
            {
                CurrentPlayer = (roll1 > roll2) ? Player1 : Player2;
                ShowAlert(string.Format("{0} moves first.", CurrentPlayer.Name));
            }

            IsDiceRolled = true;
            DiceRoll     = new BGDiceRoll(roll1, roll2);
            MoveOptions  = new BGMoveOptions(CurrentPlayer.ID, Board.GetBoardMap(), DiceRoll);
            EventHelper.Raise(this, MoveOptionsUpdated);

            if (!MoveOptions.CanMove())
            {
                ShowAlert(string.Format("{0} can not move and must yield this turn.", CurrentPlayer.Name));
                yield return(Wait(3f));

                EndTurn();
            }
            else if (CurrentPlayer.IsAIControlled)
            {
                List <BGMove> moves = new AIPlayerDefault().GetMove(Board.GetBoardMap(), MoveOptions, DiceRoll);

                foreach (BGMove move in moves)
                {
                    yield return(new WaitForSeconds(1f));

                    MoveChecker(move);
                }

                yield return(new WaitForSeconds(3f));

                EndTurn();
            }
        }

        IsLocked = false;
    }
Пример #7
0
    /// <summary>
    /// Gets a list of all moves that can be made for the specified player with the specified board and dice roll.
    /// </summary>
    private List <BGMove> GetMoves(BGPlayerID player, BGBoardMap board, BGDiceRoll diceRoll)
    {
        List <BGMove> moves = new List <BGMove>();

        if (player == BGPlayerID.None)
        {
            return(moves);
        }

        BGPoint home = board.GetHome(player);
        BGPoint jail = board.GetJail(player);

        BGPoint[] innerTable = board.GetInnerTable(player);
        BGPoint[] outerTable = board.GetOuterTable(player);

        // Find available moves.

        if (jail.Count > 0)
        {
            for (int roll = 1; roll <= 6; roll++)
            {
                if (diceRoll.CanUse(roll) && !outerTable[roll - 1].IsBlocking(player))
                {
                    moves.Add(new BGMove(jail, outerTable[roll - 1], roll));
                }
            }
        }
        else
        {
            for (int roll = 1; roll <= 6; roll++)
            {
                if (diceRoll.CanUse(roll))
                {
                    for (BGPointID point = BGPointID.Point1; point <= BGPointID.Point24; point++)
                    {
                        BGPoint from = board.GetPoint(point);

                        if (from.IsOccupiedBy(player))
                        {
                            BGPoint to = null;

                            if (player == BGPlayerID.Player1 && ((point - roll) >= BGPointID.Point1))
                            {
                                to = board.GetPoint(point - roll);
                            }
                            else if (player == BGPlayerID.Player2 && ((point + roll) <= BGPointID.Point24))
                            {
                                to = board.GetPoint(point + roll);
                            }

                            if (to != null && !to.IsBlocking(player))
                            {
                                moves.Add(new BGMove(from, to, roll));
                            }
                        }
                    }
                }
            }

            if (!outerTable.Any(point => point.IsOccupiedBy(player)))
            {
                // Get max distance from home.

                int maxDistance = 0;

                for (int i = 0; i < innerTable.Length; i++)
                {
                    if (innerTable[i].IsOccupiedBy(player))
                    {
                        maxDistance = i + 1;
                    }
                }

                // Find moves that can be used to bear off.

                for (int roll = 1; roll <= 6; roll++)
                {
                    if (diceRoll.CanUse(roll))
                    {
                        if (innerTable[roll - 1].IsOccupiedBy(player))
                        {
                            moves.Add(new BGMove(innerTable[roll - 1], home, roll));
                        }
                        else if (maxDistance > 0 && innerTable[maxDistance - 1].IsOccupiedBy(player) && roll >= maxDistance)
                        {
                            moves.Add(new BGMove(innerTable[maxDistance - 1], home, roll));
                        }
                    }
                }
            }
        }

        return(moves);
    }