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. edit

Delphi/Pascal Solution

Answer :

Answer:

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

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

  Writeln;
End;


VB.NET Solution

Answer :

Answer:

   
    '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
                    Console.Write("Please enter column: ")
                    Column = Console.ReadLine()
                    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
                    Console.Write("Please enter row: ")
                    Row = Console.ReadLine()
                    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:

Answer :

Answer:

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("Please try again")
    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:
      print("Please enter a valid value.")
  #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

Answer :

Answer:

//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)){
    	column = console.readInteger("Please enter column: "); 
        if(column > 9 || column < 0){
        	console.println("Not a valid option...");
        } else {
            row = console.readInteger("Please enter row: ");
            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();
	    column = console.readInteger("Please enter column: ");
	    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();
    	row = console.readInteger("Please enter row: ");
    	 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(){
    // Author: Asadullah H
    int column;
    int row;
    int[] move;	
    move = new int[2];
    console.println();
    column=console.readByte("Please enter a column: "); 
    row=console.readByte("Please enter a row: ");	
	move[0] = row;
	move[1] = column;
    return move;
  }


C# Solution

Answer :

Answer:

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

    private static void GetRowColumn(ref int Row, ref int Column) {
	Console.WriteLine();
	Console.Write("Please enter column: ");
	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: ");
	}

	Console.Write("Please enter row: ");
	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: ");
            string ColumnTemp = Console.ReadLine();
            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: ");
            string RowTemp = Console.ReadLine();
            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();
        Console.Write("Please enter column: ");
        Column = Convert.ToInt32(Console.ReadLine());

        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();
        Console.Write("Please enter row: ");
        Row = Convert.ToInt32(Console.ReadLine());

        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. edit

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

Delphi/Pascal Solution

Answer :

Answer:

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 - Better :

Answer:

' 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

Answer :

Answer:

   
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

Answer - Better :

Answer:

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"


Answer :

Answer:

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

Answer :

Answer:

//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

Answer :

Answer:

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! edit

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

Delphi/Pascal Solution

Answer :

Answer:

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

  Writeln;

  GetMainMenuChoice := StrToInt(Choice);
End;


VB.NET Solution

Answer :

Answer:

'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
                    Console.Write("Please enter column: ")
                    Column = Console.ReadLine()
                    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
                    Console.Write("Please enter row: ")
                    Row = Console.ReadLine()
                    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

Answer :

Answer:

def GetMainMenuChoice():
  print("Please enter your choice: ", end="")
  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

Answer :

Answer:

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


C# Solution

Answer :

Answer:

/*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();

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

            Console.Write("Please enter row: ");
            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. edit

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

Answer :

Answer:


VB.NET Solution

Answer (works) :

Answer:

'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)")
                save = Console.ReadLine().ToLower
            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

Answer:

Answer:

' 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")
            save = Console.ReadLine
        End If
        If save = "y" Then
            SaveGame(Board, Filename)
        End If
    Loop Until GameWon
End Sub

'change LoadGame to support loading the game

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
            If Console.ReadLine = "o" Then
                Console.WriteLine("Enter the filename: ")
                Filename = Console.ReadLine
            End If
            Using FileReader As StreamReader = New StreamReader("C:\" & Filename)
                For Row = 0 To 9
                    Line = FileReader.ReadLine()
                    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

Answer :

Answer:

'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

'to load, edited version of original loadgame subroutine

    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.

        Using FileReader As StreamReader = New StreamReader(Filename)
            For Row = 0 To 9
                Line = FileReader.ReadLine()
                For Column = 0 To 9
                    Board(Row, Column) = Line(Column)
                Next
            Next
        End Using
    End Sub


Python Solution

Answer :

Answer:

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

Answer :

Answer:

//Author: Dan H
void playGame(char[][] board, Ship[] ships) {
		boolean gameWon = false;
		int moves = 0;
		while (!gameWon) {
			printBoard(board);
			console.println("Moves Made: " + moves);

			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];
		int menuOption = 0;
		while (menuOption != 9) {
			setUpBoard(board);
			setUpShips(ships);
			displayMenu();
			menuOption = getMainMenuChoice();
			if (menuOption == 1) {
				placeRandomShips(board, ships);
				playGame(board, ships);
			}
			if (menuOption == 2) {
				loadGame(TrainingGame, board);
				playGame(board, ships);
			}
			if (menuOption == 3) {
				loadGame(PreviousGame, board);
				playGame(board, ships);
			}
		}
	}


C# Solution

Answer :

Answer:

// 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

 private static void DisplayMenu()
    {
        Console.WriteLine("MAIN MENU");
        Console.WriteLine("");
        Console.WriteLine("1. Start new game");
        Console.WriteLine("2. Load Training game");
        Console.WriteLine("3. Load Recent game"); //added another menu option for loading the recent 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? ");
            string save = Console.ReadLine();
            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();
        DisplayMenu();
        GetMainMenuChoice();
    }

 static void Main(string[] args)
    {
        ShipType[] Ships = new ShipType[6];
        char[,] Board = new char[10, 10];
        int MenuOption = 0;
        while (MenuOption != 9)
        {
            SetUpBoard(ref Board);
            SetUpShips(ref Ships);
            DisplayMenu();
            MenuOption = GetMainMenuChoice();
            if (MenuOption == 1)
            {
                PlaceRandomShips(ref Board, Ships);
                PlayGame(ref Board, ref Ships);
            }
            if (MenuOption == 2)
            {
                LoadGame(TrainingGame, ref Board);
                PlayGame(ref Board, ref Ships);
            }
            if (MenuOption== 3)
            {
                SaveGame(RecentGame, ref Board);
                PlayGame(ref Board, ref Ships);
            }


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

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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:


Python Solution

Answer :

Answer:

###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"
  MenuOption = 0
  while not MenuOption == 9:
    Board = SetUpBoard(boardSize)
    Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
    DisplayMenu()
    MenuOption = GetMainMenuChoice()
    if MenuOption == 1:
      PlaceRandomShips(Board, Ships, boardSize)
      PlayGame(Board,Ships,boardSize)
    if MenuOption == 2:
      LoadGame(TRAININGGAME, Board)
      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"
  MenuOption = 0
  while not MenuOption == 9:
    Board = SetUpBoard(boardSize)
    Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
    DisplayMenu()
    MenuOption = GetMainMenuChoice()
    if MenuOption == 1:
      PlaceRandomShips(Board, Ships, boardSize)
      PlayGame(Board,Ships,boardSize)
    if MenuOption == 2:
      LoadGame(TRAININGGAME, Board)
      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

Answer :

Answer:

// (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

Answer :

Answer:


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

Delphi/Pascal Solution

Answer :

Answer:

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;
    Ships[5].Name := 'USS Enterprise'; //Add a name to your boat and follow previous format
    Ships[5].Size := 6;                 //Add a size to your boat and follow previous format

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

Answer :

Answer:

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
        Dim MenuOption As Integer

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


Python Solution

Answer :

Answer:

#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"
  MenuOption = 0
  while not MenuOption == 9:
    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
    DisplayMenu()
    MenuOption = GetMainMenuChoice()
    if MenuOption == 1:
      PlaceRandomShips(Board, Ships)
      PlayGame(Board,Ships)
    if MenuOption == 2:
      LoadGame(TRAININGGAME, Board)
      PlayGame(Board, Ships)


Java Solution

Answer :

Answer:

//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];
		int menuOption = 0;
		while (menuOption != 9) {
			setUpBoard(board);
			setUpShips(ships);
			displayMenu();
			menuOption = getMainMenuChoice();
			if (menuOption == 1) {
				placeRandomShips(board, ships);
				playGame(board, ships);
			}
			if (menuOption == 2) {
				loadGame(TrainingGame, board);
				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

Answer :

Answer:

// <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];
        int MenuOption = 0;
        while (MenuOption != 9)
        {
            SetUpBoard(ref Board);
            SetUpShips(ref Ships);
            DisplayMenu();
            MenuOption = GetMainMenuChoice();
            if (MenuOption == 1)
            {
                PlaceRandomShips(ref Board, Ships);
                PlayGame(ref Board, ref Ships);
            }
            if (MenuOption == 2)
            {
                LoadGame(TrainingGame, ref Board);
                PlayGame(ref Board, ref Ships);
            }
        }
    }


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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

 Function GetMainMenuChoice()
        Dim Choice As Integer
        Try
            Console.Write("Please enter your choice: ")
            Choice = Console.ReadLine()
            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

Answer :

Answer:

def GetMainMenuChoice():
  try:      # TRY to take a correct input here.
    print("Please enter your choice: ", end="")
    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()
    DisplayMenu()
    GetMainMenuChoice()


Java Solution

Answer :

Answer:

//AQA console already covers this


C# Solution

Answer :

Answer:

// - Oleksandr Buzan
private static int GetMainMenuChoice()
    {
        string Choice = null;
        int Choice2 = 0;
        bool CheckInput = false;
        while (CheckInput == false)
        {
            Console.Write("Please enter your choice: ");
            Choice = Console.ReadLine();
            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. edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

 Function GetMainMenuChoice()
        Dim Choice As Integer
        Try
            Console.Write("Please enter your choice: ")
            Choice = Console.ReadLine()
            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

Answer :

Answer:

def GetMainMenuChoice():
 print("Please enter your choice: ", end="")
 Choice = input()
 while Choice not in ["1","2","9"]:
   Choice = input("Please enter your choice: ")
 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
3. Please enter your answers in the answer boxes thank you (easily done from visual editor).


Java Solution

Answer :

Answer:

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


C# Solution

Answer :

Answer:

'''May 2017'''

private static int GetMainMenuChoice()
{
	int Choice = 0;
	Console.Write("Please enter your choice: ");
	while (!Int32.TryParse(Console.ReadLine(), out Choice))
	{
		Console.Write("Incorrect input\r\n");
		DisplayMenu();
		Console.WriteLine();
	}
	Console.WriteLine();
	return Choice;
}

//Luke Moll, Bridgwater College
    private static int GetMainMenuChoice()
    {
        int Choice = 0;
        Console.Write("Please enter your choice: ");

        while (true)
        {
            try
            {
                Choice = Convert.ToInt32(Console.ReadLine());
                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. edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

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

Answer :

Answer:

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

Answer :

Answer:

/**
     * 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

Answer :

Answer:

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). edit

-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

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

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

Answer :

Answer:

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

Answer :

Answer:

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


C# Solution

Answer :

Answer:

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). edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

'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
                    Console.Write("Please enter column: ")
                    Column = Console.ReadLine()
                    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
                    Console.Write("Please enter row: ")
                    Row = Console.ReadLine()
                    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

Answer :

Answer:

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

Answer :

Answer:

//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){
	    column = console.readInteger("Please enter column: ");			
	    row = console.readInteger("Please enter row: ");
    }
    console.println();
    move[0] = row;
    move[1] = column;
    return move;
  }


C# Solution

Answer :

Answer:

//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();
            Console.Write("Please enter column: ");
            ColumnChoice = Console.ReadLine();
            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.");
                Console.WriteLine("Please try again");
                ColumnChoice = ""; //Resets the Column While Loop
            }
            while (RowChoice == "")
            {
                Console.WriteLine();
                Console.Write("Please enter row: ");
                RowChoice = Console.ReadLine();
                if (BoardArray.Contains(RowChoice))
                {
                    Row = Convert.ToInt8(RowChoice);
                }
                else
                {
                    Console.WriteLine("That is Not a valid input.");
                    Console.WriteLine("Please try again");
                    RowChoice = "";//Resets the Row While Loop
                }
            }
            Console.WriteLine();
        }
    }


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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution bad

Answer :

Answer:

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

        Do
            
            DisplayMenu()
            MenuOption = GetMainMenuChoice()

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

            If MenuOption = 1 Then

                PlaceRandomShips(Board, Ships)
                PlayGame(Board, Ships)
            ElseIf MenuOption = 2 Then
                LoadGame(TrainingGame, Board)
                PlayGame(Board, Ships)
            End If
        Loop Until MenuOption = 9
    End Sub

Sub SetUpShips(ByRef Ships() As TShip, ByRef addship As Boolean)  'Add parameter addship
        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
        If addship = True Then
            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
            type = Console.ReadLine
            Ships(5).Name = Ships(type).Name
            Ships(5).Size = type
        End If
    End Sub


Python Solution

Answer :

Answer:

###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"
  MenuOption = 0
  while not MenuOption == 9:
    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 
    DisplayMenu()
    MenuOption = GetMainMenuChoice()
    if MenuOption == 1:
      PlaceRandomShips(Board, Ships)
      PlayGame(Board,Ships,shipTypes)
    if MenuOption == 2:
      LoadGame(TRAININGGAME, Board)
      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"
  MenuOption = 0
  while not MenuOption == 9:
    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)
    DisplayMenu()
    MenuOption = GetMainMenuChoice()
    if MenuOption == 1:
      PlaceRandomShips(Board, Ships)
      PlayGame(Board,Ships,shipTypes)
    if MenuOption == 2:
      LoadGame(TRAININGGAME, Board)
      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

Answer :

Answer:


C# Solution

Answer :

Answer:


Validate Position of Shot edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

'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

            Console.Write("Please enter column: ")
            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
                Console.WriteLine("Please enter a number")
            End If


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


            Console.Write("Please enter row: ")
                    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

Answer :

Answer:

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

Answer :

Answer:

//Author: Harnaam J

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

		while (!valid) {

			console.println();
			column = console.readInteger("Please enter column: ");
			row = console.readInteger("Please enter row: ");
			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

Answer :

Answer:


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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

'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
'Addition to Sub DisplayMenu()
Console.WriteLine("3. Start new multiplayer game")
'Addition to Sub Main()
            ElseIf MenuOption = 3 Then
                SetUpBoard(Board_Two)
                PlaceRandomShips(Board, Ships)
                PlaceRandomShips(Board_Two, Ships)
                PlayMultiGame(Board, Board_Two, Ships)
            End If


Python Solution

Answer :

Answer:

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()

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

def GetMenuChoice(Player1Name):
  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":
  DisplayMenu()
  Choice = GetMenuChoice(Player1Name)
  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

Answer :

Answer:


C# Solution

Answer :

Answer:


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

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

Answer :

Answer:

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

Answer :

Answer:

'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()
'Addition to Sub SetUpShips():
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

Answer :

Answer:

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()


Answer - Alternative :

Answer:


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

Answer :

Answer:

//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

Answer :

Answer:

'''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");
                    Console.ReadLine();
                }
            }

            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");
                    Console.ReadLine();
                }
            }

                
        
            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");
                    Console.ReadLine();
                }
            }
            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");
                    Console.ReadLine();
                }
            }
            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");
                    Console.ReadLine();
                }
            }
            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) edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:


Python Solution

Answer :

Answer:

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

Answer :

Answer:

// 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){
		  column = console.readInteger("Please enter column for missile: ");			
		   
		  if(column >= 0 && column <=9){
			  loop = true;
		  }else{
			  console.println("Not a valid option...");
		  }
	  }
	  loop = false;
	  while(loop != true){
		  row = console.readInteger("Please enter row for missile: ");			
	        
		  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

Answer :

Answer:


Could ask for leaderboard. (very unlikely) edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:


Python Solution

Answer :

Answer:

def add_to_scores(word, score):
    import pickle
    try:
        with open("high_scores.pickle", "rb") as f:
            high_scores = pickle.load(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")

  name = input("please enter your name for the high score board")

  high_scores = add_to_scores(name, score)
  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

Answer :

Answer:


C# Solution

Answer :

Answer:


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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

Console.Clear()


Python Solution

Answer :

Answer:

###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

Answer :

Answer:


C# Solution

Answer :

Answer:

Randomize ship positions edit

VB.NET Solution

Answer :

Answer:

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) edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:


Python Solution

Answer :

Answer:

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

Answer :

Answer:


C# Solution

Answer :

Answer:


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

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:

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

Answer :

Answer:

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

Answer :

Answer:


C# Solution

Answer :

Answer:

Allow user to enter their own ships on the board edit

Delphi/Pascal Solution

Answer :

Answer:


VB.NET Solution

Answer :

Answer:


Java Solution

Answer :

Answer:


C# Solution

Answer :

Answer:

Python Solution

Answer :

Answer:

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


Load Text File edit

VB.NET Solution

Answer :

Answer:

'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
            Using FileReader As StreamReader = New StreamReader(Filename)
                currentScore = FileReader.ReadLine()

                For Row = 0 To 9
                    Line = FileReader.ReadLine()
                    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

Answer :

Answer:

//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
    Readln(CurrentFile, Line);
    For Column := 0 To 9 Do
      Board[Row][Column] := Line[Column + 1];
  End;
  CloseFile(CurrentFile);
End;

Python Solution

Answer :

Answer:

###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.
'''
def load(Board):
    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):
            boardLines.append(f.readline()) #Read the file to the temp list
        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
'''
def DisplayMenu():
    print "MAIN MENU"
    print
    print "1. Start new game"
    print "2. Load training game"
    print "3. Load a saved game" #Added a new option to the menu for loading
    print "9. Quit"
    print

if __name__ == "__main__":
    TRAININGGAME = "Training.txt"
    MenuOption = 0
    while not MenuOption == 9:
        Board = SetUpBoard()
        Ships = [["Aircraft Carrier", 5], ["Battleship", 4], ["Submarine", 3], ["Destroyer", 3], ["Patrol Boat", 2]]
        DisplayMenu()
        MenuOption = GetMainMenuChoice()
        if MenuOption == 1:
            PlaceRandomShips(Board, Ships)
            PlayGame(Board, Ships)
        if MenuOption == 2:
            LoadGame(TRAININGGAME, Board)
            PlayGame(Board, Ships)
        if MenuOption == 3: #Handle the new option here
            Board = load(Board)
            PlayGame(Board, Ships)


Allow diagonal placement of ships edit

Java Solution j

Answer :

Answer:

//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

Answer :

Answer:


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 edit

VB.NET Solution

Answer 1 :

Answer:

'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")
        coordinate = Console.ReadLine

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

    End Sub


Answer 2 :

Answer:

'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")
            coordinateval = Console.ReadLine
            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

Answer:

Answer:

###Solution by Robert Nixon - Wheatley Park School

def GetRowColumn():
  print
  Coordinates = raw_input("Please enter your coordinates in the form xy: ")
  Row = int(Coordinates[1])
  Column = int(Coordinates[0])
  print
  return Row, Column

Java Solution

Answer:

Answer:

//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 edit

VB.NET Solution

Answer :

Answer:

'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

Answer :

Answer:

###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:

Answer :

Answer:

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. edit

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:

Answer :

Answer:

### 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

Answer :

Answer:


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

Java Solution

Answer :

Answer:


Python

Answer :

Answer:


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.")