Let's play with Dinfio!
This is the AI vs Human 3x3 Tic Tac Toe game using Non-recursive Minimax algorithm.
' Tic Tac Toe game using Non-recursive Minimax algorithm
import gui
var board = array(10)
var move_stack = []
var move_count = 0
var is_game_over = false
var human_wins = 0, ai_wins = 0, draws = 0
const box_size = 64
const box_space = 4
const margin_top = 20, margin_left = 20
const human_colour = colour.hex("0dc2ff")
const ai_colour = colour.hex("ff0d72")
start
create_gui()
reset_board()
stop
function create_gui()
global window = gui_window("Tic Tac Toe in Dinfio", 400, 270)
global box = array(9)
global box_label = array(9)
var index = 0
for i, 0, 2
for j, 0, 2
x = j * box_size + box_space * j
y = i * box_size + box_space * i
box[index] = gui_panel(window, x + margin_left, y + margin_top, box_size, box_size)
box[index].setbackgroundcolour(colour.white)
box[index].addevent(event.mouseleftdown, player_move(index))
box_label[index] = gui_label("", box[index], 0, box_size / 2 - 13, box_size, 32, align.centre)
box_label[index].setfontsize(24)
box_label[index].setfontbold(true)
box_label[index].setforegroundcolour(colour.white)
box_label[index].addevent(event.mouseleftdown, player_move(index))
index += 1
endfor
endfor
global label_score = gui_label("Human Wins: " & human_wins & "\nAI Wins: " & ai_wins & "\nDraws: " & draws, window, 240, 20, 180, 400)
global button_reset = gui_button("Reset Board", window, 240, 100, 140, 26)
label_score.setfontsize(16)
label_score.setfontbold(true)
button_reset.addevent(event.click, reset_board())
window.show()
stop
function minimax(board, move_stack, move_count)
var _move_count = move_count
var score_stack = []
var original_move_count = _move_count
var move, score, player
var result = -1
' First move
if _move_count <= 1
return iif(board[4] == 0, 4, 8)
endif
while true
player = 1 - (_move_count % 2) * 2
if game_won(board)
score_stack[_move_count] = -(10 - _move_count) * player
elseif (_move_count == 9)
score_stack[_move_count] = 0
else
move_stack[_move_count] = -1
score_stack[_move_count] = -player * 10
_move_count += 1
endif
while true
_move_count -= 1
if _move_count < original_move_count; break; endif
move = move_stack[_move_count]
if move >= 0
score = score_stack[_move_count + 1]
if (board[move] == 1) == (score > score_stack[_move_count])
score_stack[_move_count] = score
if _move_count == original_move_count
result = move
endif
endif
board[move] = 0
endif
while true
move += 1
if !(move < 9 && board[move] != 0); break; endif
endwhile
if move != 9; break; endif
endwhile
if _move_count < original_move_count; break; endif
_move_count = do_move(board, move_stack, _move_count, move)
endwhile
return result
stop
function player_move(index)
if board[index] != 0 || is_game_over; return; endif
move_count = do_move(board, move_stack, move_count, index)
update_box()
if check_winner(); return; endif
ai_move = minimax(board, move_stack, move_count)
move_count = do_move(board, move_stack, move_count, ai_move)
update_box()
check_winner()
stop
function check_winner()
for i, 0, 2
value = board[i * 3]
if value != 0 && value == board[i * 3 + 1] && value == board[i * 3 + 2]
if value == 1
is_game_over = true
human_wins += 1
update_label()
messagebox("Human wins!", "Tic Tac Toe")
elseif value == -1
is_game_over = true
ai_wins += 1
update_label()
messagebox("AI wins!", "Tic Tac Toe")
endif
return true
endif
value = board[i]
if value != 0 && value == board[i + 3] && value == board[i + 6]
if value == 1
is_game_over = true
human_wins += 1
update_label()
messagebox("Human wins!", "Tic Tac Toe")
elseif value == -1
is_game_over = true
ai_wins += 1
update_label()
messagebox("AI wins!", "Tic Tac Toe")
endif
return true
endif
if value != 0 && value == board[4] && value == board[8 - i]
if value == 1
is_game_over = true
human_wins += 1
update_label()
messagebox("Human wins!", "Tic Tac Toe")
elseif value == -1
is_game_over = true
ai_wins += 1
update_label()
messagebox("AI wins!", "Tic Tac Toe")
endif
return true
endif
endfor
if move_count >= 9
is_game_over = true
draws += 1
update_label()
messagebox("Game ties!", "Tic Tac Toe")
return true
endif
return false
stop
function reset_board()
board = array(10)
move_stack = []
move_count = 0
is_game_over = false
update_box()
stop
function update_box()
for i, 0, 8
if board[i] == 1
box_label[i].settext("X")
box[i].setbackgroundcolour(human_colour)
elseif board[i] == -1
box_label[i].settext("O")
box[i].setbackgroundcolour(ai_colour)
else
box_label[i].settext("")
box[i].setbackgroundcolour(colour.white)
endif
endfor
window.refresh()
stop
function update_label()
label_score.settext("Human Wins: " & human_wins & "\nAI Wins: " & ai_wins & "\nDraws: " & draws)
stop
function do_move(board, move_stack, move_count, move)
board[move] = 1 - (move_count % 2) * 2
move_stack[move_count] = move
return move_count + 1
stop
function game_won(board)
var value
for i, 0, 2
value = board[i * 3]
if value != 0 && value == board[i * 3 + 1] && value == board[i * 3 + 2]
return true
endif
value = board[i]
if value != 0 && value == board[i + 3] && value == board[i + 6]
return true
endif
if value != 0 && value == board[4] && value == board[8 - i]
return true
endif
endfor
return false
stop
Screenshots: