2017-10-20 72 views
1

我試圖寫模擬內存匹配遊戲程序的Python 3代碼:「列表索引範圍的」在Python記憶匹配遊戲錯誤

編寫扮演的記憶配對遊戲程序。當它啓動時,程序會提示用戶輸入包含這些卡的遊戲板的行數和列數。卡的總數量必須均勻。假設棋盤尺寸至多爲8乘9或9乘8.您的卡片必須從1到(行數*列數)//2編號。2.您的程序允許玩家指定她想要的卡片通過座標系選擇。

我已經寫了一切,但我不斷收到一個小錯誤,我不能爲我的生活弄清楚。當我嘗試使用下面的示例輸入來運行程序,我得到的錯誤「列表索引超出範圍」:

>>> main() 
Enter number of rows 3 
Enter number of columns 3 
> ***The value of rows X columns must be even. Try again.*** 
Enter number of rows 2 
Enter number of columns 3 
> * * * 
> * * * 
Enter coordinates for first card 3 1 [THE ERROR IS GENERATED HERE] 
<<< 

據我所知,3是在這種情況下,陣列之外,但是我的代碼寫應該是以字符串的形式返回錯誤消息。相反,該程序崩潰。如果有人能指引我朝着正確的方向發展,我將不勝感激。以下是我寫的完整代碼:

import random 

class Card(object): 
    def __init__(self,value): 
     self._face = 0 
     self._value = value 

    def __str__(self): 
     if self._face == True: 
      output = str(self._value) 
     else: 
      output = "*" 
     return output 

    def __eq__(self,other): 
     if type(self)!=type(other): 
      output = False 
     elif self._value == other._value: 
      output = True 
     else: 
      output = False 
     return output 


class Deck(object): 
    def __init__(self, pairs): 
     self._pairs = pairs 
     self._cards = [] 
     for cards in range(self._pairs): 
      self._cards.append(Card(cards)) 
      self._cards.append(Card(cards)) 

    def shuffle(self): 
     random.shuffle(self._cards) 

    def deal(self,index): 
     return self._cards[index] 

    def cardsleft(self): 
     return len(self._cards) 

