Source

--TIC TAC TOE - JANUARY 1977 - 101 MAGAZINE

-- game datas
function _init()
    winner = false
    turn = "O"

    checks = {
        {1,2,3},
        {4,5,6},
        {7,8,9},
        {1,4,7},
        {2,5,8},
        {3,6,9},
        {1,5,9},
        {3,5,7}
    }

    board = {
        x = 192/2-90/2, -- get a x to have the board centered
        y = 10,
        width = 90,
        height = 90
    }

    squares = {}
    positions = {}
    set_squares()

    cursor = 1

    timer = 0
    time_max = 3

    updateBoard = true
end

-- setting functions
function set_squares()
    -- an init function that get the squares coordinates out of the board values
    squares.width = board.width/3
    squares.height = board.height/3

    id = 1
    for i = 0, 1, 1/3 do
        for j = 0, 1, 1/3 do
            if j < 1 and i < 1 then
                squares[id] = {x, y}
                squares[id].x = board.x + board.width * j
                squares[id].y = board.y + board.height * i
                positions[id] = ""
                id = id + 1
            end
        end
    end
end

function end_turn()
    if turn == "O" then
        turn = "X"
    else 
        turn = "O"
    end
end

function reset_game()
    for i, pos in ipairs(positions) do
        positions[i] = ""
    end
    winner = false
    updateBoard = true
    timer = 0
    turn = "O"
end

-- input functions
function _mmove(x,y)
    if not winner then
        mouse_cursor(x, y)
    end
end

function mouse_cursor(x, y)
    --change the cursor with the mouse while hovering squares
    for id, square in ipairs(squares) do
        if x >= square.x and x <= square.x + squares.width
        and y >= square.y and y <= square.y + squares.height
        then
            cursor = id
            updateBoard = true
        end
    end
end

function _mpress(x,y,b)
    if b == 1 and not winner then mouse_play(x,y) end
    if winner and timer > time_max then reset_game() end --restart the game when game over
end

function mouse_play(x,y)
    for id, square in ipairs(squares) do
        if x >= square.x and x <= square.x + squares.width
        and y >= square.y and y <= square.y + squares.height
        and positions[id] == ""
        then
            positions[id] = turn
            updateBoard = true
            winner = check_board()
            if not winner then
                end_turn()
            end
        end
    end
end

function _kpress(key)
    if not winner then
        keyboard_cursor(key)
    end
    if winner and timer > time_max then reset_game() end
end

function keyboard_cursor(k)
    if k == "left" and cursor > 1 then
        cursor = cursor - 1
    elseif k == "right" and cursor < 9 then
        cursor = cursor + 1
    elseif k == "up" and cursor > 3 then
        cursor = cursor - 3
    elseif k == "down" and cursor < 7 then
        cursor = cursor + 3
    end

    if k == "x" or k =="c" or k == "v" then
        keyboard_play()
    end

    updateBoard = true
end

function keyboard_play()
    if positions[cursor] == "" then
        positions[cursor] = turn
        winner = check_board()
        if not winner then
            end_turn()
        end
    end
end

-- checking function
function check_board()
    count = 0
    for i, check in ipairs(checks) do
        for j, square in ipairs(check) do
            if positions[square] == turn then
                count = count + 1
            end
        end
        if count == 3 then
            return true
        end
        count = 0
    end
    -- check draw
    for i, pos in ipairs(positions) do
        if pos == "" then
            count = count + 1
        end
    end

    if count == 0 then
        turn = ""
        return true
    else
        return false
    end
end


-- drawing functions
function draw_board()
    clear(2)
    color(8)
    -- horizontal lines
    for i=0, board.height, board.height/3 do
        line(board.x - 1, board.y + i, board.x + board.width, board.y + i)
    end
    -- vertical lines
    for i=0, board.width, board.width/3 do
        line(board.x + i, board.y , board.x + i, board.y + board.height)
    end
end

function draw_cursor()
    for id, square in pairs(squares) do
        if id == cursor then
            color(10)
            rect(square.x+squares.width/2-2, square.y-2, 4, 4)
            Sprite(1,square.x+squares.width/2-4, square.y+2)
        end
    end
end

function draw_squares()
    for id, square in ipairs(squares) do
            color(1)
            rect(square.x+1, square.y+1, squares.width-1, squares.height-1)
        -- O drawing a circle in position of the square
        if positions[id] == "O" then
            color(13)
            circle_line(square.x+squares.width/2, square.y+squares.height/2, 10)
        -- X drawing two line in position of the square
        elseif positions[id] == "X" then
            color(9)
            line(square.x+squares.width/2+10, square.y+squares.height/2-10, square.x+squares.width/2-10, square.y+squares.height/2+10)
            line(square.x+squares.width/2-10, square.y+squares.height/2-10, square.x+squares.width/2+10, square.y+squares.height/2+10)
        end
    end
end

function clearMsg()
    rect(0, 110, 200, 20, 12)
end

function draw_message()
    clearMsg()
    color(1)
    print("THIS IS THE TURN OF "..turn..".", 55, 118)
end

function draw()
    draw_board()
    draw_squares()
    draw_message()
    draw_cursor()
end

-- game functions
function _update(dt)
    if winner then
        game_over()
        timer = timer + dt
    end

    if updateBoard then
        draw()
        updateBoard = false
    end
end

function game_over()
    clearMsg()
    color(1)
    if turn == "" then
        print("DRAW!", 35, 118)
    else
        print(turn.." WON!", 30, 118)
    end
    if timer > time_max then
        print("PRESS A BUTTON TO START AGAIN.", 60, 118)
    else
        print("REPLAY IN".." "..(time_max-floor(timer)).."...", 60,118)
    end
end

Last updated