Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

C# Question: Battleship AI~ The AI should have three modes, 1) Hunt 2) Agression 3)Sink Hunt should be a method to select cells within the

C# Question:

Battleship AI~

The AI should have three modes, 1) Hunt 2) Agression 3)Sink

Hunt should be a method to select cells within the array to attck obviously

Agression should be how upon detection of an enemy ship the AI should focus on attacking allr emaining cells systematically until that ship has been sunk

Sink should be the after the AI sinks a ship, it declairs what ship was sunk and return to hunt mode for the following turn.

Implement a multiplayer battleship AI.

The rules are the same as last week.

The game is played on an NxN grid

Each player will place a specified set of ships

The ships will vary in length from 2 to 5.

There can be any number or any size ship including 0

EXCEPT the battleship which there will always be 1 and only 1

Player order will be random but fixed at the start of the game

Each round consists of each player making a grid selection in turn

Each grid selection will be played into all players grid. Including the current players grid

Each player will respond with HIT, MISS or SANK {ship name}

If a players battleship is sunk that player is removed from the game

Repeat from #4 until 1 player remains

That player is the winner

Design update

Examine the test framework from blackboard.

Review the IPlayer interface this is the entry point to your code. You will need to implement each of these functions. Does this interface provide you with enough information to implement? If not speak to your instructor maybe accommodations can be made

Review the DumbPlayer and RandomPlayer implementations to see an example of how simple AIs can be built.

Run the code and watch the game play out between the example players

Complete the AI

Your code should be able to play against the provided AIs and also will be challenged by the AIs from other teams as well as one from the instructor

If your code takes an unreasonable amount of time or crashes then your player will be removed from the game.

Since you have the test harness you should be able to run many test passes yourself against the sample AIs

Note any attempts to use reflection or any other similar techniques to determine other players positions will be considered cheating and result in 0 for the assignment.

Grid.cs --

using System; using System.Collections.Generic; using System.Security.Cryptography.X509Certificates;

