Describes a battleship player
예제 #1
0
        /// <summary>
        /// Main battleship game loop
        /// </summary>
        /// <param name="opponent">Name of opponent</param>
        /// <param name="width">Width of board</param>
        /// <param name="height">Height of board</param>
        /// <param name="ships">Ships in play</param>
        /// <param name="offense">Offensive strategy</param>
        /// <param name="defense">Defensive strategy</param>
        public void GameLoop(string opponent, int width, int height, List<Ship> ships, BattleshipPlayer player)
        {
            #region Argument Validation

            if (width < 1)
                throw new ArgumentException("width");

            if (height < 1)
                throw new ArgumentException("height");

            if (ships == null)
                throw new ArgumentNullException("ships");

            if (ships.Count == 0)
                throw new ArgumentException("ships");

            if (player == null)
                throw new ArgumentNullException("player");

            #endregion

            _width = width;
            _height = height;
            _ships = ships;
            _shipCount = ships.Count;
            _player = player;

            // Initialize the command dictionary
            _commands =  new Dictionary<string, Func<string, CommandResult>>()
            {
                { "accept", Accept },
                { "reject", Reject },
                { "fire", Fire },
                { "hit", Hit },
                { "miss", Miss },
                { "incoming", Incoming },
                { "sink", Sink },
                { "win", Win },
                { "loss", Loss },
                { "tie", Tie },
                { "exit", Exit }
            };

            try
            {
                // Initialize the player
                CommandResult lastResult = CommandResult.Continue;

                _player.Initialize(_width, _height, _ships, opponent);

                // Write out initial positions of the ships
                List<Ship> placedShips = _player.Defense.PlaceShips();
                foreach (Ship ship in placedShips)
                {
                    Console.WriteLine(ship.ToString());
                    Console.Out.Flush();
            #if DEBUG
                    _player.Log(">> " + ship.ToString());
            #endif
                }

                // Main game loop
                do
                {
                    // Get incoming command
                    string command = Console.ReadLine();
            #if DEBUG
                    _player.Log("<< " + command);
            #endif

                    if (String.IsNullOrEmpty(command))
                    {
                        Debug.WriteLine("Unexpected input: No data received.");
                        break;
                    }

                    // Split the command up
                    string[] parsedCommand = command.Split(delimiters);

                    if (parsedCommand != null && parsedCommand.Length > 0)
                    {
                        // See if an argument was sent with the command
                        string commandArgument = null;
                        if (parsedCommand.Length > 1)
                        {
                            commandArgument = parsedCommand[1];
                        }

                        // Determine what command was sent
                        Func<string, CommandResult> commandFunction;
                        if (_commands.TryGetValue(parsedCommand[0].ToLower(), out commandFunction))
                        {
                            lastResult = commandFunction(commandArgument);
                        }
                        else
                        {
                            Debug.WriteLine("Invalid command: " + command);
                        }
                    }
                    else
                    {
                        Debug.Write("Failed to parse command, attempting to continue.");
                    }
                } while (lastResult == CommandResult.Continue);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unexpected error occurred.  Exception: " + ex.Message);
                Console.WriteLine("Stack Trace: " + ex.StackTrace);
            #if DEBUG
                player.Log("Unexpected error occurred.  Exception: " + ex.Message);
                player.Log("Stack Trace: " + ex.StackTrace);
            #endif
                player.Cleanup(GameEndState.Loss);
                return;
            }

            Debug.WriteLine("Exiting...");
        }
        /// <summary>
        /// Initializes a battleship offense
        /// </summary>
        /// <param name="player">owning player</param>  
        public void Initialize(BattleshipPlayer player)
        {
            AdaptivePlayer = player as AdaptiveBattleshipPlayer;
            _laplaceSmoothHits = (int)((double)_laplaceSmoothFactor * (double)AdaptivePlayer.Ships.Sum(x => x.Size) / (double)(AdaptivePlayer.Width * AdaptivePlayer.Height));
            _score = BattleshipStatisticalUtility.ShipPossibilityMatrix(AdaptivePlayer.Width, AdaptivePlayer.Height, AdaptivePlayer.Ships);
            _notAdjacentScore = BattleshipStatisticalUtility.ShipPossibilityMatrix(AdaptivePlayer.Width, AdaptivePlayer.Height, AdaptivePlayer.Ships);

            DetermineRemainingPositions();

            _parity = BattleshipGame.Random.NextDouble() < 0.5;

            // We start out assuming they don't allow adjacent ships, if we find out that they do in any play through, assume that the do
            if (AdaptivePlayer.Data.AllowsAdjacent > 0)
                _assumeAdjacent = true;
            else
                _assumeAdjacent = false;
        }
        /// <summary>
        /// Initializes a battleship defense
        /// </summary>
        /// <param name="player">owning player</param>
        public void Initialize(BattleshipPlayer player)
        {
            AdaptivePlayer = player as AdaptiveBattleshipPlayer;

            _positionProbability = BattleshipStatisticalUtility.ShipPossibilityMatrix(AdaptivePlayer.Width, AdaptivePlayer.Height, AdaptivePlayer.Ships, out _totalPositions);

            // If we haven't played this player before, initialize the shot matrix with the position probability matrix
            if (AdaptivePlayer.Data.Wins + AdaptivePlayer.Data.Losses + AdaptivePlayer.Data.Ties == 0)
            {
                for(var i = 0; i < AdaptivePlayer.Height; ++i)
                {
                    for(var j = 0; j < AdaptivePlayer.Width; ++j)
                    {
                        AdaptivePlayer.Data.IncomingShots[i][j] = _positionProbability[i, j];
                    }
                }
            }
            else
            {
                _totalPositions = 0;
                for(var i = 0; i < AdaptivePlayer.Height; ++i)
                {
                    for(var j = 0; j < AdaptivePlayer.Width; ++j)
                        _totalPositions += AdaptivePlayer.Data.IncomingShots[i][j];
                }
            }

            _incomingShots = new int[AdaptivePlayer.Width, AdaptivePlayer.Height];
        }