Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Using Python3, memory matching game played by children is to start with a deck o

ID: 3591158 • Letter: U

Question

Using Python3, memory matching game played by children is to start with a deck of cards which contains identical pairs. For example, given six cards in the deck, two might be labeled 1, two labeled 2 and two labeled 3. The cards are shuffled and placed face down on a board. A player then selects two cards that are face down, turns them face up, and if the cards match they are left face up. If the two cards do not match, they are returned to their original face down position. The game continues until all cards are face up.

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 as shown in the sample run below. All the cards that are face down are indicated by *. For example, in the following layout of a 4 by 4 game board

the pair of 8 which are face up are at coordinates (1,1) and (3,2). Pay attention to how the coordinates are specified: row number followed by column number, both start at index 1, not zero. A sample run of the game is as follows:

Another sample run is as follows:

A third sample run is as follows:

Design Requirements: You need to use three classes: Card, Deck and Game. Card stores both the card's value and face (a string or Boolean variable to indicate whether the card is facing up or down). Deck contains the cards needed for the game. It will contain among its methods a method to deal a card, another for shuffling the deck, and a method that returns number of cards left in the deck. These two classes are not identical to the classes Card and Deck discussed in the book but are very similar. The class Game simulates playing a single game and represents the interaction between the user and the other classes. Its instance members store a 2D list (of card objects) representing the game board where the cards are placed, number of rows and number of columns of the game board. Among the instance methods of the Game class: play(), which simulates playing the game; isGameOver(), which checks whether or not the game is over; displayBoard(), which displays the board; populateBoard(), which creates the initial 2D list of identical pairs of cards with all the cards facing down. Most probably, you will need to write other instance methods as you see appropriate.    

Use the following test program:

Explanation / Answer

import pygame
import random
from itertools import product
from pygame.locals import *
from pygame.color import Color


# the constants
FPS = 30
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 400
SQUARE_SIZE = 50
SQUARE_GAP = 10
BOARD_WIDTH = 8
BOARD_HEIGHT = 4
X_MARGIN = (SCREEN_WIDTH - (BOARD_WIDTH * (SQUARE_SIZE + SQUARE_GAP))) // 2
Y_MARGIN = (SCREEN_HEIGHT - (BOARD_HEIGHT * (SQUARE_SIZE + SQUARE_GAP))) // 2

# the board size must be even due to pairs
assert (BOARD_HEIGHT * BOARD_WIDTH) % 2 == 0, 'The board size must be even'

# the shapes
DIAMOND = 'diamond'
SQUARE = 'square'
TRIANGLE = 'triangle'
CIRCLE = 'circle'

BGCOLOR = Color('blue')

# the main function
def main():
global screen, clock

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Memory game')

clock = pygame.time.Clock()

shape = (DIAMOND, SQUARE, TRIANGLE, CIRCLE)
colors = (Color('cyan'), Color('magenta'), Color('gray'), Color('chocolate'))

# There should be enough symbols
assert len(shape) * len(colors) >= BOARD_HEIGHT * BOARD_WIDTH // 2, 'There are not sufficient icons'

board = get_random_board(shape, colors)
revealed = [[False] * BOARD_WIDTH for i in range(BOARD_HEIGHT)] # keeps track of visibility of square

mouse_x = None
mouse_y = None
mouse_clicked = False
first_selection = None

running = True
start_game_animation(board)

while running:
screen.fill(BGCOLOR)
draw_board(board, revealed)

for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEMOTION:
mouse_x, mouse_y = pygame.mouse.get_pos()
elif event.type == MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
mouse_clicked = True

x, y = get_pos(mouse_x, mouse_y)

if x is not None and y is not None:
if not revealed[x][y]:
if mouse_clicked:
revealed[x][y] = True
draw_square(board, revealed, x, y)

if first_selection is None:
first_selection = (x, y)
else:
pygame.time.wait(1000)
if board[x][y] != board[first_selection[0]][first_selection[1]]:
revealed[x][y] = False
revealed[first_selection[0]][first_selection[1]] = False
first_selection = None

if game_won(revealed):

game_won_animation(board, revealed)

board = get_random_board(shape, colors)
revealed = [[False] * BOARD_WIDTH for i in range(BOARD_HEIGHT)]
start_game_animation(board)

else:
draw_select_box(x, y)

mouse_clicked = False
pygame.display.update()


def game_won(revealed):
""" Returns whether all squares are found"""

return all(all(x) for x in revealed)


def game_won_animation(board, revealed):
""" Flashes background colors when the game is won"""

