2017-04-21 146 views
0

我正在爲作業寫一個井字棋遊戲。它需要使用面向對象的編程。Python - OOP井字遊戲

我的問題是實現一種方法,檢查板子是否已滿並用相同的玩家重新開始遊戲。 我已經嘗試遍歷整個場地,檢查所有字段是否已滿,但沒有成功。

我也有一些麻煩推動獲勝球員,並促進以前的球員,如果他選擇一個佔領領域。我想我需要改變我的主要功能中的for循環,以跟蹤玩家或轉身,但我不知道如何。

class Player(object): 
    def __init__(self, name, symbol, initial_score=0): 
     self.name= name 
     self.symbol= symbol 
     self.score= initial_score 

    def won_match(self): 
     self.score+= 100 

    def lost_match(self): 
     self.score-= 50 

    def show_score(self): 
     print('Player {}: {} points'.format(self.name, self.score)) 

class PlayingField(object): 
    def __init__(self): 
     self.field= [ 
        [None, None, None], 
        [None, None, None], 
        [None, None, None] 
        ] 

    def show_field(self): 
     for row in self.field: 
      for player in row: 
       print('_' if player is None else player.symbol,end=' ') 
      print() 

    def set_player(self, x, y, player): 
     if self.field[y][x] is not None: 
      return False 

     self.field[y][x]= player 

     return True 

    def full_board(self): 
    for row in self.field: 
     for col in row: 
      if col is None: 
       return False 
     return True 

    def check_won(self, x, y, player): 
    if self.field[0][x] == player and self.field[1][x] == player and self.field[2][x] == player: 
     return True 
    elif self.field[y][0] == player and self.field[y][1] == player and self.field[y][2] == player: 
     return True 
    elif self.field[0][0] == player and self.field[1][1] == player and self.field[2][2] == player: 
     return True 
    elif self.field[0][2] == player and self.field[1][1] == player and self.field[2][0] == player: 
     return True 
    else: 
     return False 


def main(): 
    name_1= input('Name of Player 1: ') 
    name_2= input('Name of Player 2: ') 

    players= [ 
       Player(name_1, 'X'), 
       Player(name_2, 'O') 
       ] 

    field= PlayingField() 

    while True: 
     for player in players: 
      field.show_field() 

      x= int(input('Player {} choose your column: '.format(player.name))) - 1 

      y= int(input('Player {} choose your row: '.format(player.name))) - 1 

      if not field.set_player(x, y, player): 
       print('That field is already occupied.') 

      elif field.full_board(): 
      field.show_field() 
      print('full board') 
      for player in players: 
       print('{}: {}'.format(player.name, player.score)) 
      field= PlayingField() 

      elif field.check_won(player): 
       field.show_field() 
       print('Player {} won the game.'.format(player.name)) 
       print('Score') 
       for player in players: 
        if field.check_won(player) == True: 
         player.won_match() 
        elif field.check_won(player) == False: 
         player.lost_match() 
        print('{}: {}'.format(player.name, player.score)) 
       field= PlayingField() 

if __name__ == '__main__': 
    main() 
+3

「我已經嘗試遍歷遊戲區域,檢查所有字段是否已滿,但沒有成功。」這是一個有效的方法,*如何*它不起作用? – timgeb

+0

這是一個不錯的[tic-tac-toe參考](https://inventwithpython.com/chapter10.html) – GiantsLoveDeathMetal

+0

你應該考慮'check_won'的遞歸解決方案,而不是硬編碼有效的「完整板」。您的解決方案不會針對N×N大小的主板進行擴展。請查看n皇后問題,它與解決井字棋板有相似的邏輯。 – chukkwagon

回答

0

爲了檢查板子是否已滿,我們只需遍歷每個元素並檢查一個非無值。

您目前有

def full_board(self): 
    for row in self.field: 
     for col in self.field: 
      if col == '_': 
       return False 
      else: 
       return True 

記得,self.field是列表的列表。我們想要做的是檢查所有三個列表中的所有元素。

def full_board(self): 
    for row in self.field: # all good so far 
     for col in row: # <-- now we're iterating through each list in self.field 
     if col is None: 
      return False # the board is not full if there's at least one empty space 
    return True # we looked at every element and they were all occupied 

你的錯誤太早返回。在您的版本中,您可以檢查一個元素,然後根據該值確定真/假值。爲了檢查所有的的元素,你需要在for循環之後返回True。

至於所選位置的驗證,您需要做的只是持續提示,直到某個位置有效。

在while循環

,你可以有這樣的事情

x, y = prompt_for_position() 

while not pos_is_valid(x,y): 
    x, y = prompt_for_position() 

# now we can be sure that the chosen position is valid 

這裏,prompt_for_position可以只要求用戶提供一個X/Y,和pos_is_valid可以在X和Y,並告訴你,如果它是一個有效的位置。 (即無/空方)

希望這對你有用!

+0

首先感謝您的幫助。我編輯了代碼。我明白我在full_board方法中做了什麼錯誤,但是在你的解釋之下的部分..我不明白。我試圖在我的主要功能中實現該方法。它以某種方式工作。但每當第一行充滿符號時,他都會返回True,我不能向我解釋原因。我應該提到,我兩週前開始使用python進行編碼,一半的代碼來自我的導師。 – Hans

+0

您的full_board方法中的縮進現在已關閉。確保返回True在循環之外。如果你的返回True是在一個循環內,這意味着它將遍歷一行/列然後返回。 – chatton