2016-09-06 91 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)。