Minimax algorithm for Connect Four isn't working properly

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

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

I’m going to assume this is the function the NPC references when attempting to select the best move. It would be helpful if you added comments as a lot of the referenced variables are underlined blue (indicating at least from the portion of the script you provided that they aren’t declared).

Remember to define functions like you did with the first function in the provided script, it integrates them into the current environment which makes accessing/referencing and thus calling them quicker.

I apologise for not adding comments as this is my first time ever posting. I also forgot to mention that this is just a snippet of the script, and therefore c4 and AddCircle() are already defined. c4 is defined as a table with 6 entries each one having 7 values, and AddCircle is just a function that adds a circle in a specific column.