Skip to content

Module quickpython.examples.memory

/games/memory.py

Copyright (c) 2019 ShineyDev

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

View Source
"""

/games/memory.py

    Copyright (c) 2019 ShineyDev

    Licensed under the Apache License, Version 2.0 (the "License");

    you may not use this file except in compliance with the License.

    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software

    distributed under the License is distributed on an "AS IS" BASIS,

    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    See the License for the specific language governing permissions and

    limitations under the License.

"""

__authors__ = [("shineydev", "contact@shiney.dev")]

__maintainers__ = [("shineydev", "contact@shiney.dev")]

__version_info__ = (1, 0, 0, "final", 0)

__version__ = "{0}.{1}.{2}{3}{4}".format(

    *[str(n)[0] if (i == 3) else str(n) for (i, n) in enumerate(__version_info__)]

)

import os

import random

import re

import string

import time

import pyfiglet

GRID_SIZES = {"easy": 6, "intermediate": 10, "hard": 14}

CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"£$%^&*()-_=+[{]};:'@#~,<.>/?\\|`¬áé"

class Memory:

    def __init__(self, difficulty: str):

        """

        initializes a `Memory` object

        """

        self.grid_size = GRID_SIZES[difficulty]

        self.characters = CHARACTERS[: (((self.grid_size // 2) ** 2) * 2)]

        self.message = ""

    def game(self):

        """

        starts the game

        """

        self.known = [" "] * len(self.characters * 2)

        characters = [character for character in self.characters * 2]

        random.shuffle(characters)

        while " " in self.known:

            cls()

            print()

            self.show_grid()

            print()

            if self.message:

                print(self.message)

                print()

                self.message = ""

            coordinates = input("coordinates;\n> ").strip().upper()

            if not self.valid_coordinates(coordinates):

                self.message = "invalid coordinates"

                continue

            first_row, first_column = self.parse_coordinates(coordinates)

            if self.known[(first_row * self.grid_size) + first_column] != " ":

                self.message = "invalid coordinates"

                continue

            self.known[(first_row * self.grid_size) + first_column] = characters[

                (first_row * self.grid_size) + first_column

            ]

            while True:

                cls()

                print()

                self.show_grid()

                print()

                if self.message:

                    print(self.message)

                    print()

                    self.message = ""

                coordinates = input("> ").strip().upper()

                if self.valid_coordinates(coordinates):

                    second_row, second_column = self.parse_coordinates(coordinates)

                    if self.known[(second_row * self.grid_size) + second_column] != " ":

                        self.message = "invalid coordinates"

                        continue

                    self.known[(second_row * self.grid_size) + second_column] = characters[

                        (second_row * self.grid_size) + second_column

                    ]

                    break

                self.message = "invalid coordinates"

            cls()

            print()

            self.show_grid()

            time.sleep(1)

            if (

                not self.known[(first_row * self.grid_size) + first_column]

                == self.known[(second_row * self.grid_size) + second_column]

            ):

                self.known[(first_row * self.grid_size) + first_column] = " "

                self.known[(second_row * self.grid_size) + second_column] = " "

        cls()

        print()

        self.show_grid()

        print()

        print("congrats")

    def parse_coordinates(self, coordinates: str):

        """

        generates a (row : int, column : int) tuple from coordinates

        arguments:

            coordinates :: str   :: the coordinates convert

        returns:

                        :: tuple :: a (row : int, column : int) tuple

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        row = int(match.group("row")) - 1

        column = string.ascii_uppercase.index(match.group("column"))

        return (row, column)

    def show_grid(self):

        """"""

        print(

            "       {0}".format(

                "   ".join([character for character in string.ascii_lowercase][: self.grid_size])

            )

        )

        print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

        i = 1

        for (j, k) in enumerate(self.known, 1):

            if j % (self.grid_size) == 0:

                print("| {0} |".format(k))

                print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

            elif j % (self.grid_size) == 1:

                print("  {0:>2} | {1} ".format(i, k), end="")

                i += 1

            else:

                print("| {0} ".format(k), end="")

    def start(self):

        """

        calls `self.game` in a 'would you like to play again?' loop

        """

        choice = "y"

        while choice.startswith("y"):

            cls()

            print(pyfiglet.figlet_format("Memory"))

            print()

            input("enter to play\nctrl + c to quit to main menu\n\n")

            self.game()

            choice = input("\nwould you like to play again?\n> ").strip()

    def valid_coordinates(self, coordinates: str):

        """

        determines whether `coordinates` are valid

        arguments:

            coordinates :: str  :: the coordinates to check

        returns:

                        :: bool :: whether `coordinates` are valid

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        if match:

            return True

        return False

if __name__ == "__main__":

    difficulty = None

    while difficulty not in {"easy", "intermediate", "hard"}:

        cls()

        print()

        difficulty = input("difficulty;\n> ").strip()

    game = Memory(difficulty)

    game.start()

Variables

CHARACTERS
GRID_SIZES

Classes

Memory

class Memory(
    difficulty: str
)
View Source
class Memory:

    def __init__(self, difficulty: str):

        """

        initializes a `Memory` object

        """

        self.grid_size = GRID_SIZES[difficulty]

        self.characters = CHARACTERS[: (((self.grid_size // 2) ** 2) * 2)]

        self.message = ""

    def game(self):

        """

        starts the game

        """

        self.known = [" "] * len(self.characters * 2)

        characters = [character for character in self.characters * 2]

        random.shuffle(characters)

        while " " in self.known:

            cls()

            print()

            self.show_grid()

            print()

            if self.message:

                print(self.message)

                print()

                self.message = ""

            coordinates = input("coordinates;\n> ").strip().upper()

            if not self.valid_coordinates(coordinates):

                self.message = "invalid coordinates"

                continue

            first_row, first_column = self.parse_coordinates(coordinates)

            if self.known[(first_row * self.grid_size) + first_column] != " ":

                self.message = "invalid coordinates"

                continue

            self.known[(first_row * self.grid_size) + first_column] = characters[

                (first_row * self.grid_size) + first_column

            ]

            while True:

                cls()

                print()

                self.show_grid()

                print()

                if self.message:

                    print(self.message)

                    print()

                    self.message = ""

                coordinates = input("> ").strip().upper()

                if self.valid_coordinates(coordinates):

                    second_row, second_column = self.parse_coordinates(coordinates)

                    if self.known[(second_row * self.grid_size) + second_column] != " ":

                        self.message = "invalid coordinates"

                        continue

                    self.known[(second_row * self.grid_size) + second_column] = characters[

                        (second_row * self.grid_size) + second_column

                    ]

                    break

                self.message = "invalid coordinates"

            cls()

            print()

            self.show_grid()

            time.sleep(1)

            if (

                not self.known[(first_row * self.grid_size) + first_column]

                == self.known[(second_row * self.grid_size) + second_column]

            ):

                self.known[(first_row * self.grid_size) + first_column] = " "

                self.known[(second_row * self.grid_size) + second_column] = " "

        cls()

        print()

        self.show_grid()

        print()

        print("congrats")

    def parse_coordinates(self, coordinates: str):

        """

        generates a (row : int, column : int) tuple from coordinates

        arguments:

            coordinates :: str   :: the coordinates convert

        returns:

                        :: tuple :: a (row : int, column : int) tuple

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        row = int(match.group("row")) - 1

        column = string.ascii_uppercase.index(match.group("column"))

        return (row, column)

    def show_grid(self):

        """"""

        print(

            "       {0}".format(

                "   ".join([character for character in string.ascii_lowercase][: self.grid_size])

            )

        )

        print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

        i = 1

        for (j, k) in enumerate(self.known, 1):

            if j % (self.grid_size) == 0:

                print("| {0} |".format(k))

                print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

            elif j % (self.grid_size) == 1:

                print("  {0:>2} | {1} ".format(i, k), end="")

                i += 1

            else:

                print("| {0} ".format(k), end="")

    def start(self):

        """

        calls `self.game` in a 'would you like to play again?' loop

        """

        choice = "y"

        while choice.startswith("y"):

            cls()

            print(pyfiglet.figlet_format("Memory"))

            print()

            input("enter to play\nctrl + c to quit to main menu\n\n")

            self.game()

            choice = input("\nwould you like to play again?\n> ").strip()

    def valid_coordinates(self, coordinates: str):

        """

        determines whether `coordinates` are valid

        arguments:

            coordinates :: str  :: the coordinates to check

        returns:

                        :: bool :: whether `coordinates` are valid

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        if match:

            return True

        return False

Methods

game
def game(
    self
)

starts the game

View Source
    def game(self):

        """

        starts the game

        """

        self.known = [" "] * len(self.characters * 2)

        characters = [character for character in self.characters * 2]

        random.shuffle(characters)

        while " " in self.known:

            cls()

            print()

            self.show_grid()

            print()

            if self.message:

                print(self.message)

                print()

                self.message = ""

            coordinates = input("coordinates;\n> ").strip().upper()

            if not self.valid_coordinates(coordinates):

                self.message = "invalid coordinates"

                continue

            first_row, first_column = self.parse_coordinates(coordinates)

            if self.known[(first_row * self.grid_size) + first_column] != " ":

                self.message = "invalid coordinates"

                continue

            self.known[(first_row * self.grid_size) + first_column] = characters[

                (first_row * self.grid_size) + first_column

            ]

            while True:

                cls()

                print()

                self.show_grid()

                print()

                if self.message:

                    print(self.message)

                    print()

                    self.message = ""

                coordinates = input("> ").strip().upper()

                if self.valid_coordinates(coordinates):

                    second_row, second_column = self.parse_coordinates(coordinates)

                    if self.known[(second_row * self.grid_size) + second_column] != " ":

                        self.message = "invalid coordinates"

                        continue

                    self.known[(second_row * self.grid_size) + second_column] = characters[

                        (second_row * self.grid_size) + second_column

                    ]

                    break

                self.message = "invalid coordinates"

            cls()

            print()

            self.show_grid()

            time.sleep(1)

            if (

                not self.known[(first_row * self.grid_size) + first_column]

                == self.known[(second_row * self.grid_size) + second_column]

            ):

                self.known[(first_row * self.grid_size) + first_column] = " "

                self.known[(second_row * self.grid_size) + second_column] = " "

        cls()

        print()

        self.show_grid()

        print()

        print("congrats")
parse_coordinates
def parse_coordinates(
    self,
    coordinates: str
)

generates a (row : int, column : int) tuple from coordinates

arguments: coordinates :: str :: the coordinates convert

returns: :: tuple :: a (row : int, column : int) tuple

View Source
    def parse_coordinates(self, coordinates: str):

        """

        generates a (row : int, column : int) tuple from coordinates

        arguments:

            coordinates :: str   :: the coordinates convert

        returns:

                        :: tuple :: a (row : int, column : int) tuple

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        row = int(match.group("row")) - 1

        column = string.ascii_uppercase.index(match.group("column"))

        return (row, column)
show_grid
def show_grid(
    self
)
View Source
    def show_grid(self):

        """"""

        print(

            "       {0}".format(

                "   ".join([character for character in string.ascii_lowercase][: self.grid_size])

            )

        )

        print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

        i = 1

        for (j, k) in enumerate(self.known, 1):

            if j % (self.grid_size) == 0:

                print("| {0} |".format(k))

                print("     {0}".format("-" * ((self.grid_size * 4) + 1)))

            elif j % (self.grid_size) == 1:

                print("  {0:>2} | {1} ".format(i, k), end="")

                i += 1

            else:

                print("| {0} ".format(k), end="")
start
def start(
    self
)

calls self.game in a 'would you like to play again?' loop

View Source
    def start(self):

        """

        calls `self.game` in a 'would you like to play again?' loop

        """

        choice = "y"

        while choice.startswith("y"):

            cls()

            print(pyfiglet.figlet_format("Memory"))

            print()

            input("enter to play\nctrl + c to quit to main menu\n\n")

            self.game()

            choice = input("\nwould you like to play again?\n> ").strip()
valid_coordinates
def valid_coordinates(
    self,
    coordinates: str
)

determines whether coordinates are valid

arguments: coordinates :: str :: the coordinates to check

returns: :: bool :: whether coordinates are valid

View Source
    def valid_coordinates(self, coordinates: str):

        """

        determines whether `coordinates` are valid

        arguments:

            coordinates :: str  :: the coordinates to check

        returns:

                        :: bool :: whether `coordinates` are valid

        """

        pattern = re.compile(

            r"(?P<column>[A-{0}])(?P<row>{1})".format(

                string.ascii_uppercase[self.grid_size - 1],

                "|".join([str(i) for i in range(1, self.grid_size + 1)][::-1]),

            )

        )

        match = re.match(pattern, coordinates)

        if match:

            return True

        return False