简体   繁体   中英

"List index out of range" error in Python Memory Match game

I am trying to write the Python 3 code for a program that simulates the memory matching game:

Write a program that plays the memory matching game. When it starts, the program prompts the user for the number of rows and columns for the game board that contains the cards. The total number of cards must be even. Assume that the board dimensions are at most 8 by 9 or 9 by 8. Your cards must be numbered from 1 through (number of rows * number of columns) / / 2. Your program allows the player to specify the cards that she would like to select through a coordinate system.

I have written everything, but I keep getting one small error that I cannot for the life of me figure out. When I try to run the program using the following sample inputs, I get the error "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] 
<<<

I understand that the 3 is outside of the array in this case, but the code I wrote is supposed to return an error message in the form of a string. Instead, the program crashes. If somebody could guide me in the right direction, I would appreciate it. Here is the full code I have written:

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

You seemed to have mixed up rows and columns. In populateBoard you use the first coordinate of _board as rows, the second one as columns. In guessFirst you check the first coordinate against the number of columns, and the second one against the number of rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM