Tic_Tac_Toe游戏即井字棋游戏

一直很喜欢玩井字棋,学了python之后,就开始想办法实现一下,看了一些资料,终于实现了,如下所示,有些方法个人觉得不是特别简洁,欢迎大家批评指正!

import random #调用随机数库
#打印Board
def drawBoard(board):
    """
    This function prints out the board that it was passed.
    Board is a list of 10 strings representing the board (ignore index 0)
    The board is numbered like the keyboard's number pad.
    """
    for i in range(1,12):
        if i in [1,3,5,7,9,11]:
            for j in range(1,12):
                if j in [4,8]:
                    print("|",end="")
                else:
                    print(" ",end="")
        elif i in [2,6,10]:
            for j in range(1,12):
                if j in [4,8]:
                    print("|",end="")
                elif j in [2,6,10]:
                    if (i,j) == (2,2):
                        print(board[1],end="")
                    elif (i,j) == (2,6):
                        print(board[2],end="")
                    elif (i,j) == (2,10):
                        print(board[3],end="")
                    elif (i,j) == (6,2):
                        print(board[4],end="")
                    elif (i,j) == (6,6):
                        print(board[5],end="")
                    elif (i,j) == (6,10):
                        print(board[6],end="")
                    elif (i,j) == (10,2):
                        print(board[7],end="")
                    elif (i,j) == (10,6):
                        print(board[8],end="")
                    elif (i,j) == (10,10):
                        print(board[9],end="")   
                else:
                    print(" ",end="")
        else:
            for j in range(11):
                print("-",end="")  
        print()
    
#获取用户的Letter    
def inputPlayerLetter():
    """
    Lets the player type which letter ('X' or 'O') they want to be.
    Returns a list with the player's letter as the first item, 
    and the computer's letter as the second.
    
    """
    # set the user's input to letter
    # if letter is neither 'X' nor 'O', ask user to input again
    # until letter is 'X' or 'O'
    flag = True
    while flag:
        letter = input("Do you want to be X or O?")
        if letter == "X":
            flag = False
            return ['X','O']
        elif letter == "O":
            flag = False
            return ['O','X']
    
    
    # if letter is 'X', return ['X','O']
    # else return ['O','X']

#决定谁先开始
def whoGoesFirst():
    """ 
    randomly choose the player who goes first
    """
    # use the randint function in random module (look for the help manual)
    # then return a random integer from [0,1]
    # if the return integer is 0, return 'computer'
    # else return 'player'
    n = random.randint(0,1)
    if n == 0:
        return 'computer'
    else:
        return 'player'

#判断用户是否继续       
def playAgain():
    """This function returns True if the player wants to play again, 
    otherwise it returns False"""
    print('Do you want to play again?(yes or no)')
    # write one line code to implement this function
    return True if input().lower().startswith()=='y' else False

#下一步棋
def makeMove(board,letter,move):
    """This function adds the player's move to the board"""
    board[move] = letter

#判断是否胜利    
def isWinner(board,letter):
    """
    Given a board and a player's letter, 
    this function returns True if the player has won. 
    """
    return ((board[1]==letter and board[2]==letter and board[3]==letter)or 
            (board[4]==letter and board[5]==letter and board[6]==letter)or 
            (board[7]==letter and board[8]==letter and board[9]==letter)or 
            (board[1]==letter and board[4]==letter and board[7]==letter)or 
            (board[2]==letter and board[5]==letter and board[8]==letter)or 
            (board[3]==letter and board[6]==letter and board[9]==letter)or 
            (board[1]==letter and board[5]==letter and board[9]==letter)or 
            (board[3]==letter and board[5]==letter and board[7]==letter))

#判断是否空闲
def isSpaceFree(board,move):
    """Return True if the passed move is free on the passed board"""
    # write one line of code to finish this function
    return True if board[move] == " " else False

#得到用户的下一步
def getPlayerMove(board):
    """Let the player type in their move."""
    # ask the player to input their move
    # until int(move) is a number between 1 to 9 and the move is free on board
    # then return move as a number
    print("What is your next move? (1-9)")
    move = eval(input())
    while not isSpaceFree(board,move) or move not in [1,2,3,4,5,6,7,8,9]: 
        move = eval(input())
    return move

#从随机列表中取一步
def chooseRandomMoveFromList(board,movesList):
    """
    Returns a valid move from the passed list on the passed baord.
    Returns None if there is no valid move"""
    possibleMoves = []
    # for each move in movesList, 
    # if the move is free on board,
    # then add the move to possibleMoves
    for i in movesList:
        if board[i] == " ":
            possibleMoves.append(i)
    
    
    # if the length of possibleMoves is not 0
    # then randomly choose one and return it
    # else renturn None
    # you may need choice function in random module
    if len(possibleMoves) != 0:
        n = random.randint(0,len(possibleMoves)-1)
        return possibleMoves[n]
    return None

#得到board的一份拷贝(深拷贝)    
def getBoardCopy(board):
    copy_board = []
    for i in board:
        copy_board.append(i)
    return copy_board

