Python Memory Match游戏中的“列表索引超出范围”错误

时间:2017-10-20 00:51:21

标签: python memory

我正在尝试为模拟内存匹配游戏的程序编写Python 3代码:

  

编写一个播放记忆匹配游戏的程序。当它启动时,程序会提示用户输入包含卡片的游戏板的行数和列数。卡的总数必须是偶数。假设电路板尺寸最多为8乘9或9乘8.您的卡必须从1到(行数*列数)/ 2编号。您的程序允许玩家指定她想要的卡通过坐标系选择。

我已经写完了所有内容,但是我一直有一个小错误,我不能为我的生活弄清楚。当我尝试使用以下示例输入运行程序时,出现错误“List index out of range”:

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

1 个答案:

答案 0 :(得分:1)

你似乎混淆了行和列。在populateBoard中,您使用_board的第一个坐标作为行,第二个坐标作为列。在guessFirst中,您根据列数检查第一个坐标,并根据行数检查第二个坐标。