# A-level Computing/AQA/Problem Solving, Programming, Data Representation and Practical Exercise/Skeleton code/2016 Exam/Skeleton code 2016 Problems(section D in comp1 and most likely section c in paper1 this year)

This is Comp1 for the new Computer Science Specification even though it is under the Computing Wiki. Keep in mind that there is another Comp1 exam for Computing (for retakes?) and this is the place for this older exam. There should be a new wiki for Computer Science with links from both wikis to each other.

Welcome to the paper 1 section C (what used to be section D in past COMP1 papers) for the new 2016 AQA Computer Science Exam.

This is where suggestions can be made about what some of the questions might be and how can we solve them.

Please be respectful and do not vandalise or tamper with the page, as this would affect students' preparation for their exams!

I wish you all good luck with the exam, hopefully we can make it a little easier on ourselves by working together.

## Checking to see if you're off the board - If the player enters over 9 or under 0 it will crash the game.

Delphi/Pascal Solution

```Procedure GetRowColumn(Var Row: Integer; Var Column: Integer);
Begin
Writeln;

while (Column < 0) OR (Column > 9) Do
while (Row < 0) OR (Row > 9) Do
begin
Writeln('This is not a valid row, please re-enter');
end;

Writeln;
End;
```

VB.NET Solution

```
'Error detection against any input

'Subroutine to get coordinates from user

Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)

'Boolean variables to check whether the input is valid
Dim validCol, validRow As Boolean

Console.WriteLine()

Do
Try
Do
If Column < 0 Or Column > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validCol = True
Console.WriteLine()
Loop Until Column < 10 And Column >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validCol = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidCol = True
Loop Until validCol = True

Do
Try
Do
If Row < 0 Or Row > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validRow = True
Console.WriteLine()
Loop Until Row < 10 And Row >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validRow = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidRow = True
Loop Until validRow = True

Console.Clear()
End Sub
```

Python Solution:

```def GetRowColumn():
print()
Success = False
while Success is False:
Column = int(input("Please enter column: "))
Row = int(input("Please enter row: "))
print()
if Column >= 0 and Column <= 9 and Row >= 0 and Row <= 9:
Success = True
else:
print("Sorry that is an invalid sqaure")
print()
print()
return Row, Column
```

This is a simple way to check the validity of row and column's entered values to ensure they do not exceed the size of the board. The maximum size of the board being 9 and minimum size being 0.

Another way could be to use the 'Try and Except' function in Python, this would help to cover multiple input errors and include the method above in a slightly more efficient way.

```def GetRowColumn():
print()
while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Column = int(input("Please enter column: "))
while Column not in range (0,10):               # while loop to handle correct range (0-9)
print("Input given is off the game board.")
break                      # break free if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")

while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Row = int(input("Please enter row: "))          # try and collect input value for Column
while Row not in range (0,10):               # while loop to handle correct range (0-9)
print("Input given is off the game board.")
break                      # break free from While Loop if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")
print()
return Row, Column
```
```def GetRowColumn():
print()
while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Column = int(input("Please enter column: "))
while Column not in range (0,10):               # while loop to handle correct range (0-9)
print("Input given is off the game board.")
break                      # break free if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")

while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Row = int(input("Please enter row: "))          # try and collect input value for Column
while Row not in range (0,10):               # while loop to handle correct range (0-9)
print("Input given is off the game board.")
break                      # break free from While Loop if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")
print()
return Row, Column
```

This is some more top-notch code from your friendly neighborhood Oliver James Cooke.

```def GetRowColumn():
#asks the player to make a move
while True:
try:
#if the column is more than 9 it asks again
Column = int(input("Please enter column: "))
if Column not in range(0,10):
#gives the error message if its more than 9
raise ValueError

#if the row is more than 9 it asks again
Row = int(input("Please enter row: "))
if Row not in range(0,10):
#gives the error messages if its more than 9
raise ValueError

break
except ValueError:
#returns the values
return Row, Column

#Here is a bit of code for you fantastic pack of code blokes.
# "When you look into an abyss, the abyss also looks into you."
```

Java Solution

```//Author: Dan H
int[] getRowColumn(){
int column=-1;
int row=-1;
int[] move;
move = new int[2];
while((row < 0 || row > 9) || (column < 0 || column > 9)){
if(column > 9 || column < 0){
console.println("Not a valid option...");
} else {
if(row > 9 || row < 0){
console.println("Not a valid option...");
row=-1;
} else {
move[0] = row;
move[1] = column;
}
}
}
return move;
}
```

Alternative, checking column and then row separately:

```// Author Asadullah H
int[] getRowColumn(){
int column = 10;
int row = 10;
int[] move;
move = new int[2];

// make sure column is on the grid
while(column < 0 || column > 9){
console.println();
if((column < 0 || column > 9)){
console.println("That number is not valid.");
}
}
// make sure row is on the grid
while(row < 0 || row > 9){
console.println();
if((row < 0 || row > 9)){
console.println("That number is not valid.");
}
}

move[0] = row;
move[1] = column;
return move;
}
```

Alternative, with no checking, instead invalid values are truncated.

```
int[] getRowColumn(){
int column;
int row;
int[] move;
move = new int[2];
console.println();
move[0] = row;
move[1] = column;
return move;
}
```

C# Solution

```'''May 2017''' - you scrubs. Here is some neat code.

private static void GetRowColumn(ref int Row, ref int Column) {
Console.WriteLine();
Column = -1;
while (!Int32.TryParse(Console.ReadLine(), out Column) || Column < 0 || Column > 9) {
Console.Write("Invalid input. Please enter an integer from 0 to 9: ");
}

Row = -1;
while (!Int32.TryParse(Console.ReadLine(), out Row) || Row < 0 || Row > 9) {
Console.Write("Invalid input. Please enter an integer from 0 to 9: ");
}
Console.WriteLine();
}

'''June 2016''' - Bit of a late addition, but this is my method to stop ANY wrong input from crashing the program.
This works by storing the input as a string, checking if it can be converted to an int, and only then will it overwrite the Column/Row data.

private static void GetRowColumn(ref int Row, ref int Column)
{
Column = 10;
int ColumnParsed = 0;
while ((Column > 9) || (Column < 0))
{
Console.WriteLine();
Console.WriteLine("Please enter a valid column: ");
bool isValid = int.TryParse(ColumnTemp, out ColumnParsed);
if (isValid = true)
{
Column = ColumnParsed;
}
}

Row = 10;
int RowParsed = 0;
while ((Row > 9) || (Row < 0))
{
Console.WriteLine();
Console.WriteLine("Please enter a valid row: ");
bool isValid = int.TryParse(RowTemp, out RowParsed);
if (isValid = true)
{
Row = RowParsed;
}
}
}

Courtesy of the legend known of Lloyd, ~Bridgwater College.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

THIS CODE SOLVE THE PROBLEM OF THE CODE CRASHING IF AN INTEGER BELOW 0 OR ABOVE 9 IS ENTERED BUT THE CODE WILL STILL CRASH IF ANYTHING BUT AN INTEGER IS ENTERED - Aquinas College

private static void GetRowColumn(ref int Row, ref int Column)
{
bool loop = true;
while (loop == true)// this will mean that if a number below 0 and above 9 is entered for the column it will loop back to this
{
Console.WriteLine();

if (Column > 9 || Column < 0)
{
Console.WriteLine("Off the board!");// this is will appear if the column is invalid
}
else
{
loop = false;// if the column is right the loop will become false and wont repeat
}
}

bool loop2 = true;
while (loop2 == true)// this will mean that if a number below 0 and above 9 is entered for the row it will loop back to this
{
Console.WriteLine();

if (Row > 9 || Row < 0)
{
Console.WriteLine("Off the board!");// this is will appear if the row is invalid
}
else
{
loop2 = false;// if the row is right the loop will become false and wont repeat
}
}
}
```

