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.