python - 实施终极井字游戏,但在一个子板上获胜会结束游戏
问题描述
我正在尝试用 python 制作一个终极井字游戏,它与实际游戏略有不同,因为当任何一个子板获胜时,该游戏就会结束。我正在使用带有 alpha-beta 修剪的 minimax 算法来找出机器人玩的最佳动作。问题是,当我运行代码并且是 bot 播放动作的时候,它会无休止地运行,而不会得出结论并返回 best_move。
与董事会的沟通已经处理完毕。我需要的是最好的价值,一旦我得到它,我就可以从那个状态检索索引。
最初,一旦游戏开始,用户会被提示从 1-9 移动,然后将其馈送到函数: Boards 是一个列表列表,其中包含每个子板的状态。
# choose a move to play
def play1(user_move):
# print_board(boards)
boards_list = main_boards.tolist()
player = 1
depth = 20
end_move = make_bot_move(boards_list, user_move, player, depth)
place(curr, end_move, 1)
return end_move
make_bot_move 函数获取人类的位置并计算出它应该在哪个子板上发挥其 best_move:
def make_bot_move(state, user_move, player, depth):
#sub_board = state[user_move]
# if suboptimal(state, user_move, player) != 0:
# return suboptimal(state, user_move, player)
pseudo_states = successors(state, player, user_move)
best_move = (-inf, None)
alpha = -inf
beta = inf
for x in pseudo_states:
state = x[0]
index = x[1]
val = minimax(state, index, opponent(player), depth-1, alpha, beta)
if val > best_move[0]:
best_move = (val, index)
# print("val = ", val)
# print_board(s[0])
return best_move[1]
后继函数返回它可以下棋的可能状态:
def successors(boards, player, user_move):
sub_board = boards[user_move]
value_index = []
possible_states = []
for idx, value in enumerate(sub_board):
if value == 0 and idx != 0:
value_index.append(idx)
copied_board = deepcopy(boards)
possible_states.append(get_possible_state(copied_board, user_move, idx, player))
#print(possible_states)
return zip(possible_states, value_index)
最后,每一个可能的移动都被输入到 minimax 函数,该函数返回最佳移动的 val:
def minimax(state, last_move, player, depth, alpha, beta):
if depth <= 0 or get_game_status(state, player) != 0:
return evaluate(state, opponent(player))
if player == 1:
max_eval = -inf
pseudo_states = successors(state, player, last_move)
for x in pseudo_states:
state = x[0]
index = x[1]
print(depth)
#print_board(np.array(state))
eval = minimax(state, index, opponent(player), depth-1, alpha, beta)
max_eval = max(max_eval, eval)
alpha = max(alpha, eval)
if beta<= alpha:
break
#print_board(np.array(state))
return max_eval
if player == 2:
min_eval = inf
pseudo_states = successors(state, player, last_move)
for x in pseudo_states:
state = x[0]
index = x[1]
print(depth)
#print_board(np.array(state))
eval = minimax(state, index, opponent(player), depth - 1, alpha, beta)
min_eval = min(min_eval, eval)
beta = min(beta, eval)
if beta<= alpha:
break
#print_board(np.array(state))
return min_eval
想知道是否有人赢了|| 损失 || DRAW,get_game_status 函数在 minimax 函数内部调用:
def get_game_status(state, player):
other_player = opponent(player)
for each_box in state[1:10]:
win_state = [
[each_box[1], each_box[2], each_box[3]],
[each_box[4], each_box[5], each_box[6]],
[each_box[7], each_box[8], each_box[9]],
[each_box[1], each_box[4], each_box[7]],
[each_box[2], each_box[5], each_box[8]],
[each_box[3], each_box[6], each_box[9]],
[each_box[1], each_box[5], each_box[9]],
[each_box[3], each_box[5], each_box[7]],
]
if [player, player, player] in win_state:
return player
elif [other_player, other_player, other_player] in win_state:
return other_player
else:
return 0
并且使用评估函数处理评分:
def evaluate(state, player):
if(get_game_status(state, player) and player ==1) :
score = 10
elif(get_game_status(state, player) and player == 2):
score = -10
else:
score = 0
return score
预期的结果是获得最好的移动,但相反,它无休止地运行。
请建议我应该做出哪些改变,或者我哪里出错了。
解决方案
推荐阅读
- c# - 游戏对象出现在 Hierachy 中,但在相机中不可见
- c - 如何链接在不同系统架构上编译的共享库?
- vue.js - 如何在 Bootstrap-Vue 中使用点击事件
在 Vue.js 中? - elasticsearch - 如何从弹性搜索中的模板映射新索引
- android - 如何更改滚动视图中元素的滚动速度
- python-3.x - 如何在 QComboBox 中添加和排序项目
- node.js - Firebase Admin SDK 仅更新给定参数
- java - 休眠 ORM 本机查询到带有键的 Json 对象
- php - 无法从套接字 [104] 读取:对等 aws 重置连接
- pandas - 多个数据帧上的多处理池映射产生 TypeError