记忆游戏的代码优化

时间:2015-03-18 02:14:00

标签: python

我为课堂制作了这张记忆卡配对游戏,觉得我写了比我更多的代码。有没有办法优化这个?这项任务只是为了获得一个有效的计划,但我觉得我需要学习一些优化。

import random
class Card(object):
""" A card object with value but not suit"""

    def __init__(self, value):
        """Creates a card with the given value and suit."""
        self.value = value
        self.face = 0

    def showFace(self):
        '''flips the card over'''
        self.face = 1

    def __str__(self):
        """Returns the string representation of a card."""
        return str(self.value)

class Deck(object):
""" A deck containing cards."""

    def __init__(self, rows, columns):
        """Creates a full deck of cards."""
        self._cards = []
        self._rows = rows
        self._columns = columns
        for value in range(1,(int((self._rows*self._columns)/2))+1):
            c = Card(value)
            self._cards.append(c)
            self._cards.append(c)

    def shuffle(self):
        """Shuffles the cards."""
        random.shuffle(self._cards)

    def deal(self):
        """Removes and returns the top card or None 
        if the deck is empty."""
        if len(self) == 0:
            return None
        else:
            return self._cards.pop(0)

    def __len__(self):
        """Returns the number of cards left in the deck."""
        return len(self._cards)

    def __str__(self): 
        """Returns the string representation of a deck."""
        self.result = ''
        for c in self._cards:
            self.result = self.result + str(c) + '\n'
        return self.result

class Game(Deck,Card):
    '''Runs the memory game'''
    def __init__(self, rows, columns):
        '''gets rows and columns for the game'''
        self._rows = rows
        self._columns = columns

    def play(self):
        '''starts the game'''
        self._deck = Deck(self._rows, self._columns)
        self._deck.shuffle()
        Game.populateBoard(self)
        matches = 0
        #While the game is not finished
        while True:
            while True: #The First Card
                try:
                    coor1 = input("Enter coordinates for first card ")
                    coor1 = coor1.split(' ') # Removes spaces
                    coor1 = [x for x in coor1 if x != ' ']  # puts in list
                    coor1 = [int(x)-1 for x in coor1 if x == x] # converts
                except IndexError:
                    print('***Invalid coordinates! Try again.***')
                except ValueError:
                    print('***Invalid coordinates! Try again.***')
                else:
                    try: #Check if coordinates are valid
                        if 0 > coor1[0] or coor1[0] > self._rows\
                            or 0 > coor1[1] or coor1[1] > self._columns:
                            print('***Invalid coordinates! Try again.***')
                        else:
                            guess1 = self._gameboard[coor1[0]][coor1[1]]
                            break
                    except IndexError:
                        print('***Invalid coordinates! Try again.***')
            while True: # The Second Card
                try:
                    coor2 = input("Enter coordinates for second card ")
                    coor2 = coor2.split(' ') # Removes Spaces
                    coor2 = [x for x in coor2 if x != ' '] # puts in list
                    coor2 = [int(x)-1 for x in coor2 if x == x]# converts
                except IndexError:
                    print('***Invalid coordinates! Try again.***')
                except ValueError:
                    print('***Invalid coordinates! Try again.***')
                else:
                    try: #Check if coordinates are valid
                        if 0 > coor2[0] or coor2[0] > self._rows\
                            or 0 > coor2[1] or coor2[1] > self._columns:
                            print('***Invalid coordinates! Try again.***')
                        else:
                            guess2 = self._gameboard[coor2[0]][coor2[1]]
                            break
                    except IndexError:
                        print('***Invalid coordinates! Try again.***')

            if guess1 == guess2\
                and coor2[0]-coor1[0] == 0\
                and coor2[1]-coor1[1] == 0:#User enters same input for 1 and 2
                print("***That's the same card! Try again.***")
            elif guess1 == guess2:
                guess1.showFace()
                Game.showBoard(self)
                matches += 1
                if matches == ((self._rows * self._columns)/2):
                    break
            else:
                Game.showBoard(self)
                print('Not an identical pair. Found',guess1,'at ('+
                      str(coor1[0]+1)+','+ str(coor1[1]+1)+') and', guess2,
                      'at ('+str(coor2[0]+1)+','+str(coor2[1]+1)+')')

    def populateBoard(self):
        '''populates the game board'''
        self._gameboard = []
        for row in range(self._rows):
            self._gameboard.append([0] * self._columns)
        for row in range(len(self._gameboard)):
            for column in range(len(self._gameboard[row])):
                self._gameboard[row][column] = self._deck.deal()
        Game.showBoard(self)

    def showBoard(self):
        '''shows the board'''
        for row in self._gameboard:
            for card in row:
                if card.face == 0:
                    print('*', end =" ")     
                else:
                    print(card, end= " ")
            print()


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

2 个答案:

答案 0 :(得分:0)

以下是几个可以简化代码的地方

def populateBoard(self):
    '''populates the game board'''
    self._gameboard = [self._deck.deal() for row in self._rows
                       for column in self._columns]
    self.showBoard()

def showBoard(self):
    '''shows the board'''
    for row in self._gameboard:
        print(*(card if card.face else '*' for card in row))

答案 1 :(得分:0)

多次计算

coor1[0]。考虑将结果分配给局部变量,然后使用此局部变量。