p.s. (if you can't do this, you will fail)

## Add a feature which tells the player the type of warship they hit.

This feature may defeat the point of the game. But we shall give it a go anyway.

Delphi/Pascal Solution

```Procedure MakePlayerMove(Var Board: TBoard; Var Ships: TShips);
Var
Row: Integer;
Column: Integer;
Begin
GetRowColumn(Row, Column);
If (Board[Row][Column] = 'm') Or (Board[Row][Column] = 'h') Then
Writeln('Sorry, you have already shot at the square (', Column, ',', Row,'). Please try again.')
Else If Board[Row][Column] = '-' Then
Begin
Writeln('Sorry, (', Column, ',', Row, ') is a miss.');
Board[Row][Column] := 'm';
End
Else
Begin
Writeln('Hit at (', Column, ',', Row, ').');
if (Board[Row][Column] = 'A') then
writeln('You hit an Aircraft Carrier');
if (Board[Row][Column] = 'B') then
writeln('You hit a Battleship');
if (Board[Row][Column] = 'S') then
writeln('You hit a Submarine');
if (Board[Row][Column] = 'D') then
writeln('You hit a Destroyer');
if (Board[Row][Column] = 'P') then
writeln('You hit a Patrol Boat');

Board[Row][Column] := 'h';
End;
End;
```

VB.NET Solution

```' Answer is more efficient than previous code which utilised a dictionary
Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip)
Dim Row As Integer
Dim Column As Integer
Dim shipNum As Integer = -1
GetRowColumn(Row, Column)
If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Or ship_labels.ContainsKey(Board(Row, Column)) Then
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")
ElseIf Board(Row, Column) = "-" Then
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Board(Row, Column) = "m"
Else
Do
shipNum += 1
If Ships(shipNum).Name(0) = Board(Row, Column) Then
Console.WriteLine("Hit at (" & Column & "," & Row & "). You hit a " & Ships(shipNum).Name)
End If
Loop Until Ships(shipNum).Name(0) = Board(Row, Column)
Board(Row, Column) = "h"
End If
End Sub
```

```
Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip)
Dim Row As Integer
Dim Column As Integer
GetRowColumn(Row, Column)
If Board(Row, Column) = "m" Or Board(Row, Column) = "a" Or Board(Row, Column) = "b" Or Board(Row, Column) = "s" Or Board(Row, Column) = "d" Or Board(Row, Column) = "p" Then
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")
ElseIf Board(Row, Column) = "-" Then
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Board(Row, Column) = "m"
Else
Console.WriteLine("Hit at (" & Column & "," & Row & ").")
Board(Row, Column) = Chr(Asc(Board(Row, Column)) + 32)

Select Case Board(Row, Column)
Case "a"
Console.WriteLine()
Console.WriteLine("You hit an Aircraft Carrier.")
Case "b"
Console.WriteLine()
Console.WriteLine("You hit a Battleship.")
Case "s"
Console.WriteLine()
Console.WriteLine("You hit a Submarine.")
Case "d"
Console.WriteLine()
Console.WriteLine("You hit a Destroyer.")
Case "p"
Console.WriteLine()
Console.WriteLine("You hit a Patrol Boat.")
End Select
End If
End Sub
```

Python Solution

```def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.")
elif Board[Row][Column] == "-":
print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.")
Board[Row][Column] = "m"
else:
print("Hit at (" + str(Column) + "," + str(Row) + ").")
for Ship in Ships:
if Ship[0][0] == Board[Row][Column]:
print(Ship[0])
Board[Row][Column] = "h"
```

```def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.")
elif Board[Row][Column] == "-":
print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.")
Board[Row][Column] = "m"
else:
print("Hit at (" + str(Column) + "," + str(Row) + ").")
if Board[Row][Column] == "A":
print("You hit an Aircraft Carrier")
elif Board[Row][Column] == "B":
print("You hit a Battleship")
elif Board[Row][Column] == "S":
print("You hit a Submarine")
elif Board[Row][Column] == "D":
print("You hit a Destroyer")
elif Board[Row][Column] == "P":
print("You hit a Patrol Boat")
Board[Row][Column] = "h"
```

Java Solution

```//Author: Dan H
void makePlayerMove(char[][] board, Ship[] ships) {
int[] rowColumn = getRowColumn();
int row = rowColumn[0];
int column = rowColumn[1];
if (board[row][column] == 'm' || board[row][column] == 'h') {
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
} else if (board[row][column] == '-') {
console.println("Sorry, (" + column + "," + row + ") is a miss.");
board[row][column] = 'm';
} else {
switch(board[row][column]){
case 'A':
console.println("You hit an Aircraft Carrier");
break;
case 'B':
console.println("You hit a Battleship");
break;
case 'S':
console.println("You hit a Submarine");
break;
case 'D':
console.println("You hit a Destroyer");
break;
case 'P':
console.println("You hit a Patrol Boat");
break;
}
console.println("Hit at (" + column + "," + row + ").");
board[row][column] = 'h';
}
}
```
```// Author: Emmanuel M

void makePlayerMove(char[][] board, Ship[] ships){
int[] rowColumn = getRowColumn();
int row = rowColumn[0];
int column = rowColumn[1];

if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
}
else if (board[row][column] == '-'){
console.println("Sorry, (" + column + "," + row + ") is a miss.");
board[row][column] = 'm';
}
else if (board[row][column] == 'A'){
console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")");
board[row][column] = 'a';
}
else if (board[row][column] == 'B'){
console.println("You hit a Battleship at (" + column + "," + row + ")");
board[row][column] = 'b';
}
else if (board[row][column] == 'S'){
console.println("You hit a Submarine at (" + column + "," + row + ")");
board[row][column] = 's';
}
else if (board[row][column] == 'D'){
console.println("You hit a Destroyer at (" + column + "," + row + ")");
board[row][column] = 'd';
}
else if (board[row][column] == 'P'){
console.println("You hit a Patrol Boat at (" + column + "," + row + ")");
board[row][column] = 'p';
}
}
```

C# Solution

```private static void MakePlayerMove(ref char[,] Board, ref ShipType[] Ships)
{

I worked to replace the 'h' with the specific letter of the warship hit.
The underneath solution does this quite well.
However, it is for the specific ships entered and does not automatically change if more are added/changed.

Basically, I replace the code:
* Board[Row, Column] = 'h';

With this:
for (int i = 0; i < 6-1; i++)
{
if (Board[Row, Column] == System.Convert.ToChar(Ships[i].Name[0]))
{
Board[Row, Column] = System.Convert.ToChar(Ships[i].Name.ToLower()[0]);
}
}

This converts the first letter of the ship name into a character, then converts it to lower case.
The visibility of the letter is handled in a different subroutine (the lower case will be visible).
Only thing I didn't get around to is replacing the '6' with the max element in the array. Work this out yeah ;D

Courtesy of the legend known of Lloyd, ~Bridgwater College.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// Hamza Asif - Nelson and Colne College
// Added a few adjustments so that when the player hits a ship, it identifies it with a smaller case letter (such as 'a' for aircraft carrier) - Oleksandr Buzan
int Row = 0;
int Column = 0;
GetRowColumn(ref Row, ref Column);
if (Board[Row, Column] == 'm' || Board[Row, Column] == 'h')
{
Console.WriteLine("Sorry, you have already shot at the square (" + Column + "," + Row + "). Please try again.");
}
else if (Board[Row, Column] == '-')
{
Console.WriteLine("Sorry, (" + Column + "," + Row + ") is a miss.");
Board[Row, Column] = 'm';
}
else
{
Console.WriteLine("Hit at (" + Column + "," + Row + ").");
if (Board[Row, Column] == 'A')
{
Console.WriteLine("You hit an Aircraft Carrier");
Board[Row, Column] = 'a';
}
else if (Board[Row, Column] == 'B')
{
Console.WriteLine("You hit a Battleship");
Board[Row, Column] = 'b';
}
else if (Board[Row, Column] == 'S')
{
Console.WriteLine("You hit a Submarine");
Board[Row, Column] = 's';
}
else if (Board[Row, Column] == 'D')
{
Console.WriteLine("You hit a Destroyer");
Board[Row, Column] = 'd';
}
else if (Board[Row, Column] == 'P')
{
Console.WriteLine("You hit a Patrol Boat");
Board[Row, Column] = 'p';
}
}
}
```

## No error checking for erroneous inputs - if a string is entered the program crashes!

This is highly unlikely to come up as it is already implemented in Java but it is good practice nonetheless.

Delphi/Pascal Solution

```Function GetMainMenuChoice: Integer;
Var
Choice: String;
Begin
while (Choice <> '1') AND (Choice <> '2') AND (Choice <> '9') Do
begin
writeln('This is not a valid input, please enter again');
end;

Writeln;

End;
```

VB.NET Solution

```'Subroutine to get coordinates from user

Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)

'Boolean variables to check whether the input is valid
Dim validCol, validRow As Boolean

Console.WriteLine()

Do
Try
Do
If Column < 0 Or Column > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validCol = True
Console.WriteLine()
Loop Until Column < 10 And Column >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validCol = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidCol = True
Loop Until validCol = True

Do
Try
Do
If Row < 0 Or Row > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validRow = True
Console.WriteLine()
Loop Until Row < 10 And Row >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validRow = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidRow = True
Loop Until validRow = True
```

Python Solution

```def GetMainMenuChoice():
Choice = input()
while Choice not in ["1","2","9"]:
print("Please enter a valid option: ", end="")
Choice = input()
Choice = int(Choice)
print()
return Choice
```

Java Solution

```    //Already covered in the AQAConsole as this is considered a more complex standard of programming (not likely in AS)
```

C# Solution

```/*One way to do this is to put all the Convert.ToInt32 (Console.ReadLine ()) in a
try / catch and reasonably assume that any problem that happens is because of non-integer input
This happens here, and also in GetMainMenuChoice().
A slightly nicer solution is to create another method which reads an integer input from the user
with the instructions as a parameter */

private static void GetRowColumn(ref int Row, ref int Column)
{
Console.WriteLine();

while (!int.TryParse(Console.ReadLine(), out Column) || Column < 0 || Column > 9)
Console.Write("Please enter a valid column (Integer from 0 to 9): ");

while (!int.TryParse(Console.ReadLine(), out Row) || Row < 0 || Row > 9)
Console.Write("Please enter a valid row (Integer from 0 to 9): ");

Console.WriteLine();
}

/* Or with a method to get integer input ..... */

/* get an integer input from the user */
private static int GetIntegerInput(string instructions)
{
while (true) {
try {
Console.WriteLine (instructions);
int response = Convert.ToInt32 (Console.ReadLine ());
return response;
} catch {
Console.WriteLine ("Please try again, and make sure you enter an integer.");
}
}
}

private static void GetRowColumn(ref int Row, ref int Column)
{
Console.WriteLine();
Column = GetIntegerInput("Please enter column: ");
Row = GetIntegerInput("Please enter row: ");
Console.WriteLine();
}
```

## Save Game File - The player is able to save an unfinished game.

This would involve adding another menu item between 2 and 9 perhaps to load a saved game?
Saving a game part way through would mean just saving a .txt file and having the option to open it much in the same way a training file works.
We would also need to make sure that when a game is saved it deletes the previous save file, or maybe allow for there to be multiple save slots.

Delphi/Pascal Solution

VB.NET Solution

```'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form
'edit PlayGame by adding two if statements
Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip)
Dim GameWon As Boolean = False
Dim gamelimit As Integer = 50
Dim save As String
Console.WriteLine()

Do
PrintBoard(Board)
MakePlayerMove(Board, Ships)
CurrentScore = CurrentScore + 1
Console.WriteLine("You have taken {0} move (s),", CurrentScore)
GameWon = CheckWin(Board)
If GameWon Then
Console.WriteLine("All ships sunk!")
Console.WriteLine()
End If
If save <> "y" Then 'If the user hasn't already specified he wants to save, then this question is posed after every move
Console.WriteLine("Do you want to save (y/n)")
End If
If save = "y" Then
SaveGame(Board) 'If the user has specified that he wants to save this game, the programme executes the save function
End If
Loop Until GameWon Or CurrentScore = 50 ' This pits a limit on the score that is available or the number of moves. If they go over 50 moves/goes it ends the game
If CurrentScore = 50 Then
Console.WriteLine("You used all your moves up. Try again ")
'This is the Save Game subroutine
Sub SaveGame(ByRef Board(,) As Char)
Dim row, column As Integer
Dim line As String

Using filewriter As StreamWriter = New StreamWriter(UserGame.txt)

For row = 0 To 9
For column = 0 To 9
line += Board(row, column) 'For every column in the line, the letter that corresponds to the board positions is copied into the string line
Next
line += vbNewLine 'Every time the programme goes onto a new row, a new line is added to the string line

Next

filewriter.WriteLine(line) ' the string line is saved to the text document
End Using
End Sub

End Sub
```

VB.NET Solution

```' this answer does not work
' Modify playgame to prompt for save
Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip)
Dim GameWon As Boolean = False
Dim save As Char
Dim Filename As String = ""
Do
PrintBoard(Board)
MakePlayerMove(Board, Ships, Turns)
GameWon = CheckWin(Board)
If GameWon Then
PrintBoard(Board)
Console.WriteLine("All ships sunk!")
Console.WriteLine()
End If
If save <> "y" Then
Console.WriteLine("Save Game? y or n")
End If
If save = "y" Then
SaveGame(Board, Filename)
End If
Loop Until GameWon
End Sub

Sub LoadGame(ByVal Filename As String, ByRef Board(,) As Char)
Dim Row As Integer
Dim Column As Integer
Dim Line As String
Dim except As Boolean
Console.WriteLine("Load training game or open a saved game? t or o")
Do
Try
Console.WriteLine("Enter the filename: ")
End If
For Row = 0 To 9
For Column = 0 To 9
Board(Row, Column) = Line(Column)
Next
Next

End Using
except = False
Catch e As Exception
Console.WriteLine("Please enter a valid name: ")
except = True
End Try
Loop While except
End Sub

'Save the Game

Sub SaveGame(ByVal Board(,) As Char, ByRef savedGame As String)
Dim row, column As Integer
Dim line As String = ""
If savedGame.Length = 0 Then
Console.WriteLine("What would you like to save the game as? ")
savedGame = "C:\" & Console.ReadLine & ".txt"
End If
Using fileWriter As StreamWriter = New StreamWriter(savedGame)
For row = 0 To 9
For column = 0 To 9
line += Board(row, column)
Next
line += vbNewLine
Next
line = line.TrimEnd(Chr(9))
fileWriter.Write(line)
End Using
End Sub

'Alternate Savegame Function (Define Filename as "training.txt" earlier in the program)
Sub Savegame(ByVal Filename As String, ByRef Board(,) As Char)
Dim row As Integer
Dim line As String

Using Filewriter As StreamWriter = New StreamWriter(Filename)
For row = 0 To 9
line = ((Board(row, 0)) & (Board(row, 1)) & (Board(row, 2)) & (Board(row, 3)) & (Board(row, 4)) & (Board(row, 5)) & (Board(row, 6)) & (Board(row, 7)) & (Board(row, 8)) & (Board(row, 9)))
Filewriter.WriteLine(line)
Next
End Using
Console.WriteLine("Game Saved")
End Sub
```

```'This code doesn't work. "Board" is unspecified and is classed as an invalid exception error due to Board(,) not being able to be used in the GetRowColoumn area. No idea how to fix this. This code is close, but it needs to be improved for it to work thoroughly without exception errors.

'to save the game
'(prompt to save in GetRowColoumn subroutine)

Console.WriteLine("do you want to save? y or n")
Dim save As String = Console.ReadLine().ToLower

If save = "y" Then
SaveGame(Board)
End If

Sub SaveGame(ByVal Board(,) As Char)
Dim Row As Integer
Dim Column As Integer
Dim line As String = ""
Dim filename As String

Console.WriteLine("What would you like to save the game as?")
filename = "C:" & Console.ReadLine() & ".txt"
'substitute for file location (could be changed so user can input whole file path)
Using FileWriter As StreamWriter = New StreamWriter(filename)
For Row = 0 To 9
For Column = 0 To 9
line += Board(Row, Column)

Next
line += vbNewLine
Next
line = line.TrimEnd(Chr(9))
FileWriter.Write(line)
End Using
End Sub

Sub LoadGame(ByVal Filename As String, ByRef Board(,) As Char)
Dim Row As Integer
Dim Column As Integer
Dim Line As String

Console.WriteLine("training game or other saved game? t or o")
Dim input As String = Console.ReadLine().ToLower

If input = "o" Then
Console.WriteLine("What game would you like to open")
Filename = "C:" & Console.ReadLine() & ".txt"
End If       ' substitute for file path or let user input their own.

For Row = 0 To 9
For Column = 0 To 9
Board(Row, Column) = Line(Column)
Next
Next
End Using
End Sub
```

Python Solution

```Solution for 3.3:

def SaveGame(Board):
print("Saving Game:")
saveFilename = "BattleshipSave.txt"             # Gives the SaveFile a specific name (don't forget the .txt extension)
# Need to create a 'String' version of the BOARD Variable (to write to .txt file)
BoardText = str(Board)
with open(saveFilename, "w") as SaveFile:       # Open the save file in WRITE 'w' mode.

for Row in range(10):                             # for each of the 10 Rows on the Board, do the below.
for Column in range(10):                        # for each of the 10 Column spaces within that Row, do the following.
SaveFile.writelines(str(Board[Row][Column]))  # Write the contents of the current 'Board' Space to the file.
SaveFile.writelines("\n")                       # Starts a new line after saving each Row of the Board to the file.

SaveFile.close()                                # Close the file access afterwards.

Solution for 2.7:

def SaveGame(Board):
FileName = raw_input("Enter a file name: ")
FileName = FileName + ".txt"
SaveFile = open(FileName, "w")
for Row in range(10):
for Column in range(10):
SaveFile.write(Board[Row][Column])
SaveFile.write("\n")
SaveFile.close()

# Add a call to this subroutine 'SaveGame(Board)' in to the main 'PlayGame' subroutine.
# Try to add it after the player has made the move, so the game progress is up to date.
# This will Save the game progress after each turn to an external .txt file.
gl with the exam guys. Have fun!!!!!
```

You will need to add a call to this subroutine into the main PlayGame(Board) subroutine to get it to save the Progress after each turn.

```def PlayGame(Board, Ships):
GameWon = False
while not GameWon:
PrintBoard(Board)
print()
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board)
SaveGame(Board)                 # Call SaveGame subroutine after the player has made a move.
if GameWon:
print("All ships sunk!")
print()
```

Java Solution

```//Author: Dan H
void playGame(char[][] board, Ship[] ships) {
boolean gameWon = false;
int moves = 0;
while (!gameWon) {
printBoard(board);

AQAWriteTextFile2016 write = new AQAWriteTextFile2016();
String saveGame = console.readLine("Save Game (y/n)?");
if (saveGame.toLowerCase().equals("y")) {
write.openFile("src/main/PreviousGame.txt");
String s = "";
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 10; x++) {
s += board[x][y];
if(x==9) s += "\r\n";
}
}
write.writeToTextFile(s);
write.closeFile();
}
makePlayerMove(board, ships);
moves++;
gameWon = checkWin(board, ships);
if (gameWon) {
console.println("All ships sunk in " + moves + " moves!");
console.println();
}
}
}
public Main() {
final String TrainingGame = "src/main/Training.txt";
final String PreviousGame = "src/main/PreviousGame.txt";
char board[][] = new char[10][10];
Ship ships[] = new Ship[6];
setUpBoard(board);
setUpShips(ships);
placeRandomShips(board, ships);
playGame(board, ships);
}
playGame(board, ships);
}
playGame(board, ships);
}
}
}
```

C# Solution

```// This is our semi-functional save game code, the only problem is that after you have saved the game and return to the main menu any menu choice will load the previously saved game, you can avoid this by exiting the console window and restarting the program.
public struct ShipType
{
public string Name;
public int Size;
}

const string TrainingGame = "Training.txt";
const string RecentGame = "Recent.txt"; // add a new constant string for the load recent game text file

{
Console.WriteLine("");
Console.WriteLine("1. Start new game");
Console.WriteLine("9. Quit");
Console.WriteLine();
}

private static void PlayGame(ref char[,] Board, ref ShipType[] Ships)
{
bool GameWon = false;
while (GameWon == false)
{
PrintBoard(Board);
MakePlayerMove(ref Board, ref Ships);
GameWon = CheckWin(Board);
if (GameWon == true)
{
Console.WriteLine("All ships sunk!");
Console.WriteLine();
}
Console.WriteLine("Do you want to save the game? ");
if (save == "Yes" || save == "yes" || save == "y" || save == "Y")
{
SaveGame(RecentGame, ref Board);
}
}
}

private static void SaveGame(string TrainingGame, ref char[,] Board)
{
Console.WriteLine("Saving...");
using (var BoardFile = new StreamWriter(RecentGame))
{
for (int h = 0; h < 10; h++)
{
for (int v = 0; v < 10; v++)
{
//write format string to file
BoardFile.Write(Board[h, v]);
}
}
}
Console.Clear();
}

static void Main(string[] args)
{
ShipType[] Ships = new ShipType[6];
char[,] Board = new char[10, 10];
{
SetUpBoard(ref Board);
SetUpShips(ref Ships);
{
PlaceRandomShips(ref Board, Ships);
PlayGame(ref Board, ref Ships);
}
{
PlayGame(ref Board, ref Ships);
}
{
SaveGame(RecentGame, ref Board);
PlayGame(ref Board, ref Ships);
}
```

## How would the game be extended to use a bigger board?

Unlikely as all the ship data would need to be changed. It would take too long in the exam.

Delphi/Pascal Solution

VB.NET Solution

Python Solution

```###Solution by Robert Nixon - Wheatley Park School
'''
The programmers have originally hardcoded the size of the board into the relevant functions and procedures.
Here I have set the 'boardSize' variable to the number of rows and columns I want (as mentioned in the Java solution). The value 12 will result in a board which is 11*11 in size.
The advantage of this is that I can change the size of the board by changing one number.
I have also passed 'boardSize' into the appropriate functions.
'''
if __name__ == "__main__":
boardSize = 12 #Just change this value to change the size of the board
TRAININGGAME = "Training.txt"
Board = SetUpBoard(boardSize)
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
PlaceRandomShips(Board, Ships, boardSize)
PlayGame(Board,Ships,boardSize)
PlayGame(Board, Ships,boardSize)

'''
You could now set the size of the board to a user defined value.
It will crash for some values because the ships won't fit on the board e.g if you entered 2.
If I was doing this in the exam I would add an error check in and set a lower limit (depending on how large my ships are) and an upper limit to prevent display errors from a very large board.
I don't think this is likely to come up but it's easy enough to do:
'''

if __name__ == "__main__":
boardSize = int(raw_input("How big should the board be? ")) #Just change this line
TRAININGGAME = "Training.txt"
Board = SetUpBoard(boardSize)
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
PlaceRandomShips(Board, Ships, boardSize)
PlayGame(Board,Ships,boardSize)
PlayGame(Board, Ships,boardSize)

'''
Below are all the functions/procedures which required the new 'boardSize' variable.
'''

def SetUpBoard(boardSize):
Board = []
for Row in range(boardSize):
BoardRow = []
for Column in range(boardSize):
BoardRow.append("-")
Board.append(BoardRow)
return Board

def PlaceRandomShips(Board, Ships, boardSize):
for Ship in Ships:
Valid = False
while not Valid:
Row = random.randint(0, 9)
Column = random.randint(0, 9)
HorV = random.randint(0, 1)
if HorV == 0:
Orientation = "v"
else:
Orientation = "h"
Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation, boardSize)
print "Computer placing the " + Ship[0]
PlaceShip(Board, Ship, Row, Column, Orientation)

def ValidateBoatPosition(Board, Ship, Row, Column, Orientation, boardSize):
if Orientation == "v" and Row + Ship[1] > boardSize:
return False
elif Orientation == "h" and Column + Ship[1] > boardSize:
return False
else:
if Orientation == "v":
for Scan in range(Ship[1]):
if Board[Row + Scan][Column] != "-":
return False
elif Orientation == "h":
for Scan in range(Ship[1]):
if Board[Row][Column + Scan] != "-":
return False
return True

def CheckWin(Board, boardSize):
for Row in range(boardSize):
for Column in range(boardSize):
if Board[Row][Column] in ["A","B","S","D","P"] :
return False
return True
'''
Here I have added in an exception to make the board display correctly for double digit values.
'''
def PrintBoard(Board, boardSize):
print
print "The board looks like this: "
print
print "",
for Column in range(boardSize):
print " " + str(Column) + " ",
print
for Row in range(boardSize):
if Row <= 9:
print str(Row) + " ", #Add in a space for values less than or equal to 9
elif Row > 9:
print str(Row),
for Column in range(boardSize):
if Board[Row][Column] == "-":
print " ",
elif Board[Row][Column] in ["A","B","S","D","P"]:
print " ",
else:
print Board[Row][Column],
if Column != boardSize - 1:
print "|",
print

def PlayGame(Board, Ships, boardSize):
GameWon = False
while not GameWon:
PrintBoard(Board, boardSize)
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board, boardSize)
if GameWon:
print "All ships sunk!"
print
```

Java Solution

```// (Edit by : Asadullah: use '''ctrl+h''' and replace the number 10 with any number you want by clicking replace all, but check all the replacements in case you have made additional adjustments. It may also be replaced with an appropriate constant such as BOARD_SIZE
```

C# Solution

## How could the game be changed to add another ship?

Delphi/Pascal Solution

```procedure PlaceRandomShips(var Board: TBoard; Ships: TShips);
var
Valid: boolean;
Ship: TShip;
Row: integer;
Column: integer;
HorV: integer;
Count: integer;
Orientation: char;
begin
Randomize;
for Count := 0 to 5 do //(Changes the value to the fifth boat)
begin

function CheckWin(Board: TBoard): boolean;
var
Row: integer;
Column: integer;
GameWon: boolean;
begin
GameWon := True;
for Row := 0 to 9 do
for Column := 0 to 9 do
if (Board[Row][Column] = 'A') or (Board[Row][Column] = 'B') or
(Board[Row][Column] = 'S') or (Board[Row][Column] = 'D') or
(Board[Row][Column] = 'P') or (Board[Row][Column] = 'E') //add this with a letter that represents your boat

procedure PrintBoard(Board: TBoard);
var
Row: integer;
Column: integer;
begin
Writeln;
Writeln('The board looks like this: ');
Writeln;
Write(' ');
for Column := 0 to 9 do
begin
Write(' ', Column, '  ');
end;
Writeln;
for Row := 0 to 9 do
begin
Write(Row, ' ');
for Column := 0 to 9 do
begin
if Board[Row][Column] = '-' then
Write(' ')
else if (Board[Row][Column] = 'A') or (Board[Row][Column] = 'B') or
(Board[Row][Column] = 'S') or (Board[Row][Column] = 'D') or
(Board[Row][Column] = 'P') or (Board[Row][Column] = 'E') then //Do the same thing, as stated previously
Write(' ')
else
Write(Board[Row][Column]);
if (Column <> 9) then
Write(' | ');
end;
Writeln;
end;
end;

procedure SetUpShips(var Ships: TShips);
begin
Ships[0].Name := 'Aircraft Carrier';
Ships[0].Size := 5;
Ships[1].Name := 'Battleship';
Ships[1].Size := 4;
Ships[2].Name := 'Submarine';
Ships[2].Size := 3;
Ships[3].Name := 'Destroyer';
Ships[3].Size := 3;
Ships[4].Name := 'Patrol Boat';
Ships[4].Size := 2;

type
TBoard = array[0..9, 0..9] of string;

TShip = record
Name: string;
Size: integer;
end;
TShips = array[0..5] of TShip;
```

VB.NET Solution

```1).
'The boat placed will be displayed as "F" for Frigate
Function CheckWin(ByVal Board(,) As Char)
Dim Row As Integer
Dim Column As Integer
For Row = 0 To 9
For Column = 0 To 9
If Board(Row, Column) = "A" Or Board(Row, Column) = "B" Or Board(Row, Column) = "S" Or Board(Row, Column) = "D" Or Board(Row, Column) = "P" Or Board(Row, Column) = "F" Then
Return False
End If
Next
Next
Return True
End Function

Sub PrintBoard(ByVal Board(,) As Char)
Dim Row As Integer
Dim Column As Integer
Console.WriteLine()
Console.WriteLine("The board looks like this: ")
Console.WriteLine()
Console.Write(" ")
For Column = 0 To 9
Console.Write(" " & Column & "  ")
Next
Console.WriteLine()
For Row = 0 To 9
Console.Write(Row & " ")
For Column = 0 To 9
If Board(Row, Column) = "-" Then
Console.Write(" ")
ElseIf Board(Row, Column) = "A" Or Board(Row, Column) = "B" Or Board(Row, Column) = "S" Or Board(Row, Column) = "D" Or Board(Row, Column) = "P" Or Board(Row, Column) = "F" Then
Console.Write(" ")
Else
Console.Write(Board(Row, Column))
End If
If Column <> 9 Then
Console.Write(" | ")
End If
Next
Console.WriteLine()
Next
End Sub

Sub SetUpShips(ByRef Ships() As TShip)
Ships(0).Name = "Aircraft Carrier"
Ships(0).Size = 5
Ships(1).Name = "Battleship"
Ships(1).Size = 4
Ships(2).Name = "Submarine"
Ships(2).Size = 3
Ships(3).Name = "Destroyer"
Ships(3).Size = 3
Ships(4).Name = "Patrol Boat"
Ships(4).Size = 2
Ships(5).Name = "Frigate"
Ships(5).Size = 4
End Sub
'Ensure the Structure Array is changed to accommodate extra ships
Sub Main()
Dim Board(9, 9) As Char
Dim Ships(5) As TShip

'It is very simple to add, it only requires about four lines of extra code
```

Python Solution

```#I have only showed the functions that have been edited to add new ships. Code edited and shared by Christian Manners
def CheckWin(Board):
for Row in range(10):
for Column in range(10):
if Board[Row][Column] in ["A","B","S","D","P","F", "C"]: #Added "F" and "C" for the new ships
return False
return True

def PrintBoard(Board):
print()
print("The board looks like this: ")
print()
print (" ", end="")
for Column in range(10):
print(" " + str(Column) + "  ", end="")
print()
for Row in range(10):
print (str(Row) + " ", end="")
for Column in range(10):
if Board[Row][Column] == "-":
print(" ", end="")
elif Board[Row][Column] in ["A","B","S","D","P","F", "C"]: #Same as before added "F" and "C" for the new ships
print(" ", end="")
else:
print(Board[Row][Column], end="")
if Column != 9:
print(" | ", end="")
print()

if __name__ == "__main__":
TRAININGGAME = "Training.txt"
Board = SetUpBoard()
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2], ["Frigate", 3], ["Cruiser", 3]] #added ["Frigate", 3] and ["Cruiser", 3] to the array
PlaceRandomShips(Board, Ships)
PlayGame(Board,Ships)
PlayGame(Board, Ships)
```

Java Solution

```//Author: Dan H
void setUpShips(Ship[] ships) {
ships[0] = new Ship();
ships[0].name = "Aircraft Carrier";
ships[0].size = 5;
ships[1] = new Ship();
ships[1].name = "Battleship";
ships[1].size = 4;
ships[2] = new Ship();
ships[2].name = "Submarine";
ships[2].size = 3;
ships[3] = new Ship();
ships[3].name = "Destroyer";
ships[3].size = 3;
ships[4] = new Ship();
ships[4].name = "Patrol Boat";
ships[4].size = 2;
ships[5] = new Ship(); //Adding a random ship
ships[5].name = "USS Enterprise";
ships[5].size = 6;
}
public Main() {
final String TrainingGame = "src/main/Training.txt";
char board[][] = new char[10][10];
Ship ships[] = new Ship[6];
setUpBoard(board);
setUpShips(ships);
placeRandomShips(board, ships);
playGame(board, ships);
}
playGame(board, ships);
}
}
}
boolean checkWin(char[][] board, Ship[] ships) {
for (int row = 0; row < 10; row++) {
for (int column = 0; column < 10; column++) {
if (board[row][column] == 'A' || board[row][column] == 'B' || board[row][column] == 'S'
|| board[row][column] == 'D' || board[row][column] == 'P' || board[row][column]=='U') {
return false;
}
}
}
return true;
}
/*IMPORTANT I DON'T WANT TO PASTE TOO MUCH, REMEMBER TO CHANGE:
else if (board[row][column] == 'A' || board[row][column] == 'B' || board[row][column] == 'S'
|| board[row][column] == 'D' || board[row][column] == 'P' || board[row][column]=='U')
{
console.print(" ");
}
Inside of printBoard()*/
```

C# Solution

```// <u>'''THIS DOES NOT WORK AS THE SHIP IS NOT HIDDEN- Aquinas College'''</u>
//I knew that your previous method didn't work, so I added a few bits of code before so that:
//-The ship can be hidden from the user
//-The ship can be checked to make sure that it was sunk, so that the game ends
//Please don't delete my work, thank you... - Oleksandr Buzan

private static bool CheckWin(char[,] Board)
{
for (int Row = 0; Row < 10; Row++)
{
for (int Column = 0; Column < 10; Column++)
{
if (Board[Row, Column] == 'A' || Board[Row, Column] == 'B' || Board[Row, Column] == 'S' || Board[Row, Column] == 'D' || Board[Row, Column] == 'P' || Board[Row, Column] == 'R') // This checks that all the enemy ships have been sunk, if not then...
{
return false;
}
}
}
return true;
}
private static void PrintBoard(char[,] Board)
{
Console.WriteLine();
Console.WriteLine("The board looks like this: ");
Console.WriteLine();
Console.Write(" ");
for (int Column = 0; Column < 10; Column++)
{
Console.Write(" " + Column + "  ");
}
Console.WriteLine();
for (int Row = 0; Row < 10; Row++)
{
Console.Write(Row + " ");
for (int Column = 0; Column < 10; Column++)
{
if (Board[Row, Column] == '-')
{
Console.Write(" ");
}
else if (Board[Row, Column] == 'A' || Board[Row, Column] == 'B' || Board[Row, Column] == 'S' || Board[Row, Column] == 'D' || Board[Row, Column] == 'P' || Board[Row, Column] == 'R') //This checks for any characters that aren't spaces. If there are, then...
{
Console.Write(" "); //Replace the output with a space
}
else
{
Console.Write(Board[Row, Column]);
}
if (Column != 9)
{
Console.Write(" | ");
}
}
Console.WriteLine();
}
}
private static void SetUpShips(ref ShipType[] Ships)
{                                           // Hamza Asif - Nelson and Colne College
Ships[0].Name = "Aircraft Carrier";
Ships[0].Size = 5;
Ships[1].Name = "Battleship";
Ships[1].Size = 4;
Ships[2].Name = "Submarine";
Ships[2].Size = 3;
Ships[3].Name = "Destroyer";
Ships[3].Size = 3;
Ships[4].Name = "Patrol Boat";
Ships[4].Size = 2;
Ships[5].Name = "Random Ship's Name";
Ships[5].Size = 10;
}

static void Main(string[] args)
{
ShipType[] Ships = new ShipType[6]; // Total amount of ships. Start counting at 0
char[,] Board = new char[10, 10];
{
SetUpBoard(ref Board);
SetUpShips(ref Ships);
{
PlaceRandomShips(ref Board, Ships);
PlayGame(ref Board, ref Ships);
}
{
PlayGame(ref Board, ref Ships);
}
}
}
```

## Game crashes at the main menu if a string is entered or if the menu option does not exist.

Delphi/Pascal Solution

VB.NET Solution

``` Function GetMainMenuChoice()
Dim Choice As Integer
Try
Console.WriteLine()
If Choice <> "1" And Choice <> "2" And Choice <> "9" Then
Console.WriteLine("ERROR: Invalid input!")
End If
Return Choice
Catch Ex As Exception
Console.WriteLine("Please enter a valid input (1, 2 or 9)")
End Try
End Function
```

Python Solution

```def GetMainMenuChoice():
try:      # TRY to take a correct input here.
Choice = int(input())
print()
return Choice
except(TypeError, ValueError, NameError, IOError):    # Make an exception for any incorrectly entered choice.
print()
print("Please enter one of the options listed")     # Print error message and display menu, then ask for input again.
print()
```

Java Solution

```//AQA console already covers this
```

C# Solution

```// - Oleksandr Buzan
{
string Choice = null;
int Choice2 = 0;
bool CheckInput = false;
while (CheckInput == false)
{
if (Choice != "1" && Choice != "2" && Choice != "9")
{
Console.WriteLine("This is an invalid option");
}
else
{
CheckInput = true;
}
}
Choice2 = Convert.ToInt32(Choice);
Console.WriteLine();
return Choice2;
}
```

## On menu you can enter any number. But it crashes when you enter a letter.

Delphi/Pascal Solution

VB.NET Solution

``` Function GetMainMenuChoice()
Dim Choice As Integer
Try
Console.WriteLine()
If Choice <> "1" And Choice <> "2" And Choice <> "9" Then
Console.WriteLine("ERROR: Invalid input!")
End If
Return Choice
Catch Ex As Exception
Console.WriteLine("Please enter a valid input (1, 2 or 9)")
End Try
End Function
```

Python Solution

```def GetMainMenuChoice():
Choice = input()
while Choice not in ["1","2","9"]:
Choice = int(Choice)
print()
return Choice

1. Using a simple list in which it checks if the value is there or not if it is not then you will be asked repeatedly until an integer is input.
2. Let my name be known Mustafa
```

Java Solution

```/**This is covered by the AQA Console code already**/
```

C# Solution

```'''May 2017'''

{
int Choice = 0;
{
Console.Write("Incorrect input\r\n");
Console.WriteLine();
}
Console.WriteLine();
return Choice;
}

//Luke Moll, Bridgwater College
{
int Choice = 0;

while (true)
{
try
{
Console.WriteLine();
break;
}
catch (Exception e)//Catches FormatException and OverflowException (latter when valid int is entered but is too large for Int32)
{
Console.Write("Try again: ");
continue;
}
}
return Choice;
}
```

## Limit the number of moves for the player to use.

Delphi/Pascal Solution

VB.NET Solution

```Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip)
'Give the play a finite number of ammo, when they run out of ammo, they
Dim GameWon As Boolean = False
Dim GameLost As Boolean = False
Dim NumShots As Integer
Dim NumShotsLeft As Integer
NumShots = 0
NumShotsLeft = 25
Do
NumShots += 1
NumShotsLeft -= 1
PrintBoard(Board)
MakePlayerMove(Board, Ships)
Console.WriteLine("Shots taken: " & NumShots)
Console.WriteLine("Shots remaining: " & NumShotsLeft)
GameWon = CheckWin(Board)
If NumShotsLeft = 0 Then
GameLost = True
End If
If GameLost = True Then
Console.WriteLine("Bad Luck! You ran out of ammo!")
Console.WriteLine()
End If

If GameWon Then
Console.WriteLine("All ships sunk!")
Console.WriteLine()
End If
Loop Until GameWon Or GameLost
'END
End Sub
```

Python Solution

```def PlayGame(Board, Ships):
GameWon = False
MAXMOVES = 30           # Setup the Maximum amount of moves here, as a CONSTANT (Capital letters).
movesLeft = MAXMOVES    # Assign the CONSTANT of MAXMOVES to a usable Variable.
while not GameWon:
PrintBoard(Board)

print()
print("You have {} moves left".format(movesLeft))   # the .format() puts the variable into the printed string.
MakePlayerMove(Board, Ships)
movesLeft = movesLeft - 1     # subtract 1 move after the player has made a move.
if movesLeft == 0:
print("You have run out of moves/ammo!!")
return

GameWon = CheckWin(Board)
if GameWon:
print("All ships sunk!")
print()
```

Java Solution

```/**
* Function to play the game
*
* @param board - Board to be played on
* @param ships - Ships to be played with
*/
void playGame(char[][] board, Ship[] ships)
{
// Game is not one to begin
boolean gameWon = false;

// While the game hasn't been one
for(int moveIndex = 0; moveIndex < 5; moveIndex++)
{
// Print the board
printBoard(board);

// Get the players move
makePlayerMove(board, ships);

// Check if user has one
gameWon = checkWin(board, ships);

// If the user has one the game tell them
if(gameWon)
{
// All ships sunk!
console.println("All ships sunk!");

// New line
console.println();

break;
}

char quit = console.readChar("Would you like to exit and save?(Y/n)");

if(quit == 'y' || quit == 'Y')
{
String filename = console.readLine("Name game: ");

saveGame(filename, board);
break;
}
}

if(!gameWon)
{
System.out.println("Game Lost - Too many moves");
}
}
```

C# Solution

```private static void PlayGame(ref char[,] Board, ref ShipType[] Ships)
{
bool GameWon = false;
int MaxMoves = 30;
while (GameWon == false)
{
PrintBoard(Board);
MakePlayerMove(ref Board, ref Ships);
GameWon = CheckWin(Board);
if (GameWon == true)
{
Console.WriteLine("All ships sunk!");
Console.WriteLine();
}
else
{
MaxMoves -= 1;
Console.WriteLine("You have " + MaxMoves + " move left!");
if (MaxMoves == 0)
{
Console.WriteLine("You have run out of moves!");
break;
}
}
}
```

## No score is given (tell user how many moves they took to win).

-Give % accuracy?(user moves/least possible moves) -Could also add a high score list written to a file (Which would mean adding -another option in the menu).

Delphi/Pascal Solution

VB.NET Solution

```Module Module1
Const TrainingGame As String = "Training.txt"
Dim Moves As Integer = 0
...
Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip)
Dim Row As Integer
Dim Column As Integer
GetRowColumn(Row, Column)
If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")
ElseIf Board(Row, Column) = "-" Then
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Board(Row, Column) = "m"
Moves += 1
Else
Console.WriteLine("Hit at (" & Column & "," & Row & ").")
Board(Row, Column) = "h"
Moves += 1
End If
End Sub
...
Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip)
Dim GameWon As Boolean = False
Dim Acc As Single
Do
PrintBoard(Board)
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board)
If GameWon = True Then
Console.WriteLine("All ships sunk!")
Console.WriteLine()
Console.WriteLine("You had a " & hitProb(Board) & "% accuracy!")
Console.WriteLine("You also took " & Moves & " Moves!")
End If
Loop Until GameWon
End Sub

...

Function hitProb(ByVal Board(,) As Char)
Dim misses, hits, ratio As Integer
For row As Integer = 0 To 9
For column As Integer = 0 To 9
If Board(row, column) = "m" Then
misses += 1
ElseIf Board(row, column) = "h" Then
hits += 1
End If
Next
Next
ratio = (hits / (hits + misses))  * 100
Return ratio
End Function
```

Python Solution

```Here we create a calculation 'CalcScore()' function to calculate the accuracy percentage. We then integrate it into the 'PlayGame()' function with global variables (unfortunately the easiest way) to allow the code to run at the correct time with minimal function editing.

def CalcScore():
global FinalScore
print("You Completed The Game In " + str(FinalScore) + " Moves!")
Accuracy = (17/FinalScore)*100
print("Your Accuracy Was " + str(Accuracy) + "%")

def PlayGame(Board, Ships):
global FinalScore
GameWon = False
while not GameWon:
PrintBoard(Board)
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board)
FinalScore += 1
if GameWon:
print("All ships sunk!")
FinalScore += 1
CalcScore()

But Don't forget

FinalScore = 0

At the start!
```

Java Solution

```//Author: Dan H
void playGame(char[][] board, Ship[] ships) {
boolean gameWon = false;
int moves=0;
while (!gameWon) {
printBoard(board);
makePlayerMove(board, ships);
moves++;
gameWon = checkWin(board, ships);
if (gameWon) {
console.println("All ships sunk in "+moves+" moves!");
console.println();
}
}
}
```

C# Solution

```private static void PlayGame(ref char[,] Board, ref ShipType[] Ships)
{
bool GameWon = false;
bool GameLost = false;
int MaxMoves = 7;
int Moves = 0;
int MovesLeft=MaxMoves;
while (GameWon == false && GameLost==false)
{
PrintBoard(Board);
Console.WriteLine("You have taken " + Moves + " moves so far");
Console.WriteLine("You have " + MovesLeft + " moves left");
MakePlayerMove(ref Board, ref Ships);
Moves += 1;
MovesLeft = MaxMoves - Moves;
GameWon = CheckWin(Board);
if (GameWon == true)
{
Console.WriteLine("All ships sunk!");
Console.WriteLine();
}
if (MovesLeft==0)
{
PrintBoard(Board);
Console.WriteLine("You ran out of moves!");

GameLost = true;
}
if (GameLost==true || GameWon==true)
{
int hits=0;
int misses=0;
for (int row=0;row<10;row++)
{
for (int column = 0; column < 10; column++)
if (Board[row, column] == 'h')
hits += 1;
else if (Board[row, column] == 'm')
misses += 1;
}
double Accuracy = (Convert.ToDouble(hits) / Convert.ToDouble(hits + misses)) * 100;
Console.WriteLine("You were "+Math.Round(Accuracy,2).ToString()+"% accurate");
}
}
}
```

## Crashes if no input on column or row: (possibly use a try catch statement).

Delphi/Pascal Solution

VB.NET Solution

```'Subroutine to get coordinates from user

Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)

'Boolean variables to check whether the input is valid
Dim validCol, validRow As Boolean

Console.WriteLine()

Do
Try
Do
If Column < 0 Or Column > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validCol = True
Console.WriteLine()
Loop Until Column < 10 And Column >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validCol = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidCol = True
Loop Until validCol = True

Do
Try
Do
If Row < 0 Or Row > 9 Then
Console.WriteLine()
Console.WriteLine("Invalid Input")
End If
'Sets value to true if the input is valid
validRow = True
Console.WriteLine()
Loop Until Row < 10 And Row >= 0
Catch Ex As Exception
'If the Exception code is run then the value is
'set to false and the code loops
validRow = False
Console.WriteLine()
Console.WriteLine("Enter number from 0 to 9")
Console.WriteLine()
End Try
'Code will loop until the ValidRow = True
Loop Until validRow = True
```

Python Solution

One to use the 'Try and Except' function in Python is shown below, this would help to cover a simple ValueError (string typed in place of an integer input); it also works for the input of a NULL value.

```def GetRowColumn():
print()
while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Column = int(input("Please enter column: "))    # try and collect input value for Column
break                      # break free if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")

while True:   # while user makes incorrect inputs (wrong type, range) it loops to try again.
try:
Row = int(input("Please enter row: "))          # try and collect input value for Column
break                      # break free from While Loop if input is valid.
except ValueError:           # If the user gives the wrong data type, it will give an error and loop round to try again.
print("Incorrect input given, needs to be 0-9.")
print()
return Row, Column
```

Java Solution

```//Author: Dan H
int[] getRowColumn(){
//Method devised from AQAConsole2016
int column=Integer.MIN_VALUE;
int row=Integer.MIN_VALUE;
int[] move;
move = new int[2];
console.println();
while(row==Integer.MIN_VALUE || column == Integer.MIN_VALUE){
}
console.println();
move[0] = row;
move[1] = column;
return move;
}
```

C# Solution

```//This code checks the User input in comparison to the preset correct inputs 0 - 9
//~ Kaine Atherton
private static void GetRowColumn(ref int Row, ref int Column)
{
string ColumnChoice = "";
string RowChoice = "a"; //Makes sure the Row while loop doesnt conflict with the Column
//while loop
while (ColumnChoice == "")
{
Console.WriteLine();
string[] BoardArray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
if (BoardArray.Contains(ColumnChoice))
{
Column = Convert.ToInt8(ColumnChoice);
RowChoice = ""; //Starts the Row While Loop only when the column while succeeds
}
else
{
Console.WriteLine("That is Not a valid input.");
ColumnChoice = ""; //Resets the Column While Loop
}
while (RowChoice == "")
{
Console.WriteLine();
if (BoardArray.Contains(RowChoice))
{
Row = Convert.ToInt8(RowChoice);
}
else
{
Console.WriteLine("That is Not a valid input.");
RowChoice = "";//Resets the Row While Loop
}
}
Console.WriteLine();
}
}
```

## Add multiple ships of the same type in one game.

Delphi/Pascal Solution

```Sub Main()
Dim Board(9, 9), answer As Char
Dim Ships(5) As TShip                       'Change to array size to 5

Do

Console.WriteLine("Would you like to add any ships? (Y/N)")         'Add this and place SetUpBoard and ships to else
SetUpBoard(Board)
SetUpShips(Ships, True)
Else
SetUpBoard(Board)
SetUpShips(Ships, False)
End If

PlaceRandomShips(Board, Ships)
PlayGame(Board, Ships)
PlayGame(Board, Ships)
End If
End Sub

Ships(0).Name = "Aircraft Carrier"
Ships(0).Size = 5
Ships(1).Name = "Battleship"
Ships(1).Size = 4
Ships(2).Name = "Submarine"
Ships(2).Size = 3
Ships(3).Name = "Destroyer"
Ships(3).Size = 3
Ships(4).Name = "Patrol Boat"
Ships(4).Size = 2
Dim type As Integer
Console.WriteLine("What type of ship would you like to add? (Please select only 1)") 'Only one for now because of space issues
For count = 0 To 4
Console.WriteLine(count + 1 & ". " & Ships(count).Name)
Next
Ships(5).Name = Ships(type).Name
Ships(5).Size = type
End If
End Sub
```

Python Solution

```###Solution by Robert Nixon - Wheatley Park School
'''
To make this task easier, remove the hardcoded lists which are used in the PrintBoard procedure and the CheckWin function.
Below is the code I changed to achieve this:
'''
if __name__ == "__main__":
TRAININGGAME = "Training.txt"
Board = SetUpBoard()
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2], ["Patrol Boat", 2]]
shipTypes = ["A","B","S","D","P","P"] #Here is the new list
PlaceRandomShips(Board, Ships)
PlayGame(Board,Ships,shipTypes)
PlayGame(Board, Ships, shipTypes)
'''
It's passed through the PlayGame procedure.
'''
def PlayGame(Board, Ships, shipTypes):
GameWon = False
while not GameWon:
PrintBoard(Board, shipTypes)
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board, shipTypes)
if GameWon:
print "All ships sunk!"
print
'''
And used by these functions/procedures.
'''
def CheckWin(Board, shipTypes):
for Row in range(10):
for Column in range(10):
if Board[Row][Column] in shipTypes :
return False
return True

def PrintBoard(Board, shipTypes):
print
print "The board looks like this: "
print
print "",
for Column in range(10):
print " " + str(Column) + " ",
print
for Row in range(10):
print str(Row),
for Column in range(10):
if Board[Row][Column] == "-":
print " ",
elif Board[Row][Column] in shipTypes:
print Board[Row][Column],
else:
print Board[Row][Column],
if Column != 9:
print "|",
print

'''
Removing the hardcoded list means that if you want to add more ships you just have to change the list in one place.
All you now need to do to add multiple ships of the same type is to copy+paste values from both lists so that you have two:
'''
if __name__ == "__main__":
TRAININGGAME = "Training.txt"
Board = SetUpBoard()
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2], ["Patrol Boat", 2]] #Here I have added another patrol boat
shipTypes = ["A","B","S","D","P","P"] #Here is the new list (with an added "P" for the extra patrol boat)
PlaceRandomShips(Board, Ships)
PlayGame(Board,Ships,shipTypes)
PlayGame(Board, Ships, shipTypes)
```

When I modify the code to show the position of the ships when the game is played, I get this result:

I now have two patrol boats on the board.

Java Solution

C# Solution

## Validate Position of Shot

Delphi/Pascal Solution

VB.NET Solution

```'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form
Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)
Dim validCollumn, validRow As Boolean ' These are currently set for the user to define them
Do

Dim Columnvalue As String = Console.ReadLine()
If Integer.TryParse(Columnvalue, Column) Then 'If Columnvalue is an integer, true is returned

If Column < 0 Or Column > 9 Then
Console.WriteLine("Please enter a number that is between 0 and 9")
Else
validColumn = True 'Sets value to true if the input is valid
Console.WriteLine()
End If
Else
End If

Loop Until validColumn = True   'Code will loop until the ValidCol = True
' Below is the exact same code, but for the row.
Do

Dim Rowvalue As String = Console.ReadLine()
If Integer.TryParse(Rowvalue, Row) Then 'If Rowvalue is an integer, true is returned
If Row < 0 Or Row > 9 Then
Console.WriteLine(" That is an invalid Input")

Else
Console.WriteLine()
validRow = True  'Sets value to true if the input is valid
End If
Else
Console.WriteLine("This is not a number")
End If

'Code will loop until the ValidRow = True
Loop Until validRow = True
End Sub
```

Python Solution

```def PlayGame(Board, Ships):
GameWon = False
MAXMOVES = 30
# This can be changed to make it easier or harder.
movesleft = MAXMOVES
while not GameWon:
PrintBoard(Board)

print("You have {} moves left".format(movesleft))
MakePlayerMove(Board, Ships)
movesleft = movesleft - 1
if movesleft == 0:
print("You ran out of shots, game over")
return

GameWon = CheckWin(Board)
if GameWon:
print("All ships sunk!")
print()
```

Java Solution

```//Author: Harnaam J

int[] getRowColumn() {
int column;
int row;
int[] move;
move = new int[2];
boolean valid = false;

while (!valid) {

console.println();
console.println();

if (column < 0 || column > 9 || row < 0 || row > 9) {
console.println("You're off the board!");
} else {
move[0] = row;
move[1] = column;
valid = true;
}
}
return move;
}
```

C# Solution

## Add a multiplayer option (another person or the computer).

Delphi/Pascal Solution

VB.NET Solution

```'This is for PvP.

'New Subroutine
Sub PlayMultiGame(ByVal Board(,) As Char, ByVal Board_Two(,) As Char, ByVal Ships() As TShip)
Dim GameWon As Boolean = False
Dim TurnSwitch As Boolean = True
Do
If TurnSwitch Then
Console.WriteLine("Turn: Player One")
PrintBoard(Board)
MakePlayerMove(Board, Ships)
GameWon = CheckWin(Board)
If GameWon Then
Console.WriteLine("All ships sunk!")
Console.WriteLine("Player One wins!")
Console.WriteLine()
End If
Else
Console.WriteLine("Turn: Player Two")
PrintBoard(Board_Two)
MakePlayerMove(Board_Two, Ships)
GameWon = CheckWin(Board_Two)
If GameWon Then
Console.WriteLine("All ships sunk!")
Console.WriteLine("Player Two wins!")
Console.WriteLine()
End If
End If
TurnSwitch = Not TurnSwitch
Loop Until GameWon
End Sub
Console.WriteLine("3. Start new multiplayer game")
SetUpBoard(Board_Two)
PlaceRandomShips(Board, Ships)
PlaceRandomShips(Board_Two, Ships)
PlayMultiGame(Board, Board_Two, Ships)
End If
```

Python Solution

This code overhaul allows two players to compete. Player 1 is represented on the game board by pieces labelled 'A'. Player 2 is represented on the game board by pieces labelled 'B'. This retains the neat structure of the game board.

```#Skeleton Program for the AQA COMP1 Summer 2016 examination
#this code should be used in conjunction with the preliminary material
#written by the AQA COMP1 Programmer Team
#developed in a Python 3.4 programming environment

def SetUpGameBoard(Board, Boardsize):
for Row in range(1, BoardSize + 1):
for Column in range(1, BoardSize + 1):
if (Row == (BoardSize + 1) // 2 and Column == (BoardSize + 1) // 2 + 1) or (Column == (BoardSize + 1) // 2 and Row == (BoardSize + 1) // 2 + 1):
Board[Row][Column] = "A"
elif (Row == (BoardSize + 1) // 2 + 1 and Column == (BoardSize + 1) // 2 + 1) or (Column == (BoardSize + 1) // 2 and Row == (BoardSize + 1) // 2):
Board[Row][Column] = "B"
else:
Board[Row][Column] = " "

def ChangeBoardSize():
BoardSize = int(input("Enter a board size (between 4 and 9): "))
while not(BoardSize >= 4 and BoardSize <= 9):
BoardSize = int(input("Enter a board size (between 4 and 9): "))
return BoardSize

def GetHuman1PlayerMove(Player1Name):
print(Player1Name, "enter the coordinates of the square where you want to place your piece: ", end="")
Coordinates = int(input())
return Coordinates

def GetHuman2PlayerMove(Player2Name):
print(Player2Name, "enter the coordinates of the square where you want to place your piece: ", end="")
Coordinates = int(input())
return Coordinates

def GameOver(Board, BoardSize):
for Row in range(1 , BoardSize + 1):
for Column in range(1, BoardSize + 1):
if Board[Row][Column] == " ":
return False
return True

def GetPlayer1Name():
Player1Name = input("What is your name? ")
return Player1Name

def GetPlayer2Name():
Player2Name = input("What is your name? ")
return Player2Name

def CheckIfMoveIsValid(Board, Move):
Row = Move % 10
Column = Move // 10
MoveIsValid = False
if Board[Row][Column] == " ":
MoveIsValid = True
return MoveIsValid

def GetPlayerScore(Board, BoardSize, Piece):
Score = 0
for Row in range(1, BoardSize + 1):
for Column in range(1, BoardSize + 1):
if Board[Row][Column] == Piece:
Score = Score + 1
return Score

def CheckIfThereArePiecesToFlip(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection):
RowCount = StartRow + RowDirection
ColumnCount = StartColumn + ColumnDirection
FlipStillPossible = True
FlipFound = False
OpponentPieceFound = False
while RowCount <= BoardSize and RowCount >= 1 and ColumnCount >= 1 and ColumnCount <= BoardSize and FlipStillPossible and not FlipFound:
if Board[RowCount][ColumnCount] == " ":
FlipStillPossible = False
elif Board[RowCount][ColumnCount] != Board[StartRow][StartColumn]:
OpponentPieceFound = True
elif Board[RowCount][ColumnCount] == Board[StartRow][StartColumn] and not OpponentPieceFound:
FlipStillPossible = False
else:
FlipFound = True
RowCount = RowCount + RowDirection
ColumnCount = ColumnCount + ColumnDirection
return FlipFound

def FlipOpponentPiecesInOneDirection(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection):
FlipFound = CheckIfThereArePiecesToFlip(Board, BoardSize, StartRow, StartColumn, RowDirection, ColumnDirection)
if FlipFound:
RowCount = StartRow + RowDirection
ColumnCount = StartColumn + ColumnDirection
while Board[RowCount][ColumnCount] != " " and Board[RowCount][ColumnCount] != Board[StartRow][StartColumn]:
if Board[RowCount][ColumnCount] == "A":
Board[RowCount][ColumnCount] = "B"
else:
Board[RowCount][ColumnCount] = "A"
RowCount = RowCount + RowDirection
ColumnCount = ColumnCount + ColumnDirection

def MakeMove(Board, BoardSize, Move, HumanPlayersTurn):
Row = Move % 10
Column = Move // 10
if HumanPlayersTurn:
Board[Row][Column] = "A"
else:
Board[Row][Column] = "B"
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 1, 0)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, -1, 0)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 0, 1)
FlipOpponentPiecesInOneDirection(Board, BoardSize, Row, Column, 0, -1)

def PrintLine(BoardSize):
print("   ", end="")
for Count in range(1, BoardSize * 2):
print("_", end="")
print()

def DisplayGameBoard(Board, BoardSize):
print()
print("  ", end="")
for Column in range(1, BoardSize + 1):
print(" ", end="")
print(Column, end="")
print()
PrintLine(BoardSize)
for Row in range(1, BoardSize + 1):
print(Row, end="")
print(" ", end="")
for Column in range(1, BoardSize + 1):
print("|", end="")
print(Board[Row][Column], end="")
print("|")
PrintLine(BoardSize)
print()

print("(p)lay game")
print("(e)nter player 1 name")
print("(o)pponent's name")
print("(c)hange board size")
print("(q)uit")
print()

print(Player1Name, "enter the letter of your chosen option: ", end="")
Choice = input()
return Choice

def CreateBoard():
Board = []
for Count in range(BoardSize + 1):
Board.append([])
for Count2 in range(BoardSize + 1):
Board[Count].append("")
return Board

def PlayGame(Player1Name, Player2Name, BoardSize):
Board = CreateBoard()
SetUpGameBoard(Board, BoardSize)
Human1PlayersTurn = False
while not GameOver(Board, BoardSize):
Human1PlayersTurn = not Human1PlayersTurn
DisplayGameBoard(Board, BoardSize)
MoveIsValid = False
while not MoveIsValid:
if Human1PlayersTurn:
Move = GetHuman1PlayerMove(Player1Name)
else:
Move = GetHuman2PlayerMove(Player2Name)
MoveIsValid = CheckIfMoveIsValid(Board, Move)
MakeMove(Board, BoardSize, Move, Human1PlayersTurn)
DisplayGameBoard(Board, BoardSize)
Human1PlayerScore = GetPlayerScore(Board, BoardSize, "A")
Human2PlayerScore = GetPlayerScore(Board, BoardSize, "B")
if Human1PlayerScore > Human2PlayerScore:
print("Well done", Player1Name, ", you have won the game!")
elif Human1PlayerScore == Human2PlayerScore:
print("That was a draw!")
else:
print("Well done", Player2Name, ", you have won the game!")
print()

BoardSize = 6
Player1Name = ""
Player2Name = ""
Choice = ""
while Choice != "q":
if Choice == "p":
PlayGame(Player1Name, Player2Name, BoardSize)
elif Choice == "e":
Player1Name = GetPlayer1Name()
elif Choice =="o":
Player2Name = GetPlayer2Name()
elif Choice == "c":
BoardSize = ChangeBoardSize()

# Niels Victor @ Portland Place School
```

An alternative method to multiplayer. Although Neil's code suffices, this code might be more efficient.

```def PlayerPlaceShips(Board, Ships):
for Ship in Ships:
while True:
PrintBoard(Board, 1)
print("Where would you like to place", Ship[0])
while True:
try:
Column = int(input("Please select column: "))
if Column > 9:
raise ValueError
break
except ValueError:
print("That is not a valid column")

while True:
try:
Row = int(input("Please select row: "))
if Row > 9:
raise ValueError
break
except ValueError:
print("That is not a valid row")

while True:
Orientation = input("what orientation would you like the boat to be?")
if Orientation == "h" or Orientation == "v":
break
else:
print("That is not a valid orientation")

if ValidateBoatPosition(Board, Ship, Row, Column, Orientation) == True:
break
else:print("That is not a valid position")

PlaceShip(Board, Ship, Row, Column, Orientation)
return Board

def MultiplayerGame(Ships):
player1_Board = SetUpBoard()
player2_Board = SetUpBoard()

print("First player1 will place their ships")
player1_Board = PlayerPlaceShips(player1_Board, Ships)
PrintBoard(player1_Board, 1)

print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")

print("Now player2 will place their ships")
player2_Board = PlayerPlaceShips(player2_Board, Ships)
PrintBoard(player2_Board, 1)

print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")

x = player1_Board
player1_Board = player2_Board
player2_Board = x

print("Now the game will begin\n")
GameWon = 0

while True:
print("Player1s Turn")
PrintBoard(player1_Board, 0)
MakePlayerMove(player1_Board, Ships)
if CheckWin(player1_Board):
print("Player 1 wins")
break

print("Player2s Turn")
PrintBoard(player2_Board, 0)
MakePlayerMove(player2_Board, Ships)
if CheckWin(player2_Board):
print("Player 2 wins")
break

#My name is Oliver Cooke, and you've just been educated.
```

Java Solution

C# Solution

## Add a message for destroying warships (can be coded in a similar way to CheckWin (Board)).

This adds a message to the user as soon as a Ship has been destroyed.
It may quite easily crop up in the exam, as a simple way to get it to work is to copy and modify the existing CheckWin (Board) subroutine.
This works by scanning the entire board to check for the existence of ships. You can then check which exist.

Delphi/Pascal Solution

```Procedure MakePlayerMove(Var Board: TBoard; Var Ships: TShips);
Var
Row: Integer;
Column: Integer;
Begin
GetRowColumn(Row, Column);
If (Board[Row][Column] = 'm') Or (Board[Row][Column] = 'h') Then
Writeln('Sorry, you have already shot at the square (', Column, ',', Row,'). Please try again.')
Else If Board[Row][Column] = '-' Then
Begin
Writeln('Sorry, (', Column, ',', Row, ') is a miss.');
Board[Row][Column] := 'm';
End
Else
Begin
Writeln('Hit at (', Column, ',', Row, ').');
if (Board[Row][Column] = 'A') then
writeln('You hit an Aircraft Carrier');
if (Board[Row][Column] = 'B') then
writeln('You hit a Battleship');
if (Board[Row][Column] = 'S') then
writeln('You hit a Submarine');
if (Board[Row][Column] = 'D') then
writeln('You hit a Destroyer');
if (Board[Row][Column] = 'P') then
writeln('You hit a Patrol Boat');
if (Board[Row][Column] = 'E') then
writeln('You hit the USS Enterprise'); //Remove this if you have five ships.
Board[Row][Column] := 'h';
End;
End;
```

VB.NET Solution

```'Solution 1
Sub DisplayWin(ByVal Board(,) As Char)
'Display a message if the player destroys a warship.
Dim NoA As Integer = 0
Dim NoB As Integer = 0
Dim NoF As Integer = 0
Dim NoP As Integer = 0
Dim NoD As Integer = 0
Dim NoS As Integer = 0
Dim Row As Integer
Dim Column As Integer
For Row = 0 To 9
For Column = 0 To 9
If Board(Row, Column) = "P" Then
NoP += -1
End If
If Board(Row, Column) = "A" Then
NoA += -1
End If
If Board(Row, Column) = "B" Then
NoB += -1
End If
If Board(Row, Column) = "D" Then
NoD += -1
End If
If Board(Row, Column) = "S" Then
NoS += -1
End If
If Board(Row, Column) = "F" Then
NoF += -1
End If
Next
Next
If NoA = 0 Then Console.WriteLine("You sunk an Aircraft Carrier!")
If NoP = 0 Then Console.WriteLine("You sunk a Patrol Boat!")
If NoB = 0 Then Console.WriteLine("You sunk a Battleship!")
If NoD = 0 Then Console.WriteLine("You sunk a Destroyer!")
If NoS = 0 Then Console.WriteLine("You sunk a Submarine!")
If NoF = 0 Then Console.WriteLine("You sunk a Frigate!")
End Sub

Sub MakePlayerMove...
...
...
Console.WriteLine("Hit at (" & Column & "," & Row & ").")
Board(Row, Column) = "h"
Call DisplayWin(Board)

'Solution 2
'Global Variable:
Dim Hits As Integer()
Hits = {0, 0, 0, 0, 0}
'New Subroutine:
Sub CheckTypeHit(ByVal Piece As Char, ByRef Ships() As TShip)
For Each Type In Ships
If Type.Name(0) = Piece Then
Hits(Array.IndexOf(Ships, Type)) += 1
If Hits(Array.IndexOf(Ships, Type)) = Type.Size Then
Console.WriteLine("You've destroyed the " & Type.Name & "!")
Else
Console.WriteLine("You've hit the " & Type.Name & ".")
End If
Exit For
End If
Next
End Sub

'Solution 3
'In Sub makeplayermove
If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")
ElseIf Board(Row, Column) = "-" Then
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Board(Row, Column) = "m"

ElseIf Board(Row, Column) = "A" Then
Console.WriteLine("You hit an aircraft carrier at " & Column & "," & Row)
Board(Row, Column) = "a"
Ships(0).Size = Ships(0).Size - 1
If Ships(0).Size = 0 Then
Console.WriteLine("You sunk an Aircraft Carrier.")
End If
'You can find out the ship number in the SetUpShips subroutine
'You can change the code to suit other ships like destroyers by changing the ship variable and the console.writeline text.
```

Python Solution

This subroutine works similarly to the existing CheckWin(Board). It is called in the same position, too.
Probably not the best example that could be coded in, but it works, and in a way that has already been demonstrated in the skeleton code.

```def CheckShipsSunk(Board):
Aircraft Carrier = 0        # sets up integer variables for each ship type.
Battleship = 0
Submarine = 0
Destroyer = 0
PatrolBoat = 0

for Row in range(10):         # for each Row, repeat the following...
for Column in range(10):    # for each Column in that Row, do the following checks.
if Board[Row][Column] == "A":   # if space holds an "A" then add 1 to Aircraft Carrier total.
Aircraft Carrier += 1
elif Board[Row][Column] == "B": # if space holds an "B" then add 1 to Battleship total.
Battleship += 1
elif Board[Row][Column] == "S": # if space holds an "S" then add 1 to Submarine total.
Submarine += 1
elif Board[Row][Column] == "D": # if space holds an "D" then add 1 to Destroyer total.
Destroyer += 1
elif Board[Row][Column] == "P": # if space holds an "P" then add 1 to Patrol Boat total.
Patrol Boat += 1

print() # blank line space on output

if Aircraft Carrier == 0:                               # IF there are no "A" spaces on Board, then Aircraft Carrier must be sunk.
print("Aircraft Carrier sunk!")
else:
print("Aircraft Carrier hits needed", Aircraft Carrier)    # ELSE print how many hits needed. This bit isn't necessary really but could be added if you wanted to.
if Battleship == 0:
print("Battleship sunk!")
if Submarine == 0:
print("Submarine sunk!")
if Destroyer == 0:
print("Destroyer sunk!")
if PatrolBoat == 0:
print("Patrol Boat sunk!")
```

The PlayGame(Board, Ships) subroutine has had a simple line added to call the CheckShipsSunk(Board) subroutine when the game is running.

```def PlayGame(Board, Ships):
GameWon = False
while not GameWon:
PrintBoard(Board)
MakePlayerMove(Board, Ships)
CheckShipsSunk(Board)                  # This line needs adding to call the CheckShipsSunk(Board) subroutine when the game is running.
GameWon = CheckWin(Board)
if GameWon:
print("All ships sunk!")
print()
```

This solution is simple and uses the lengths of the ships stored in the ships' 2D array.

``` def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.")
elif Board[Row][Column] == "-":
print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.")
Board[Row][Column] = "m"
else:
print("Hit at (" + str(Column) + "," + str(Row) + ").")
for Ship in Ships:
if Ship[0][0] == Board[Row][Column]:     # Checks which ship has been hit
Ship[1] -= 1                           # Subtracts 1 from its length in the array
if Ship[1] < 1:                        # Checks if the ship has been hit as many times as its length
print('Ship sunk!')
Board[Row][Column] = "h"

```

Java Solution

```//Author: Dan H
class Ship {
String name;
int size;
int hits=0;
}
void makePlayerMove(char[][] board, Ship[] ships) {
int[] rowColumn = getRowColumn();
int row = (rowColumn[0]);
int column = (rowColumn[1]);
if (board[row][column] == 'm' || board[row][column] == 'h') {
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
} else if (board[row][column] == '-') {
console.println("Sorry, (" + column + "," + row + ") is a miss.");
board[row][column] = 'm';
} else {
switch (board[row][column]) {
case 'A':
console.println("You hit an Aircraft Carrier");
ships[0].hits++;
break;
case 'B':
console.println("You hit a Battleship");
ships[1].hits++;
break;
case 'S':
console.println("You hit a Submarine");
ships[2].hits++;
break;
case 'D':
console.println("You hit a Destroyer");
ships[3].hits++;
break;
case 'P':
console.println("You hit a Patrol Boat");
ships[4].hits++;
break;
case 'U':
console.println("You hit the USS Enterprise");
ships[5].hits++;
break;
}
console.println("Hit at (" + column + "," + row + ").");
board[row][column] = 'h';
}
for(int i=0; i<ships.length; i++){
if(ships[i].hits == ships[i].size){
console.println("You have sunk my "+ships[i].name);
}
}
}
```

C# Solution

```'''May 2017'''

public struct ShipType
{
public string Name;
public int Size;
public bool Sunk;
}

private static string CheckSunk(ref char[,] Board, ref ShipType[] Ships)
{
for (int ship = 0; ship < Ships.Length; ship++)
{
if (!Ships[ship].Sunk)
{
Ships[ship].Sunk = true;
for (int Column = 0; Column < 10; Column++)
{
for (int Row = 0; Row < 10; Row++)
{
if (Board[Row, Column] == Ships[ship].Name[0])
{
Ships[ship].Sunk = false;
}
}
}
if (Ships[ship].Sunk)
{
return Ships[ship].Name;
}
}
}
return string.Empty;
}

private static void PlayGame(ref char[,] Board, ref ShipType[] Ships)
{
// Other code
string shipSunk = CheckSunk(ref Board, ref Ships);
if (shipSunk != string.Empty)
{
Console.WriteLine("{0} sunk!", shipSunk);
}
//Other code
}

private static void SetUpShips(ref ShipType[] Ships)
{
Ships[0].Name = "Aircraft Carrier";
Ships[0].Size = 5;
Ships[0].Sunk = false;

Ships[1].Name = "Battleship";
Ships[1].Size = 4;
Ships[1].Sunk = false;

Ships[2].Name = "Submarine";
Ships[2].Size = 3;
Ships[2].Sunk = false;

Ships[3].Name = "Destroyer";
Ships[3].Size = 3;
Ships[2].Sunk = false;

Ships[4].Name = "Patrol Boat";
Ships[4].Size = 2;
Ships[2].Sunk = false;
}

/********************************************************************************/

Aquinas College
This contains the code needed to get the program to tell you when you've sunk a ship

public struct ShipType
{
public string Name;
public int Size;
public int HitCount;
}
private static void MakePlayerMove(ref char[,] Board, ref ShipType[] Ships)
{
int Row = 0; // Data type called 'Row' is declared as an integer, with a value of 0
int Column = 0; // Data type called 'Column' is declared as an integer, with a value of 0
GetRowColumn(ref Row, ref Column); //Execute method 'GetRowColumn' to ask for the user what square they want to shoot at
if (Board[Row, Column] == 'm' || Board[Row, Column] == 'h') //If characters 'm' or 'h' are detected in the multi dimensional array ([6,9] for example) then...
{
Console.WriteLine("Sorry, you have already shot at the square (" + Column + "," + Row + "). Please try again."); //Output a message telling them that they have already shot that square
}
else if (Board[Row, Column] == '-') //If character '-' is detected in the multi dimensional array ([5,5] for example) then...
{
Console.WriteLine("Sorry, (" + Column + "," + Row + ") is a miss."); //Output a message for the user which tells them that they haven't hit anything (missed)
Board[Row, Column] = 'm'; //Replace the character '-' (that the user has just 'shot') with the character 'm' to indicate that it's a miss, so that later the computer/program can tell them that they have already shot that square
}
else //Otherwise...
{
Console.WriteLine("Hit at (" + Column + "," + Row + ")."); //Output a message telling the user that they have hit a ship, indicating where its position is
if (Board[Row, Column] == 'A') //If character 'A' is detected in the multi dimensional array ([4,3] for example) then...
{
Console.WriteLine("You hit an Aircraft Carrier");

Ships[0].HitCount = Ships[0].HitCount + 1;

if (Ships[0].HitCount == Ships[0].Size)
{
Console.WriteLine("You sank an Aircraft Carrier");
}
}

else if (Board[Row, Column] == 'B')  //If character 'B' is detected in the multi dimensional array ([0,0] for example) then...
{
Console.WriteLine("You hit a Battleship");
Ships[1].HitCount = Ships[1].HitCount + 1;

if (Ships[1].HitCount == Ships[1].Size)
{
Console.WriteLine("You sank a Battleship");
}
}

else if (Board[Row, Column] == 'S') //If character 'S' is detected in the multi dimensional array ([1,1] for example) then...
{
Console.WriteLine("You hit a Submarine"); //Tell the user that they have hit a submarine
Ships[2].HitCount = Ships[2].HitCount + 1;

if (Ships[2].HitCount == Ships[2].Size)
{
Console.WriteLine("You sank a Submarine");
}
}
else if (Board[Row, Column] == 'D') //If character 'D' is detected in the multi dimensional array ([9,7] for example) then...
{
Console.WriteLine("You hit a Destroyer"); //Tell the user that they have hit a destroyer
Ships[3].HitCount = Ships[3].HitCount + 1;

if (Ships[3].HitCount == Ships[3].Size)
{
Console.WriteLine("You sank a Destroyer");
}
}
else if (Board[Row, Column] == 'P') //If character 'P' is detected in the multi dimensional array ([0,9] for example) then...
{
Console.WriteLine("You hit a Patrol Boat"); //Tell the user that they have hit a patrol boat
Ships[4].HitCount = Ships[4].HitCount + 1;

if (Ships[4].HitCount == Ships[4].Size)
{
Console.WriteLine("You sank a Patrol Boat");
}
}
Board[Row, Column] = 'h'; //Replace the character '-' (that the user has just 'shot') with the character 'h' to indicate that it's a hit, so that later the computer/program can tell them that they have already shot that square
}
}
private static void SetUpShips(ref ShipType[] Ships)
{
Ships[0].Name = "Aircraft Carrier";
Ships[0].Size = 5;
Ships[0].HitCount = 0;
Ships[1].Name = "Battleship";
Ships[1].Size = 4;
Ships[1].HitCount = 0;
Ships[2].Name = "Submarine";
Ships[2].Size = 3;
Ships[2].HitCount = 0;
Ships[3].Name = "Destroyer";
Ships[3].Size = 3;
Ships[3].HitCount = 0;
Ships[4].Name = "Patrol Boat";
Ships[4].Size = 2;
Ships[4].HitCount = 0;
Ships[5].Name = "Rubber Dinghy"; // added a new ship (change name for exam)
Ships[5].Size = 1;
Ships[5].HitCount = 0;
}
```

## Bonus special missile when you sink a ship (such as one with a larger range). (unnecessary)

Delphi/Pascal Solution

VB.NET Solution

Python Solution

```def PlayerMisssile(Board, Ships):
Row, Column = GetRowColumn()
MissileHit_Range = []
MissileHit_Range.append([Column,Row])
MissileHit_Range.append([Column,Row-1])
MissileHit_Range.append([Column+1,Row-1])
MissileHit_Range.append([Column+1,Row])
MissileHit_Range.append([Column+1,Row+1])
MissileHit_Range.append([Column,Row+1])
MissileHit_Range.append([Column-1, Row+1])
MissileHit_Range.append([Column-1,Row])
MissileHit_Range.append([Column-1,Row-1])
print(MissileHit_Range)
for each in MissileHit_Range:
print(Board[each[1]][each[0]])
if Board[each[1]][each[0]] == "m" or Board[each[1]][each[0]] == "h":
print("")
elif Board[each[1]][each[0]] == "-":
Board[each[1]][each[0]] = "m"
else:
Board[each[1]][each[0]] = "h"
```

Java Solution

```// Author: Emmanuel M
// P.S Called it a rocket instead of a missile :)

private int hits = 0;
private int miss = 0;

// Edited makePlayerMove to add hits and misses

void makePlayerMove(char[][] board, Ship[] ships){
int[] rowColumn = getRowColumn();
int row = rowColumn[0];
int column = rowColumn[1];

if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
}
else if (board[row][column] == '-'){
console.println("Sorry, (" + column + "," + row + ") is a miss.");
board[row][column] = 'm';
miss ++;
}
else if (board[row][column] == 'A'){
console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")");
board[row][column] = 'a';
hits++;
}
else if (board[row][column] == 'B'){
console.println("You hit a Battleship at (" + column + "," + row + ")");
board[row][column] = 'b';
hits++;
}
else if (board[row][column] == 'S'){
console.println("You hit a Submarine at (" + column + "," + row + ")");
board[row][column] = 's';
hits++;
}
else if (board[row][column] == 'D'){
console.println("You hit a Destroyer at (" + column + "," + row + ")");
board[row][column] = 'd';
hits++;
}
else if (board[row][column] == 'P'){
console.println("You hit a Patrol Boat at (" + column + "," + row + ")");
board[row][column] = 'p';
hits++;
}
}

// made a method called MakePlayerMoveRC for missileMove to avoid interruptions with Game
void makePlayerMoveRC(char[][] board,int row,int column){
int[] rowColumn = getRowColumn();
int row = rowColumn[0];
int column = rowColumn[1];
if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
}
else if(board[row][column] == '-'){
console.println("Sorry, (" + column + "," + row + ") is a miss.");
board[row][column] = 'm';
miss ++;
}
else if(board[row][column] == 'A'){
console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")");
board[row][column] = 'a';
hits++;
}
else if(board[row][column] == 'B'){
console.println("You hit a Battleship at (" + column + "," + row + ")");
board[row][column] = 'b';
hits++;
}
else if(board[row][column] == 'S'){
console.println("You hit a Submarine at (" + column + "," + row + ")");
board[row][column] = 's';
hits++;
}
else if(board[row][column] == 'D'){
console.println("You hit a Destroyer at (" + column + "," + row + ")");
board[row][column] = 'd';
hits++;
}
else if(board[row][column] == 'P'){
console.println("You hit a Patrol Boat at (" + column + "," + row + ")");
board[row][column] = 'p';
hits++;
}
}

void missileMove(char[][] board){
int column = -1;
int row = -1;
console.println();
boolean loop = false;
while(loop != true){

if(column >= 0 && column <=9){
loop = true;
}else{
console.println("Not a valid option...");
}
}
loop = false;
while(loop != true){

if(row >= 0 && row <=9){
loop = true;
}else{
console.println("Not a valid option...");
}
}
console.println();
// Checks to make sure missile is on the Board
if(column == 0 && row == 0){
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
makePlayerMoveRC(board, row, column+1);
makePlayerMoveRC(board, row+1, column+1);
}
else if(column == 0 &&row == 9){
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row-1, column+1);
makePlayerMoveRC(board, row, column+1);
}
else if(column == 9 &&row == 0){
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row+1, column-1);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
}
else if(column == 9 &&row == 9){
makePlayerMoveRC(board, row -1, column-1);
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
}
else if(column == 9&&row != 0||column == 9&&row != 9){
makePlayerMoveRC(board, row -1, column-1);
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row+1, column-1);
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
}
else if(column == 0 && row != 0||column == 0 && row != 9){
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
makePlayerMoveRC(board, row-1, column+1);
makePlayerMoveRC(board, row, column+1);
makePlayerMoveRC(board, row+1, column+1);
}
else if(row == 0 && column != 0||row == 0 && column != 9){
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row+1, column-1);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
makePlayerMoveRC(board, row, column+1);
makePlayerMoveRC(board, row+1, column+1);
}
else if(row == 9 && column != 0||row == 9 && column != 9){
makePlayerMoveRC(board, row -1, column-1);
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row-1, column+1);
makePlayerMoveRC(board, row, column+1);
}
else{
makePlayerMoveRC(board, row -1, column-1);
makePlayerMoveRC(board, row, column-1);
makePlayerMoveRC(board, row+1, column-1);
makePlayerMoveRC(board, row-1, column);
makePlayerMoveRC(board, row, column);
makePlayerMoveRC(board, row+1, column);
makePlayerMoveRC(board, row-1, column+1);
makePlayerMoveRC(board, row, column+1);
makePlayerMoveRC(board, row+1, column+1);
}
}
// Edited playGame
void playGame(char[][] board, Ship[] ships){
boolean gameWon = false;
boolean loop = false;
int SM = 0;
while(!gameWon){
printBoard(board);
while(SM > 1&&loop ==false){
NOM = hits+miss;
String sg = console.readLine("Do you want to use your missile? y/n ");
if(sg.equalsIgnoreCase("yes")||sg.startsWith("y")){
missileMove(board);
printBoard(board);
gameWon = checkWin(board, ships);
if(gameWon){
console.println("All ships sunk!");
console.println();
loop = true;
}
SM =SM -1;
}else{
loop = true;
}
}

makePlayerMove(board, ships);
gameWon = checkWin(board, ships);

if(gameWon){
console.println("All ships sunk!");
console.println();
}

if(hits == 3){
console.println("You gained a missile");
SM = SM +1;
}
if(hits == 5||hits == 8||hits == 13||hits == 15||hits == 20){
console.println("You gained a missile");
SM= SM +1;
}

}
}
```

C# Solution

Delphi/Pascal Solution

VB.NET Solution

Python Solution

```def add_to_scores(word, score):
import pickle
try:
with open("high_scores.pickle", "rb") as f:
except:
high_scores = []

high_scores.append((word, score))
high_scores = sort_high_scores(high_scores)

with open("high_scores.pickle", "wb") as f:
pickle.dump(high_scores, f)

return high_scores

def sort_high_scores(scores):
for i in range(len(scores)):
for k in range(len(scores) - 1, i, - 1):
if int(scores[k][1]) < int(scores[k - 1][1]):
tmp = scores[k]
scores[k] = scores[k - 1]
scores[k-1] = tmp
return scores

def PlayGame(Board, Ships, Hack):
#cycles through each round
GameWon = False
score = 0

while not GameWon:
score += 1
PrintBoard(Board, Hack)
MakePlayerMove(Board, Ships)
#checks the function gamewon and breaks the loop if so
GameWon = CheckWin(Board)
if GameWon:
print("All ships sunk!\n")

print("the highest scoring players are: ")
for num, i in enumerate(high_scores):
if num < 10:
print(num + 1, i[0] ,"-", i[1])
else:
break

by Oliver Cooke
"God is dead, and we've killed him"
```

Java Solution

C# Solution

## Clear the environment after every turn has taken place. (pointless)

Delphi/Pascal Solution

VB.NET Solution

```Console.Clear()
```

Python Solution

```###Solution by Robert Nixon - Wheatley Park School
'''The first example is cross-platform, it uses 'cls' if on a windows system but 'clear' if anything else (OSX or Linux I think):'''
import os

def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
clear = lambda: os.system('cls' if os.name=='nt' else 'clear') #Concise way of doing it using lambda
clear() #Remember to call the function on the next line
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again."
elif Board[Row][Column] == "-":
print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss."
Board[Row][Column] = "m"
else:
print "Hit at (" + str(Column) + "," + str(Row) + ")."
Board[Row][Column] = "h"

'''I doubt they would expect a cross-platform solution for full marks, so you can just deal with it like this:'''
import os

def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
os.system('cls') #Modify the string inside in accordance with your os
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again."
elif Board[Row][Column] == "-":
print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss."
Board[Row][Column] = "m"
else:
print "Hit at (" + str(Column) + "," + str(Row) + ")."
Board[Row][Column] = "h"
```

Java Solution

C# Solution

## Randomize ship positions

VB.NET Solution

```Sub PlaceRandomShips(ByRef Board(,) As Char, ByVal Ships() As TShip)
Dim Valid As Boolean
Dim Row As Integer
Dim Column As Integer
Dim Orientation As Char
Dim HorV As Integer
For Each Ship In Ships
Valid = False
While Not Valid
'Just add the word Randomize() in to fix this
Randomize()
Row = Int(Rnd() * 10)
Column = Int(Rnd() * 10)
HorV = Int(Rnd() * 2)
If HorV = 0 Then
Orientation = "v"
Else
Orientation = "h"
End If
Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation)
End While
Console.WriteLine("Computer placing the " & Ship.Name)
PlaceShip(Board, Ship, Row, Column, Orientation)
Next
End Sub
```

## Allow the player to fire a salvo (i.e. simultaneously enter coordinates for three shots and then make the move)

Delphi/Pascal Solution

VB.NET Solution

Python Solution

```Here, we can integrate simple loops to make the code work. I made a minor edit to the code of the GetRowColumn() and MakePlayerMove() functions to allow the salvo to take place.

def GetRowColumn():
Column=[]
Row=[]
print()
for i in range(3):
Column.append(int(input("Please enter column For Shot "+ str(i+1) +": ")))
Row.append(int(input("Please enter row For Shot "+ str(i+1) +": ")))
print()
return Row, Column

def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
for i in range(3):
if Board[Row[i-1]][Column[i-1]] == "m" or Board[Row[i-1]][Column[i-1]] == "h":
print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.")
elif Board[Row[i-1]][Column[i-1]] == "-":
print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.")
Board[Row[i-1]][Column[i-1]] = "m"
else:
print("Hit at (" + str(Column) + "," + str(Row) + ").")
Board[Row[i-1]][Column[i-1]] = "h"
```

Java Solution

C# Solution

## Don't subtract a move when a coordinate has been re-entered.

Delphi/Pascal Solution

VB.NET Solution

This shows how I subtract 1 from the current score every time the same coordinate is entered:

```'Answer submitted by David Popovici of Colchester Royal Grammar School Sixth Form
Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip)
Dim Row As Integer
Dim Column As Integer
GetRowColumn(Row, Column)
Console.WriteLine("Hit at (" & Column & "," & Row & ").")
If Board(Row, Column) = "m" Or Board(Row, Column) = "a" Or Board(Row, Column) = "b" Or Board(Row, Column) = "s" Or Board(Row, Column) = "d" Or Board(Row, Column) = "p" Then
Console.ForegroundColor = ConsoleColor.DarkMagenta
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")
currentScore -= 1 'you can see this here
Console.ForegroundColor = ConsoleColor.Gray

ElseIf Board(Row, Column) = "-" Then

Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Console.ForegroundColor = ConsoleColor.Gray
Board(Row, Column) = "m"

Else

Console.ForegroundColor = ConsoleColor.Magenta
Select Case Board(Row, Column)
Case "A"
Console.WriteLine("You hit an Aircraft Carrier")
Board(Row, Column) = "a"
Case "B"
Console.WriteLine("You hit a Battleship")
Board(Row, Column) = "b"
Case "P"
Console.WriteLine("You hit a Patrol Boat")
Board(Row, Column) = "p"
Case "D"
Console.WriteLine("You hit a Destroyer")
Board(Row, Column) = "d"
Case "S"
Console.WriteLine("You hit a Submarine")
Board(Row, Column) = "s"
End Select
Console.ForegroundColor = ConsoleColor.Gray
End If
```

Python Solution

How to add a set number of turns and how to not miss a turn when the same coordinate is re-entered:

```###Solution by Robert Nixon - Wheatley Park School

def MakePlayerMove(Board, Ships, maxMoves):
Row, Column = GetRowColumn()
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again." #Don't add anything here (the point of the task)
elif Board[Row][Column] == "-":
print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss."
Board[Row][Column] = "m"
maxMoves = maxMoves - 1 #Change moves at a miss
print "You have "+str(maxMoves)+" moves left."
else:
print "Hit at (" + str(Column) + "," + str(Row) + ")."
Board[Row][Column] = "h"
maxMoves = maxMoves - 1 #Change moves at a hit
print "You have "+str(maxMoves)+" moves left."
return maxMoves #Return maxMoves to the previous procedure

def PlayGame(Board, Ships):
maxMoves = 30 #Choose the number of moves you want the player to have
GameWon = False
GameLost = False #Create another variable used to terminate the loop
while not GameWon and not GameLost: #Add the game lost condition to the loop
PrintBoard(Board)
maxMoves = MakePlayerMove(Board, Ships, maxMoves) #Change number of moves when player takes a turn
if maxMoves == 0: #End of game condition which is run if the player runs out of moves
GameLost = True
print("You ran out of moves!")
quit = raw_input("Press enter to try again!") #Runs 'if __name__ == "__main__":' again
GameWon = CheckWin(Board)
if GameWon:
print "All ships sunk!"
print "Moves left: "+str(maxMoves)
print
```

Java Solution

C# Solution

## Allow user to enter their own ships on the board

Delphi/Pascal Solution

VB.NET Solution

Java Solution

C# Solution

Python Solution

```def PlayerPlaceShips(Board, Ships):
for Ship in Ships:
while True:
PrintBoard(Board, 1)
print("Where would you like to place", Ship[0])
while True:
try:
Column = int(input("Please select column: "))
if Column > 9:
raise ValueError
break
except ValueError:
print("That is not a valid column")

while True:
try:
Row = int(input("Please select row: "))
if Row > 9:
raise ValueError
break
except ValueError:
print("That is not a valid row")

while True:
Orientation = input("what orientation would you like the boat to be?")
if Orientation == "h" or Orientation == "v":
break
else:
print("That is not a valid orientation")

if ValidateBoatPosition(Board, Ship, Row, Column, Orientation) == True:
break
else:print("That is not a valid position")

PlaceShip(Board, Ship, Row, Column, Orientation)
return Board

#Oliver Cooke TM
```

VB.NET Solution

```'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form
Sub LoadSavedGame(ByVal Filename As String, ByRef Board(,) As Char)
Dim Row, Column As Integer
Dim Line As String
Try

For Row = 0 To 9
For Column = 0 To 9
Board(Row, Column) = Line(Column)
Next
Next
End Using
Catch ex As Exception 'An exception occurs if the file could not be found
Console.WriteLine("Could not find file. Do you want to see error file? (y/n)")
Dim Yes As String = Console.ReadLine.ToLower
If Yes = "y" Then
Console.WriteLine(ex)
End If
Console.WriteLine("Starting a new random game")
PlaceRandomShips(Board, Ships)

End Try
End Sub
```

Delphi/Pascal Solution

```//Sam B
Procedure LoadGame(filename: String; Var Board: TBoard);
Var
Line: String;
CurrentFile: Text;
Row: Integer;
Column: Integer;
Begin
AssignFile(CurrentFile, filename);
Reset(CurrentFile);
For Row := 0 To 9 Do
Begin
For Column := 0 To 9 Do
Board[Row][Column] := Line[Column + 1];
End;
CloseFile(CurrentFile);
End;
```

Python Solution

```###Solution by Robert Nixon - Wheatley Park School
'''
Save function adapted from the Saving the game tutorial changed so it asks the player if they want to save the game.
Also deals with invalid file names.
'''
def save(Board):
try:
file = raw_input("Enter the name of the file you want to use. No need to add .txt!")
file = file + ".txt"
f = open(file,"w")
for Row in range(10):
for Column in range(10):
f.write(Board[Row][Column])
f.write("\n")
f.close()
except IOError:
print "There was a problem with saving that game!"

'''
This function will load any file you choose.
'''
try:
file = raw_input("Enter the name of the file you want to load. No need to add .txt!") #Get the name of the file to load
file = file + ".txt"
boardLines = [] #Create an list for the unformatted board to be written to
f = open(file,"r")
for i in range(10):
for Row in range(10):
for Column in range(10):
Board[Row][Column] = boardLines[Row][Column] #Overwrite whatever is currently in the Board list.
f.close()
except IOError:
print "There was a problem using that file."
return Board #Return the new board
'''
Other Edits
'''
print
print "1. Start new game"
print "9. Quit"
print

if __name__ == "__main__":
TRAININGGAME = "Training.txt"
Board = SetUpBoard()
Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
PlaceRandomShips(Board, Ships)
PlayGame(Board, Ships)
PlayGame(Board, Ships)
if MenuOption == 3: #Handle the new option here
PlayGame(Board, Ships)
```

## Allow diagonal placement of ships

Java Solution j

```//author: zac peel-orange
void placeShip(char[][] board, Ship ship, int row, int column, char orientation){
if(orientation == 'v'){
for (int scan = 0; scan < ship.size; scan++){
board[row + scan][column] = ship.name.charAt(0);
}
}
else if (orientation == 'h'){
for (int scan = 0; scan < ship.size; scan++){
board[row][column + scan] = ship.name.charAt(0);
}
}
else if (orientation == 'd'){
for (int scan = 0; scan < ship.size; scan++){
board[row+scan][column + scan] = ship.name.charAt(0);
}
}
else if (orientation == 'b'){
for (int scan = 0; scan < ship.size; scan++){
board[row-scan][column + scan] = ship.name.charAt(0);
}
}
}

boolean validateBoatPosition(char[][] board, Ship ship, int row, int column, char orientation){
if(orientation == 'v' && row + ship.size > 10){
return false;
}
else if(orientation == 'h' && column + ship.size > 10){
return false;
}
else if(orientation == 'd' && (column + ship.size > 10 || row + ship.size > 10)){
return false;
}
else if(orientation == 'b' && (column + ship.size > 10 || row - ship.size < 0)){
return false;
}
else{
if(orientation == 'v'){
for (int scan = 0; scan < ship.size; scan++){
if (board[row + scan][column] != '-'){
return false;
}
}
}
else if(orientation == 'h'){
for (int scan = 0; scan < ship.size; scan++){
if(board[row][column + scan] != '-'){
return false;
}
}
}
else if(orientation == 'd'){
for (int scan = 0; scan < ship.size; scan++){
if(board[row + scan][column + scan] != '-'){
return false;
}
}
}
else if(orientation == 'b'){
for (int scan = 0; scan < ship.size; scan++){
if(board[row - scan][column + scan] != '-'){
return false;
}
}
}
}
return true;
}
```

Python

Changes have to be made to 3 of the functions; ValidateBoatPoisition, PlaceShip and PlaceRandomShips:

```def PlaceRandomShips(Board, Ships):
for Ship in Ships:
Valid = False
while not Valid:
Row = random.randint(0, 9)
Column = random.randint(0, 9)
HorV = random.randint(0, 2)                                             # Changed to (0,2) to allow for diagonal boat position to be selected
if HorV == 0:
Orientation = "v"
elif HorV == 1:
Orientation = "d"                                                     # Added elif to give ~1/3 chance for diagonal boat to be placed
else:
Orientation = "h"
Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation)
print("Computer placing the " + Ship[0])
PlaceShip(Board, Ship, Row, Column, Orientation)

def PlaceShip(Board, Ship, Row, Column, Orientation):
if Orientation == "v":
for Scan in range(Ship[1]):
Board[Row + Scan][Column] = Ship[0][0]
elif Orientation == "h":
for Scan in range(Ship[1]):
Board[Row][Column + Scan] = Ship[0][0]
elif Orientation == "d":                                                     # elif statement that places a diagonal ship. Each piece is down and to the right of the last.
for Scan in range(Ship[1]):
Board[Row + Scan][Column + Scan] = Ship[0][0]

def ValidateBoatPosition(Board, Ship, Row, Column, Orientation):
if Orientation in ["v","d"] and Row + Ship[1] > 10:                          # used 'in' to include the diagonal boat in checks for row and column validation.
return False
elif Orientation in ["h","d"] and Column + Ship[1] > 10:
return False
else:
if Orientation == "v":
for Scan in range(Ship[1]):
if Board[Row + Scan][Column] != "-":
return False
elif Orientation == "h":
for Scan in range(Ship[1]):
if Board[Row][Column + Scan] != "-":
return False
elif Orientation == "d":                                                   # final elif that checks the diagonal boat collides with nothing else.
for Scan in range(Ship[1]):
if Board[Row + Scan][Column + Scan] != "-":
return False
return True
```

## Allow user to enter two-digit co-ordinates, so 35 instead of 3 then 5

VB.NET Solution

```'this is a simple way of doing this
'the number is entered and then separated by the left and right command
'if you do not understand this, talk to your teacher about it, as they are useful commands

Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)

Dim coordinate As Integer

Console.WriteLine("please enter the coordinates that you would like to hit. e.g. 3,5 = 35")
Console.Writeline("the column is the first number, the row is the second number")

'this selects the furthest left number
Column = Left(coordinate, 1)
'this selects the furthest right number
Row = Right(coordinate, 1)

End Sub
```

```'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form
'Error checks as well as answers the question
Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer)

Dim coordinateval As String
Dim works As Boolean = False
Do
Console.WriteLine("please enter the coordinates that you would like to hit. e.g. (3,5) = 35")
Console.WriteLine("the column is the first number, the row is the second number")
If coordinateval.Length > 2 Then
works = False

If Integer.TryParse(coordinateval(0), Column) Then ' Checks if first character of input is a number
If Column < 0 Or Column > 9 Then  ' Checks if column is in range
Console.WriteLine("Column must be between 0 and 9")
Else
works = True

End If
Else
Console.WriteLine("This is not a number")
End If 'this is repeated for row

If Integer.TryParse(coordinateval(1), Row) Then
If Row < 0 Or Row > 9 Then
Console.WriteLine("Row must be between 0 and 9")
Else
works = True
End If
Else
Console.WriteLine("This is not a number")
End If
End If

Loop Until works = True

End Sub

End Sub
```

Python Solution

```###Solution by Robert Nixon - Wheatley Park School

def GetRowColumn():
print
Row = int(Coordinates[1])
Column = int(Coordinates[0])
print
return Row, Column
```

Java Solution

```//Solution by Psalmjrel Paulin - St. Brendan's Sixthform College

int[] getRowColumn(){
int column, row, coord;
int[] move;
move = new int[2];
console.println();
coord = console.readInteger("Enter COORDINATES in format 'xy' ");
row = coord%10;
column = (coord/10)%10;
console.println();
move[0] = row;
move[1] = column;
return move;
}
```

## If a miss, scan one element near the miss to see if a ship is present

VB.NET Solution

```'this is an inefficient method, change from Sub to Function as integer, create a nested for loop (row then column, both cycling from (row/column - 1) to (row/column + 1), if structure inside this: if off board, do nothing, else (on board), check to see if ship is present, return true if so [for loop will then be exited as value returned]
' currently no need to pass any value ByRef, only pass the board, row and column

'firstly create the sub routine you are going to use
Sub checknear(ByVal row As Integer, ByVal column As Integer, ByRef Board(,) As Char, ByRef close As Boolean)

Dim columnhigh, columnlow As Integer
Dim rowhigh, rowlow As Integer
'you do this to the column and row so that you can use all of the coordinates around where you have played
columnhigh = column + 1
columnlow = column - 1
rowhigh = row + 1
rowlow = row - 1

'all of these if statements use the above integers to check if there is a ship nearby
'it does not specify what ship is nearby
If Board(rowlow, columnlow) = "A" Or Board(rowlow, columnlow) = "B" Or Board(rowlow, columnlow) = "S" Or Board(rowlow, columnlow) = "D" Or Board(rowlow, columnlow) = "P" Then
close = True
End If

If Board(rowhigh, columnlow) = "A" Or Board(rowhigh, columnlow) = "B" Or Board(rowhigh, columnlow) = "S" Or Board(rowhigh, columnlow) = "D" Or Board(rowhigh, columnlow) = "P" Then
close = True
End If

If Board(rowlow, columnhigh) = "A" Or Board(rowlow, columnhigh) = "B" Or Board(rowlow, columnhigh) = "S" Or Board(rowlow, columnhigh) = "D" Or Board(rowlow, columnhigh) = "P" Then
close = True
End If

If Board(rowhigh, columnhigh) = "A" Or Board(rowhigh, columnhigh) = "B" Or Board(rowhigh, columnhigh) = "S" Or Board(rowhigh, columnhigh) = "D" Or Board(rowhigh, columnhigh) = "P" Then
close = True
End If

If Board(row, columnlow) = "A" Or Board(rowlow, columnlow) = "B" Or Board(rowlow, columnlow) = "S" Or Board(rowlow, columnlow) = "D" Or Board(rowlow, columnlow) = "P" Then
close = True
End If

If Board(rowhigh, column) = "A" Or Board(rowhigh, columnlow) = "B" Or Board(rowhigh, columnlow) = "S" Or Board(rowhigh, columnlow) = "D" Or Board(rowhigh, columnlow) = "P" Then
close = True
End If

If Board(rowlow, column) = "A" Or Board(rowlow, columnhigh) = "B" Or Board(rowlow, columnhigh) = "S" Or Board(rowlow, columnhigh) = "D" Or Board(rowlow, columnhigh) = "P" Then
close = True
End If

If Board(row, columnhigh) = "A" Or Board(rowhigh, columnhigh) = "B" Or Board(rowhigh, columnhigh) = "S" Or Board(rowhigh, columnhigh) = "D" Or Board(rowhigh, columnhigh) = "P" Then
close = True
End If
End Sub

'after doing this go to makeplayermove and dim close and set it to false
Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip)
Dim Row As Integer
Dim Column As Integer
Dim close As Boolean = False

'then further down in the code, call on you new sub routine
If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then
Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.")

ElseIf Board(Row, Column) = "-" Then
Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.")
Board(Row, Column) = "m"
'this is where you should add the sub
checknear(Row, Column, Board, close)
'here is where you will use close to say the move was close to a hit
If close = True Then
Console.WriteLine("You were close")
End If
Else
```

Python Solution

```###Solution by Robert Nixon - Wheatley Park School
def MakePlayerMove(Board, Ships):
Row, Column = GetRowColumn()
if Board[Row][Column] == "m" or Board[Row][Column] == "h":
print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again."
elif Board[Row][Column] == "-":
print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss."
Board[Row][Column] = "m"
scanning = True
while scanning == True:
try:
scanner = raw_input("Choose the coordinates around your miss to scan. Input as xy: ")
columnScan = int(scanner[0])
rowScan = int(scanner[1])
if columnScan < Column - 1 or columnScan > Column + 1 or rowScan < Row - 1 or rowScan > Row + 1:
raise ValueError
elif columnScan > 9 or columnScan < 0 or rowScan > 9 or rowScan < 0:
raise ValueError
else:
print("You have scanned the cell ("+str(columnScan)+","+str(rowScan)+") that cell contains: "+str(Board[rowScan][columnScan]))
scanning = False
except ValueError:
print("You have entered invalid coordinates. Please try again. Hint: You can only enter coordinates 1 cell away from you.")
else:
print "Hit at (" + str(Column) + "," + str(Row) + ")."
Board[Row][Column] = "h"
```

Java Solution:

```void makePlayerMove(char[][] board, Ship[] ships){
int[] rowColumn = getRowColumn();
int row = rowColumn[0];
int column = rowColumn[1];

if (board[row][column] == 'm' || board[row][column] == 'h'){
console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again.");
}
else if (board[row][column] == '-'){

console.println("Sorry, (" + column + "," + row + ") is a miss.");

//This uses two loops, one to loop through each row, which then loops through three columns in the row,
//the column before the shot, the column for the shot and the column after the shot. The same applies
//for the rows. If it finds a ship, it knows you are near.
//It also does some error checking, as it only allows values that are in the grid.
for ( int x = row - 1; x < row + 2; x++ ) {
for (int y = column - 1; y < column + 2; y++) {
if (x >= 0 && x <= 9 && y >= 0 && y <= 9) {
if (board[x][y] == 'A' || board[x][y] == 'B' || board[x][y] == 'S' || board[x][y] == 'D' || board[x][y] == 'P') {
console.println("I can tell you, however, that you are close to a ship.");
}
}
}
}

board[row][column] = 'm';
}
else{
console.println("Hit at (" + column + "," + row + ").");
board[row][column] = 'h';
}
}
```

## Performing Run-length Encoding on the 'Board', possibly useful when saving the game.

Performing some Run-length Encoding on the 'Board', possibly useful when saving the game. This would work in a similar way to the 'Generate FEN' question from last year's COMP1 paper.

Python Solution:

```### Solution programmed by S Wood - Ossett Sixth Form College.

#---------- NEW Subroutine - Encodes the Board, uses run-length encoding --------------------------------------
def encodeBoard(Board):
print("Saving Shorthand - Game Board: \n")
saveFilename = "BattleshipSave(Short).txt"     # Gives the SaveFile a specific name (don't forget the .txt extension)

longBoard = ""
for Row in range(10):                   # for each of the 10 Rows on the Board.
for Column in range(10):              # for each of the 10 Columns in that Row.
longBoard = longBoard + str(Board[Row][Column])   # add contents of that space to a 'longBoard' string.
longBoard = longBoard + "\n"          # identifies where each row is separated.

print("Long string for each space on Board")    # to see what the full thing looks like.
print(longBoard)
print()

#----------------------- COMPLEX - Encodes amount of characters (if more than 1 consecutively e.g. 10- or 4A)
print("Encoding...")
count = 1
prev = ""
shortBoard = str("")                          # Creates empty string for encoded Board

for character in longBoard:                   # Loops over each character in longBoard (above)
if character != prev:                       # IF not the same as previous character, add to shortBoard string.
#if prev:
if count == 1:
shortBoard = shortBoard + (prev)        # IF count is 1 then only add the character
else:
shortBoard = shortBoard + str(count)    # IF more than 1 then add count then character.
shortBoard = shortBoard + (prev)
count = 1                                 # count gets reset for new character here.
prev = character                          # previous is now the character just looked at.
else:
count += 1
else:                                         # This bit covers the final character in the loop.
if count == 1:                              # Could be multiple of that final one so same check as above.
shortBoard = shortBoard + (character)
else:
shortBoard = shortBoard + str(count)
shortBoard = shortBoard + (character)

print(shortBoard)   # print finished board here...

# --------- Save this newly encoded format --------------
with open(saveFilename, "w") as SaveFile:       # Open the save file in WRITE 'w' mode.
SaveFile.writelines(shortBoard)             # Write the contents of the current Board Space to the file.
SaveFile.close()                                # Close the file access afterwards.

return shortBoard

### NOTE: You will need to call this subroutine from the PlayGame section so that it is actually carried out.
### A student had this question, so we created this solution.
```

C# Solution

## Torpedo Function: fires vertically until a ship is hit or a column has been torpedoed.

Java Solution

Python

Changes have to be made to the subroutine 'PlayGame' as well as creating a new subroutine 'MakeTorpedoMove'.

```# Author - S Wood - Ossett Sixth

#-------------------------------------------------- AMEND 'PlayGame' as shown below
def PlayGame(Board, Ships):
GameWon = False
TorpedoUsed = False     # TORPEDO - Added this Boolean value, as torpedo has either been fired or not.

while not GameWon:
PrintBoard(Board)

#----------------- Start of Torpedo adjustments ----------------
if not TorpedoUsed:
TorpedoChosen = input("Fire a torpedo? (Y/N)")
if TorpedoChosen == "Y":
MakePlayerTorpedoMove(Board, Ships)   # Calls the new subroutine above.
TorpedoChosen = "N"
TorpedoUsed = True            # Set TorpedoUsed to True, so it cannot be triggered again.
else:
MakePlayerMove(Board, Ships)  # Make a normal move only if the previous conditions are not met.
#----------------- End of Torpedo adjustments ------------------

GameWon = CheckWin(Board)
if GameWon:
print("All ships sunk!")
print()

#-------------------------------------------------- NEW Subroutine below this line
def MakePlayerTorpedoMove(Board, Ships):
Row, Column = GetRowColumn()  # Fetch Row and Column inputs from this subroutine.

# WHILE you have Rows left to hit and there is a miss or an empty space, continue to move Torpedo.
while Row > 0 and (Board[Row][Column] == "m" or Board[Row][Column] == "-"):
Board[Row][Column] = "m"    # Set this new space to a miss.
Row = Row - 1               # Move the Row up the grid by 1 space.

# IF current position is NOT 'empty' or 'a miss', then it must be a ship or previous hit.
if Board[Row][Column] != "-" and Board[Row][Column] != "m":
print("Torpedo hits at (" + str(Column) + "," + str(Row) + ").")
Board[Row][Column] = "h"    # change to position to a hit.

# ELSE the Torpedo failed to hit anything in that Column of spaces.
else:
print("Torpedo failed to hit a ship.")
```