Reputation: 33
I have created a battleship like game, and have it all completed except for one detail.
I have the following input statement: x, y = input("Enter two numbers here: ").split() with the 2 numbers being entered corresponding to the players chosen coordinates. I also need to be able to handle the entry of 'q' or 'h' for the quit or help options. However, since i am taking two variables from this statement when only a q or h is entered i get the error that the statement needs 2 elements to unpack, which makes sense. Any pointers on how to get around this?
import random, math
class oceanTreasure:
def __init__(self):
self.board = self.board()
self.found = 0
self.left = 3
self.sonarsLeft = 20
self.chests= []
self.chest()
def board(self):
board = []
for x in range(16): # the main list is a list of 60 lists
board.append([])
for y in range(61): # each list in the main list has 15 single-character strings.
board[x].append('~')
return board
def chest(self):
chest1 = [random.randint(0,60), random.randint(0,15)]
chest2 = [random.randint(0,60), random.randint(0,15)]
chest3 = [random.randint(0,60), random.randint(0,15)]
self.chests = [chest1, chest2, chest3]
def getChestsLeft(self):
return self.found
def getChests(self):
return self.chests
def getTreasuresLeft(self):
return self.left
def getSonarsLeft(self):
return self.sonarsLeft
def dropSonar(self,x,y):
ySonar = ['a','b','c','d','e','f','g']
whichAxis, axis = self.checkDistance(x,y)
if whichAxis == True:
sonar = axis
if whichAxis == 'xaxis':
sonar = axis
elif whichAxis == 'yaxis':
sonar = ySonar[axis-1]
elif whichAxis == None:
sonar = axis
self.board[int(y)][int(x)] = sonar
self.sonarsLeft -=1
return axis
def checkDistance(self,x,y):
closest = self.chests[0]
distance = 100
for chest in self.chests:
temp = math.sqrt(math.pow((chest[0]-int(x)),2) + math.pow((chest[1]-int(y)),2))
if temp < distance:
closest = chest
distance = temp
xaxis =math.fabs((closest[0] - int(x)))
yaxis = math.fabs((closest[1]-int(y)))
if yaxis == 0 and xaxis == 0:
self.chests.remove(closest)
self.found +=1
self.left -=1
return True, 'X'
elif xaxis <= 9 and yaxis <=5 :
if yaxis == 0 :
return 'xaxis',int(math.fabs(xaxis))
if xaxis == 0 :
return 'yaxis',int(math.fabs(yaxis))
if min(xaxis//2,yaxis) ==(xaxis//2) :
return 'xaxis', int(math.fabs(xaxis))
elif min(xaxis//2,yaxis) == (yaxis) or xaxis == 0 :
return 'yaxis', int(math.fabs(yaxis))
else: return None,0
def drawBoard(self):
firstLine = ' '
for i in range(1,7):
firstLine += (' '*9) + str(i)
print(firstLine)
secondLine = ' '
secondLine += ('0123456789' *6)
print(secondLine)
print()
i = 0
for i in range(0,16):
boardRow = ''
for x in range(0,61):
boardRow += str(self.board[i][x])
if i < 10:
print(str(i) +' ' + str(boardRow) + str(i))
if i >= 10:
print(str(i) +' ' + str(boardRow) + str(i))
print()
print(secondLine)
print(firstLine)
device = 'devices'
if self.sonarsLeft ==1:
device = 'device'
print('You have %s sonar %s availabe. You have found %s treasures and have %s left' %(self.sonarsLeft, device, self.found, self.left))
ocean = oceanTreasure()
ocean.drawBoard()
gameOver = False
instructionsList = ['This is a treasure hunting game.' , 'You begin the game with 20 sonar devices available (each device has a range of 9 units in the x axis and 5 in the y axis).','When you place a device, if an "O" is displayed that means there are no chests in range.', 'If a number from 1-9 is displayed, the closest chest is within n units away on the X axis.', 'If a letter from a-e is displayed, the closest chest is n units away on the Y axis (a =1, b =2 and so on...).', 'The game ends when you run out of sonar devices, all the treasure is found or you enter "q" to quit.', 'Thanks for playing and happy hunting!']
while ocean.getTreasuresLeft() != 0 and ocean.getSonarsLeft() >0 and gameOver == False:
response = False
coordinate = False
while response == False:
inputString = input("Enter two numbers seperated by a space (X Y): ")
if inputString == 'q':
gameOver = True
response = True
elif inputString == 'h':
for instruction in instructionsList:
print(instruction)
response = True
else:
try:
x,y = inputString.split()
assert int(x) <=60 and int(y) <=15
response = True
coordinate = True
except AssertionError:
print('Please enter a valid move')
if gameOver == True:
break
#whichAxis, axis =ocean.checkDistance(x,y)
#print(axis)
if coordinate == True:
axis = ocean.dropSonar(x,y)
ocean.drawBoard()
if axis == 'X':
print('Congratulations, you have found a treasure!')
if ocean.getTreasuresLeft() == 0:
print('Congratulations, you found all the treasure')
elif ocean.getSonarsLeft() == 0:
print('Sorry, you ran out of sonar devices, the remaining chests were: %s ' % str(ocean.getChests()))
Upvotes: 0
Views: 284
Reputation: 159
You can just separate the input:
# get the input
ipt = input("Enter two numbers here: ")
# check if your option is entered
if ipt == 'q' or ipt == 'h':
# do something
else:
x,y = ipt.split()
Upvotes: 0
Reputation: 358
may be this, for example:
a = input("text")
b = a.split()
if len(b) == 1:
if b[0] == 'q':
return
elif b[0] == 'h':
print 'it is help ... '
elif len(b) == 2:
# process for two inputted numbers
Upvotes: 1
Reputation: 1705
How about separating the tests to be a little clearer:
input_string = input("Enter two numbers here: ")
if input_string == 'q':
do_quit()
elif input_string == 'h':
do_help()
else:
x,y = input_string.split()
That way you can test for your special cases, and process the x and y if they are not found.
Upvotes: 4