1
提前爲數據轉儲道歉。我正在用Python重新創建戰艦遊戲。我在def battleship
函數中遇到了麻煩,計算機和用戶試圖猜測彼此的座標。計算機正確猜測用戶座標的概率爲e/x
,其中e是剩餘船舶的數量,x是未知座標的數量。問題在於,如果用戶錯過了,我怎樣才能訪問本地變量x
,當用戶打出一個命中時,該變量被分配一個值?由於這是一個遞歸函數,因此如果用戶未命中,則不定義x
。我仍然希望計算機在用戶錯過時猜測玩家的戰艦位置。但是,我收到的錯誤消息是:local variable 'x' referenced before assignment
Python戰列艦遊戲,遞歸故障
感謝您的耐心等待。似乎應該有一個簡單的解決方案。
import random
import sys
globalValue=0 #for length of hitlist
loopcondition=True
compdestruction=0 #keep track of number of destroyed ships
userdestruction=0
destroyedships=[];
hitlist=[]; #a global variable
#to end the program
you=[];
youhitship=[];
class Battleship(object):
""" Ship object container. A game where the user tries to destroy the enemy's ships User tries to guess computer's position x and y """
def __init__(self, size, numberships,position_x,position_y):
self.position_x=position_x
self.position_y=position_y
self.numberships=numberships
self.size = size
def plotships(self,numberships):
"""input is integer coordinates for ships and output is an array of arrays with battleship locations CREATES THE HITLIST DONT REPEAT"""
while len(hitlist)<numberships:
r=Battleship.randomness(self)
if r not in hitlist:
hitlist.append(r)
originalhitlist=len(hitlist)
global globalValue
globalValue+=originalhitlist
def destroy(self):
""" Destroys the ship's point supplied if it contains it """
compChoose=Battleship.randomness(self) #computer's attak pair
print('computer choice is '+str(compChoose))
ship=[self.position_x,self.position_y]
print('Your Turn...')
if ship in hitlist:
print('Direct hit Captain')
global userdestruction
hitlist.remove(ship)
userdestruction+=1
CompWreck=GameBoard(self.size)
CompWreck.update(ship,self.size, destroyedships) #empty (at first) lists with coordinates of up-to-date list of destroyed ships
else:
print('Drat! missed!')
print('\nComps Turn')
if compChoose in you:
print('Kabloom. Your ships sunk.')
global compdestruction
you.remove(compChoose)
compdestruction+=1
YourWreck=GameBoard(self.size) #create an instance of GameBoard
YourWreck.update(ship,self.size,youhitship)
else:
print('Yay! The computer missed!\n')
def randomness(self):
"""random coordinates for computer firing and computer ship location"""
rand_x=random.choice(range(self.size))
rand_y=random.choice(range(self.size))
randcoord=[rand_x,rand_y]
return randcoord
class GameBoard(object):
""" The container for the ships """
def __init__(self, size):
"""Initialize clean GameBoard depending on size, etc """
self.size=size
self.destroyed = 'x' # representation for destroyed area
self.clear = '-' # representation for clear water
def printBoard(self,destroytheseships):
""" Print the current gameboard state"""
global compdestruction
global userdestruction
global globalValue
global loopcondition
graf='' #printed board
x=-1 #so the first row is 0, within the range of hitlist coordinates defined in Battleship.plotships(self)
for row in range(self.size): #for every row inside the first set of brackets
x+=1 #x,y pairs mark the possible ship locations
graf+='\n'
y=-1 #so the first column is 0
for column in range(self.size):
y+=1
if [x,y] in destroytheseships:
graf+=self.destroyed
else:
graf+=self.clear
print(graf)
if userdestruction == globalValue:
print('You Win!')
sys.exit('Game Over')
if compdestruction>=originalyou:
print('You Lose' )
sys.exit('Game Over')
def update(self,ship,size,witchlist):#It matter whether it's computer or user's turn. WITCHLIST defines which list you're choosing from
""" Updates the gameboard according to updated ship """
witchlist.append(ship)
newboard=GameBoard(size) #create a new instance with the same sized board
newboard.printBoard(witchlist)
#Game Interface do it once
size=int(input('Gameboard size'))
numberships=int(input('Waiting for Number of enemy ships'))
b=Battleship(size,numberships,0,0)
b.plotships(numberships) #create a hitlist and returns the original length of hitlist array
for i in range(numberships): #create list of your ships
you_x=int(input('Please enter a X coordinate for your ship'))
you_y=int(input('Please enter a Y coordinate for your ship'))
if ((you_x not in range(0,size)) or (you_y not in range(0,size))):
print('please chooose a different pair of coordinates within board boundaries\n')
continue
your_xy=[you_x,you_y]
you.append(your_xy)
originalyou=len(you)
while loopcondition==True: #take another turn as long as all the ships are not destroyed
ex=int(input('Waiting for attack X coordinate'))
why=int(input('Waiting for attack Y coordinate'))
if ((ex not in range(0,size)) or (why not in range(0,size))):
print('please chooose a different pair of coordinates within board boundaries\n')
continue
b=Battleship(size,numberships,ex,why)
b.destroy()
爲了讓這個任務更容易處理,我建議使用類重構你的代碼。一個好的骨架可以作爲這篇文章的答案可以找到: http://stackoverflow.com/questions/20179953/simple-battleships-game-implementation-in-python 使用類將使這個問題更容易使用並更簡單地添加新功能。 – NicolaiF
把這個壓縮到[mcve]不僅會使這個問題更容易回答,還可能導致你自己回答問題。 (這也會迫使你將這個超級函數分割成更小的塊,這隻能幫助你。) –
我按照你的建議重構了代碼,謝謝! – st4rgut