如何修复使用 python 的匹配游戏中的 int 错误?

How to fix the int error in a matching game using python?

好的,我一直在尝试这个。继续陷入 'int' 错误。

描述:

幼儿玩的一种常见的记忆配对游戏是从一副包含相同对的纸牌开始。例如,给定一副牌中的六张牌,其中两张可能标记为 1,两张标记为 2,另外两张标记为 3。将这些牌洗好并面朝下放在棋盘上。然后玩家选择两张面朝下的牌,将它们翻面朝上,如果牌相匹配,则将它们面朝上。如果两张牌不匹配,则将它们放回原来的面朝下位置。游戏一直持续到所有牌面朝上为止。

样本input/output:

main()

您输入的行数和列数... 输入行数:3

输入列数:2

* *
* *
* *

然后你像这样输入坐标...

输入第一张卡片的坐标:1 1

输入第二张牌的坐标:3 1

不是一对。在 (1,1) 找到 2 个,在 (3,1)

找到 1 个
* *
* *
* *

输入第一张卡片的坐标:1 2

输入第二张卡片的坐标:2 2

不是一对。在 (1,2) 找到 2 个,在 (2,2)

找到 3 个
* *
* *
* *

输入第一张卡片的坐标:1 1

输入第二张卡片的坐标:1 2

2 2
* *
* *

输入第一张卡片的坐标:3 1

输入第二张牌的坐标:3 2

不是一对。在 (3,1) 找到 1 个,在 (3,2)

找到 3 个
2 2
* *
* *

输入第一张卡片的坐标:2 1

输入第二张牌的坐标:3 1

2 2
1 *
1 *

输入第一张卡片的坐标:3 2

输入第二张卡片的坐标:2 2

2 2
1 3
1 3

要求:

设计要求:您需要使用三个classes:Card、Deck 和Game。 Card 存储了牌面值和牌面(一个字符串或布尔变量,表示牌面朝上还是朝下)。 Deck 包含游戏所需的卡片。它将在其方法中包含一个发牌方法,另一个洗牌方法,以及一个 returns 牌组中剩余牌数的方法。这两个 classes 与书中讨论的 classes Card and Deck 不同,但有许多共同点。 class 游戏模拟玩单个游戏并代表用户与其他 class 之间的交互。它的实例成员存储一个二维列表(卡片对象),表示放置卡片的游戏板、游戏板的行数和列数。 Gameclass的实例方法中:play(),模拟玩游戏; isGameOver(),检查游戏是否结束; displayBoard(),显示棋盘; populateBoard(),它创建了相同卡片对的初始 2D 列表,所有卡片都面朝下。很可能,您需要编写您认为合适的其他实例方法。

到目前为止我的代码:

import random

class Card(object):
    '''A card object with a suit and face'''

    def __init__(self, value):
        '''Stores both the card's value and face'''   
        self._value = value
        self._face = False

    def getValue(self):
        '''Get the value of the card'''
        return self._value

    def getFace(self):
        '''Get the face of the card'''
        return self._face
    def setFace(self):
        self._face = True

class Deck(object):

    def __init__(self, pairs):
        self._pairs = pairs
        self._cards = []
        for cards in range(self._pairs):
            c1 = Card(cards)
            self._cards.append(c1)
            c2 = Card(cards)
            self._cards.append(c2)

    def deal(self):
        if len(self) == 0:
           return None
        else:
           return self._cards.pop(0)

    def shuffle(self):
        '''Shuffels the cards.'''
        random.shuffle(self._cards)

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

