I'm nearing the end of a lesson on creating a very simple battleship game. Basically you get 4 chances to guess the location of the ship. if you lose: game over. If you win before all 4 chances you're supposed to end the game using a "break" function.
Problem is: After inserting "break", I get an error msg reading:
File "python", line 33
SyntaxError: 'break' outside loop
Here is my code, please and thank you for any help it is much appreciated:
from random import randint
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
print "Let's play Battleship!"
print_board(board)
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
print ship_row
print ship_col
turn = 1
for turn in range(4):
print turn
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
print "Oops, that's not even in the ocean."
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
print turn + 1
print_board(board)
if turn == 3:
print "Game Over"
Your break is outside the loop indeed. Try to fix indentation in if-else statement on line 31 like this:
for turn in range(4):
...
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
...
Related
I'm making a 2-play Battleship game in python and have been struggling with this for a while now:
I apologise if the question is poorly worded but I was to know how I can make my game log the match score at the end of the three games with something like:
print('Match score is' + score + 'Player' + (whoever) + 'wins!)
I'm not entirely sure how to implement this myself I have a range for games in range(3), but I don't know how to log the final score.
Also, how can I change the symbol for player_two so that I am not using an 'X' for both players? I've tried changing the input_check() but I get more errors than I did before.
from random import randint
game_board = []
player_one = {
"name": "Player 1",
"wins": 0,
"lose": 0
}
player_two = {
"name": "Player 2",
"wins": 0,
"lose": 0
}
# Building our 5 x 5 board
def build_game_board(board):
for item in range(5):
board.append(["O"] * 5)
def show_board(board):
print("Find and sink the ship!")
for row in board:
print(" ".join(row))
# Defining ships locations
def load_game(board):
print("WELCOME TO BATTLESHIP!")
print("START")
del board[:]
build_game_board(board)
show_board(board)
ship_col = randint(1, len(board))
ship_row = randint(1, len(board[0]))
return {
'ship_col': ship_col,
'ship_row': ship_row,
}
ship_points = load_game(game_board)
# Players will alternate turns.
def player_turns(total_turns):
if total_turns % 2 == 0:
total_turns += 1
return player_one
else:
return player_two
# Allows new game to start
def play_again():
global ship_points
answer = input("Would you like to play again? ")
if answer == "yes" or answer == "y":
ship_points = load_game(game_board)
else:
print("Thanks for playing!")
exit()
# What will be done with players guesses
def input_check(ship_row, ship_col, player, board):
guess_col = 0
guess_row = 0
while True:
try:
guess_row = int(input("Guess Row:")) - 1
guess_col = int(input("Guess Col:")) - 1
except ValueError:
print("Enter a number only: ")
continue
else:
break
match = guess_row == ship_row - 1 and guess_col == ship_col - 1
not_on_game_board = (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4)
if match:
player["wins"] += 1
print("Congratulations! You sunk my battleship!")
print("Thanks for playing!")
play_again()
elif not match:
if not_on_game_board:
print("Oops, that's not even in the ocean.")
elif board[guess_row][guess_col] == "X":
print("You guessed that one already.")
else:
print("You missed my battleship!")
board[guess_row][guess_col] = "X"
show_board(game_board)
else:
return 0
def main():
begin = input('Type \'start\' to begin: ')
while (begin != str('start')):
begin = input('Type \'start\' to begin: ')
for games in range(3):
for turns in range(6):
if player_turns(turns) == player_one:
# print(ship_points)
print("Player One")
input_check(
ship_points['ship_row'],
ship_points['ship_col'],
player_one, game_board
)
elif player_turns(turns) == player_two:
print("Player Two")
input_check(
ship_points['ship_row'],
ship_points['ship_col'],
player_two, game_board
)
if turns == 5:
print("The game is a draw")
play_again()
if __name__ == "__main__":
main()
You can use style string formatting to print the log.
print('Match score is %d : %d(Player1 : Player2)' % (player_one["wins"], player_two["wins"]))
For more information about string formatting, check this link.
To change the symbol for Player 2, you can change the following code.
elif board[guess_row][guess_col] == "X" or board[guess_row][guess_col] == "Y":
print("You guessed that one already.")
else:
print("You missed my battleship!")
if player == player_one:
board[guess_row][guess_col] = "X"
else:
board[guess_row][guess_col] = "Y"
I am currently making a simple Battleships game using Python 3, but I can't seem to get the board to display. Here is my code;
# Battleships
def main():
pass
if __name__ == '__main__':
main()
from random import randint
# this initialises the board
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print (" ".join(row))
# this starts the game and prints the board
print ("Let's play Battleship!")
print_board(board)
# defines the location of the ship
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
# asks the player to make a guess
for turn in range(5):
guess_row = int(input("Guess Row:"))
guess_col = int(input("Guess Col:"))
# if the player guesses correctly, then the game ends cleanly
if guess_row == ship_row and guess_col == ship_col:
print ("Congratulations! You sunk my battleship!")
else:
# if the player guesses outside the board, then the following message appears
if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
print ("Oh dear, you've hit an island!")
# a warning if the guess has already been made by the player
elif(board[guess_row][guess_col] == "X"):
print ("That guess has already been made.")
# if the guess is wrong, then the relevant board place is marked with an X
else:
print ("You've missed my battleship!")
board[guess_row][guess_col] = "X"
# prints the turn and updates the board accordingly
print ("Turn " + str(turn+1) + " out of 5.")
print_board(board)
# if the user has had 5 guesses, it's game over
if turn >= 3:
print ("You sunk my battleship! We're gonna need a bigger boat.")
The game accepts the co-ordinates, but doesn't print anything to do with the board or if the player makes a repeated guess or one that's outside the field of play.
Any help would be much appreciated!
Your code asks for 5 sets of guesses before it does anything with them, because the code to respond to a guess is outside of the loop asking for the guesses. I'm, ahem, guessing that in your testing you never entered enough guesses to get past that loop. Move the guess-processing code into the loop, and you should at least see reactions to those guesses.
You are iterating over the loop THEN all the if statements. Put all the if statements inside the for loop. Add a counter saying if you hit my ship add one point (score += 1) then
if score >= 3:
print ("You sunk my battleship! We're gonna need a bigger boat.")
import random
from datetime import date
grid = []
def createGrid():
global grid
grid = []
for i in range(0,10):
grid.append([])
for j in range(0,10):
grid[i].append("W")
def renderGrid():
global grid
for i in range(0,10):
for j in range(0,10):
block = grid[i][j]
if block == "s": block = "W"
print(block,end=" ")
print()
print()
def placeGrid():
xsize = 10
ysize = 10
shipBlocks = 17
length = 2
submarineException = True
while shipBlocks > 0:
x = random.randint(0,xsize-1)
y = random.randint(0,ysize-1)
value = 1
cx = 0
cy = 0
if random.randint(0,1) == 1:
value = -value
if random.randint(0,1) == 1:
cx = value
else:
cy = value
broken = False
for b in range(0,length):
xpos = x+cx*b
ypos = y+cy*b
if xpos<0 or xpos>xsize-1 or ypos<0 or ypos>ysize-1: broken = True
if broken: continue
for b in range(0,length):
grid[x+cx*b][y+cy*b] = "s"
shipBlocks = shipBlocks - length
if length == 3:
if submarineException:
submarineException = False
else:
length+=1
else:
length+=1
def runGame():
name = input("Enter your username: ")
global grid
createGrid()
placeGrid()
hits = 0
while True:
won = True
for row in grid:
for character in row:
if character == "s":
won = False
if won:
print("You have won the game in "+str(hits)+" hits!")
renderGrid()
y = input("Hit X: ")
x = input("Hit Y: ")
try:
x = int(x)-1
y = int(y)-1
if x < 0 or y < 0:
raise
if grid[x][y] == "s":
grid[x][y] = "S"
print("Ship hit.")
elif grid[x][y] == "S":
print("You already hit here.")
continue
hits+=1
except Exception as e:
print("Error, number from 1 to 10 please.")
#stackoverflow saves lives
runGame()
This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 7 years ago.
I'm having issues with this code, when i run the code, it always prints "Oops, that's not even in the ocean." no matter what i type. Also if i write letters the code crashes. How can i add a typo check fonction that could solve the crash and make the code resistant from typos from the user. Thank you in advance !
from random import randint
#initializing board + this is my list
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
#starting the game and printing the board
print "Let's play Battleship!"
print_board(board)
#defining where the ship is
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
#asking the user for a guess
for turn in range(4):
guess_row = raw_input("Guess Row:")
guess_col = raw_input("Guess Col:")
# if the user's right, the game ends
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
#warning if the guess is out of the board
if (guess_row < 0 or guess_row > 5) or (guess_col < 0 or guess_col > 5):
print "Oops, that's not even in the ocean."
#warning if the guess was already made
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
#if the guess is wrong, mark the point with an X and start again
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
# Print turn and board again here
print "Turn " + str(turn+1) + " out of 4."
print_board(board)
#if the user have made 4 tries, it's game over
if turn >= 3:
print "Game Over"
Your problem lies in the fact that raw_input returns a string, you need to cast it to an integer like this:
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
So I've been going through Codecademy's Python lessons. I enjoyed the Battleship game I created in one of the lessons, but one thing annoyed me. The player has to constantly keep in mind that the rows and columns count 0-4 rather than 1-5. I've already made an attempt to fix this, but I'm not sure if it's messing with my ship placement.
Here's my original code:
from random import randint
#Create 5x5 game board
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
#Start game
print "Let's play Battleship!"
print_board(board)
#Randomly place ship
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
#Process player guesses max 4 turns
for turn in range(4):
print "Turn: %d" % (turn + 1)
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
print "Oops, that's not even in the ocean."
print_board(board)
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
print_board(board)
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
print_board(board)
if turn > 2:
print "Game Over"
Here's my attempt to change the board count:
from random import randint
#Create 5x5 game board
board = ['dummy']
for x in range(5):
board.append(["O"] * 6)
def print_board(board):
for row in board:
print " ".join(row[1:])
#Start game
print "Let's play Battleship!"
print_board(board[1:])
#Randomly place ship
def random_row(board):
return randint(1, len(board[1:]) - 1)
def random_col(board):
return randint(1, len(board[1:]) - 1)
ship_row = random_row(board[1:])
ship_col = random_col(board[1:])
print "%d,%d" % (ship_row, ship_col)
#Process player guesses max 4 turns
for turn in range(4):
print "Turn: %d" % (turn + 1)
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
if (guess_row < 1 or guess_row > 5) or (guess_col < 1 or guess_col > 5):
print "Oops, that's not even in the ocean."
print_board(board[1:])
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
print_board(board[1:])
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
print_board(board[1:])
if turn > 2:
print "Game Over"
The print "%d,%d" % (ship_row, ship_col) is only in there so I can test the ship placement. I haven't seen a ship placed in a position higher than 3 on rows or columns. Not sure if I screwed the code or if it's just dumb luck. Any insight is appreciated and if you know an easier to accomplish this please let me know. I've been thinking guess_row = int(raw_input("Guess Row:")) - 1 but haven't tested it yet.
Well sometimes the obvious answer is the right one.
I changed:
for turn in range(4):
print "Turn: %d" % (turn + 1)
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
To:
for turn in range(4):
print "Turn: %d" % (turn + 1)
guess_row = int(raw_input("Guess Row:")) - 1
guess_col = int(raw_input("Guess Col:")) - 1
This allows the player to enter a choice of 1-5 rather than 0-4
This is the "Battleship!" problem that is covered in Codecademy (Python) I want to put a condition wherein the number of turns does not get incremented in the case that the user enterers a value of row/column that is repeated or outside limits. I can't figure out what the problem is in this code:
from random import randint
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
print "Let's play Battleship!"
print_board(board)
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
print ship_row
print ship_col
# Everything from here on should go in your for loop!
for turn in range(4):
# Be sure to indent four spaces!
print "Turn", turn + 1
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
break
else:
if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
print "Oops, that's not even in the ocean."
print "Please try again."
# turn -= 1 Why doesn't this work? The "Game Over" message does not get displayed at the end of the game if such a case arises (but the game still ends!), which means the value of turn does not reach 3. But still when 'turn + 1' is printed, the value gets incremented even if such a condition is encountered.
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
print "Please try again."
# turn -= 1 Same as last message.
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
if turn == 3:
print "Game Over"
# Print (turn + 1) here!
print_board(board)
There is only a very small error in your code, from what I can see. The last if statement, which includes your "Game Over" string, is indented incorrectly. Move it left one block:
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
if turn == 3:
print "Game Over"
# Print (turn + 1) here!
print_board(board)
Here is my complete code from that exercise:
from random import randint
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
print "Let's play Battleship!"
print_board(board)
def random_row(board):
return randint(0, len(board) - 1)
def random_col(board):
return randint(0, len(board[0]) - 1)
ship_row = random_row(board)
ship_col = random_col(board)
print ship_row
print ship_col
for turn in range(4):
print "Turn", turn + 1
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
if guess_row == ship_row and guess_col == ship_col:
print "Congratulations! You sunk my battleship!"
else:
if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
print "Oops, that's not even in the ocean."
elif(board[guess_row][guess_col] == "X"):
print "You guessed that one already."
else:
print "You missed my battleship!"
board[guess_row][guess_col] = "X"
print_board(board)
if turn == 3:
print "Game Over"
A for turn in range(4): loop doesn't work the way you think it does.
It's equivalent to this:
_range = [0, 1, 2, 3]
_it = iter(_range)
while True:
try:
turn = next(_it)
except StopIteration:
break
# your code here
You don't have to understand all of the details there, but they key point is that, each time through the loop, it's assigning a new value to turn, which comes straight out of the iterator, and has nothing to do with the old value of turn. So, your changes to turn are irrelevant.
So, how do you fix it?
One way is to replace the for loop with a while loop that explicitly maintains turn, so you can explicitly decrement it—or, better, just not increment it. For example:
turn = 0
while turn < 4:
# your code, slightly modified
# do turn += 1 only when the turn is valid
# don't do turn += 1 when the turn is invalid
The other way is to put another loop inside this for loop that just repeats until the player makes a valid turn:
for turn in range(4):
while True:
# your code, slightly modified
# do break only when the turn is valid
# do nothing, or continue, when the turn is invalid
While I'm at it, there's another problem in your code.
That if turn == 3 part is either wrong, or unnecessary. The game is over when the player is out of turns. You know the player is out of turns when you finish the loop. You don't need any extra test for it. So:
for or while or whatever:
# stuff
print "Game Over"