Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

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)

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

This is Comp1 for the new Computer Science Specification even though it is under the Computing Wiki. Keep in mind that there is another Comp1 exam for Computing (for retakes?) and this is the place for this older exam. There should be a new wiki for Computer Science with links from both wikis to each other. Welcome to the paper 1 section C (what used to be section D in past COMP1 papers) for the new 2016 AQA Computer Science Exam. This is where suggestions can be made about what some of the questions might be and how can we solve them. Please be respectful and do not vandalise or tamper with the page, as this would affect students' preparation for their exams! I wish you all good luck with the exam, hopefully we can make it a little easier on ourselves by working together. Checking to see if you're off the board - If the player enters over 9 or under 0 it will crash the game. Delphi/Pascal Solution Procedure GetRowColumn(Var Row: Integer; Var Column: Integer); Begin Writeln; 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 '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: 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 //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 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 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 } } } Add a feature which tells the player the type of warship they hit. This feature may defeat the point of the game. But we shall give it a go anyway. Delphi/Pascal Solution Procedure MakePlayerMove(Var Board: TBoard; Var Ships: TShips); Var Row: Integer; Column: Integer; Begin GetRowColumn(Row, Column); If (Board[Row][Column] = 'm') Or (Board[Row][Column] = 'h') Then Writeln('Sorry, you have already shot at the square (', Column, ',', Row,'). Please try again.') Else If Board[Row][Column] = '-' Then Begin Writeln('Sorry, (', Column, ',', Row, ') is a miss.'); Board[Row][Column] := 'm'; End Else Begin Writeln('Hit at (', Column, ',', Row, ').'); if (Board[Row][Column] = 'A') then writeln('You hit an Aircraft Carrier'); if (Board[Row][Column] = 'B') then writeln('You hit a Battleship'); if (Board[Row][Column] = 'S') then writeln('You hit a Submarine'); if (Board[Row][Column] = 'D') then writeln('You hit a Destroyer'); if (Board[Row][Column] = 'P') then writeln('You hit a Patrol Boat'); Board[Row][Column] := 'h'; End; End; VB.NET Solution ' Answer is more efficient than previous code which utilised a dictionary Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) Dim Row As Integer Dim Column As Integer Dim shipNum As Integer = -1 GetRowColumn(Row, Column) If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Or ship_labels.ContainsKey(Board(Row, Column)) Then Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") ElseIf Board(Row, Column) = "-" Then Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Board(Row, Column) = "m" Else Do shipNum += 1 If Ships(shipNum).Name(0) = Board(Row, Column) Then Console.WriteLine("Hit at (" & Column & "," & Row & "). You hit a " & Ships(shipNum).Name) End If Loop Until Ships(shipNum).Name(0) = Board(Row, Column) Board(Row, Column) = "h" End If End Sub Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) Dim Row As Integer Dim Column As Integer GetRowColumn(Row, Column) If Board(Row, Column) = "m" Or Board(Row, Column) = "a" Or Board(Row, Column) = "b" Or Board(Row, Column) = "s" Or Board(Row, Column) = "d" Or Board(Row, Column) = "p" Then Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") ElseIf Board(Row, Column) = "-" Then Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Board(Row, Column) = "m" Else Console.WriteLine("Hit at (" & Column & "," & Row & ").") Board(Row, Column) = Chr(Asc(Board(Row, Column)) + 32) Select Case Board(Row, Column) Case "a" Console.WriteLine() Console.WriteLine("You hit an Aircraft Carrier.") Case "b" Console.WriteLine() Console.WriteLine("You hit a Battleship.") Case "s" Console.WriteLine() Console.WriteLine("You hit a Submarine.") Case "d" Console.WriteLine() Console.WriteLine("You hit a Destroyer.") Case "p" Console.WriteLine() Console.WriteLine("You hit a Patrol Boat.") End Select End If End Sub Python Solution def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() if Board[Row][Column] == "m" or Board[Row][Column] == "h": print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.") elif Board[Row][Column] == "-": print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.") Board[Row][Column] = "m" else: print("Hit at (" + str(Column) + "," + str(Row) + ").") for Ship in Ships: if Ship[0][0] == Board[Row][Column]: print(Ship[0]) Board[Row][Column] = "h" def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() if Board[Row][Column] == "m" or Board[Row][Column] == "h": print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.") elif Board[Row][Column] == "-": print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.") Board[Row][Column] = "m" else: print("Hit at (" + str(Column) + "," + str(Row) + ").") if Board[Row][Column] == "A": print("You hit an Aircraft Carrier") elif Board[Row][Column] == "B": print("You hit a Battleship") elif Board[Row][Column] == "S": print("You hit a Submarine") elif Board[Row][Column] == "D": print("You hit a Destroyer") elif Board[Row][Column] == "P": print("You hit a Patrol Boat") Board[Row][Column] = "h" Java Solution //Author: Dan H void makePlayerMove(char[][] board, Ship[] ships) { int[] rowColumn = getRowColumn(); int row = rowColumn[0]; int column = rowColumn[1]; if (board[row][column] == 'm' || board[row][column] == 'h') { console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if (board[row][column] == '-') { console.println("Sorry, (" + column + "," + row + ") is a miss."); board[row][column] = 'm'; } else { switch(board[row][column]){ case 'A': console.println("You hit an Aircraft Carrier"); break; case 'B': console.println("You hit a Battleship"); break; case 'S': console.println("You hit a Submarine"); break; case 'D': console.println("You hit a Destroyer"); break; case 'P': console.println("You hit a Patrol Boat"); break; } console.println("Hit at (" + column + "," + row + ")."); board[row][column] = 'h'; } } // Author: Emmanuel M void makePlayerMove(char[][] board, Ship[] ships){ int[] rowColumn = getRowColumn(); int row = rowColumn[0]; int column = rowColumn[1]; if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){ console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if (board[row][column] == '-'){ console.println("Sorry, (" + column + "," + row + ") is a miss."); board[row][column] = 'm'; } else if (board[row][column] == 'A'){ console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")"); board[row][column] = 'a'; } else if (board[row][column] == 'B'){ console.println("You hit a Battleship at (" + column + "," + row + ")"); board[row][column] = 'b'; } else if (board[row][column] == 'S'){ console.println("You hit a Submarine at (" + column + "," + row + ")"); board[row][column] = 's'; } else if (board[row][column] == 'D'){ console.println("You hit a Destroyer at (" + column + "," + row + ")"); board[row][column] = 'd'; } else if (board[row][column] == 'P'){ console.println("You hit a Patrol Boat at (" + column + "," + row + ")"); board[row][column] = 'p'; } } C# Solution private static void MakePlayerMove(ref char[,] Board, ref ShipType[] Ships) { I worked to replace the 'h' with the specific letter of the warship hit. The underneath solution does this quite well. However, it is for the specific ships entered and does not automatically change if more are added/changed. Basically, I replace the code: * Board[Row, Column] = 'h'; With this: for (int i = 0; i < 6-1; i++) { if (Board[Row, Column] == System.Convert.ToChar(Ships[i].Name[0])) { Board[Row, Column] = System.Convert.ToChar(Ships[i].Name.ToLower()[0]); } } This converts the first letter of the ship name into a character, then converts it to lower case. The visibility of the letter is handled in a different subroutine (the lower case will be visible). Only thing I didn't get around to is replacing the '6' with the max element in the array. Work this out yeah ;D Courtesy of the legend known of Lloyd, ~Bridgwater College. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Hamza Asif - Nelson and Colne College // Added a few adjustments so that when the player hits a ship, it identifies it with a smaller case letter (such as 'a' for aircraft carrier) - Oleksandr Buzan int Row = 0; int Column = 0; GetRowColumn(ref Row, ref Column); if (Board[Row, Column] == 'm' || Board[Row, Column] == 'h') { Console.WriteLine("Sorry, you have already shot at the square (" + Column + "," + Row + "). Please try again."); } else if (Board[Row, Column] == '-') { Console.WriteLine("Sorry, (" + Column + "," + Row + ") is a miss."); Board[Row, Column] = 'm'; } else { Console.WriteLine("Hit at (" + Column + "," + Row + ")."); if (Board[Row, Column] == 'A') { Console.WriteLine("You hit an Aircraft Carrier"); Board[Row, Column] = 'a'; } else if (Board[Row, Column] == 'B') { Console.WriteLine("You hit a Battleship"); Board[Row, Column] = 'b'; } else if (Board[Row, Column] == 'S') { Console.WriteLine("You hit a Submarine"); Board[Row, Column] = 's'; } else if (Board[Row, Column] == 'D') { Console.WriteLine("You hit a Destroyer"); Board[Row, Column] = 'd'; } else if (Board[Row, Column] == 'P') { Console.WriteLine("You hit a Patrol Boat"); Board[Row, Column] = 'p'; } } } No error checking for erroneous inputs - if a string is entered the program crashes! This is highly unlikely to come up as it is already implemented in Java but it is good practice nonetheless. Delphi/Pascal Solution Function GetMainMenuChoice: Integer; Var Choice: String; Begin 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 '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 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 //Already covered in the AQAConsole as this is considered a more complex standard of programming (not likely in AS) C# Solution /*One way to do this is to put all the Convert.ToInt32 (Console.ReadLine ()) in a try / catch and reasonably assume that any problem that happens is because of non-integer input This happens here, and also in GetMainMenuChoice(). A slightly nicer solution is to create another method which reads an integer input from the user with the instructions as a parameter */ private static void GetRowColumn(ref int Row, ref int Column) { Console.WriteLine(); 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. 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. VB.NET Solution 'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form 'edit PlayGame by adding two if statements Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip) Dim GameWon As Boolean = False Dim gamelimit As Integer = 50 Dim save As String Console.WriteLine() Do PrintBoard(Board) MakePlayerMove(Board, Ships) CurrentScore = CurrentScore + 1 Console.WriteLine("You have taken {0} move (s),", CurrentScore) GameWon = CheckWin(Board) If GameWon Then Console.WriteLine("All ships sunk!") Console.WriteLine() End If If save <> "y" Then 'If the user hasn't already specified he wants to save, then this question is posed after every move Console.WriteLine("Do you want to save (y/n)") 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 (does not work) ' 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 '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 Solution for 3.3: def SaveGame(Board): print("Saving Game:") saveFilename = "BattleshipSave.txt" # Gives the SaveFile a specific name (don't forget the .txt extension) # Need to create a 'String' version of the BOARD Variable (to write to .txt file) BoardText = str(Board) with open(saveFilename, "w") as SaveFile: # Open the save file in WRITE 'w' mode. for Row in range(10): # for each of the 10 Rows on the Board, do the below. for Column in range(10): # for each of the 10 Column spaces within that Row, do the following. SaveFile.writelines(str(Board[Row][Column])) # Write the contents of the current 'Board' Space to the file. SaveFile.writelines("\n") # Starts a new line after saving each Row of the Board to the file. SaveFile.close() # Close the file access afterwards. Solution for 2.7: def SaveGame(Board): FileName = raw_input("Enter a file name: ") FileName = FileName + ".txt" SaveFile = open(FileName, "w") for Row in range(10): for Column in range(10): SaveFile.write(Board[Row][Column]) SaveFile.write("\n") SaveFile.close() # Add a call to this subroutine 'SaveGame(Board)' in to the main 'PlayGame' subroutine. # Try to add it after the player has made the move, so the game progress is up to date. # This will Save the game progress after each turn to an external .txt file. gl with the exam guys. Have fun!!!!! You will need to add a call to this subroutine into the main PlayGame(Board) subroutine to get it to save the Progress after each turn. def PlayGame(Board, Ships): GameWon = False while not GameWon: PrintBoard(Board) print() MakePlayerMove(Board, Ships) GameWon = CheckWin(Board) SaveGame(Board) # Call SaveGame subroutine after the player has made a move. if GameWon: print("All ships sunk!") print() Java Solution //Author: Dan H void playGame(char[][] board, Ship[] ships) { boolean gameWon = false; int moves = 0; while (!gameWon) { printBoard(board); 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 // 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? Unlikely as all the ship data would need to be changed. It would take too long in the exam. Python Solution ###Solution by Robert Nixon - Wheatley Park School ''' The programmers have originally hardcoded the size of the board into the relevant functions and procedures. Here I have set the 'boardSize' variable to the number of rows and columns I want (as mentioned in the Java solution). The value 12 will result in a board which is 11*11 in size. The advantage of this is that I can change the size of the board by changing one number. I have also passed 'boardSize' into the appropriate functions. ''' if __name__ == "__main__": boardSize = 12 #Just change this value to change the size of the board TRAININGGAME = "Training.txt" 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 // (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 How could the game be changed to add another ship? Delphi/Pascal Solution procedure PlaceRandomShips(var Board: TBoard; Ships: TShips); var Valid: boolean; Ship: TShip; Row: integer; Column: integer; HorV: integer; Count: integer; Orientation: char; begin Randomize; for Count := 0 to 5 do //(Changes the value to the fifth boat) begin function CheckWin(Board: TBoard): boolean; var Row: integer; Column: integer; GameWon: boolean; begin GameWon := True; for Row := 0 to 9 do for Column := 0 to 9 do if (Board[Row][Column] = 'A') or (Board[Row][Column] = 'B') or (Board[Row][Column] = 'S') or (Board[Row][Column] = 'D') or (Board[Row][Column] = 'P') or (Board[Row][Column] = 'E') //add this with a letter that represents your boat procedure PrintBoard(Board: TBoard); var Row: integer; Column: integer; begin Writeln; Writeln('The board looks like this: '); Writeln; Write(' '); for Column := 0 to 9 do begin Write(' ', Column, ' '); end; Writeln; for Row := 0 to 9 do begin Write(Row, ' '); for Column := 0 to 9 do begin if Board[Row][Column] = '-' then Write(' ') else if (Board[Row][Column] = 'A') or (Board[Row][Column] = 'B') or (Board[Row][Column] = 'S') or (Board[Row][Column] = 'D') or (Board[Row][Column] = 'P') or (Board[Row][Column] = 'E') then //Do the same thing, as stated previously Write(' ') else Write(Board[Row][Column]); if (Column <> 9) then Write(' | '); end; Writeln; end; end; procedure SetUpShips(var Ships: TShips); begin Ships[0].Name := 'Aircraft Carrier'; Ships[0].Size := 5; Ships[1].Name := 'Battleship'; Ships[1].Size := 4; Ships[2].Name := 'Submarine'; Ships[2].Size := 3; Ships[3].Name := 'Destroyer'; Ships[3].Size := 3; Ships[4].Name := 'Patrol Boat'; Ships[4].Size := 2; 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 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 #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 //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 // THIS DOES NOT WORK AS THE SHIP IS NOT HIDDEN- Aquinas College //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. VB.NET Solution 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 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() 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 //AQA console already covers this C# Solution // - 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; } '''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. VB.NET Solution Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip) 'Give the player a finite number of ammo; when they run out of ammo, they lose Dim GameWon As Boolean = False Dim GameLost As Boolean = False Dim NumShots As Integer Dim NumShotsLeft As Integer NumShots = 0 NumShotsLeft = 25 Do NumShots += 1 NumShotsLeft -= 1 PrintBoard(Board) MakePlayerMove(Board, Ships) Console.WriteLine("Shots taken: " & NumShots) Console.WriteLine("Shots remaining: " & NumShotsLeft) GameWon = CheckWin(Board) If NumShotsLeft = 0 Then GameLost = True End If If GameLost = True Then Console.WriteLine("Bad Luck! You ran out of ammo!") Console.WriteLine() End If If GameWon Then Console.WriteLine("All ships sunk!") Console.WriteLine() End If Loop Until GameWon Or GameLost 'END End Sub Python Solution def PlayGame(Board, Ships): GameWon = False MAXMOVES = 30 # Setup the Maximum amount of moves here, as a CONSTANT (Capital letters). movesLeft = MAXMOVES # Assign the CONSTANT of MAXMOVES to a usable Variable. while not GameWon: PrintBoard(Board) print() print("You have {} moves left".format(movesLeft)) # the .format() puts the variable into the printed string. MakePlayerMove(Board, Ships) movesLeft = movesLeft - 1 # subtract 1 move after the player has made a move. if movesLeft == 0: print("You have run out of moves/ammo!!") return GameWon = CheckWin(Board) if GameWon: print("All ships sunk!") print() Java Solution /** * Function to play the game * * @param board - Board to be played on * @param ships - Ships to be played with */ void playGame(char[][] board, Ship[] ships) { // Game is not one to begin boolean gameWon = false; // While the game hasn't been one for(int moveIndex = 0; moveIndex < 5; moveIndex++) { // Print the board printBoard(board); // Get the players move makePlayerMove(board, ships); // Check if user has one gameWon = checkWin(board, ships); // If the user has one the game tell them if(gameWon) { // All ships sunk! console.println("All ships sunk!"); // New line console.println(); break; } char quit = console.readChar("Would you like to exit and save?(Y/n)"); if(quit == 'y' || quit == 'Y') { String filename = console.readLine("Name game: "); saveGame(filename, board); break; } } if(!gameWon) { System.out.println("Game Lost - Too many moves"); } } C# Solution private static void PlayGame(ref char[,] Board, ref ShipType[] Ships) { bool GameWon = false; int MaxMoves = 30; while (GameWon == false) { PrintBoard(Board); MakePlayerMove(ref Board, ref Ships); GameWon = CheckWin(Board); if (GameWon == true) { Console.WriteLine("All ships sunk!"); Console.WriteLine(); } else { MaxMoves -= 1; Console.WriteLine("You have " + MaxMoves + " move left!"); if (MaxMoves == 0) { Console.WriteLine("You have run out of moves!"); break; } } } No score is given (tell user how many moves they took to win). Give % accuracy? (user moves/least possible moves) Could also add a high score list written to a file (Which would mean adding another option in the menu). VB.NET Solution Module Module1 Const TrainingGame As String = "Training.txt" Dim Moves As Integer = 0 ... Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) Dim Row As Integer Dim Column As Integer GetRowColumn(Row, Column) If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") ElseIf Board(Row, Column) = "-" Then Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Board(Row, Column) = "m" Moves += 1 Else Console.WriteLine("Hit at (" & Column & "," & Row & ").") Board(Row, Column) = "h" Moves += 1 End If End Sub ... Sub PlayGame(ByVal Board(,) As Char, ByVal Ships() As TShip) Dim GameWon As Boolean = False Dim Acc As Single Do PrintBoard(Board) MakePlayerMove(Board, Ships) GameWon = CheckWin(Board) If GameWon = True Then Console.WriteLine("All ships sunk!") Console.WriteLine() Console.WriteLine("You had a " & hitProb(Board) & "% accuracy!") Console.WriteLine("You also took " & Moves & " Moves!") End If Loop Until GameWon End Sub ... Function hitProb(ByVal Board(,) As Char) Dim misses, hits, ratio As Integer For row As Integer = 0 To 9 For column As Integer = 0 To 9 If Board(row, column) = "m" Then misses += 1 ElseIf Board(row, column) = "h" Then hits += 1 End If Next Next ratio = (hits / (hits + misses)) * 100 Return ratio End Function Python Solution Here we create a calculation 'CalcScore()' function to calculate the accuracy percentage. We then integrate it into the 'PlayGame()' function with global variables (unfortunately the easiest way) to allow the code to run at the correct time with minimal function editing. def CalcScore(): global FinalScore print("You Completed The Game In " + str(FinalScore) + " Moves!") Accuracy = (17/FinalScore)*100 print("Your Accuracy Was " + str(Accuracy) + "%") def PlayGame(Board, Ships): global FinalScore GameWon = False while not GameWon: PrintBoard(Board) MakePlayerMove(Board, Ships) GameWon = CheckWin(Board) FinalScore += 1 if GameWon: print("All ships sunk!") FinalScore += 1 CalcScore() But Don't forget FinalScore = 0 At the start! Java Solution //Author: Dan H void playGame(char[][] board, Ship[] ships) { boolean gameWon = false; int moves=0; while (!gameWon) { printBoard(board); 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 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). VB.NET Solution 'Subroutine to get coordinates from user Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer) 'Boolean variables to check whether the input is valid Dim validCol, validRow As Boolean Console.WriteLine() Do Try Do 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 One to use the 'Try and Except' function in Python is shown below, this would help to cover a simple ValueError (string typed in place of an integer input); it also works for the input of a NULL value. def GetRowColumn(): print() while True: # while user makes incorrect inputs (wrong type, range) it loops to try again. try: Column = int(input("Please enter column: ")) # try and collect input value for Column break # break free if input is valid. except ValueError: # If the user gives the wrong data type, it will give an error and loop round to try again. print("Incorrect input given, needs to be 0-9.") while True: # while user makes incorrect inputs (wrong type, range) it loops to try again. try: Row = int(input("Please enter row: ")) # try and collect input value for Column break # break free from While Loop if input is valid. except ValueError: # If the user gives the wrong data type, it will give an error and loop round to try again. print("Incorrect input given, needs to be 0-9.") print() return Row, Column Java Solution //Author: Dan H int[] getRowColumn(){ //Method devised from AQAConsole2016 int column=Integer.MIN_VALUE; int row=Integer.MIN_VALUE; int[] move; move = new int[2]; console.println(); while(row==Integer.MIN_VALUE || column == Integer.MIN_VALUE){ column = console.readInteger("Please enter column: "); row = console.readInteger("Please enter row: "); } console.println(); move[0] = row; move[1] = column; return move; } C# Solution //This code checks the User input in comparison to the preset correct inputs 0 - 9 //~ Kaine Atherton private static void GetRowColumn(ref int Row, ref int Column) { string ColumnChoice = ""; string RowChoice = "a"; //Makes sure the Row while loop doesnt conflict with the Column //while loop while (ColumnChoice == "") { Console.WriteLine(); 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. VB.NET Solution 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 ###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: thumb I now have two patrol boats on the board. Validate Position of Shot VB.NET Solution 'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer) Dim validCollumn, validRow As Boolean ' These are currently set for the user to define them Do 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 def PlayGame(Board, Ships): GameWon = False MAXMOVES = 30 # This can be changed to make it easier or harder. movesleft = MAXMOVES while not GameWon: PrintBoard(Board) print("You have {} moves left".format(movesleft)) MakePlayerMove(Board, Ships) movesleft = movesleft - 1 if movesleft == 0: print("You ran out of shots, game over") return GameWon = CheckWin(Board) if GameWon: print("All ships sunk!") print() Java Solution //Author: Harnaam J int[] getRowColumn() { int column; int row; int[] move; move = new int[2]; boolean valid = false; while (!valid) { console.println(); 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; } Add a multiplayer option (another person or the computer). VB.NET Solution 'This is for PvP. 'New Subroutine Sub PlayMultiGame(ByVal Board(,) As Char, ByVal Board_Two(,) As Char, ByVal Ships() As TShip) Dim GameWon As Boolean = False Dim TurnSwitch As Boolean = True Do If TurnSwitch Then Console.WriteLine("Turn: Player One") PrintBoard(Board) MakePlayerMove(Board, Ships) GameWon = CheckWin(Board) If GameWon Then Console.WriteLine("All ships sunk!") Console.WriteLine("Player One wins!") Console.WriteLine() End If Else Console.WriteLine("Turn: Player Two") PrintBoard(Board_Two) MakePlayerMove(Board_Two, Ships) GameWon = CheckWin(Board_Two) If GameWon Then Console.WriteLine("All ships sunk!") Console.WriteLine("Player Two wins!") Console.WriteLine() End If End If TurnSwitch = Not TurnSwitch Loop Until GameWon End Sub '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 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("Player 1's Turn") PrintBoard(player1_Board, 0) MakePlayerMove(player1_Board, Ships) if CheckWin(player1_Board): print("Player 1 wins") break print("Player 2's Turn") PrintBoard(player2_Board, 0) MakePlayerMove(player2_Board, Ships) if CheckWin(player2_Board): print("Player 2 wins") break #Oliver Cooke Add a message for destroying warships (can be coded in a similar way to CheckWin (Board)). This adds a message to the user as soon as a Ship has been destroyed. It may quite easily crop up in the exam, as a simple way to get it to work is to copy and modify the existing CheckWin (Board) subroutine. This works by scanning the entire board to check for the existence of ships. You can then check which exist. Delphi/Pascal Solution Procedure MakePlayerMove(Var Board: TBoard; Var Ships: TShips); Var Row: Integer; Column: Integer; Begin GetRowColumn(Row, Column); If (Board[Row][Column] = 'm') Or (Board[Row][Column] = 'h') Then Writeln('Sorry, you have already shot at the square (', Column, ',', Row,'). Please try again.') Else If Board[Row][Column] = '-' Then Begin Writeln('Sorry, (', Column, ',', Row, ') is a miss.'); Board[Row][Column] := 'm'; End Else Begin Writeln('Hit at (', Column, ',', Row, ').'); if (Board[Row][Column] = 'A') then writeln('You hit an Aircraft Carrier'); if (Board[Row][Column] = 'B') then writeln('You hit a Battleship'); if (Board[Row][Column] = 'S') then writeln('You hit a Submarine'); if (Board[Row][Column] = 'D') then writeln('You hit a Destroyer'); if (Board[Row][Column] = 'P') then writeln('You hit a Patrol Boat'); if (Board[Row][Column] = 'E') then writeln('You hit the USS Enterprise'); //Remove this if you have five ships. Board[Row][Column] := 'h'; End; End; VB.NET Solution 'Solution 1 Sub DisplayWin(ByVal Board(,) As Char) 'Display a message if the player destroys a warship. Dim NoA As Integer = 0 Dim NoB As Integer = 0 Dim NoF As Integer = 0 Dim NoP As Integer = 0 Dim NoD As Integer = 0 Dim NoS As Integer = 0 Dim Row As Integer Dim Column As Integer For Row = 0 To 9 For Column = 0 To 9 If Board(Row, Column) = "P" Then NoP += -1 End If If Board(Row, Column) = "A" Then NoA += -1 End If If Board(Row, Column) = "B" Then NoB += -1 End If If Board(Row, Column) = "D" Then NoD += -1 End If If Board(Row, Column) = "S" Then NoS += -1 End If If Board(Row, Column) = "F" Then NoF += -1 End If Next Next If NoA = 0 Then Console.WriteLine("You sunk an Aircraft Carrier!") If NoP = 0 Then Console.WriteLine("You sunk a Patrol Boat!") If NoB = 0 Then Console.WriteLine("You sunk a Battleship!") If NoD = 0 Then Console.WriteLine("You sunk a Destroyer!") If NoS = 0 Then Console.WriteLine("You sunk a Submarine!") If NoF = 0 Then Console.WriteLine("You sunk a Frigate!") End Sub Sub MakePlayerMove... ... ... Console.WriteLine("Hit at (" & Column & "," & Row & ").") Board(Row, Column) = "h" Call DisplayWin(Board) 'Solution 2 'Global Variable: Dim Hits As Integer() '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 This subroutine works similarly to the existing CheckWin(Board). It is called in the same position, too. Probably not the best example that could be coded in, but it works, and in a way that has already been demonstrated in the skeleton code. def CheckShipsSunk(Board): Aircraft Carrier = 0 # sets up integer variables for each ship type. Battleship = 0 Submarine = 0 Destroyer = 0 PatrolBoat = 0 for Row in range(10): # for each Row, repeat the following... for Column in range(10): # for each Column in that Row, do the following checks. if Board[Row][Column] == "A": # if space holds an "A" then add 1 to Aircraft Carrier total. Aircraft Carrier += 1 elif Board[Row][Column] == "B": # if space holds an "B" then add 1 to Battleship total. Battleship += 1 elif Board[Row][Column] == "S": # if space holds an "S" then add 1 to Submarine total. Submarine += 1 elif Board[Row][Column] == "D": # if space holds an "D" then add 1 to Destroyer total. Destroyer += 1 elif Board[Row][Column] == "P": # if space holds an "P" then add 1 to Patrol Boat total. Patrol Boat += 1 print() # blank line space on output if Aircraft Carrier == 0: # IF there are no "A" spaces on Board, then Aircraft Carrier must be sunk. print("Aircraft Carrier sunk!") else: print("Aircraft Carrier hits needed", Aircraft Carrier) # ELSE print how many hits needed. This bit isn't necessary really but could be added if you wanted to. if Battleship == 0: print("Battleship sunk!") if Submarine == 0: print("Submarine sunk!") if Destroyer == 0: print("Destroyer sunk!") if PatrolBoat == 0: print("Patrol Boat sunk!") The PlayGame(Board, Ships) subroutine has had a simple line added to call the CheckShipsSunk(Board) subroutine when the game is running. def PlayGame(Board, Ships): GameWon = False while not GameWon: PrintBoard(Board) MakePlayerMove(Board, Ships) CheckShipsSunk(Board) # This line needs adding to call the CheckShipsSunk(Board) subroutine when the game is running. GameWon = CheckWin(Board) if GameWon: print("All ships sunk!") print() This solution is simple and uses the lengths of the ships stored in the ships' 2D array. def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() if Board[Row][Column] == "m" or Board[Row][Column] == "h": print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.") elif Board[Row][Column] == "-": print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.") Board[Row][Column] = "m" else: print("Hit at (" + str(Column) + "," + str(Row) + ").") for Ship in Ships: if Ship[0][0] == Board[Row][Column]: # Checks which ship has been hit Ship[1] -= 1 # Subtracts 1 from its length in the array if Ship[1] < 1: # Checks if the ship has been hit as many times as its length print('Ship sunk!') Board[Row][Column] = "h" Java Solution //Author: Dan H class Ship { String name; int size; int hits=0; } void makePlayerMove(char[][] board, Ship[] ships) { int[] rowColumn = getRowColumn(); int row = (rowColumn[0]); int column = (rowColumn[1]); if (board[row][column] == 'm' || board[row][column] == 'h') { console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if (board[row][column] == '-') { console.println("Sorry, (" + column + "," + row + ") is a miss."); board[row][column] = 'm'; } else { switch (board[row][column]) { case 'A': console.println("You hit an Aircraft Carrier"); ships[0].hits++; break; case 'B': console.println("You hit a Battleship"); ships[1].hits++; break; case 'S': console.println("You hit a Submarine"); ships[2].hits++; break; case 'D': console.println("You hit a Destroyer"); ships[3].hits++; break; case 'P': console.println("You hit a Patrol Boat"); ships[4].hits++; break; case 'U': console.println("You hit the USS Enterprise"); ships[5].hits++; break; } console.println("Hit at (" + column + "," + row + ")."); board[row][column] = 'h'; } for(int i=0; i<ships.length; i++){ if(ships[i].hits == ships[i].size){ console.println("You have sunk my "+ships[i].name); } } } C# Solution '''May 2017''' public struct ShipType { public string Name; public int Size; public bool Sunk; } private static string CheckSunk(ref char[,] Board, ref ShipType[] Ships) { for (int ship = 0; ship < Ships.Length; ship++) { if (!Ships[ship].Sunk) { Ships[ship].Sunk = true; for (int Column = 0; Column < 10; Column++) { for (int Row = 0; Row < 10; Row++) { if (Board[Row, Column] == Ships[ship].Name[0]) { Ships[ship].Sunk = false; } } } if (Ships[ship].Sunk) { return Ships[ship].Name; } } } return string.Empty; } private static void PlayGame(ref char[,] Board, ref ShipType[] Ships) { // Other code string shipSunk = CheckSunk(ref Board, ref Ships); if (shipSunk != string.Empty) { Console.WriteLine("{0} sunk!", shipSunk); } //Other code } private static void SetUpShips(ref ShipType[] Ships) { Ships[0].Name = "Aircraft Carrier"; Ships[0].Size = 5; Ships[0].Sunk = false; Ships[1].Name = "Battleship"; Ships[1].Size = 4; Ships[1].Sunk = false; Ships[2].Name = "Submarine"; Ships[2].Size = 3; Ships[2].Sunk = false; Ships[3].Name = "Destroyer"; Ships[3].Size = 3; Ships[2].Sunk = false; Ships[4].Name = "Patrol Boat"; Ships[4].Size = 2; Ships[2].Sunk = false; } /********************************************************************************/ Aquinas College This contains the code needed to get the program to tell you when you've sunk a ship public struct ShipType { public string Name; public int Size; public int HitCount; } private static void MakePlayerMove(ref char[,] Board, ref ShipType[] Ships) { int Row = 0; // Data type called 'Row' is declared as an integer, with a value of 0 int Column = 0; // Data type called 'Column' is declared as an integer, with a value of 0 GetRowColumn(ref Row, ref Column); //Execute method 'GetRowColumn' to ask for the user what square they want to shoot at if (Board[Row, Column] == 'm' || Board[Row, Column] == 'h') //If characters 'm' or 'h' are detected in the multi dimensional array ([6,9] for example) then... { Console.WriteLine("Sorry, you have already shot at the square (" + Column + "," + Row + "). Please try again."); //Output a message telling them that they have already shot that square } else if (Board[Row, Column] == '-') //If character '-' is detected in the multi dimensional array ([5,5] for example) then... { Console.WriteLine("Sorry, (" + Column + "," + Row + ") is a miss."); //Output a message for the user which tells them that they haven't hit anything (missed) Board[Row, Column] = 'm'; //Replace the character '-' (that the user has just 'shot') with the character 'm' to indicate that it's a miss, so that later the computer/program can tell them that they have already shot that square } else //Otherwise... { Console.WriteLine("Hit at (" + Column + "," + Row + ")."); //Output a message telling the user that they have hit a ship, indicating where its position is if (Board[Row, Column] == 'A') //If character 'A' is detected in the multi dimensional array ([4,3] for example) then... { Console.WriteLine("You hit an Aircraft Carrier"); Ships[0].HitCount = Ships[0].HitCount + 1; if (Ships[0].HitCount == Ships[0].Size) { Console.WriteLine("You sank an Aircraft Carrier"); 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) Python Solution def PlayerMissile(Board, Ships): Row, Column = GetRowColumn() MissileHit_Range = [] MissileHit_Range.append([Column,Row]) MissileHit_Range.append([Column,Row-1]) MissileHit_Range.append([Column+1,Row-1]) MissileHit_Range.append([Column+1,Row]) MissileHit_Range.append([Column+1,Row+1]) MissileHit_Range.append([Column,Row+1]) MissileHit_Range.append([Column-1, Row+1]) MissileHit_Range.append([Column-1,Row]) MissileHit_Range.append([Column-1,Row-1]) print(MissileHit_Range) for each in MissileHit_Range: print(Board[each[1]][each[0]]) if Board[each[1]][each[0]] == "m" or Board[each[1]][each[0]] == "h": print("") elif Board[each[1]][each[0]] == "-": Board[each[1]][each[0]] = "m" else: Board[each[1]][each[0]] = "h" Java Solution // Author: Emmanuel M // P.S Called it a rocket instead of a missile :) private int hits = 0; private int miss = 0; // Edited makePlayerMove to add hits and misses void makePlayerMove(char[][] board, Ship[] ships){ int[] rowColumn = getRowColumn(); int row = rowColumn[0]; int column = rowColumn[1]; if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){ console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if (board[row][column] == '-'){ console.println("Sorry, (" + column + "," + row + ") is a miss."); board[row][column] = 'm'; miss ++; } else if (board[row][column] == 'A'){ console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")"); board[row][column] = 'a'; hits++; } else if (board[row][column] == 'B'){ console.println("You hit a Battleship at (" + column + "," + row + ")"); board[row][column] = 'b'; hits++; } else if (board[row][column] == 'S'){ console.println("You hit a Submarine at (" + column + "," + row + ")"); board[row][column] = 's'; hits++; } else if (board[row][column] == 'D'){ console.println("You hit a Destroyer at (" + column + "," + row + ")"); board[row][column] = 'd'; hits++; } else if (board[row][column] == 'P'){ console.println("You hit a Patrol Boat at (" + column + "," + row + ")"); board[row][column] = 'p'; hits++; } } // made a method called MakePlayerMoveRC for missileMove to avoid interruptions with Game void makePlayerMoveRC(char[][] board,int row,int column){ int[] rowColumn = getRowColumn(); int row = rowColumn[0]; int column = rowColumn[1]; if (board[row][column] == 'm' || board[row][column] == 'h'|| board[row][column] == 'a'|| board[row][column] == 'b'|| board[row][column] == 's'|| board[row][column] == 'd'|| board[row][column] == 'p'){ console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if(board[row][column] == '-'){ console.println("Sorry, (" + column + "," + row + ") is a miss."); board[row][column] = 'm'; miss ++; } else if(board[row][column] == 'A'){ console.println("You hit an Aircraft Carrier at (" + column + "," + row + ")"); board[row][column] = 'a'; hits++; } else if(board[row][column] == 'B'){ console.println("You hit a Battleship at (" + column + "," + row + ")"); board[row][column] = 'b'; hits++; } else if(board[row][column] == 'S'){ console.println("You hit a Submarine at (" + column + "," + row + ")"); board[row][column] = 's'; hits++; } else if(board[row][column] == 'D'){ console.println("You hit a Destroyer at (" + column + "," + row + ")"); board[row][column] = 'd'; hits++; } else if(board[row][column] == 'P'){ console.println("You hit a Patrol Boat at (" + column + "," + row + ")"); board[row][column] = 'p'; hits++; } } void missileMove(char[][] board){ int column = -1; int row = -1; console.println(); boolean loop = false; while(loop != true){ 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; } } } Could ask for leaderboard. (very unlikely) Python Solution 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 Clear the environment after every turn has taken place. (pointless) Delphi/Pascal Solution VB.NET Solution Console.Clear() Python Solution ###Solution by Robert Nixon - Wheatley Park School '''The first example is cross-platform, it uses 'cls' if on a windows system but 'clear' if anything else (OSX or Linux I think):''' import os def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() clear = lambda: os.system('cls' if os.name=='nt' else 'clear') #Concise way of doing it using lambda clear() #Remember to call the function on the next line if Board[Row][Column] == "m" or Board[Row][Column] == "h": print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again." elif Board[Row][Column] == "-": print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss." Board[Row][Column] = "m" else: print "Hit at (" + str(Column) + "," + str(Row) + ")." Board[Row][Column] = "h" '''I doubt they would expect a cross-platform solution for full marks, so you can just deal with it like this:''' import os def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() os.system('cls') #Modify the string inside in accordance with your os if Board[Row][Column] == "m" or Board[Row][Column] == "h": print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again." elif Board[Row][Column] == "-": print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss." Board[Row][Column] = "m" else: print "Hit at (" + str(Column) + "," + str(Row) + ")." Board[Row][Column] = "h" Randomize ship positions VB.NET Solution Sub PlaceRandomShips(ByRef Board(,) As Char, ByVal Ships() As TShip) Dim Valid As Boolean Dim Row As Integer Dim Column As Integer Dim Orientation As Char Dim HorV As Integer For Each Ship In Ships Valid = False While Not Valid 'Just add the word Randomize() in to fix this Randomize() Row = Int(Rnd() * 10) Column = Int(Rnd() * 10) HorV = Int(Rnd() * 2) If HorV = 0 Then Orientation = "v" Else Orientation = "h" End If Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation) End While Console.WriteLine("Computer placing the " & Ship.Name) PlaceShip(Board, Ship, Row, Column, Orientation) Next End Sub Allow the player to fire a salvo (i.e. simultaneously enter coordinates for three shots and then make the move) Python Solution Here, we can integrate simple loops to make the code work. I made a minor edit to the code of the GetRowColumn() and MakePlayerMove() functions to allow the salvo to take place. def GetRowColumn(): Column=[] Row=[] print() for i in range(3): Column.append(int(input("Please enter column For Shot "+ str(i+1) +": "))) Row.append(int(input("Please enter row For Shot "+ str(i+1) +": "))) print() return Row, Column def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() for i in range(3): if Board[Row[i-1]][Column[i-1]] == "m" or Board[Row[i-1]][Column[i-1]] == "h": print("Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again.") elif Board[Row[i-1]][Column[i-1]] == "-": print("Sorry, (" + str(Column) + "," + str(Row) + ") is a miss.") Board[Row[i-1]][Column[i-1]] = "m" else: print("Hit at (" + str(Column) + "," + str(Row) + ").") Board[Row[i-1]][Column[i-1]] = "h" Don't subtract a move when a coordinate has been re-entered. VB.NET Solution This shows how I subtract 1 from the current score every time the same coordinate is entered: 'Answer submitted by David Popovici of Colchester Royal Grammar School Sixth Form Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) Dim Row As Integer Dim Column As Integer GetRowColumn(Row, Column) Console.WriteLine("Hit at (" & Column & "," & Row & ").") If Board(Row, Column) = "m" Or Board(Row, Column) = "a" Or Board(Row, Column) = "b" Or Board(Row, Column) = "s" Or Board(Row, Column) = "d" Or Board(Row, Column) = "p" Then Console.ForegroundColor = ConsoleColor.DarkMagenta Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") currentScore -= 1 'you can see this here Console.ForegroundColor = ConsoleColor.Gray ElseIf Board(Row, Column) = "-" Then Console.ForegroundColor = ConsoleColor.Red Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Console.ForegroundColor = ConsoleColor.Gray Board(Row, Column) = "m" Else Console.ForegroundColor = ConsoleColor.Magenta Select Case Board(Row, Column) Case "A" Console.WriteLine("You hit an Aircraft Carrier") Board(Row, Column) = "a" Case "B" Console.WriteLine("You hit a Battleship") Board(Row, Column) = "b" Case "P" Console.WriteLine("You hit a Patrol Boat") Board(Row, Column) = "p" Case "D" Console.WriteLine("You hit a Destroyer") Board(Row, Column) = "d" Case "S" Console.WriteLine("You hit a Submarine") Board(Row, Column) = "s" End Select Console.ForegroundColor = ConsoleColor.Gray End If Python Solution How to add a set number of turns and how to not miss a turn when the same coordinate is re-entered: ###Solution by Robert Nixon - Wheatley Park School def MakePlayerMove(Board, Ships, maxMoves): Row, Column = GetRowColumn() if Board[Row][Column] == "m" or Board[Row][Column] == "h": print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again." #Don't add anything here (the point of the task) elif Board[Row][Column] == "-": print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss." Board[Row][Column] = "m" maxMoves = maxMoves - 1 #Change moves at a miss print "You have "+str(maxMoves)+" moves left." else: print "Hit at (" + str(Column) + "," + str(Row) + ")." Board[Row][Column] = "h" maxMoves = maxMoves - 1 #Change moves at a hit print "You have "+str(maxMoves)+" moves left." return maxMoves #Return maxMoves to the previous procedure def PlayGame(Board, Ships): maxMoves = 30 #Choose the number of moves you want the player to have GameWon = False GameLost = False #Create another variable used to terminate the loop while not GameWon and not GameLost: #Add the game lost condition to the loop PrintBoard(Board) maxMoves = MakePlayerMove(Board, Ships, maxMoves) #Change number of moves when player takes a turn if maxMoves == 0: #End of game condition which is run if the player runs out of moves GameLost = True print("You ran out of moves!") quit = raw_input("Press enter to try again!") #Runs 'if __name__ == "__main__":' again GameWon = CheckWin(Board) if GameWon: print "All ships sunk!" print "Moves left: "+str(maxMoves) print Allow user to enter their own ships on the board Python Solution def PlayerPlaceShips(Board, Ships): for Ship in Ships: while True: PrintBoard(Board, 1) print("Where would you like to place", Ship[0]) while True: try: Column = int(input("Please select column: ")) if Column > 9: raise ValueError break except ValueError: print("That is not a valid column") while True: try: Row = int(input("Please select row: ")) if Row > 9: raise ValueError break except ValueError: print("That is not a valid row") while True: Orientation = input("what orientation would you like the boat to be?") if Orientation == "h" or Orientation == "v": break else: print("That is not a valid orientation") if ValidateBoatPosition(Board, Ship, Row, Column, Orientation) == True: break else:print("That is not a valid position") PlaceShip(Board, Ship, Row, Column, Orientation) return Board #Oliver Cooke Load Text File VB.NET Solution 'Submitted by David Popovici of Colchester Royal Grammar School Sixth Form Sub LoadSavedGame(ByVal Filename As String, ByRef Board(,) As Char) Dim Row, Column As Integer Dim Line As String Try 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 //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 ###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 Java Solution //author: zac peel-orange void placeShip(char[][] board, Ship ship, int row, int column, char orientation){ if(orientation == 'v'){ for (int scan = 0; scan < ship.size; scan++){ board[row + scan][column] = ship.name.charAt(0); } } else if (orientation == 'h'){ for (int scan = 0; scan < ship.size; scan++){ board[row][column + scan] = ship.name.charAt(0); } } else if (orientation == 'd'){ for (int scan = 0; scan < ship.size; scan++){ board[row+scan][column + scan] = ship.name.charAt(0); } } else if (orientation == 'b'){ for (int scan = 0; scan < ship.size; scan++){ board[row-scan][column + scan] = ship.name.charAt(0); } } } boolean validateBoatPosition(char[][] board, Ship ship, int row, int column, char orientation){ if(orientation == 'v' && row + ship.size > 10){ return false; } else if(orientation == 'h' && column + ship.size > 10){ return false; } else if(orientation == 'd' && (column + ship.size > 10 || row + ship.size > 10)){ return false; } else if(orientation == 'b' && (column + ship.size > 10 || row - ship.size < 0)){ return false; } else{ if(orientation == 'v'){ for (int scan = 0; scan < ship.size; scan++){ if (board[row + scan][column] != '-'){ return false; } } } else if(orientation == 'h'){ for (int scan = 0; scan < ship.size; scan++){ if(board[row][column + scan] != '-'){ return false; } } } else if(orientation == 'd'){ for (int scan = 0; scan < ship.size; scan++){ if(board[row + scan][column + scan] != '-'){ return false; } } } else if(orientation == 'b'){ for (int scan = 0; scan < ship.size; scan++){ if(board[row - scan][column + scan] != '-'){ return false; } } } } return true; } Python Changes have to be made to 3 of the functions; ValidateBoatPosition, PlaceShip and PlaceRandomShips: def PlaceRandomShips(Board, Ships): for Ship in Ships: Valid = False while not Valid: Row = random.randint(0, 9) Column = random.randint(0, 9) HorV = random.randint(0, 2) # Changed to (0,2) to allow for diagonal boat position to be selected if HorV == 0: Orientation = "v" elif HorV == 1: Orientation = "d" # Added elif to give ~1/3 chance for diagonal boat to be placed else: Orientation = "h" Valid = ValidateBoatPosition(Board, Ship, Row, Column, Orientation) print("Computer placing the " + Ship[0]) PlaceShip(Board, Ship, Row, Column, Orientation) def PlaceShip(Board, Ship, Row, Column, Orientation): if Orientation == "v": for Scan in range(Ship[1]): Board[Row + Scan][Column] = Ship[0][0] elif Orientation == "h": for Scan in range(Ship[1]): Board[Row][Column + Scan] = Ship[0][0] elif Orientation == "d": # elif statement that places a diagonal ship. Each piece is down and to the right of the last. for Scan in range(Ship[1]): Board[Row + Scan][Column + Scan] = Ship[0][0] def ValidateBoatPosition(Board, Ship, Row, Column, Orientation): if Orientation in ["v","d"] and Row + Ship[1] > 10: # used 'in' to include the diagonal boat in checks for row and column validation. return False elif Orientation in ["h","d"] and Column + Ship[1] > 10: return False else: if Orientation == "v": for Scan in range(Ship[1]): if Board[Row + Scan][Column] != "-": return False elif Orientation == "h": for Scan in range(Ship[1]): if Board[Row][Column + Scan] != "-": return False elif Orientation == "d": # final elif that checks the diagonal boat collides with nothing else. for Scan in range(Ship[1]): if Board[Row + Scan][Column + Scan] != "-": return False return True Allow user to enter two-digit co-ordinates, so 35 instead of 3 then 5 VB.NET Solution 'this is a simple way of doing this 'the number is entered and then separated by the left and right command 'if you do not understand this, talk to your teacher about it, as they are useful commands Sub GetRowColumn(ByRef Row As Integer, ByRef Column As Integer) Dim coordinate As Integer Console.WriteLine("please enter the coordinates that you would like to hit. e.g. 3,5 = 35") Console.Writeline("the column is the first number, the row is the second number") 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 '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 ###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 //Solution by Psalmjrel Paulin - St. Brendan's Sixthform College int[] getRowColumn(){ int column, row, coord; int[] move; move = new int[2]; console.println(); coord = console.readInteger("Enter COORDINATES in format 'xy' "); row = coord%10; column = (coord/10)%10; console.println(); move[0] = row; move[1] = column; return move; } If a miss, scan one element near the miss to see if a ship is present VB.NET Solution 'this is an inefficient method, change from Sub to Function as integer, create a nested for loop (row then column, both cycling from (row/column - 1) to (row/column + 1), if structure inside this: if off board, do nothing, else (on board), check to see if ship is present, return true if so [for loop will then be exited as value returned] ' currently no need to pass any value ByRef, only pass the board, row and column 'firstly create the sub routine you are going to use Sub checknear(ByVal row As Integer, ByVal column As Integer, ByRef Board(,) As Char, ByRef close As Boolean) Dim columnhigh, columnlow As Integer Dim rowhigh, rowlow As Integer 'you do this to the column and row so that you can use all of the coordinates around where you have played columnhigh = column + 1 columnlow = column - 1 rowhigh = row + 1 rowlow = row - 1 'all of these if statements use the above integers to check if there is a ship nearby 'it does not specify what ship is nearby If Board(rowlow, columnlow) = "A" Or Board(rowlow, columnlow) = "B" Or Board(rowlow, columnlow) = "S" Or Board(rowlow, columnlow) = "D" Or Board(rowlow, columnlow) = "P" Then close = True End If If Board(rowhigh, columnlow) = "A" Or Board(rowhigh, columnlow) = "B" Or Board(rowhigh, columnlow) = "S" Or Board(rowhigh, columnlow) = "D" Or Board(rowhigh, columnlow) = "P" Then close = True End If If Board(rowlow, columnhigh) = "A" Or Board(rowlow, columnhigh) = "B" Or Board(rowlow, columnhigh) = "S" Or Board(rowlow, columnhigh) = "D" Or Board(rowlow, columnhigh) = "P" Then close = True End If If Board(rowhigh, columnhigh) = "A" Or Board(rowhigh, columnhigh) = "B" Or Board(rowhigh, columnhigh) = "S" Or Board(rowhigh, columnhigh) = "D" Or Board(rowhigh, columnhigh) = "P" Then close = True End If If Board(row, columnlow) = "A" Or Board(rowlow, columnlow) = "B" Or Board(rowlow, columnlow) = "S" Or Board(rowlow, columnlow) = "D" Or Board(rowlow, columnlow) = "P" Then close = True End If If Board(rowhigh, column) = "A" Or Board(rowhigh, columnlow) = "B" Or Board(rowhigh, columnlow) = "S" Or Board(rowhigh, columnlow) = "D" Or Board(rowhigh, columnlow) = "P" Then close = True End If If Board(rowlow, column) = "A" Or Board(rowlow, columnhigh) = "B" Or Board(rowlow, columnhigh) = "S" Or Board(rowlow, columnhigh) = "D" Or Board(rowlow, columnhigh) = "P" Then close = True End If If Board(row, columnhigh) = "A" Or Board(rowhigh, columnhigh) = "B" Or Board(rowhigh, columnhigh) = "S" Or Board(rowhigh, columnhigh) = "D" Or Board(rowhigh, columnhigh) = "P" Then close = True End If End Sub 'after doing this go to makeplayermove and dim close and set it to false Sub MakePlayerMove(ByRef Board(,) As Char, ByRef Ships() As TShip) Dim Row As Integer Dim Column As Integer Dim close As Boolean = False 'then further down in the code, call on you new sub routine If Board(Row, Column) = "m" Or Board(Row, Column) = "h" Then Console.WriteLine("Sorry, you have already shot at the square (" & Column & "," & Row & "). Please try again.") ElseIf Board(Row, Column) = "-" Then Console.WriteLine("Sorry, (" & Column & "," & Row & ") is a miss.") Board(Row, Column) = "m" 'this is where you should add the sub checknear(Row, Column, Board, close) 'here is where you will use close to say the move was close to a hit If close = True Then Console.WriteLine("You were close") End If Else Python Solution ###Solution by Robert Nixon - Wheatley Park School def MakePlayerMove(Board, Ships): Row, Column = GetRowColumn() if Board[Row][Column] == "m" or Board[Row][Column] == "h": print "Sorry, you have already shot at the square (" + str(Column) + "," + str(Row) + "). Please try again." elif Board[Row][Column] == "-": print "Sorry, (" + str(Column) + "," + str(Row) + ") is a miss." Board[Row][Column] = "m" scanning = True while scanning == True: try: scanner = raw_input("Choose the coordinates around your miss to scan. Input as xy: ") columnScan = int(scanner[0]) rowScan = int(scanner[1]) if columnScan < Column - 1 or columnScan > Column + 1 or rowScan < Row - 1 or rowScan > Row + 1: raise ValueError elif columnScan > 9 or columnScan < 0 or rowScan > 9 or rowScan < 0: raise ValueError else: print("You have scanned the cell ("+str(columnScan)+","+str(rowScan)+") that cell contains: "+str(Board[rowScan][columnScan])) scanning = False except ValueError: print("You have entered invalid coordinates. Please try again. Hint: You can only enter coordinates 1 cell away from you.") else: print "Hit at (" + str(Column) + "," + str(Row) + ")." Board[Row][Column] = "h" Java Solution: void makePlayerMove(char[][] board, Ship[] ships){ int[] rowColumn = getRowColumn(); int row = rowColumn[0]; int column = rowColumn[1]; if (board[row][column] == 'm' || board[row][column] == 'h'){ console.println("Sorry, you already shot at the square (" + column + "," + row + "). Please try again."); } else if (board[row][column] == '-'){ console.println("Sorry, (" + column + "," + row + ") is a miss."); //This uses two loops, one to loop through each row, which then loops through three columns in the row, //the column before the shot, the column for the shot and the column after the shot. The same applies //for the rows. If it finds a ship, it knows you are near. //It also does some error checking, as it only allows values that are in the grid. for ( int x = row - 1; x < row + 2; x++ ) { for (int y = column - 1; y < column + 2; y++) { if (x >= 0 && x <= 9 && y >= 0 && y <= 9) { if (board[x][y] == 'A' || board[x][y] == 'B' || board[x][y] == 'S' || board[x][y] == 'D' || board[x][y] == 'P') { console.println("I can tell you, however, that you are close to a ship."); } } } } board[row][column] = 'm'; } else{ console.println("Hit at (" + column + "," + row + ")."); board[row][column] = 'h'; } } Performing Run-length Encoding on the 'Board', possibly useful when saving the game. Performing some Run-length Encoding on the 'Board', possibly useful when saving the game. This would work in a similar way to the 'Generate FEN' question from last year's COMP1 paper. Python Solution: ### Solution programmed by S Wood - Ossett Sixth Form College. #---------- NEW Subroutine - Encodes the Board, uses run-length encoding -------------------------------------- def encodeBoard(Board): print("Saving Shorthand - Game Board: \n") saveFilename = "BattleshipSave(Short).txt" # Gives the SaveFile a specific name (don't forget the .txt extension) longBoard = "" for Row in range(10): # for each of the 10 Rows on the Board. for Column in range(10): # for each of the 10 Columns in that Row. longBoard = longBoard + str(Board[Row][Column]) # add contents of that space to a 'longBoard' string. longBoard = longBoard + "\n" # identifies where each row is separated. print("Long string for each space on Board") # to see what the full thing looks like. print(longBoard) print() #----------------------- COMPLEX - Encodes amount of characters (if more than 1 consecutively e.g. 10- or 4A) print("Encoding...") count = 1 prev = "" shortBoard = str("") # Creates empty string for encoded Board for character in longBoard: # Loops over each character in longBoard (above) if character != prev: # IF not the same as previous character, add to shortBoard string. #if prev: if count == 1: shortBoard = shortBoard + (prev) # IF count is 1 then only add the character else: shortBoard = shortBoard + str(count) # IF more than 1 then add count then character. shortBoard = shortBoard + (prev) count = 1 # count gets reset for new character here. prev = character # previous is now the character just looked at. else: count += 1 else: # This bit covers the final character in the loop. if count == 1: # Could be multiple of that final one so same check as above. shortBoard = shortBoard + (character) else: shortBoard = shortBoard + str(count) shortBoard = shortBoard + (character) print(shortBoard) # print finished board here... # --------- Save this newly encoded format -------------- with open(saveFilename, "w") as SaveFile: # Open the save file in WRITE 'w' mode. SaveFile.writelines(shortBoard) # Write the contents of the current Board Space to the file. SaveFile.close() # Close the file access afterwards. return shortBoard ### NOTE: You will need to call this subroutine from the PlayGame section so that it is actually carried out. ### A student had this question, so we created this solution. Torpedo Function: fires vertically until a ship is hit or a column has been torpedoed. Python Changes have to be made to the subroutine 'PlayGame' as well as creating a new subroutine 'MakeTorpedoMove'. # Author - S Wood - Ossett Sixth #-------------------------------------------------- AMEND 'PlayGame' as shown below def PlayGame(Board, Ships): GameWon = False TorpedoUsed = False # TORPEDO - Added this Boolean value, as torpedo has either been fired or not. while not GameWon: PrintBoard(Board) #----------------- Start of Torpedo adjustments ---------------- if not TorpedoUsed: TorpedoChosen = input("Fire a torpedo? (Y/N)") if TorpedoChosen == "Y": MakePlayerTorpedoMove(Board, Ships) # Calls the new subroutine above. TorpedoChosen = "N" TorpedoUsed = True # Set TorpedoUsed to True, so it cannot be triggered again. else: MakePlayerMove(Board, Ships) # Make a normal move only if the previous conditions are not met. #----------------- End of Torpedo adjustments ------------------ GameWon = CheckWin(Board) if GameWon: print("All ships sunk!") print() #-------------------------------------------------- NEW Subroutine below this line def MakePlayerTorpedoMove(Board, Ships): Row, Column = GetRowColumn() # Fetch Row and Column inputs from this subroutine. # WHILE you have Rows left to hit and there is a miss or an empty space, continue to move Torpedo. while Row > 0 and (Board[Row][Column] == "m" or Board[Row][Column] == "-"): Board[Row][Column] = "m" # Set this new space to a miss. Row = Row - 1 # Move the Row up the grid by 1 space. # IF current position is NOT 'empty' or 'a miss', then it must be a ship or previous hit. if Board[Row][Column] != "-" and Board[Row][Column] != "m": print("Torpedo hits at (" + str(Column) + "," + str(Row) + ").") Board[Row][Column] = "h" # change to position to a hit. # ELSE the Torpedo failed to hit anything in that Column of spaces. else: print("Torpedo failed to hit a ship.")