class Game(object):

    def __init__(self, rows, columns):
        self._deck = Deck((rows * columns)//2)
        self._rows = rows
        self._columns = columns
        self._board = []
        for row in range(self._rows):
            self._board.append([0] * columns)

    def populateBoard(self):
        self._deck_shuffle()
        for columns in self._columns:
            for rows in self._rows:
                self._board[rows][columns] = self._deck_deal()

    def displayBoard(self):
        for rows in self._rows:
            for columns in self._columns:
                if self._board[rows][columns]._getFace() == False:
                    print('*')
                else:
                    print(self._board[rows][columns._getValue()])
                print()

    def play(self):
        while True:
            if self.isGameOver() == False:
                break
            self.displayBoard()              
            coord1 = input('Enter coordinates for the first card: ')
            coord2 = input('Enter coordinates for the second card: ')
            newCoord1 = coord1.split(" ")
            newCard1 = self._board[int(newCoord1[0])][int(newCoord1[1])].getValue()
            newCoord2 = coord2.split(" ")
            newCard2 = self._board[int(newCoord2[0])][int(newCoord2[1])].getValue()
            if newCard1 != newCard2:
                print("Not an identical pair. Found", newCard1, "at", newCoord1, "and", newcard2, "at", newCoord2)
            else:
                self._board[int(newCoord1[0])][int(newCoord1[1])].setFace()
                self._board[int(newCoord2[0])][int(newCoord2[1])].setFace()

    def isGameOver(self):             
        face = False
        for rows in self._rows:
            for columns in self._columns:
                if self._board[row][column] == False:
                    face = True
        return face

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

抱歉格式问题。这个网站让我很困惑。哈哈。如果有人能帮助我,那就太好了。

精确回溯:

Traceback (most recent call last):
  File "C:\Users\River\Desktop\Hw-3.py", line 135, in <module>
    main()
  File "C:\Users\River\Desktop\Hw-3.py", line 132, in main
    game.play()
  File "C:\Users\River\Desktop\Hw-3.py", line 84, in play
    self.displayBoard()
  File "C:\Users\River\Desktop\Hw-3.py", line 74, in displayBoard
    if self._board[rows][columns].getFace() == False:
AttributeError: 'int' object has no attribute 'getFace'

有时这个

Traceback (most recent call last):
  File "C:\Users\River\Desktop\Hw-3.py", line 130, in <module>
    main()
  File "C:\Users\River\Desktop\Hw-3.py", line 127, in main
    game.play()
  File "C:\Users\River\Desktop\Hw-3.py", line 79, in play
    self.displayBoard()
  File "C:\Users\River\Desktop\Hw-3.py", line 67, in displayBoard
    for rows in self._rows:
TypeError: 'int' object is not iterable

也许是 str 方法?没有把握。如果是,不知道如何为此写一个..

我解决了你的大部分问题。见内评论。您的代码未被考虑 "Pythonic",但我保留了大部分代码。

您对变量和方法名称的选择可以改进。 例如,当遍历棋盘的行和列时,使用 rowcol 作为迭代变量。

此外,Card class 中的 getFace() 方法也许可以更好地重命名为 isFaceUp(),或者类似的东西。在这种情况下,取消与 False 的比较也会使阅读更自然。

另一个问题是您对 setters/getters 的使用。他们不被视为 "Pythonic" 正如其他人已经在评论中建议的那样。

各种方法都有错误,有些是初级的,看来你是想一下子把所有东西都写出来。一次 write/test/debug 小段代码通常是个好主意。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function  # I'm using Python 2.7 so need this

import random


class Card(object):
    '''A card object with a suit and face'''

    def __init__(self, value):
        '''Stores both the card's value and face'''
        self._value = value
        self._face = False

    # Getters and setters are not Pythonic
    # Consider using property
    def getValue(self):
        '''Get the value of the card'''
        return self._value

    def getFace(self):
        '''Get the face of the card'''
        return self._face

    def setFace(self):
        self._face = True

    def __str__(self):
        '''Override str to return printable result. Useful for debugging.'''
        return ", ".join(("Value: ", str(self._value), "Face: ", str(self._face)))


class Deck(object):

    def __init__(self, pairs):
        self._pairs = pairs
        self._cards = []
        for cards in range(self._pairs):
            c1 = Card(cards)
            self._cards.append(c1)
            c2 = Card(cards)
            self._cards.append(c2)

    def deal(self):
        if len(self) == 0:
           return None
        else:
           return self._cards.pop(0)

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

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


class Game(object):

    def __init__(self, rows, columns):
        self._deck = Deck((rows * columns)//2)
        self._rows = rows
        self._columns = columns
        self._board = []
        for row in range(self._rows):
            self._board.append([0] * self._columns)

        self.populateBoard()
        # self.revealBoard()  # For debugging


    def populateBoard(self):
        self._deck.shuffle()
        # For debugging
        # print("Deck: {}".format(map(str, self._deck._cards)))
        # self._board = [[self._deck.deal() for _ in range(self._columns)]
        #                for _ in range(self._rows)]

        # Consider renaming variables as col and row. Similar for others
        # elsewhere
        for columns in range(self._columns):
            for rows in range(self._rows):
                self._board[rows][columns] = self._deck.deal()


    def revealBoard(self):
        """For debugging. Reveal the cards for the board"""
        for rows in range(self._rows):
            for columns in range(self._columns):
                print(str(self._board[rows][columns].getValue()) + " ", end="")

            print("")


    def displayBoard(self):
        for rows in range(self._rows):
            for columns in range(self._columns):
                if self._board[rows][columns].getFace() == False:
                    print('* ', end="")
                else:
                    # print(self._board[rows][columns._getValue()])
                    print(str(self._board[rows][columns].getValue()) + " ", end="")

            print("")  # Print newline after each row


    def play(self):
        while not self.isGameOver():
            self.displayBoard()
            coord1 = raw_input('Enter coordinates for the first card: ')
            coord2 = raw_input('Enter coordinates for the second card: ')
            newCoord1 = map(int, coord1.strip().split())
            newCard1 = self._board[newCoord1[0]][newCoord1[1]].getValue()
            newCoord2 = map(int, coord2.strip().split())
            newCard2 = self._board[newCoord2[0]][newCoord2[1]].getValue()

            # Need to check that user has entered valid data here

            # newCoord1 = coord1.split(" ")
            # newCard1 = self._board[int(newCoord1[0])][int(newCoord1[1])].getValue()
            # newCoord2 = coord2.split(" ")
            # newCard2 = self._board[int(newCoord2[0])][int(newCoord2[1])].getValue()
            if newCard1 != newCard2:
                print("Not an identical pair. Found", newCard1, "at", newCoord1, "and", newCard2, "at", newCoord2)
            else:
                self._board[newCoord1[0]][newCoord1[1]].setFace()
                self._board[newCoord2[0]][newCoord2[1]].setFace()
                # self._board[int(newCoord1[0])][int(newCoord1[1])].setFace()
                # self._board[int(newCoord2[0])][int(newCoord2[1])].setFace()

        print("Game Over")
        self.displayBoard()

    def isGameOver(self):
        for rows in range(self._rows):
            if not all(card.getFace() for card in self._board[rows]):
                return False
            # for columns in range(self._columns):
            #     # If there is still one card facing down then
            #     # game is not over yet
            #     if self._board[rows][columns].getFace() == False:
            #         return False
        return True


def getUserInput(input_type):
    while True:
        try:
            val = int(raw_input("Enter number of {}: ".format(input_type)))
            if 1 <= val <= 9:
                return val
            else:
                raise ValueError
        except ValueError:
            print ("    ***Number of {} must be between 1 and 9! Try again.***".format(input_type))


def main():

    while True:
        # Force user to enter valid value for number of rows and columns
        rows = getUserInput("rows")
        columns = getUserInput("cols")

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