#得到计算机的下一步
def getComputerMove(board,computerLetter):
    """
    Given a board and the computer's letter, 
    determine where to move and return that move
    """
    if computerLetter == 'X':
        playerLetter = 'O'
    else:
        playerLetter = 'X'
    
    # Here is our algorithm for our Tic Tac Toe AI:
    # first, check if computer can win in the next move.
    # hint: for all the 9 positions, if the position is free, then make move;
    # if that move can make the computer win, then return the position.
    
    # FILL IN YOUR CODE HERE...
    for i in range(1,10):
        copy_board = getBoardCopy(board)
        if isSpaceFree(copy_board,i):
            makeMove(copy_board,computerLetter,i)
            if isWinner(copy_board,computerLetter):
                return i
    
            
    # check if the player could win on their next move, and block them.
    # otherwise, return the position that makes the player win
    # FILL IN YOUR CODE HERE...
    for i in range(1,10):
        copy_board = getBoardCopy(board)
        if isSpaceFree(copy_board,i):
            makeMove(copy_board,playerLetter,i)
            if isWinner(copy_board,playerLetter):
                return i
            
    # Try to take one of the corners, if they are free.
    move = chooseRandomMoveFromList(board,[1,3,7,9])
    if move != None:
        return move
    
    # Try to take the center, if it is free.
    if isSpaceFree(board,5):
        return 5
    
    # Move on one of the sides
    return chooseRandomMoveFromList(board,[2,4,6,8])

#判断Board是否满
def isBoardFull(board):
    """
    Return True if every space on the board has been taken. 
    Otherwise return False.
    """
    for i in range(1,10):
        if board[i] == " ":
            return False
    return True

#主体程序      
# the main body of the Tic Tac Toe 
print('Welcome to Tic Tac Toe!')
while True:
    # reset the board
    theBoard =  [' '] * 10 
    playerLetter, computerLetter = inputPlayerLetter()
    turn = whoGoesFirst()
    print('The ' + turn + ' will go first.')
    gameIsPlaying = True
    while gameIsPlaying:
        if turn == 'player': # player's turn
            # use your function to print out the board
            drawBoard(theBoard)
            # use your function to get player's move, and set it to variable move
            move = getPlayerMove(theBoard)
            # adds the player's move to the board
            makeMove(theBoard,playerLetter,move)
            # if the player has won
            if isWinner(theBoard,playerLetter):
                # print out the board
                drawBoard(theBoard)
                # print the prompt message "Hooray! You have won the game!"
                print("Hooray! You have won the game!")
                # set gameIsPlaying to False
                gameIsPlaying = False
            # else
            else:
                # if the board is full
                if isBoardFull(theBoard):
                    # print out the board
                    drawBoard(theBoard)
                    # print the prompt message "The game is a tie!"
                    print("The game is a tie!")
                    # end the loop
                    break
                # else
                else:
                    # set turn to computer
                    turn = 'computer'
        else:
            # computer's turn
            # get the computer move
            move = getComputerMove(theBoard,computerLetter)
            #  adds the computer's move to the board
            makeMove(theBoard,computerLetter,move)
            # if the computer has won
            if isWinner(theBoard,computerLetter):
                # print out the board
                drawBoard(theBoard)
                # print the prompt message "The computer has beaten you! You lose."
                print("The computer has beaten you! You lose.")
                # set gameIsPlaying to False
                gameIsPlaying = False
            # else
            else:
                # if the board is full
                if isBoardFull(theBoard):
                    # print out the board
                    drawBoard(theBoard)
                    # print the prompt message "The game is a tie!"
                    print("The game is a tie!")
                    # end the loop
                    break
                # else
                else:
                     # set turn to player.
                    turn = 'player'
                                  
    if not playAgain():
        break 

总结

1.在写getComputerMove(board,computerLetter)函数时,因为首先要去让computer预测自己是否下一步可以取得胜利,所以要不断地尝试,所以需要一份board的拷贝,而一开始我只是简单地copy_board=board,

因为这是浅拷贝,且列表是可变对象,所以导致copy_borad和board共享一段地址空间,所以copy_board的变化会引起board的变化,从而导致在下次循环开始,board发生了改变,从而发生了错误,发现这个问题之后,我思考了一下,有两种办法,首先自己写一个深拷贝列表的函数getBoardCopy(board),如下:

或者使用copy库里的深拷贝函数deepcopy()都可以使问题得到很好地解决。

2.学习的过程中,我不仅仅知道了下井字棋的奥妙,即先下角(1,3,7,9),再下中间(5),最后下边(2,4,6,8),当然,自己和对方快赢的时候,优先级最高;并且我也加深了对于python的理解,像在判断是否继续玩的时候的函数playAgain(),只用一句话就简单地实现了,如下:

还有在实现isWinner()函数时,我也只用了一句话就实现了,但是这一句话比较长,同时没有什么好的方法,只能把获胜的8种方法列举出来,如下:

最后,其实有很多函数的实现可以说是很简单了,但是我们还是需要将它作为一个函数来实现,因为,这样可以提高代码的复用,我们不需要频繁地去写同一段代码,极大地提高了我们的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值