分享一个五子棋AI算法,完整代码, 核心代码不到300行
主要思路:落子时, 遍历棋盘上所有空白位置,算出该点落子的得分,并保存下来, 最后算出最大得分的落子位置,出现多个相同得分时, 随机选择一个。
评分主要类型见代码中 socre_type枚举定义
AI强度大约为中等,和普通人对弈, 大约80%胜率。
带AI对弈的完整lua代码:
local sid = 0
local function id(initial)
sid = initial and initial or sid + 1
return sid
end
score_type = {
fazhan2 = id(), -- 发展2
fazhan3x = id(), -- 一端被阻挡的3
zudang2 = id(), -- 阻挡2
fazhan3 = id(), -- 两端无阻挡的3
zudang3 = id(), -- 阻挡对方形成的双向无阻挡的3
fazhan4x = id(), -- 发展一端阻挡的4
fazhan4 = id(), -- 发展无阻挡的4
zudang4 = id(), -- 阻挡对方单封堵的4
five = id(), -- 五子连珠
}
size = 15 -- 棋盘大小
board = {
}
-- 评分相等时,计算坐标离中心的距离
-- TODO, 优化为同时考虑坐标周围无其他方向的对手棋子
function center(i,j)
return math.abs(size/2-i) + math.abs(size/2-j)
end
-- 计算指定坐标下t类型的棋子的得分
function score(board, t, i, j)
local function get_score(left, right, t)
local line = {
}
for _, v in pairs(left) do
table.insert(line, v)
end
table.insert(line, t)
for _, v in pairs(right) do
table.insert(line, v)
end
-- local print = function() end
-- 五个的情况
for k=1, #line-4 do
if line[k]==t and line[k+1]==t and line[k+2]==t and line[k+3]==t and line[k+4]==t then
print(i,j, "five")
return score_type.five
end
end
-- 阻挡四
for k=1, #line-4 do
local diff_count = 0
local same_count = 0
for i=k, k+4 do
same_count = same_count + (line[i] == t and 1 or 0)
diff_count = diff_count + (line[i] == -t and 1 or 0)
end
if diff_count == 4 and same_count == 1 then
return score_type.zudang4
end
end
-- 四个的情况
local s = 4==(#left) and 2 or 1
for k=s