namespace Week6 { public class Grid { private readonly GridEntry[,] _grid; private readonly int _gridSize;

public Grid(int gridSize) { _gridSize = gridSize; _grid = new GridEntry[gridSize,gridSize]; //Fill the grid with empty entries marked as not hit for (int x = 0; x < gridSize; x++) { for (int y = 0; y < gridSize; y++) { _grid[x,y] = new GridEntry(); } } }

public void Add(Ships ships) { foreach (var ship in ships._ships) { if (ship.Positions == null) { throw new ArgumentException("A player has not set the ships positions"); }

foreach (var pos in ship.Positions) { if (pos.X< 0 || pos.X >_gridSize || pos.Y <0 || pos.y>= _gridSize) { throw new ArgumentException("One of the ships is outside the grid"); }

if (pos.Hit) { throw new ArgumentException("One of the players is adding a hit ship to the game"); }

if (_grid[pos.X, pos.Y].Ship != null) { throw new ArgumentException("One of the players has an overlapping ship"); }

_grid[pos.X, pos.Y].Ship = ship; } } }

public void Draw(int drawX, int drawY) { for (int x = 0; x < _gridSize; x++) { for (int y = 0; y < _gridSize; y++) { Console.SetCursorPosition(drawX + x, drawY + y); Console.ForegroundColor = (_grid[x, y].Ship == null) ? ConsoleColor.Gray : _grid[x, y].Ship.Color; //Find if this segment of the ship is hit Console.BackgroundColor = (_grid[x,y].Hit)? ConsoleColor.Red : ConsoleColor.Black; if (_grid[x, y].Ship == null) { Console.Write("."); } else { Console.Write(_grid[x, y].Ship.Character); } } }

//Reset colors Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; }

public void Attack(Position pos) { _grid[pos.X, pos.Y].Hit = true; } } }

GridEntry.cs --

namespace Week6 { public class GridEntry { public bool Hit; public Ship Ship; } }

IPlayer.cs --

using System; using System.Collections.Generic;

namespace Week6 { interface IPlayer { ///

/// Initializes the players are the start of a game and returns the positions of the ships /// Note: This method should be used to reset any AI state. It will be called once per game and each session might be multiple games /// You may also use this to generate new data structures for this game. The Test harness will handle checking for hits based on your /// returned value so it is up to you if and how you want to store the representation of your own grid /// /// What is the index of this player for this game - may change each game /// Size of the square grid - may change each game /// A list of Ships to provide positions for - may change each game. You should populate this collection with positions void StartNewGame(int playerIndex, int gridSize, Ships ships);

///

/// The name of this player - displayed in the UI /// String Name { get; }

///

/// The index of this player - it should return the index passed into the StartNewGame /// int Index { get; }

///

/// This is where you put the AI that chooses which square to target /// /// A position with an x, y coordinate Position GetAttackPosition();

///

/// The game will notify you of the results of each attack. /// /// A collection for each player still in the game /// You will get the index, the attack position and the result of the attack void SetAttackResults(List results); } }

MultiPlayerBattleShip.cs --

using System; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading;

namespace Week6 { internal class MultiPlayerBattleShip { const int GridSize = 10; //Your player should work when GridSize >=7

private static readonly Random Random = new Random();

private readonly List _players;

private List _playerGrids; private List _playerShips; private List currentPlayers;

public MultiPlayerBattleShip(List players) { this._players = players; }

internal void Play(PlayMode playMode) { currentPlayers = new List(); var availablePlayers = new List(_players); _playerGrids = new List(); _playerShips = new List();

//Add each player in a random order for (int i = 0; i < _players.Count; i++) { var player = availablePlayers[Random.Next(availablePlayers.Count)]; availablePlayers.Remove(player); currentPlayers.Add(player); }

//Tell each player the game is about to start for (int i=0; i

var count = ships._ships.Count(); int totalLength = ships._ships.Sum(ship => ship.Length); currentPlayers[i].StartNewGame(i, GridSize, ships);

//Make sure player didn't change ships if (count != ships._ships.Count() || totalLength != ships._ships.Sum(ship => ship.Length)) { throw new Exception("Ship collection has ships added or removed"); }

var grid = new Grid(GridSize); grid.Add(ships); _playerGrids.Add(grid); _playerShips.Add(ships); }

int currentPlayerIndex = 0; while (currentPlayers.Count > 1) { var currentPlayer = currentPlayers[currentPlayerIndex];

//Ask the current player for their move Position pos = currentPlayer.GetAttackPosition();

//Work out if anything was hit var results = CheckAttack(pos);

//Notify each player of the results foreach (var player in currentPlayers) { player.SetAttackResults(results); }

DrawGrids();

Console.WriteLine(" Player " + currentPlayer.Index + "[" + currentPlayer.Name + "] turn."); Console.WriteLine(" Attack: " + pos.X + "," + pos.Y); Console.WriteLine(" Results:"); foreach (var result in results) { Console.Write(" Player " + result.PlayerIndex + " " + result.ResultType); if (result.ResultType == AttackResultType.Sank) { Console.Write(" - " + result.SunkShip); } Console.WriteLine(); }

//Remove any ships with sunken battleships //Iterate backwards so that we don't mess with the indexes for (int i = currentPlayers.Count - 1; i >= 0; --i) { var player = currentPlayers[i]; if (_playerShips[player.Index].SunkMyBattleShip) { currentPlayers.Remove(player); //We never want to remvoe all the players... if (currentPlayers.Count == 1) { break; } } }

//Move to next player wrapping around the end of the collection currentPlayerIndex = (currentPlayerIndex + 1)%currentPlayers.Count;

if (playMode == PlayMode.Pause) { Console.WriteLine(" Press a key to continue"); Console.ReadKey(true); } else { Thread.Sleep(2000); } }

Console.WriteLine(); Console.WriteLine("Winner is '" + currentPlayers[0].Name + "'"); Console.ReadKey(true);

}

private List CheckAttack(Position pos) { var results = new List();

foreach (var player in currentPlayers) { var result = _playerShips[player.Index].Attack(pos);

//Mark attacks on the grid foreach (var grid in _playerGrids) { grid.Attack(pos); }

result.PlayerIndex = player.Index; results.Add(result); } return results; }

private void DrawGrids() { Console.Clear(); int drawX = 0; int drawY = 0;

for (int i=0; i < currentPlayers.Count; i++) { var player = currentPlayers[i]; var playerIndex = player.Index;

var grid = _playerGrids[playerIndex]; Console.SetCursorPosition(drawX, drawY); Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White;

Console.Write(player.Name); grid.Draw(drawX, drawY+1);

drawX += GridSize + 4; if (drawX + GridSize > Console.BufferWidth) { drawY += GridSize + 5; drawX = 0; } } }

} }

PlayMode.cs --

namespace Week6 { public enum PlayMode { Delay, Pause, } }

Program.cs --

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

namespace Week6 { class Program { static void Main(string[] args) {

List players = new List(); players.Add(new DumbPlayer("Dumb 1")); players.Add(new DumbPlayer("Dumb 2")); players.Add(new DumbPlayer("Dumb 3")); players.Add(new RandomPlayer("Random 1")); players.Add(new RandomPlayer("Random 2")); players.Add(new RandomPlayer("Random 3")); players.Add(new RandomPlayer("Random 4")); players.Add(new RandomPlayer("Random 5"));

//Your code here //players.Add(new GroupNPlayer());

MultiPlayerBattleShip game = new MultiPlayerBattleShip(players); game.Play(PlayMode.Pause); } } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Data Science For Dummies

Authors: Lillian Pierson ,Jake Porway

2nd Edition

1119327636, 978-1119327639

More Books

Students also viewed these Databases questions