2016-09-06 95 views
1

提前为数据转储道歉。我正在用Python重新创建战舰游戏。我在def battleship函数中遇到了麻烦,计算机和用户试图猜测彼此的坐标。计算机正确猜测用户坐标的概率为e/x,其中e是剩余船舶的数量,x是未知坐标的数量。问题在于,如果用户错过了,我怎样才能访问本地变量x,当用户打出一个命中时,该变量被分配一个值?由于这是一个递归函数,因此如果用户未命中,则不定义x。我仍然希望计算机在用户错过时猜测玩家的战舰位置。但是,我收到的错误消息是:local variable 'x' referenced before assignmentPython战列舰游戏,递归故障

感谢您的耐心等待。似乎应该有一个简单的解决方案。

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() 
+2

为了让这个任务更容易处理,我建议使用类重构你的代码。一个好的骨架可以作为这篇文章的答案可以找到: http://stackoverflow.com/questions/20179953/simple-battleships-game-implementation-in-python 使用类将使这个问题更容易使用并更简单地添加新功能。 – NicolaiF

+1

把这个压缩到[mcve]不仅会使这个问题更容易回答,还可能导致你自己回答问题。 (这也会迫使你将这个超级函数分割成更小的块,这只能帮助你。) –

+0

我按照你的建议重构了代码,谢谢! – st4rgut

回答

1

if表态意味着x没有未命中计算。您将不得不在else语句中添加更多逻辑来确定x应该是什么。一个起点是复制绘制图形的代码块,但只保留修改x值的行(还将x初始化为0)。