Beispiel #1
0
        // AI logic
        private void AdvanceAI()
        {
            IComputer         computer = null;
            bool              cycle    = false;
            AcquireGameStates currentState;

            // early out
            if (game == null || game.State == AcquireGameStates.GameSetup)
            {
                return;
            }

            // get the computer implementation (if this is a computer player)
            if (game.State == AcquireGameStates.TradeShares)
            {
                if (game.SharesToTrade.Player.IsComputer)
                {
                    computer = GetComputer(game.SharesToTrade.Player);
                }
            }
            else if (game.State == AcquireGameStates.SellShares)
            {
                if (game.SharesToSell.Player.IsComputer)
                {
                    computer = GetComputer(game.SharesToSell.Player);
                }
            }
            else if (game.CurrentPlayer.IsComputer)
            {
                computer = GetComputer(game.CurrentPlayer);
            }

            // not a computer player, so exit early
            if (computer == null)
            {
                // nothing
                lastComputer = null;
                return;
            }

            // guard against re-entrancy
            if (System.Threading.Interlocked.CompareExchange(ref oneThread, 1, 0) != 0)
            {
                return;
            }

            // rudimentry cycle detection, does not allow the same computer to be called twice
            cycle        = (lastComputer == computer && lastState == game.State);
            currentState = game.State; // need to cache since state will change below

            // for cycle detection trade what has happened in the past
            cycleQueue.Add(computer.ID + " " + currentState);

            // plan next move
            switch (game.State)
            {
            case AcquireGameStates.ExitGame:
                // if there are only computers playing then Exit, else let the human player decide
                if (computers.Count == game.Players.Count)
                {
                    EndGame();
                }
                else
                {
                    ContinueGame();
                }
                break;

            case AcquireGameStates.Done:
                // if only the computers than repeat again
                if (computers.Count == game.Players.Count && repeatAgain)
                {
                    StartGame();
                }
                break;

            case AcquireGameStates.PlaceTile:
                // have the computer choose a piece
                if (cycle)
                {
                    ShuffleTiles();
                }
                else
                {
                    SelectSquare(computer.SelectSquare(game.CurrentPlayer.Tiles));
                }
                break;

            case AcquireGameStates.BuyShares:
                // have the current player buy shares
                if (cycle)
                {
                    BuyShares(new CorpNames[0]);
                }
                else
                {
                    BuyShares(computer.BuyShares(game.SharesToBuy));
                }
                break;

            case AcquireGameStates.ChooseCorp:
                // have the current choose a corp
                if (cycle)
                {
                    throw new ArgumentException("Cycle detected while choosing a corp");
                }
                else
                {
                    ChooseCorp(computer.ChooseCorp(game.AvailableCorporations));
                }
                break;

            case AcquireGameStates.ChooseParentCorp:
                // have the current choose a parent corp
                if (cycle)
                {
                    throw new ArgumentException("Cycle detected while choosing a parent corp");
                }
                else
                {
                    ChooseCorp(computer.ChooseParentCorp(game.ParentCorporations));
                }
                break;

            case AcquireGameStates.NextTurn:
                // nothing
                break;

            case AcquireGameStates.SellShares:
                // have the 'sell' player choose how many shares to sell
                cycleQueue.Add(" - " + game.SharesToSell.Corporation + " " + game.SharesToSell.Price + " " + game.SharesToSell.Player.Name + " " + game.SharesToSell.Player.IsComputer);
                // TODO! cycle detection in selling will require saving the last trade and ensuring that it is not the same

                /*if (cycle) throw new ArgumentException("Cycle detected while selling shares");
                 * else */
                SellShares(computer.SellShares(game.SharesToSell));
                break;

            case AcquireGameStates.TradeShares:
                // have the 'trade' player choose how many shares to sell
                cycleQueue.Add(" - " + game.SharesToTrade.ParentCorp + "/" + game.SharesToTrade.MergedCorp + " " + game.SharesToTrade.Bonus + " " + game.SharesToTrade.Player.Name + " " + game.SharesToTrade.Player.IsComputer);
                // TODO! cycle detection in trading will require saving the last trade and ensuring that it is not the same

                /*if (cycle) throw new ArgumentException("Cycle detected while trading shares");
                 * else*/
                TradeShares(computer.TradeShares(game.SharesToTrade, game[game.SharesToTrade.ParentCorp].Shares));
                break;
            }

            // cycle detection
            lastState    = currentState; // need to cache the state since it will change above
            lastComputer = computer;

            if (System.Threading.Interlocked.CompareExchange(ref oneThread, 0, 1) != 1)
            {
                throw new ArgumentException("Lock released more than once");
            }
        }