class Game(object): 
    def __init__(self,rows,columns): 
     self._rows = rows 
     self._columns = columns 
     self._cards = (rows*columns)//2 
     self._deck = Deck(self._cards) 
     self._quit = False 
     self._turns = 0 

    #deals the cards into a 2D list 
    def populateBoard(self): 
     k = 0 
     self._board = [] 
     self._deck.shuffle() 
     for i in range(self._rows): 
      self._board.append([]) 
      for j in range(self._columns): 
       self._board[i].append(self._deck.deal(k)) 
       k+=1 

    #shows the cards on the board 
    def displayBoard(self): 
     output = "" 
     for i in range(self._rows): 
      for j in range(self._columns): 
       output += (str(self._board[i][j]) + " ") 
      output += "\n" 
     print(output) 

    #iterates through the cards to see if any are face down. if all pairs have been found, gameover 
    def isGameOver(self): 
     victory = True 
     for i in range(self._rows): 
      for j in range(self._columns): 
       if self._board[i][j]._face == False: 
        victory = False 
        break 
     if victory == True: 
      print("You Win.") 
     return victory 

    '''def play(self): 
     self.populateBoard() 
     while self._quit == False: 
      self.displayBoard() 

      self._coord1 = input("Enter the coordinates for the first card ").split(' ') 
      self._coord1 = list(map(int, self._coord1)) 
      if (self._coord1[0]-1 < self._columns) and (self._coord1[1]-1 < self._rows) and (self._coord1[0]-1 >= 0) and (self._coord1[1]-1 >= 0): 
       self._card1 = self._board[self._coord1[0]-1][self._coord1[1]-1] 
      else: 
       self._card1 = "***Invalid coordinates! Try again.***" 

      while self._card1 == "***Invalid coordinates! Try again.***": 
       print("Coordinates outside gameboard. Please give coordinates on the board") 
       self._coord1 = input("Enter the coordinates for the first card ").split(' ') 
       self._coord1 = list(map(int, self._coord1)) 
       if (self._coord1[0]-1 < self._columns) and (self._coord1[1]-1 < self._rows) and (self._coord1[0]-1 >= 0) and (self._coord1[1]-1 >= 0): 
        self._card1 = self._board[self._coord1[0]-1][self._coord1[1]-1] 
       else: 
        self._card1 = "***Invalid coordinates! Try again.***" 

      self._card1._face = 1 

      self._coord2 = input("Enter the coordinates for the second card ").split(' ') 
      self._coord2 = list(map(int, self._coord2)) 
      if (self._coord2[0]-1 < self._columns) and (self._coord2[1]-1 < self._rows) and (self._coord2[0]-1 >= 0) and (self._coord2[1]-1 >= 0): 
       self._card2 = self._board[self._coord2[0]-1][self._coord2[1]-1] 
      else: 
       self._card2 = "***Invalid coordinates! Try again.***" 

      while self._card2 == "***Invalid coordinates! Try again.***" or self._card2._face == 1:    
       if self._card2 == "***Invalid coordinates! Try again.***": 
        print("Coordinates outside gameboard. Please give coordinates on the board")     
       else: 
        print("you have already selected that card. give coordinates for a facedown card") 
       self._coord2 = input("Enter the coordinates for the second card ").split(' ') 
       self._coord2 = list(map(int, self._coord2)) 
       if (self._coord2[0]-1 < self._columns) and (self._coord2[1]-1 < self._rows) and (self._coord2[0]-1 >= 0) and (self._coord2[1]-1 >= 0): 
        self._card2 = self._board[self._coord2[0]-1][self._coord2[1]-1] 
       else: 
        self._card2 = "***Invalid coordinates! Try again.***" 

      self._card2._face = 1 
      if self._card1 == self._card2: 
       if self.isGameOver(): 
        self._quit = True 
      else: 
       print("Not an identical pair. Found " + str(self._card1) + " at (" + str(self._coord1[0]) + "," +str(self._coord1[1]) + ") and " + str(self._card2) + " at (" + str(self._coord2[0]) + "," + str(self._coord2[1]) + ")") 
       self._card1._face = 0 
       self._card2._face = 0''' 

    def guessFirst(self): 
     self._coord1 = input("Enter the coordinates for the first card ").split(' ') 
     self._coord1 = list(map(int, self._coord1)) 
     if (self._coord1[0]-1 <= self._columns) and (self._coord1[1]-1 <= self._rows) and (self._coord1[0]-1 >= 0) and (self._coord1[1]-1 >= 0): 
      output = self._board[self._coord1[0]-1][self._coord1[1]-1] 
     else: 
      output = "***Invalid coordinates! Try again.***" 
     return output 

    def guessSecond(self): 
     self._coord1 = input("Enter the coordinates for the second card ").split(' ') 
     self._coord1 = list(map(int, self._coord1)) 
     if (self._coord1[0]-1 <= self._columns) and (self._coord1[1]-1 <= self._rows) and (self._coord1[0]-1 >= 0) and (self._coord1[1]-1 >= 0): 
      output = self._board[self._coord1[0]-1][self._coord1[1]-1] 
     else: 
      output = "***Invalid coordinates! Try again.***" 
     return output 

    def play(self): 
     self.populateBoard() 
     while self._quit == False: 
      self.displayBoard() 
      self._card1 = self.guessFirst() 
      while self._card1 == "***Invalid coordinates! Try again.***": 
       print("Coordinates outside gameboard. Please give coordinates on the board") 
       self._card1 = self.guessFirst() 
      self._card1._face = 1 

      self._card2 = self.guessSecond() 
      while self._card2 == "***Invalid coordinates! Try again.***" or self._card2._face == 1: 
       if self._card2 == "***Invalid coordinates! Try again.***": 
        print("Coordinates outside gameboard. Please give coordinates on the board") 
       else: 
        print("you have already selected that card. give coordinates for a facedown card") 
       self._card2 = self.guessSecond() 
      self._card2._face = 1 
      self.displayBoard() 
      if self._card1 == self._card2: 
       if self.isGameOver(): 
        self._quit = True 
      else: 
       self._card1._face = 0 
       self._card2._face = 0 


def main(): 
    while True: 
     # Force user to enter valid value for number of rows 
     while True: 
      rows = input("Enter number of rows ") 
      if rows.isdigit() and (1 <= int(rows) <= 9): 
       rows = int(rows) 
       break 
      else: 
       print (" ***Number of rows must be between 1 and 9! Try again.***") 
       # Adding *** and indenting error message makes it easier for the user to see 

     # Force user to enter valid value for number of columns 
     while True: 
      columns = input("Enter number of columns ") 
      if columns.isdigit() and (1 <= int(columns) <= 9): 
       columns = int(columns) 
       break 
      else: 
       print (" ***Number of columns must be between 1 and 9! Try again.***") 

     if rows * columns % 2 == 0: 
      break 
     else: 
      print (" ***The value of rows X columns must be even. Try again.***") 

    game = Game(rows, columns) 
    game.play() 

if __name__ == "__main__": 
    main() 
+0

爲什麼'def play:'在三重引號字符串中? – Barmar

+1

發佈完整的錯誤消息。它應該說錯誤發生在哪一行。 – Barmar

回答

0

您似乎混淆了行和列。在populateBoard中,使用_board的第一個座標作爲行,第二個作爲列。在guessFirst中,您根據列數檢查第一個座標,按照行數檢查第二個座標。