こんにちは、戦艦ゲームをコーディングしていますが、複数の船の場所を設定するとハングするようです。ただし、コードをステップ実行すると機能します。これは私を困惑させました。これが私に悲しみを与えているコードです。
class BsGame
{
private GameHelper _gameHelper = new GameHelper();
private List<Ship> _shipList = new List<Ship>();
private int numberOfGuesses;
static void Main(string[] args)
{
BsGame b = new BsGame();
b.WelcomeMessage();
b.CreateShips();
b.PlayBattleships();
}
/// <summary>
/// Creates the ships and gets a location
/// </summary>
public void CreateShips()
{
Ship b1 = new Ship("Battleship", 5);
Ship b2 = new Ship("Battleship", 5);
Ship d1 = new Ship("Destoyer", 4);
_shipList.Add(b1);
_shipList.Add(b2);
_shipList.Add(d1);
foreach (Ship s in _shipList)
{
int size = s.Size;
List<string> newLoc = _gameHelper.PlaceShip(size);
s.Location = newLoc;
}
}
/// <summary>
/// Contains a loop that gets user input and calls
/// the game helper to force the case of the input
/// to upper to match the AlPHA coordinates constant's case
/// in the GameHelper class.
/// </summary>
public void PlayBattleships()
{
Console.WriteLine("Let's go!");
while(_shipList.Count() > 0)
{
string guess = Console.ReadLine();
guess = _gameHelper.ForceCase(guess);
CheckGuess(guess);
}
EndGame();
}
private void EndGame()
{
throw new NotImplementedException();
}
private string CheckGuess(string guess)
{
numberOfGuesses++;
string result = "miss";
foreach (Ship ship in _shipList)
{
result = ship.CheckSelf(guess);
if (result == "hit")
{
break;
}
if (result == "kill")
{
_shipList.Remove(ship);
break;
}
}
return result;
}
public void WelcomeMessage()
{
Console.WriteLine("BattleShips - Drew Watson");
Console.WriteLine("This is a simple one sided game of battleships. Your goal is to sink all ships");
Console.WriteLine("Type co-ordinated to pick a square ie, A5, B1 etc.");
}
}
}
/// <summary>
/// Handles the main game loginc off the application.
/// Creates and places ships on a grid.
/// </summary>
public class GameHelper
{
private const int MAX_ATTEMPTS = 200;
private const string ALPHA = "abcdefghij"; // Concat to 0123456789 on the X axis
private const int GRID_LENGTH = 10; // The length of a grid row
private const int GRID_SIZE = 100; // The total size of the grid
private int[] _grid; // The grid as an array of integers
private int _shipCount; // The number of ships
public GameHelper()
{
_grid = new int [GRID_SIZE];
}
/// <summary>
/// Changes the case of the co-ordinates to upper
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public string ForceCase(string input)
{
string inputLine = input;
return inputLine.ToUpper();
}
/// <summary>
/// Places a ship on the grid
/// </summary>
/// <param name="ship"></param>
/// <returns></returns>
public List<string> PlaceShip(int size)
{
List<string> alphaCells = new List<string>(); // Holds 'A5' style co-ordinates
string[] alphaCoords = new string[size];
int[] coords = new int[size];
int location = 0;
int attempts = 0; // Attempts counter
string tempConcat; // Temporary string for concatination
bool success = false;
_shipCount++;
int increment = 1;
if ((size % 3) == 1)
{
increment = GRID_LENGTH;
}
Random rnd = new Random();
while (!success && attempts++ < MAX_ATTEMPTS)
{
location = rnd.Next(GRID_SIZE);
int x = 0;
success = true;
while (success && x < size)
{
if (_grid[location] == 0)
{
coords[x++] = location;
location += increment;
if (location >= GRID_SIZE)
{
success = false;
}
if (x > 0 && (location % GRID_LENGTH == 0)) // Right edge is out of bounds
{
success = false;
}
else
{
success = true;
}
}
}
}
int i = 0;
int row = 0;
int column = 0;
while (i < size)
{
_grid[coords[i]] = 1;
row = (int)(coords[i] / GRID_LENGTH);
column = coords[i] % GRID_LENGTH;
tempConcat = Convert.ToString(ALPHA[column]).ToUpper();
string stringRow = Convert.ToString(row);
string result = String.Concat(tempConcat,stringRow);
alphaCells.Add(result);
i++;
Console.WriteLine(result);
}
return alphaCells;
}
}
public class Ship
{
// Properties
public string Name { get; set; }
public int Size { get; set; }
public List<string> Location { get; set; }
// Constructor
public Ship(string name, int size)
{
Location = new List<string>();
this.Name = name;
this.Size = size;
}
// Methods
public string CheckSelf(string input)
{
string result = "Miss";
int index = Location.IndexOf(input); // If not found returns -1
if (index >= 0)
{
Location.Remove(input); // Remove the cell
if (Location.Count == 0) // If there are no locations left
{
result = "Sink";
Console.WriteLine("BOOM! You sunk a: " + Name); // The ship has been sunk
}
else
{
result = "Hit";// Register a hit
}
}
Console.WriteLine(result);
return result;
}
}
編集::::::::::::::
複数の船を追加すると無限ループに陥りそうです。これを長い間見つめていたので、新鮮な目が役立つかもしれません:D
while (success && x < size)
{
if (_grid[location] == 0)
{
coords[x++] = location;
location += increment;
if (location >= GRID_SIZE)
{
success = false;
}
if (x > 0 && (location % GRID_LENGTH == 0)) // Right edge is out of bounds
{
success = false;
}
else
{
success = true;
}
}
}