python井字棋_Python实现基于极大极小值算法的井字棋对弈

运行效果

当前棋盘:

| | | |

| | | |

| | | |

AI为 'o' 棋,玩家为 'x' 棋,玩家先

放置棋子输入格式:行号,列号(数值为0/1/2)

请输入要放置棋的坐标:0,1

当前棋盘:

| | o | |

| | | |

| | | |

AI进行下一步...

当前棋盘:

| | o | |

| | x | |

| | | |

请输入要放置棋的坐标:0,0

当前棋盘:

| o | o | |

| | x | |

| | | |

AI进行下一步...

当前棋盘:

| o | o | x |

| | x | |

| | | |

请输入要放置棋的坐标:2,0

当前棋盘:

| o | o | x |

| | x | |

| o | | |

AI进行下一步...

当前棋盘:

| o | o | x |

| x | x | |

| o | | |

请输入要放置棋的坐标:1,2

当前棋盘:

| o | o | x |

| x | x | o |

| o | | |

AI进行下一步...

游戏结束!平局

核心代码

def cal_win_value(chessboard: Chessboard):

"""

计算当前棋盘AI的得分(AI能赢解个数减去玩家能赢的解个数)

:param chess_type 要判断的棋子种类

"""

# 如果用户直接可以赢,则得分无穷小,采取防守策略

win, winner_chess = chessboard.can_win()

if not win and winner_chess is 'both':

print("游戏结束!平局")

exit()

elif win and winner_chess is chess_player:

return MIN

num_map = {

chess_ai: 0,

chess_player: 0

}

# 分别计算当前棋局AI以及玩家能赢的解有多少种

for chess_type in [chess_ai, chess_player]:

temp_board = chessboard.copy_new()

# 将空位全部填充为某一类型的棋子

for row in range(3):

for col in range(3):

if temp_board.data[row][col] is not the_other(chess_type):

temp_board.data[row][col] = chess_type

# 计算横向可以赢的个数

for row in range(3):

row_status = True

for col in range(3):

if temp_board.data[row][col] is not chess_type:

row_status = False

if row_status is True:

num_map[chess_type] += 1

# 计算纵向可以赢的个数

for col in range(3):

col_status = True

for row in range(3):

if temp_board.data[row][col] is not chess_type:

col_status = False

if col_status is True:

num_map[chess_type] += 1

# 检查主对角线可以赢的个数

main_diag_status = True

for i in range(3):

if temp_board.data[i][i] is not chess_type:

main_diag_status = False

if main_diag_status is True:

num_map[chess_type] += 1

# 检查副对角线可以赢的个数

para_diag_status = True

for i in range(3):

if temp_board.data[2 - i][i] is not chess_type:

para_diag_status = False

if para_diag_status is True:

num_map[chess_type] += 1

return num_map[chess_ai] - num_map[chess_player]

def cal_total_value(chessboard: Chessboard, x_ai, y_ai):

"""

计算将要进行的一步棋的总得分

"""

total_value = 0

# win, winner_chess = chessboard.can_win()

# if win and winner_chess is chess_ai:

# return MAX

# elif win and winner_chess is chess_player:

# return -MIN

# 新建一个临时的棋盘,模拟之后的两步

temp_board = chessboard.copy_new()

if temp_board.can_put(x_ai, y_ai):

# AI走一步

temp_board.put_chess(chess_ai, x_ai, y_ai)

# AI可以绝杀

win, winner_chess = temp_board.can_win()

if win:

return MAX

# 若不能绝杀,则需要预测玩家,计算最大得分的解

empty_psts = chessboard.get_empty_psts()

# 遍历所有空位置,模拟玩家走一步

for x_player, y_player in empty_psts:

inner_temp_board = temp_board.copy_new()

if inner_temp_board.can_put(x_player, y_player):

# 玩家走一步

inner_temp_board.put_chess(chess_player, x_player, y_player)

# 计算当前棋盘的得分

value = cal_win_value(inner_temp_board)

total_value += value

return total_value

def ai_put(chessboard: Chessboard):

"""

AI放置一枚棋子

:param chessboard:

:return:

"""

empty_psts = chessboard.get_empty_psts()

max_value = MIN

for row, col in empty_psts:

value = cal_total_value(chessboard, row, col)

if value > max_value:

max_value = value

determined_x = row

determined_y = col

chessboard.put_chess(chess_ai, determined_x, determined_y)

完整代码

我将积累的一些算法发布到了Gihub仓库中,其中涉及一些常见的算法以及人工智能方面的算法,其中有该程序的完整实现代码。

仓库地址:https://github.com/yub1ng/Algorithm

个人博客地址:http://qiyubing.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值