color1 = Color('cyan')
color2 = BGCOLOR
for i in range(10):
color1, color2 = color2, color1
screen.fill(color1)
draw_board(board, revealed)
pygame.display.update()
pygame.time.wait(300)


def start_game_animation(board):
"""Starts game by randomly showing 5 squares"""

coordinates = list(product(range(BOARD_HEIGHT), range(BOARD_WIDTH)))
random.shuffle(coordinates)

revealed = [[False] * BOARD_WIDTH for i in range(BOARD_HEIGHT)]

screen.fill(BGCOLOR)
draw_board(board, revealed)
pygame.display.update()
pygame.time.wait(500)

for sz in range(0, BOARD_HEIGHT * BOARD_WIDTH, 5):
l = coordinates[sz: sz + 5]
for x in l:
revealed[x[0]][x[1]] = True
draw_square(board, revealed, *x)
pygame.time.wait(500)
for x in l:
revealed[x[0]][x[1]] = False
draw_square(board, revealed, *x)


def get_random_board(shape, colors):
""" Generates the board by random shuffling"""

icons = list(product(shape, colors))
num_icons = BOARD_HEIGHT * BOARD_WIDTH // 2
icons = icons[:num_icons] * 2

random.shuffle(icons)
board = [icons[i:i + BOARD_WIDTH]
for i in range(0, BOARD_HEIGHT * BOARD_WIDTH, BOARD_WIDTH)]
return board


def get_coord(x, y):
""" Gets the coordinates of particular square.
The squares are number height wise and then width wise.
So the x and y are interchanged."""

top = X_MARGIN + y * (SQUARE_SIZE + SQUARE_GAP)
left = Y_MARGIN + x * (SQUARE_SIZE + SQUARE_GAP)
return top, left


def draw_icon(icon, x, y):
"""Draws the icon of (x, y) square"""

px, py = get_coord(x, y)
if icon[0] == DIAMOND:
pygame.draw.polygon(screen, icon[1],
((px + SQUARE_SIZE // 2, py + 5), (px + SQUARE_SIZE - 5, py + SQUARE_SIZE // 2),
(px + SQUARE_SIZE // 2, py + SQUARE_SIZE - 5), (px + 5, py + SQUARE_SIZE // 2)))
elif icon[0] == SQUARE:
pygame.draw.rect(screen, icon[1],
(px + 5, py + 5, SQUARE_SIZE - 10, SQUARE_SIZE - 10))
elif icon[0] == TRIANGLE:
pygame.draw.polygon(screen, icon[1],
((px + SQUARE_SIZE // 2, py + 5), (px + 5, py + SQUARE_SIZE - 5),
(px + SQUARE_SIZE - 5, py + SQUARE_SIZE - 5)))
elif icon[0] == CIRCLE:
pygame.draw.circle(screen, icon[1],
(px + SQUARE_SIZE // 2, py + SQUARE_SIZE // 2), SQUARE_SIZE // 2 - 5)


def get_pos(cx, cy):
"""Gets the square (x, y) position from the cartesian coordinates.
The squares are number height wise and then width wise.
So the cx and cy are interchanged."""

if cx < X_MARGIN or cy < Y_MARGIN:
return None, None

x = (cy - Y_MARGIN) // (SQUARE_SIZE + SQUARE_GAP)
y = (cx - X_MARGIN) // (SQUARE_SIZE + SQUARE_GAP)

if x >= BOARD_HEIGHT or y >= BOARD_WIDTH or (cx - X_MARGIN) % (SQUARE_SIZE + SQUARE_GAP) > SQUARE_SIZE or (cy - Y_MARGIN) % (SQUARE_SIZE + SQUARE_GAP) > SQUARE_SIZE:
return None, None
else:
return x, y


def draw_square(board, revealed, x, y):
"""Draws a particular square"""

coords = get_coord(x, y)
square_rect = (*coords, SQUARE_SIZE, SQUARE_SIZE)
pygame.draw.rect(screen, BGCOLOR, square_rect)
if revealed[x][y]:
draw_icon(board[x][y], x, y)
else:
pygame.draw.rect(screen, Color('gold'), square_rect)
pygame.display.update(square_rect)


def draw_board(board, revealed):
"""Draws the entire board"""

for x in range(BOARD_HEIGHT):
for y in range(BOARD_WIDTH):
draw_square(board, revealed, x, y)


def draw_select_box(x, y):
"""Draws the highlight box around the square"""

px, py = get_coord(x, y)
pygame.draw.rect(screen, Color('red'), (px - 5, py - 5, SQUARE_SIZE + 10, SQUARE_SIZE + 10), 5)


if __name__ == '__main__':
main()

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote