Dinfio Playground

Let's play with Dinfio!




Tic Tac Toe Game

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:



Requirement: Dinfio 3.2.0 or later

← Back to the Dinfio Playground / Download this program