I’m trying to make an AI for a GUI based Connect Four game.
The issue here is that the AI “works”, but it only picks the left-most slot and only looks for vertical win checks. Basically, the AI doesn’t have intelligence.
I’ve tried changing multiple lines of code, returning in different loops and if statements, but to no avail. It either has no brain, or it just freezes my game and doesn’t make any moves at all.
local function checkAiWin(board)
pcall(function()
for player = 1,2 do
for x = 1, #board[1] do
for y = 1, #board-3 do
if board[y][x] == player and board[y+1][x] == player and board[y+2][x] == player and board[y+3][x] == player then
return true, player
end
end
end
for x = 1, #board[1]-3 do
for y = 1, #board do
if board[y][x] == player and board[y][x+1] == player and board[y][x+2] == player and board[y][x+3] == player then
return true, player
end
end
end
for x = 1, #board[1]-3 do
for y = 1, #board-3 do
if board[y][x] == player and board[y+1][x+1] == player and board[y+2][x+2] == player and board[y+3][x+3] == player then
return true, player
end
end
end
for x = 1, #board[1]-3 do
for y = 1, #board-3 do
if board[y][x] == player and board[y+1][x-1] == player and board[y+2][x-2] == player and board[y+3][x-3] == player then
return true, player
end
end
end
end
end)
end
local aiScores = {
["1"] = -100000000000000000000000,
["2"] = 10000000000000000000000000,
["tie"] = 0
}
function minimax(board, depth, maximize)
local won, playerWon = checkAiWin(board)
if won then
return aiScores[tostring(playerWon)]
else
local full = true
for i,v in pairs(board) do
if v == 0 then
full = false
end
end
if full then
return aiScores["tie"]
end
end
if maximize then
local bestScore = -math.huge
for y in pairs(board) do
for x in pairs(board[y]) do
if board[y][x] == 0 then
board[y][x] = 2
local score = minimax(board, depth + 1, false);
board[y][x] = 0
bestScore = math.max(score, bestScore)
end
end
end
return bestScore
else
local bestScore = math.huge
for y in pairs(board) do
for x in pairs(board[y]) do
if board[y][x] == 0 then
board[y][x] = 1
local score = minimax(board, depth + 1, true)
board[y][x] = 0
bestScore = math.min(score, bestScore)
end
end
end
return bestScore
end
end
function bestMove()
local bestScore = -math.huge
local bestMove = nil
for y in pairs(c4) do
for x in pairs(c4[y]) do
if c4[y][x] == 0 then
local fakeBoard = c4
fakeBoard[y][x] = 2
local score = minimax(fakeBoard, 0, false)
print(score)
fakeBoard[y][x] = 0
if (score > bestScore) then
bestScore = score
bestMove = x
end
end
end
end
AddCircle(bestMove)
end
Code in question