井字棋玩具进阶!实现人机交互!
核心博弈算法解释:
博弈函数minimax使用了极小化极大算法,通过递归和回溯的方式来模拟整个决策树的搜索过程,并根据每个节点的收益评估来进行选择。
极小化极大算法尝试在决策树的每个层级上最大化自己的收益,并且假设对手会在其层级上选择最有利于对手自己的行动。该算法递归地搜索所有可能的游戏局面,并评估它们的分数来确定最优的下一步行动。在实现过程中,假设计算机为极大化玩家,用户为极小化玩家。
该函数有三个输入参数:
board
:表示当前游戏局面的状态。depth
:表示当前搜索的深度。通常用于在达到一定深度时停止搜索或评估局面。maximizing_player
:表示当前轮到的玩家是否是极大化收益的玩家。
函数会根据棋盘状态给出不同的返回值。若用户获胜,返回-1。若计算机获胜,返回1,若平局则返回0。
接下来,如果当前轮到的是极大化(极小化)收益的玩家,则进入一个循环,遍历所有可用的移动(空位)。对于每个移动,都将创建一个新的局面,并在该位置上标记,然后递归调用 minimax 函数来评估新局面,并将返回的评估分数与当前的最大(最小)分数进行比较,更新并返回最大(最小)分数。
通过不断递归调用 minimax 函数,最终找到了最优的下一步行动,该行动的分数已经经过评估和比较,实现人机博弈。
python实现:
#标记
EMPTY = ' '
HUMAN = 'X'
COMPUTER = 'O'
def print_board(board):
print('---------')
for i in range(3):
print('|', end='')
for j in range(3):
print(board[i*3 + j], end='|')
print('\n---------')
#平局之棋盘满
def is_full(board):
return EMPTY not in board
#定义胜利
def is_winner(board, player):
winning_rows = [[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 winning_rows:
if all(board[i] == player for i in row):
return True
return False
#合法标记
def get_available_moves(board):
return [i for i, spot in enumerate(board) if spot == EMPTY]
#博弈
def minimax(board, depth, maximizing_player):
if is_winner(board, HUMAN):
return -1
elif is_winner(board, COMPUTER):
return 1
elif is_full(board):
return 0
if maximizing_player:
max_eval = float('-inf')
for move in get_available_moves(board):
new_board = board.copy()
new_board[move] = COMPUTER
eval = minimax(new_board, depth+1, False)
max_eval = max(max_eval, eval)
return max_eval
else:
min_eval = float('inf')
for move in get_available_moves(board):
new_board = board.copy()
new_board[move] = HUMAN
eval = minimax(new_board, depth+1, True)
min_eval = min(min_eval, eval)
return min_eval
#博弈结论
def get_best_move(board):
best_eval = float('-inf')
best_move = None
for move in get_available_moves(board):
new_board = board.copy()
new_board[move] = COMPUTER
eval = minimax(new_board, 0, False)
if eval > best_eval:
best_eval = eval
best_move = move
return best_move
#启动
def main():
board = [EMPTY] * 9
while True:
print_board(board)
if is_full(board):
print("It's a tie!")
break
move = -1
available_moves = get_available_moves(board)
while move not in available_moves:
move = int(input("Enter your move (0-8): "))
board[move] = HUMAN
if is_winner(board, HUMAN):
print("You win!")
break
if is_full(board):
print("It's a tie!")
break
print("Computer is thinking...")
move = get_best_move(board)
board[move] = COMPUTER
if is_winner(board, COMPUTER):
print("Computer wins!")
break
if __name__ == '__main__':
main()
本文仅为娱乐之作,如有错误欢迎指出。