zoukankan      html  css  js  c++  java
  • python 纯函数实现井字棋游戏

    1、定义全局变

    '''全局变量:
     X 和 O 表示两方的棋子;
     EMPTY 表示棋位为空;
     TIE 表示平局;
     NUM_SQUARES 表示有 9 个棋位
     '''
     
     X = "X"
     O = "O"
     EMPTY = " "
     TIE = "TIE"
     NUM_SQUARES = 9

    2、定义调用到的函数

    def ask_yes_no(question):
        '''问一个是或否的问题,用 y 或 n 回答。'''
        response = None
        while response not in ('y', 'n'):
            response = input(question).lower()
        return response
    
    
    def ask_number(question, low, high):
        '''讯问一个规定范围的数字。'''
        response = None
        while response not in range(low, high):
            response = int(input(question))
        return response
    
    
    def pieces():
        '''决定在人和机器之间谁先行棋。'''
        go_first = ask_yes_no('你先走? (y/n): ')
        if go_first == 'y':
            print('
    好,你先请。')
            human = X
            computer = O
        else:
            print('
    你放弃先手,我先走。')
            computer = X
            human = O
        return computer, human
    
    
    def new_board():
        '''创建一个棋盘。'''
        board = []
        for square in range(NUM_SQUARES):
            board.append(EMPTY)
        return board
    
    
    def display_board(board):
        '''显示棋盘。'''
        print('
    	', board[0], '|', board[1], '|', board[2])
        print('	', '---------')
        print('	', board[3], '|', board[4], '|', board[5])
        print('	', '---------')
        print('	', board[6], '|', board[7], '|', board[8], '
    ')
    
    
    def legal_moves(board):
        '''创建合法的行棋位置清单。'''
        moves = []
        for square in range(NUM_SQUARES):
            if board[square] == EMPTY:  # 该棋位为空
                moves.append(square)
        return moves
    
    
    def winner(board):
        '''判定游戏获胜者。'''
        WAYS_TO_WIN = ((0, 1, 2),  #
                       (3, 4, 5),
                       (6, 7, 8),
                       (0, 3, 6),  #
                       (1, 4, 7),
                       (2, 5, 8),
                       (0, 4, 8),  # 主对角线
                       (2, 4, 6))  # 副对角线
        # 谁先有三个棋子在一条直线上谁就获胜。
        for row in WAYS_TO_WIN:
            if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
                winner = board[row[0]]
                return winner
        
        # 没有获胜方,但棋盘已经下满,判为平局
        if EMPTY not in board:
            return TIE
    
        return None  # 没有获胜方,且非平局
    
    
    def human_move(board, human):
        '''获取玩家的行棋位置。'''  
        legal = legal_moves(board)  # 合法的行棋位置清单
        move = None
        while move not in legal:
            move = ask_number('你走哪? (0 - 8):', 0, NUM_SQUARES)
            if move not in legal:
                print('
    你选的棋位已落子,重新选择。
    ')
        print('落子无悔...')
        return move
    
    
    def computer_move(board, computer, human):
        '''获取电脑的行棋位置。'''
        
        board = board[:]  # 通过切片复制棋盘, 创建局部变量
        BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7)  # 优先的行棋位置
    
        print('我走到:', end=' ')
        
        # 在局部空间确定可以获胜的走法
        for move in legal_moves(board):  # 合法的行棋位置列表
            board[move] = computer  # 更新棋盘副本
            if winner(board) == computer:
                # 计算机能获胜
                print(move)
                return move
            # 如果计算机在该棋位行棋不能获胜,
            board[move] = EMPTY  # 悔棋,更换下一个合法棋位
        
        # 阻止玩家获胜
        for move in legal_moves(board):  # 合法的行棋位置列表
            board[move] = human  # 更新棋盘
            if winner(board) == human:
                # 在该棋位玩家行棋后将获胜
                print(move)
                return move
            # 玩家不能获胜,不行棋至此
            board[move] = EMPTY
    
        # 没有能使行棋双方立决胜负的棋位,从优先棋位选择合法行棋位置
        for move in BEST_MOVES:
            if move in legal_moves(board):
                print(move)
                return move
    
    
    def next_turn(turn):
        '''切换行棋方'''
        if turn == X:
            return O
        else:
            return X
    
        
    def congrat_winner(the_winner, computer, human):
        '''向获胜方表示祝贺或声明平局'''
        if the_winner != TIE:
            print(the_winner, '祝贺你!
    ')
        else:
            print('平局。。。
    ')
    
        if the_winner == computer:
            print('如我所料,我又胜了。
    这是否能说明计算机在给方面都优于人类呢?')
    
        elif the_winner == human:
            print('真是匪夷所思,你没捣鬼吧?人类怎么会胜? 
    不会有下次了。' )
    
        elif the_winner == TIE:
            print('你很厉害嘛,能跟计算机打成平手。')

    3、定义主函数

     

    def main():
        display_instruct()  # 显示游戏操作指南
        computer, human = pieces()  # 决定谁先行棋
        turn = X  # 先行棋方执子 X
        board = new_board()  # 创建空棋盘
        display_board(board) # 显示棋盘
    
        while not winner(board): 
            # 判定结果,在没有获胜方且不是平局时进入循环
            if turn == human:
                # 轮到玩家行棋,玩家行棋
                move = human_move(board, human)  # 玩家的行棋位置
                board[move] = human  # 更新棋盘
            else:
                # 轮到电脑行棋
                move = computer_move(board, computer, human)  # 电脑的行棋位置
                board[move] = computer  # 更新棋盘
            display_board(board)  # 显示更新后的棋盘
            turn = next_turn(turn)  # 切换行棋方
    
        the_winner = winner(board)  # 判定获胜者,返回获胜方的执子,平局返回 None
        congrat_winner(the_winner, computer, human)  # 向获胜方表示祝贺或声明是平局

    4、调用主函数,启动程序

    main()
    input('
    
    按回车键退出程序。')  # 等待用户

    在 jupyter 中演练如下:

     

     

     

     

     

  • 相关阅读:
    菜鸡的Java笔记 第十六
    菜鸡的Java笔记 第十五 this 关键字
    php 数组(2)
    菜鸡的Java笔记 第十四 String 类常用方法
    菜鸡的Java笔记 第十三 String 类的两种实例化方法
    菜鸡的Java笔记 第十二
    php 递推 递归
    bzoj2306 [Ctsc2011]幸福路径
    bzoj3712 [PA2014]Fiolki
    bzoj2958 序列染色
  • 原文地址:https://www.cnblogs.com/shanger/p/12932490.html
Copyright © 2011-2022 走看看