Exemplo n.º 1
0
        public MainWindow()
        {
            InitializeComponent();

            // track the squres
            squares = new Rectangle[AcquireConstants.BoardHeight, AcquireConstants.BoardWidth];
            for (int dim0 = 0; dim0 < AcquireConstants.BoardHeight; dim0++)
            {
                for (int dim1 = 0; dim1 < AcquireConstants.BoardWidth; dim1++)
                {
                    squares[dim0, dim1] = (Rectangle)this.FindName("rectangle" + ((dim1 + 1) + (dim0 * 12)).ToString());

                    if (null == squares[dim0, dim1])
                    {
                        throw new NullReferenceException("Square " + dim0 + " x " + dim1 + " is null!");
                    }
                }
            }

            // init data
            computers    = new Dictionary <int, IComputer>();
            lastComputer = null;
            lastState    = AcquireGameStates.Done;
            cycleQueue   = new List <string>();
            oneThread    = 0;
            playerNames  = new Dictionary <string, Oppenents>();
            playerNames.Add("Human", Oppenents.Human);
            playerNames.Add("Computer Easy", Oppenents.Random);
            playerNames.Add("Computer Hard", Oppenents.Computer2);
            playerNames.Add("Computer Very Hard", Oppenents.Computer3);
            game = null;
            GetItem <Label>(Laddmsg).Content = "";  // fix up the bad looking red block
            repeatAgain = false;
            lifetime    = new Dictionary <int, WinStats>();

            // initialize the startup screen
            for (int i = 1; i <= AcquireConstants.MaxPlayers; i++)
            {
                string basename = Lstartbase + i;
                GetItem <ComboBox>(basename, Lstartlist).Items.Clear();
                foreach (string name in playerNames.Keys)
                {
                    GetItem <ComboBox>(basename, Lstartlist).Items.Add(name);
                }

                // set the defaults
                if (i == 1)
                {
                    GetItem <ComboBox>(basename, Lstartlist).SelectedIndex = 0;
                }
                if (i == 2)
                {
                    GetItem <ComboBox>(basename, Lstartlist).SelectedIndex = 1;
                }
            }

            // start the AI thread
            aiTimer          = new DispatcherTimer();
            aiTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);
            aiTimer.Tick    += new EventHandler(AdvanceAI_Callback);
            aiTimer.Start();
        }
Exemplo n.º 2
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");
            }
        }