大爽Python入门教程 7-3 实践练习 使用类`class`组织代码

大爽Python入门公开课教案 点击查看教程总目录

在之前的,第六章第9小节,实现了一个井字棋小游戏。

这里我们把这个游戏,功能不变,换种写法。
使用类来重新组织下代码。

1 思路分析

这里用一个类去实现,直接给其起名为Game
这个Game

应该有以下属性

  • board: 存储棋盘棋子信息的二维列表
  • current: 当前玩家棋子符号,原来叫做turn,这里改个名字。

原本有以下函数

  • generate_board: 生成board
  • show_board: 展示board
  • parse_rc: 解析用户输入命令中的行与列
  • check_bunch_match: 检查某一串是否全部为当前棋子
  • check_win: 检查当前玩家是否胜利
    (当前玩家落子能否连成一条线)
  • main: 运行游戏

这里做如下调整

  1. generate_board应该放在类的构造器函数中__init__实现
  2. main改名为run,意思更适合。
  3. 原本切换玩家的代码,抽出来做成专门的方法turn_player

2 代码框架

初步代码框架如下

WELCOME = "Welcome to Tic-Tac-Toe!"
ENTER  = "%s's turn. Enter row index and column index to place (ri, ci):\n"
Invalid = "Invalid command."
Used = "The place is already occupied."


class Game:
    def __init__(self):
        pass

    def show_board(self):
        pass

    def check_bunch_match(self, bunch):
        pass

    def check_win(self):
        pass

    def turn_player(self):
        pass

    def parse_rc(self, cmd):
        pass

    def run(self):
        pass


game = Game()
game.run()

3 总代码

将上面框架中的方法,逐步实现后如下

WELCOME = "Welcome to Tic-Tac-Toe!"
ENTER  = "%s's turn. Enter row index and column index to place (ri, ci):\n"
Invalid = "Invalid command."
Used = "The place is already occupied."


class Game:
    def __init__(self):
        self.current = "X"

        self.board = [
            [" " for ci in range(3)] for ri in range(3)
        ]

    def show_board(self):
        for ri, row in enumerate(self.board):

            row_str = ""
            for ci, cell in enumerate(row):
                row_str += " %s " % cell
                if ci != 2:
                    row_str += "|"
            print(row_str)

            if ri != 2:
                print("---+---+---")

    def check_bunch_match(self, bunch):
        res = True
        for one in bunch:
            if one != self.current:
                res = False
                break

        return res

    def check_win(self):
        r, c = len(self.board), len(self.board[0])
        for ri in range(r):
            row = self.board[ri]
            if self.check_bunch_match(row):
                return True

        for ci in range(c):
            column = [self.board[ri][ci] for ri in range(r)]
            if self.check_bunch_match(column):
                return True

        diagonal_1 = [self.board[ri][ri] for ri in range(r)]
        diagonal_2 = [self.board[ri][c - ri - 1] for ri in range(r)]
        if self.check_bunch_match(diagonal_1):
            return True
        if self.check_bunch_match(diagonal_2):
            return True

        return False

    def turn_player(self):
        if self.current == "X":
            self.current = "O"
        else:
            self.current = "X"

    def parse_rc(self, cmd):
        rc = cmd.split(",")
        if len(rc) == 2:
            ri, ci = rc
            ri = ri.strip()
            ci = ci.strip()
            if ci.isdigit() and ri.isdigit():
                ci = int(ci)
                ri = int(ri)
                if 0 <= ci < 3 and 0 <= ri < 3:
                    return ri, ci

        return -1, -1

    def run(self):
        print(WELCOME)
        while True:
            self.show_board()
            cmd = input(ENTER % self.current)
            ri, ci = self.parse_rc(cmd)
            if ri >= 0:
                if self.board[ri][ci] == " ":
                    self.board[ri][ci] = self.current
                    if self.check_win():
                        self.show_board()
                        print("%s win!" % self.current)
                        return

                    self.turn_player()
                else:
                    print(Used)
            else:
                print(Invalid)


game = Game()
game.run()

运行效果和原来的(第六章第九节)是一样的,
这里就不额外展示了。

posted @ 2021-12-23 23:19  大爽歌python编程辅导  阅读(72)  评论(0编辑  收藏  举报