Python之闭包应用小游戏Tic Tac Toe

来自网易云课堂
http://study.163.com/course/courseLearn.htm?courseId=1000035#/learn/video?lessonId=1252115&courseId=1000035
‘用python做些事’-井字棋

学习这个小程序的时候想到playerMove() 函数正好可以用来练习闭包。于是做了一些改动。
# 定义闭包(move),使其可以访问其外部函数(playerMoverDeco)的变量board。
def playerMoverDeco(board):
    def move(player):
        loc = ''
        # loc指示玩家下棋子的位置
        # 初始时board中的值均为数字(str类型的数字),当一个玩家调用一次move后,loc位置变成
        # 'x' or 'o', 这样当下一个玩家调用move时,如果其选择的位置已经有棋子了,则对应位置上
        # 的值为'x' or 'o', 只有当loc对应的位置上为数字(str类型的数字)时,才是可用的位置。
        # 所以,只需要判断 if loc not in board 即可。略去isSpaceFree()。
        # 下面判断 loc == '0' 是因为初始输入的board 值为'0 1 2 3 4 5 6 7 8 9'。后面再考虑优化。
        while loc not in board or loc == '0':
            print (u'你的下一步是什么? (1-9)')
            loc = raw_input()
            
##        while not isSpaceFree(board, int(loc)):
##            print ('you can not go this way, try again ')
##            loc = raw_input()
            
        board[int(loc)] = player


        return board


    return move

main 中的调用也做了相应修改

while gameIsPlaying:                      
            # Player's turn.
            drawBoard(theBoard) 
            current_letter = Letter[turn]
            print (current_letter,' turn to play')
            board = playerMoverDeco(theBoard)
            theBoard = board(current_letter) 

            if isWinner(theBoard,current_letter):
            
                drawBoard(theBoard)
                print (u'哇! '+current_letter+u' 赢了!')
                gameIsPlaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print (u'Game over,棋力相当,平局!')
                    break
                else:
                    turn = (turn+1)%2

PS: 

raw_input() 在python中更名为 input() 

一台机器用python2.7, 另一台用python 3。把2.7下的原始代码拷到3的机器上运行一 直报错raw_input() 找不到,改成input() 就好了。


附课堂中的源代码:

#!/usr/bin/env python
# coding: utf-8
#copyRight by heibanke


def drawBoard(board):    
    # "board" is a list of 10 strings representing the board (ignore index 0)
    blank_board = '|     '*3+'|'
    edge_board = '+-----'*3+'+'
    def drawLine(board_line):
        insert_sym = '|'
        print blank_board
        print "|%3s%3s%3s%3s%3s  |"%(board_line[0],insert_sym,board_line[1],insert_sym,board_line[2])
        print blank_board
        print edge_board
        
    print edge_board
    drawLine(board[7:10])
    drawLine(board[4:7])
    drawLine(board[1:4])

def inputPlayerLetter():
    letter = ''
    while not (letter == 'X' or letter == 'O'):
        print u'你想用 X or O?'
        letter = raw_input().upper()

    if letter == 'X':
        return ['X', 'O']
    else:
        return ['O', 'X']

def playerMove(board,letter):
    # Let the player type in his move.
    move = ' '
    while move not in '1 2 3 4 5 6 7 8 9'.split():
        print u'你的下一步是什么? (1-9)'
        move = raw_input()
        try:
            if not isSpaceFree(board, int(move)):
                print u'棋盘上在%s这个位置已经有棋子了!'%move
                move=''
                continue
        except:
            print u'输入不合规则,请输入有效数字(1-9)'
            continue
        
    board[int(move)] = letter 
    
    return isWinner(board,letter)
    
def playAgain():
    # This function returns True if the player wants to play again, otherwise it returns False.
    print u'你想再玩一次吗? (yes or no)'
    return raw_input().lower().startswith('y')


def isWinner(bo, le):
    # Given a board and a player's letter, this function returns True if that player has won.
    return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
    (bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
    (bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
    (bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
    (bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
    (bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
    (bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
    (bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal


def isSpaceFree(board, move):
    # Return true if the passed move is free on the passed board.
    return board[move] == ' ' or board[move] in '1 2 3 4 5 6 7 8 9'.split()


def isBoardFull(board):
    # Return True if every space on the board has been taken. Otherwise return False.
    for i in range(1, 10):
        if isSpaceFree(board, i):
            return False
    return True





if __name__=="__main__":
    print u'欢迎来玩井字棋--Tic Tac Toe!'

    while True:
        # Reset the board
        theBoard = '0 1 2 3 4 5 6 7 8 9'.split()
        player1Letter, player2Letter = inputPlayerLetter()
        Letter = (player1Letter, player2Letter)
        print u' ' +Letter[0] + u'先走.'
        turn = 0
        gameIsPlaying = True

        while gameIsPlaying:
            
            # Player's turn.
            drawBoard(theBoard)
            current_letter = Letter[turn]
            
            print u"轮到 "+current_letter+u" 走了"
            
            if playerMove(theBoard,current_letter):
                drawBoard(theBoard)
                print u'哇! '+current_letter+u' 赢了!'
                gameIsPlaying = False
            else:
                if isBoardFull(theBoard):
                    drawBoard(theBoard)
                    print u'Game over,棋力相当,平局!'
                    break
                else:
                    turn = (turn+1)%2

        if not playAgain():
            break



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值