Tic Tac Toe(井字棋)小游戏
今天介绍的就是大家很熟悉的井字棋游戏,相信大家都玩过。但是玩这个游戏,我还真没玩过电脑。本文最精彩的地方莫过于电脑是如何落子的代码片段。
希望大家闲暇之余可以多多思考。
游戏流程图大致如下:
话不多收说,直接上代码
import random
#打印棋盘
def drawBoard(board):
print(board[7]+'|'+board[8]+'|'+board[9])
print('-----')
print(board[4]+'|'+board[5]+'|'+board[6])
print('-----')
print(board[1]+'|'+board[2]+'|'+board[3])
#玩家选择X或O
def inputPlayerLetter():
letter = ''
while not(letter == 'X' or letter == 'O'):
print('Do you want to be X or O?')
letter = input().upper()
if letter == 'X':
return ['X', 'O'] #列表索引0代表的元素是玩家所选符号,列表索引1代表的元素为电脑所选字符
else:
return ['O', 'X']
#决定先手
def whoGoesFirst():
if random.randint(0, 1) == 0: #值0或1
return 'computer'
else:
return 'player'
#走棋
def makeMove(board, letter, move): #move为棋盘索引值,letter代表棋子
board[move] = letter
#判断输赢(8种胜利可能)
def isWinner(bo, le):
return ((bo[7] == le and bo[8] == le and bo[9] == le) or
(bo[4] == le and bo[5] == le and bo[6] == le) or
(bo[1] == le and bo[2] == le and bo[3] == le) or
(bo[7] == le and bo[4] == le and bo[1] == le) or
(bo[8] == le and bo[5] == le and bo[2] == le) or
(bo[9] == le and bo[6] == le and bo[3] == le) or
(bo[7] == le and bo[5] == le and bo[3] == le) or
(bo[9] == le and bo[5] == le and bo[1] == le))
#复制游戏板的数据
def getBoardCopy(board):
boardCopy = []
for i in board:
boardCopy.append(i)
return boardCopy
#判断棋盘上的格子是否为空
def isSpaceFree(board, move):
return board[move] == '' #格子为空返回True
#玩家输入想要落子的格子的编号
def getPlayerMove(board):
move = ''
#当落子的格子编号属于(1-9)并且格子为空时退出循环
while move not in '1 2 3 4 5 6 7 8 9'.split() or not isSpaceFree(board, int(move)):
print('What is your next move?(1-9)')
move = input()
return int(move)
#电脑随机选择落点棋子
def chooseRandomMoveFormList(board, moveList):
possibleMoves = []
for i in moveList:
if isSpaceFree(board, i):
possibleMoves.append(i)
if len(possibleMoves) != 0:
return random.choice(possibleMoves)
else:
return None
#电脑玩家
def getComputerMove(board, computerLetter):
if computerLetter == 'X':
playerLetter = 'O'
else:
playerLetter = 'X'
for i in range(1, 10):
boardCopy = getBoardCopy(board)
if isSpaceFree(boardCopy, i):
makeMove(boardCopy, computerLetter, i)
if isWinner(boardCopy, computerLetter):
return i
for i in range(1, 10):
boardCopy = getBoardCopy(board)
if isSpaceFree(boardCopy, i):
makeMove(boardCopy, playerLetter, i)
if isWinner(boardCopy, playerLetter):
return i
'''如果电脑不能通过一步落子获胜,并且不需要阻止玩家的落子,它将会根据可用的空间,移动到角落、中间或边上的空间'''
move = chooseRandomMoveFormList(board, [1, 3, 7, 9]) #角
if move != None:
return move
if isSpaceFree(board, 5): #中心
return 5
return chooseRandomMoveFormList(board, [2, 4, 6, 8]) #边
#判断棋盘是否满
def isBoardFull(board):
for i in range(1, 10):
if isSpaceFree(board, i):
return False
return True
#主函数
print('Welcome to Tic-Tac-Toe!')
while True:
theBoard = ['']*10 #建立一个空棋盘
playerLetter, computerLetter = inputPlayerLetter() #inputPlayerLetter()返回值为一个含有两个元素的列表
turn = whoGoesFirst() #先手
print('The ' + turn + ' will go first.')
gameIsPlaying = True #游戏状态码
while gameIsPlaying:
if turn == 'player': #玩家回合
drawBoard(theBoard)
move = getPlayerMove(theBoard)
makeMove(theBoard, playerLetter, move)
if isWinner(theBoard, playerLetter):
drawBoard(theBoard)
print('Hooray!You have won the game!')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'computer'
else: #电脑回合
move = getComputerMove(theBoard, computerLetter)
makeMove(theBoard, computerLetter, move)
if isWinner(theBoard, computerLetter):
drawBoard(theBoard)
print('The computer has beaten you!You lose.')
gameIsPlaying = False
else:
if isBoardFull(theBoard):
drawBoard(theBoard)
print('The game is a tie!')
break
else:
turn = 'player'
print('Do you want to play again?(yes or no)')
if not input().lower().startswith('y'):
break