大爽Python入门教程 72 面向对象编程 使用类`class`组织代码

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

在之前的,第六章第9小节,实现了一个井字棋小游戏。
其代码是面向过程的,换言之使用函数来组织的。

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

这种写法是不唯一的,有非常多种写法,以下本人只是展示了一种,供大家参考。

1 思路分析

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

应该有以下属性

  • board: 存储棋盘棋子信息的二维列表
  • current: 当前玩家棋子符号。

应该有以下方法

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

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):
        self.board = []
        self.current = "X"

    def generate_board(self):
        pass

    def show_board(self):
        pass

    def check_bunch_match(self, bunch):
        return False

    def check_win(self):
        return False

    def place(self, ri, ci):
        return True

    def turn(self):
        pass

    def parse_rc(self, cmd):
        return -1, -1

    def run(self):
        while True:
            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.generate_board()
        self.current = "X"

    def generate_board(self):
        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 place(self, ri, ci):
        if self.board[ri][ci] != " ":
            return False

        self.board[ri][ci] = self.current
        return True

    def turn(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:
                res = self.place(ri, ci)
                if res:
                    if self.check_win():
                        self.show_board()
                        print("%s win!" % self.current)
                        return

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


game = Game()
game.run()

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

原文地址:https://www.cnblogs.com/BigShuang/p/15717474.html