I'm trying to create a simple two player game like the classic Battleship. Hence I'm beginning to learn Python and I'm keeping it simple. I have created a 5x5 grid and I want the players (2) to be able to place one ship 1x1 anywhere on the board. Then they take turns guessing where the other person placed their ship.
When I compiled my code I got an indent error on line 61 "else: ". I'm aware that the "H" and "M" for hit and miss will overlap since I'm outputting it to the same playing board.
I guess what I need help with is the while loops in my code.
import sys
#////////////////////////////Setting up board////////////////////////////////////
board = []
for x in range(5):
board.append(["O"] * 5)
def print_board(board):
for row in board:
print " ".join(row)
#///////////////////////////Getting input//////////////////////////////////////////
def user_row():
get_row = raw_input("Enter ship row between 1 and 5")
#Not shure if this is the best way of checking that the input is an int
if int(get_row) == False:
print "You must enter an integer between 1 and 5"
get_row = raw_input("Enter ship row...")
if int(get_row) == False:
sys.exit()
def user_col():
get_col = raw_input("Enter ship col between 1 and 5")
if int(get_col) == False:
print "You must enter an integer between 1 and 5"
get_col = raw_input("Enter ship col...")
if int(get_col) == False:
sys.exit()
#/////////////////////////Intro//////////////////////////////////////////////////////
print "Let's play Battleship!"
print "This is your ocean"
print_board(board)
#////////////////////////Placing ships//////////////////////////////////////////////
print "Player 1 your up!"
print "Player 2 look away!"
print "Place your ship..."
#Not shure if this will call the two functions chronologic and store them as index 0 and 1 in my array. That is what I want it to do
user1_ship = [user_row(), user_col()]
print_board(board)
print "Player 2 your up!"
print "Player 1 look away!"
print "Place your ship..."
user_2 = [user_row(), user_col()]
#///////////////////////guesswork?//////////////////////////////////////////////////
#Maybe while loops inside while loops is not the best way of running the code over and over until someone sinks the other persons ship
#What Im expecting is the first inside while loop to break the outer loop if the player hits the other players ship otherwise break itself. Likewise with the second inner loop.
while True:
while True:
print "Player 1 your turn"
user1_guess = [user_row(), user_col()]
if user1_guess == user2_ship:
board[user1_guess[0]][user1_guess[1]] == "H"
print "PLAYER 1 WINS!"
break
else:
board[user1_guess[0]][user1_guess[1]] == "M"
print "You missed"
break
while True:
print "Player 2 your turn"
user2_guess = [user_row(), user_col()]
if user2_guess == user1_ship:
board[user2_guess[0]][user2_guess[1]] == "H"
print "PLAYER 2 WINS!"
break
else:
board[user2_guess[0]][user2_guess[1]] == "M"
print "You missed"
break
Your indentation is incorrect... Look at this:
while True:
while True:
print "Player 1 your turn"
user1_guess = [user_row(), user_col()]
if user1_guess == user2_ship:
board[user1_guess[0]][user1_guess[1]] == "H"
print "PLAYER 1 WINS!"
break
The break statement must have the same indentation as the print statement like this:
while True:
while True:
print "Player 1 your turn"
user1_guess = [user_row(), user_col()]
if user1_guess == user2_ship:
board[user1_guess[0]][user1_guess[1]] == "H"
print "PLAYER 1 WINS!"
break
If you have some time, please read a Python Styleguide to improve the quality of your code.
Related
def random():
x_val = randint(1,100)
limit = []
limit2 = len(limit)
while True:
try:
roll = int(raw_input("Please pick a number: "))
except ValueError:
print "Please input numbers only"
continue
if limit2 <= 5:
if roll > 100 or roll < 1:
print "Exceed Limited Guess"
continue
elif roll < x_val:
limit.append(1)
sleep(1)
print "Your guess is lower!"
continue
elif roll > x_val:
limit.append(1)
sleep(1)
print "Your guess is higher!"
continue
elif roll == x_val:
print limit2
return "You guessed correct! You win!"
break
else:
print "Incorrect Input"
continue
elif limit2 > 5:
return "You guessed over 5 times. You lose, sucker..."
break
elif limit2 == 4:
print "Last guess!"
continue
print "Welcome to my world! You will have to pick a correct number from 1 to 100!
If you can do it within 5 times you win! Otherwise you suck!"
while True:
try:
start = raw_input("Start Rolling? Yes or No: ").lower()
except ValueError:
print "Answer Yes or no"
continue
if start == "y" or start == "yes" or start == "ye":
user2 = random()
print user2
elif start == "n" or start == "no" or start == "noo":
print "Ready when you are"
continue
else:
print "Answer Yes or No"
continue
Hi, I am working on a guessing game from 1-100 that I built from ground up by myself and doing research, my original code is not even close to this.
Now, I am stuck on the last part I cannot use the list to limit the input in while loop. I want to stop the game after 5 guesses. However every time it always keep going and once it win it printed out "0" for limit2 variable.
Thank you
The main problem with your code is that you never update the "counter" of the attempted tries made by the user. You initialize it at the beginning (through limit2 = len(limit)), but you never update that value, therefore causing an endless loop.
You simply need to perform the check on len(limit) instead of on limit2.
Working solution can be found below. I took the liberty of commenting limit2 (as it is not needed anymore), improving the indentation, adding two imports, replacing sleep with time.sleep, and fixing the number of checks to perform (if you are aiming at 5 maximum tries, len(limit) needs to be less than 5).
from random import randint
import time
def random():
x_val = randint(1,100)
limit = []
# limit2 = len(limit)
while True:
try:
roll = int(raw_input("Please pick a number: "))
except ValueError:
print "Please input numbers only"
continue
if len(limit) < 5:
if roll > 100 or roll < 1:
print "Exceed Limited Guess"
continue
elif roll < x_val:
limit.append(1)
time.sleep(1)
print "Your guess is lower!"
continue
elif roll > x_val:
limit.append(1)
time.sleep(1)
print "Your guess is higher!"
continue
elif roll == x_val:
print len(limit)
return "You guessed correct! You win!"
break
else:
print "Incorrect Input"
continue
elif len(limit) >= 5:
return "You guessed over 5 times. You lose, sucker..."
break
print "Welcome to my world! You will have to pick a correct number from 1 to 100! If you can do it within 5 times you win! Otherwise you suck!"
while True:
try:
start = raw_input("Start Rolling? Yes or No: ").lower()
except ValueError:
print "Answer Yes or no"
continue
if start == "y" or start == "yes" or start == "ye":
user2 = random()
print user2
elif start == "n" or start == "no" or start == "noo":
print "Ready when you are"
continue
else:
print "Answer Yes or No"
continue
Worthy of note is that -- among several other things that should be fixed in your code -- you should avoid calling a function random, since it is already a name used by a very common module.
def main_menu():
print ("Three Doors Down Figurative Language Game")
print ("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
print ("NOTE: TO SELECT, TYPE NUMBER OF OPTION")
print ("")
print (" 1) Begin Game")
print ("")
print (" 2) Options")
print ("")
print ("")
menu_selection()
def menu_selection():
valid_answer = ["1","2"]
user_choice = str(input("Make a choice.."))
if user_choice in valid_answer:
def check_valid(user_choice):
if user_choice == 1: #Error section V
return("You started the game.")
else:
user_choice != 1
return("Credits to ____, created by ____")
check_valid(user_choice) #Error Section ^
else:
print("Please use an actual entry!")
menu_selection()
def enterText():
print("ENTER ANSWER!")
print (main_menu())
Okay, so the error should be labeled. That specific if/else statment shows up as "None" and I have tried every method to fix it. One method worked for the if/else statement on the outside, but not this one.
You're taking input as a string str(input()). Then, you're checking if user_input == 1; testing to see if it is an integer, even though it is a string. Instead, try converting to an integer using int(input()). Also, the line user_input != 1 is unnecessary, it's just the equivalent of writing True in your code. Furthermore, you define a function in your if statement, which shouldn't be there:
def main_menu():
print ("Three Doors Down Figurative Language Game")
print ("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
print ("NOTE: TO SELECT, TYPE NUMBER OF OPTION")
print ("")
print (" 1) Begin Game")
print ("")
print (" 2) Options")
print ("")
print ("")
menu_selection()
def menu_selection():
valid_answer = ["1","2"]
user_choice = int(input("Make a choice.."))
if user_choice in valid_answer:
if user_choice == 1:
return("You started the game.")
else:
return("Credits to ____, created by ____")
check_valid(user_choice)
else:
print("Please use an actual entry!")
menu_selection()
def enterText():
print("ENTER ANSWER!")
print (main_menu())
Error:
Traceback (most recent call last):
File "ex36.py", line 100, in <module>
start()
File "ex36.py", line 16, in start
giant()
File "ex36.py", line 59, in giant
dead()
File "ex36.py", line 70, in dead
try_again()
File "ex36.py", line 85, in try_again
if "y" in user_input or "yes" in user_input:
TypeError: argument of type 'function' is not iterable
This is the code block that is getting the error:
def try_again():
print "Would you like to try again?"
user_input = uput
if "y" in user_input or "yes" in user_input:
start()
elif "n" in user_input or "no" in user_input:
sys.exit()
else:
try_again()
I think I am getting the error because it is recursive function but I use them through out the game and they worked untill I added try_again().
Here is the rest of the code in case it helps:
# Role Playing Game I made to practice my Python skills!
import sys
def uput(): # get user input and make it all lowercase
return raw_input("> ").lower()
def start(): #Starts the game
print "You are in room with a left and right door."
print "Which do you choose?"
user_input = uput()
if user_input == "left":
print "You open the door..."
lavapit()
elif user_input == "right":
print "You open the door..."
giant()
else:
print "Try again." + "\n" * 3
start()
def lavapit():
print "Your on the edge of valcano."
mountain(10)
print "One wrong step and you fall into the volcano!"
print "You can walk along the edge to the other side and take the path down to the base"
print "Or return to the room!"
user_input = uput()
if "walk" in user_input or "along" in user_input or "edge" in user_input:
print "You stumble."
print "And fall off into the lava!"
dead()
elif "return" in user_input or "door" in user_input or "go back" in user_input:
start()
else:
print "Try again." + "\n" * 3
lavapit()
def giant():
print "You enter a dark musty room."
print "With very high ceilings."
print "Then you hear... heavy breathing."
print "Do you walk slowly and quitely to your right or left."
right = 0
left = 0
while right <= 4 or left <= 5:
user_input = uput()
if "right" in user_input and right < 3:
print "You edge slowly to the right."
right += 1
left -= 1
elif "left" in user_input and left < 4:
print "You edge closer to the left."
right -= 1
left += 1
elif "right" in user_input and right > 2:
print "You bump into the giant and get eaten alive."
print "The giant says, 'Yum'."
dead()
elif "left" in user_input and left > 3:
print "You reach a dark hole in the wall the size of giant mouse."
print "Do you enter it?"
hole()
else:
print "Try again." + "\n" * 3
giant()
def dead():
print "-" * 30
print "Sorry you loose!"
try_again()
def hole():
user_input = uput()
if "yes" in user_input or "y" in user_input:
print "Congratulations! You won nothing!"
try_again()
elif "no" in user_input or "n" in user_input:
return
else:
hole()
def try_again():
print "Would you like to try again?"
user_input = uput
if "y" in user_input or "yes" in user_input:
start()
elif "n" in user_input or "no" in user_input:
sys.exit()
else:
try_again()
def mountain(x):
i = 2
while x > 0:
print " " * x + "#" * i
x -= 1
i += 2
start()
The problem is that in the second line of the body of the function try_again you're not calling uput, you're assigning it to user_input. You forgot the parenthesis, if you change it to this:
def try_again():
print "Would you like to try again?"
user_input = uput()
if "y" in user_input or "yes" in user_input:
start()
elif "n" in user_input or "no" in user_input:
sys.exit()
else:
try_again()
it will work.
Reading the traceback:
TypeError: argument of type 'function' is not iterable
The message is telling you that you tried to do an iteration over user_input, the iteration happened because of the in statement.
Whenever an output should result in a change of shield, the program just says 'You have 5 shields' followed by 'You Win'. I think I might have made a mistake when passing over the variables from one function to the next. Thank you in advance for the help!
def main():
while TakeTurn(word,shield) == False:
if shield == 1:
word1 = "shield"
else:
word1 = "shields"
print ("You have", shield, word1,)
if shield < 1:
print ("Sorry! You ran out of shields! You lose!")
else:
print ("You win")
#This function is the actual 'game' and will deterine what happens to the character
def TakeTurn(word1,shield1):
time.sleep(1.5)
#This means that when the user reaches 0 shields, they lose.
if shield1 < 1:
return True
#Whatever the user inputs will not actually affect the outcome
print ("You have reached", word1 ,"junction.\nDo you want to turn left (L), turn right (R) or go straight ahead(S)?")
turning = input()
#This is a simple instruction that means that the first time you come to a junction, it will say 'a junction' but the second time it will say 'another junction'
word1 = "another"
#This 'if' statement means that the program will only continue if the user has inputed the letters 'L', 'R' or 'S'
elif turning not in ["L","R","S","l","r","s"] :
time.sleep (0.7)
print ("Sorry, I didn't understand that")
TakeTurn()
else:
choice = randint (1,10)
#This is just going to display a random message which will affect the outcome
time.sleep (1)
if choice == 1:
print ("You have found the exit!")
return True
elif choice == 2:
print ("You have found a shield!")
time.sleep(1)
shield1 = shield1 +1
return False
elif choice == 3:
print ("You have found two shields!")
time.sleep(1)
shield1 = shield1 +2
return False
elif choice == 4:
print ("You have found three shields!")
time.sleep(1)
shield1 = shield1 +3
return False
elif choice == 5:
print ("A fairy has jumped into your pants!")
time.sleep(2)
print ("You lose two shields")
time.sleep(1)
shield1 = shield1 -2
return False
elif choice == 6:
treasurechest(shield1)
return False
elif choice == 7:
print ("You have tripped over a log!")
time.sleep(2)
print ("You lose a shield")
time.sleep(1)
shield1 = shield1 -1
return False
elif choice == 8:
print ("An angry teenager is staring at you in the eye.")
time.sleep(2.5)
print ("He uses laziness...")
time.sleep(1.5)
print ("It's super effective!")
time.sleep(1)
print ("You lose three shields")
time.sleep(1)
shield1 = shield1 -3
return False
elif choice == 9:
print ("You have encountered an ogre...")
time.sleep(1.5)
print ("He bashes you over the head with a steel bar")
time.sleep(2)
print ("You lose two shields")
time.sleep(1)
shield1 = shield1 -2
return False
else:
print ("A goblin aproaches and says the following:")
time.sleep(2)
goblin(shield1)
return False
You should refactor main and TakeTurn to make shield and word explicit arguments and return values. This prevents relying on scope for access to variables, without having to use global (which is usually a bad sign):
def main(shield, word):
while True:
shield, word, finished = TakeTurn(shield, word)
if finished:
break
word1 = "shield" if shield == 1 else "shields"
print ("You have {0} {1}".format(shield, word1))
if shield < 1:
print ("Sorry! You ran out of shields! You lose!")
else:
print ("You win")
And have TakeTurn return multiple values accordingly, e.g.:
elif choice == 3:
print ("You have found two shields!")
time.sleep(1)
shield1 = shield1 + 2
return shield1, word1, False
You could make things neater by making choices a list of dictionaries and picking randomly from it:
choices = [{"texts": [("You have found two shields!", 1)],
"shield change": 2, "return": False},
{"texts": [("You have encountered an ogre...", 1.5),
("He bashes you over the head with a steel bar", 2),
("You lose two shields", 1)],
"shield change": -2, "return": False},
...]
Then your main section, instead of all the elifs, becomes simply:
choice = random.choice(choices)
for text, sleep_time in choice['texts']:
print(text)
time.sleep(sleep_time)
shield1 += choice['shield change']
return shield1, word1, choice['return']
I was just introduced to python less than a week ago and I'm trying to make a simple game of blackjack. I've written out the core of the program and it seems that it's ignoring the raw input, and just continually looping through the for conditional. It doesn't matter if what I type, hit, stay, whatever. Here's the code:
def main_game():
number = random.randint(1,13)
card_type_number = random.randint(1,4)
total = 0
dealer = random.randint(1,21)
input = raw_input("Would you like to Hit or Stay? \n")
if input == "hit" or "Hit":
card_number = numberConverter(number)
card_type = typeConverter(card_type_number)
new_amount = number
print "You got a %s of %s. You currently have %s. \n" % (card_number, card_type, number)
total += number
number = random.randint(1,13)
card_type_number = random.randint(1,5)
main_game()
elif input == ("Stay" or "stay") and total == 21:
print "Holy Cow! A perfect hand!"
main_game()
elif input == ("Stay" or "stay") and total < dealer:
print "Sorry, the dealer had %s" % (dealer)
maingame()
elif input == ("Stay" or "stay") and total > 21:
print "Sorry, you have more than 21"
main_game()
else:
print "Could you say again?"
main_game()
I'm at a loss and would appreciate any help.
Thanks!
if input == "hit" or "Hit":
That means if (input == "hit") or ("Hit"), which is always true.
Try
if input == "hit" or input == "Hit":
Or
if input in ("hit", "Hit"):
Or, even better:
if input.lower() == "hit"
(same for all the other elifs)