井字游戏 Tic Tac Toe

井字游戏 Tic Tac Toe

西安电子科技大学 Python 上机实验

井字棋(Tic Tac Toe, or noughts and crosses)游戏,又称连三子 棋,OX 棋,是一种供两人玩的纸笔游戏。两个玩家轮流在九个空格中 画上代表自己的 X 或 O ,谁先将自己的符号连成一线(横连、竖连、 斜连皆可),即获得胜利。倘若在游戏过程中,在所有空格都填满的 情况下,双方都没有取得胜利,那么游戏以平局告终。游戏界面类似 我们电脑键盘中的数字小键盘。

上代码!

采用面向对象。

import random


class TicTacToe(object):
    """井字游戏的类:"""

    def __init__(self):
        # 棋盘:
        self.pos = {}
        for i in range(1, 10):
            self.pos[i] = ' '
        self.board = f'{self.pos[7]}|{self.pos[8]}|{self.pos[9]}\n-+-+-\n{self.pos[4]}|{self.pos[5]}|{self.pos[6]}\n-+-+-\n{self.pos[1]}|{self.pos[2]}|{self.pos[3]}'
        # 棋子:
        self.player, self.computer, self.whoGoFirst = None, None, None
        # 检验退出游戏:
        self.exit = False

    def draw_board(self):
        """绘制棋盘:"""
        self.board = f'{self.pos[7]}|{self.pos[8]}|{self.pos[9]}\n-+-+-\n{self.pos[4]}|{self.pos[5]}|{self.pos[6]}\n-+-+-\n{self.pos[1]}|{self.pos[2]}|{self.pos[3]}'
        print(self.board)

    def go_first(self):
        """谁先走:"""
        if random.randint(0, 1) == 0:
            self.whoGoFirst = 'computer'
            print("这轮计算机先走。")
            return None
        self.whoGoFirst = 'player'
        print("这轮玩家先走。")

    def choose(self):
        """选择棋子:"""
        player_input = input('你要选 X 还是 O ?:').upper()
        while player_input != 'X' and player_input != 'O':
            player_input = input('请输入 X 或 O:').upper()
        if player_input == 'X':
            self.player, self.computer = 'X', 'O'
        if player_input == 'O':
            self.player, self.computer = 'O', 'X'

    def checkWinner(self, letter):
        # 检测获胜:
        return ((self.pos[7] == letter and self.pos[8] == letter and self.pos[9] == letter) or
                (self.pos[4] == letter and self.pos[5] == letter and self.pos[6] == letter) or
                (self.pos[1] == letter and self.pos[2] == letter and self.pos[3] == letter) or
                (self.pos[7] == letter and self.pos[4] == letter and self.pos[1] == letter) or
                (self.pos[8] == letter and self.pos[5] == letter and self.pos[2] == letter) or
                (self.pos[9] == letter and self.pos[6] == letter and self.pos[3] == letter) or
                (self.pos[7] == letter and self.pos[5] == letter and self.pos[3] == letter) or
                (self.pos[9] == letter and self.pos[5] == letter and self.pos[1] == letter))

    @staticmethod
    def isWinner(boardCopy, letter):
        """模拟胜利条件:"""
        return ((boardCopy[7] == letter and boardCopy[8] == letter and boardCopy[9] == letter) or
                (boardCopy[4] == letter and boardCopy[5] == letter and boardCopy[6] == letter) or
                (boardCopy[1] == letter and boardCopy[2] == letter and boardCopy[3] == letter) or
                (boardCopy[7] == letter and boardCopy[4] == letter and boardCopy[1] == letter) or
                (boardCopy[8] == letter and boardCopy[5] == letter and boardCopy[2] == letter) or
                (boardCopy[9] == letter and boardCopy[6] == letter and boardCopy[3] == letter) or
                (boardCopy[7] == letter and boardCopy[5] == letter and boardCopy[3] == letter) or
                (boardCopy[9] == letter and boardCopy[5] == letter and boardCopy[1] == letter))

    def spaceFree(self, loc):
        """检测空位置:"""
        if self.pos[loc] == ' ':
            return True
        return False

    def makeMove(self, loc, boardCopy):
        """让计算机模拟下棋:"""
        # 小心能不能改变 boardCopy 这个变量
        boardCopy[loc] = self.computer

    def player_move(self):
        """让玩家移动:"""
        choose = input("你要落子的位置是 (1~9):")
        while (eval(choose) not in list(range(1, 10))) or (self.pos[eval(choose)] != ' '):
            choose = input("请输入正确的落子位置 (1~9):")
        self.pos[eval(choose)] = self.player
        self.check_board()

    def computer_move(self):
        """让计算机移动:"""

        """第一次运行:"""
        if self.whoGoFirst == 'computer':
            self.pos[random.randint(1, 9)] = self.computer
            self.whoGoFirst = None
            return

        else:
            """检测有没有能获胜的位置:"""
            for i in range(1, 10):
                # 对复制字典进行操作:
                boardCopy = self.pos.copy()
                # 检测空位置:
                if self.spaceFree(i):
                    # 模拟下棋:
                    self.makeMove(i, boardCopy)
                    if self.isWinner(boardCopy, self.computer):
                        # 如果返回的是 True:就在 i 的位置处下棋:
                        self.pos[i] = self.computer
                        self.check_board()
                        return

            """阻止玩家胜利:"""
            for i in range(1, 10):
                # 复制棋盘:
                boardCopy = self.pos.copy()
                # 模拟下棋:
                if self.spaceFree(i):
                    self.makeMove(i, boardCopy)
                    if self.isWinner(boardCopy, self.player):
                        # 在此处下棋来阻止玩家:
                        self.pos[i] = self.computer
                        self.check_board()
                        return

            """填充四个角:"""
            for i in [1, 3, 7, 9]:
                if self.pos[i] == ' ':
                    self.pos[i] = self.computer
                    return

            """填充中心:"""
            if self.pos[5] == ' ':
                self.pos[i] = self.computer
                return

            """填充四个边:"""
            for i in [2, 4, 6, 8]:
                if self.pos[i] == ' ':
                    self.pos[i] = self.computer
                    return

    def boardFill(self):
        """检验棋盘是否已经被充满:"""
        for i in range(1, 10):
            if self.pos[i] == ' ':
                return False
        return True

    def check_board(self):
        """检验棋盘"""
        if self.checkWinner(self.player):
            print("玩家获胜!")
            self.exit = True
            return
        if self.checkWinner(self.computer):
            print("计算机获胜!")
            self.exit = True
            return
        if self.boardFill():
            print("平局!")
            self.exit = True

    def run_game(self):
        """启动程序:"""
        while True:
            self.__init__()
            self.choose()
            self.go_first()
            if self.whoGoFirst == 'player':
                self.draw_board()
                while True:
                    self.player_move()
                    self.computer_move()
                    self.draw_board()
                    self.check_board()
                    if self.exit:
                        break
            if self.whoGoFirst == 'computer':
                self.computer_move()
                self.draw_board()
                while True:
                    self.player_move()
                    self.computer_move()
                    self.draw_board()
                    self.check_board()
                    if self.exit:
                        break
            
            """是否要重新游戏:"""
            choice = input("你还要再玩一次吗?(yes or no):").lower()
            while choice not in ["yes", "no"]:
                choice = input("请输入(yes or no):")
            if choice == "no":
                print("游戏结束!")
                break


if __name__ == '__main__':
    my_TicTacToe = TicTacToe()
    my_TicTacToe.run_game()

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WhenXuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值