/// <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]; }