TicTacToe Question

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 1:09 am

Hello there fellow lua-ers... love-ers.

I recently got into lua and was wondering the best way about making the tictactoe board for tictactoe... Except mine is called kittytactoe but that's besides the point. So far, I have done this.

Code: Select all

local MENU_PLAY = 0
local MENU_SETTINGS = 1
local MENU_QUIT = 2
local MENU_MAXIMUM = 2
local MENU_MINIMUM = 0
local menu_selection = 0
local change_menu = false
local main_menu = false
local play_game = false
local back = false
local quit = false
local mouseClicked = false

-- SETTINGS
local settings_selection = 0
local SETTINGS_MAXIMUM = 0
local SETTINGS_MINIMUM = 0
local SETTINGS_VOLUME = 0

function love.load()
    kitty = love.graphics.newImage("kitty.jpg")
    cursor = love.graphics.newImage("paw.png")
    game = love.graphics.newImage("gameBackground.png")
    pusheen = love.graphics.newImage("sticker.png")
    pizzaPiece = love.graphics.newImage("pizza.png")
    donutPiece = love.graphics.newImage("donuts.png")
    font = love.graphics.newFont("Babylove.ttf", 50)
    xPush = 550
    yPush = 300

    printx = 0
    printy = 0

end

function love.draw()
    love.window.setFullscreen(true, "desktop")
    mainMenu()

    if (menu_selection == MENU_QUIT) then
        quitGame()
    elseif (menu_selection == MENU_SETTINGS) then
        settings()
    elseif (menu_selection == MENU_PLAY) then
        gameBoard()
        gamePieces()
    end
end

function mainMenu()
    -- DRAW MAIN MENU SCREEN
    love.graphics.setColor(1, 1, 1, 1)
    love.graphics.draw(kitty)
    love.graphics.setFont(font)
    love.graphics.setColor(0, 0, 0, 1)
    love.graphics.print("Play", 100, 150)
    love.graphics.print("Settings", 100, 200)
    love.graphics.print("Quit", 100, 250)

    love.graphics.setColor(1, 1, 1, 1)
    if (menu_selection == MENU_PLAY) then
        love.graphics.draw(cursor, 10, 120, 0, 0.1, 0.1)
    elseif (menu_selection == MENU_SETTINGS) then
        love.graphics.draw(cursor, 10, 170, 0, 0.1, 0.1)
    elseif (menu_selection == MENU_QUIT) then
        love.graphics.draw(cursor, 10, 220, 0, 0.1, 0.1)
    end
end

function settings()
    -- DRAW THE SETTINGS SCREEN
    if (change_menu == true) then
        main_menu = false
        love.graphics.setColor(1, 1, 1, 1)
        love.graphics.draw(kitty)
        love.graphics.setColor(0, 0, 0, 1)
        love.graphics.print("Volume", 100, 150)

        love.graphics.setColor(1, 1, 1, 1)
        if (settings_selection == SETTINGS_VOLUME) then
            love.graphics.draw(cursor, 10, 120, 0, 0.1, 0.1)
        end
    end
end

function quitGame()
    -- QUIT IF QUIT IS SELECTED
    if (menu_selection == MENU_QUIT) then
        quit = true
    end
end

function previousWindow()
    if (back == true) then
        main_menu = true
        love.graphics.setColor(1, 1, 1, 1)
        love.graphics.draw(kitty)
        love.graphics.setFont(font)
        love.graphics.setColor(0, 0, 0, 1)
        love.graphics.print("Play", 100, 150)
        love.graphics.print("Settings", 100, 200)
        love.graphics.print("Quit", 100, 250)

        love.graphics.setColor(1, 1, 1, 1)
        if (menu_selection == MENU_PLAY) then
            love.graphics.draw(cursor, 10, 120, 0, 0.1, 0.1)
        elseif (menu_selection == MENU_SETTINGS) then
            love.graphics.draw(cursor, 10, 170, 0, 0.1, 0.1)
        elseif (menu_selection == MENU_QUIT) then
            love.graphics.draw(cursor, 10, 220, 0, 0.1, 0.1)
        end
    end
end

function gameBoard()
    -- DRAW THE GAMEBOARD SCREEN
    if (play_game == true) then
        main_menu = false
        love.graphics.setColor(1, 1, 1, 1)
        love.graphics.draw(game)
        love.graphics.draw(pusheen, xPush, yPush)
        love.graphics.setFont(font)
        love.graphics.setColor(0, 0, 0, 1)

        love.graphics.rectangle("fill", 100, 50, 500, 500)
        love.graphics.setColor(1, 1, 1, 1)

        -- VERTICAL LINES
        love.graphics.line(265, 50, 265, 550)
        love.graphics.line(440, 50, 440, 550)
        -- HORIZONTAL LINES
        love.graphics.line(100, 215, 600, 215)
        love.graphics.line(100, 375, 600, 375)
    end
end

function gamePieces()
    if (play_game == true) then
        main_menu = false
        if (mouseClicked == true) then
            -- love.graphics.draw(donutPiece, 120, 75, 0, 0.30, 0.30)
            -- love.graphics.draw(pizzaPiece, printx, printy, 0, 0.85, 0.85)
            love.graphics.circle("line", printx, printy, 75)
        end
    end
end

function love.keypressed(key)
    if key == "escape" then
        if (main_menu == true) then
            love.event.quit()
        else
            back = true
        end
    elseif key == "up" then
        menu_selection = math.max(menu_selection - 1, MENU_MINIMUM)
    elseif key == "down" then
        menu_selection = math.min(menu_selection + 1, MENU_MAXIMUM)
    elseif key == "return" then
        if (menu_selection == MENU_SETTINGS) then
            print("Enter key pressed")
            change_menu = true
        elseif (menu_selection == MENU_PLAY) then
            play_game = true
        elseif (menu_selection == MENU_QUIT) then
            love.event.quit()
        end
    end
end

function love.mousepressed(x, y, button)
    if button == 1 then
        mouseClicked = true
        printx = x
        printy = y
    end
end 
TLDR I made a rectangle, filled it, and made some lines but it was a very.. how do I say, random process due to the pixel approximations for where the lines should go that I ended up making. I'm pretty sure this isn't the best of ways to go about making the board itself.

This is a mess, I know. It's pretty bad. The menu for this is broken but I decided to move on to the actual
game mechanics and go back to that later.

I also have a question about mousepressed. The way I am using it here makes the circle appear on the screen but of course it's just in random pixelated areas that can be anywhere which is why I was wondering if I needed to fix my game board or fix my mousepressed. I'll have a screenshot so you can vizualize what i'm talking about.

Image

Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

Re: TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 2:39 am

Also sidenote, I guess what I'm really interested in NOW after an hour of thinking is, Is there a way to make an array of rectangles instead of doing.. what I did? I understand how to make one of them but how about 3 by 3 grid of the same rectangles/squares?

User avatar
veethree
Inner party member
Posts: 805
Joined: Sat Dec 10, 2011 7:18 pm

Re: TicTacToe Question

Post by veethree » Thu Jan 10, 2019 11:58 am

Could use a 2d array like

Code: Select all

board = {
		{0, 0, 0},
		{0, 0, 0},
		{0, 0, 0}
	}
and draw it like

Code: Select all

for y=1, #board do
		for x=1, #board[1] do
			love.graphics.rectangle("fill", x * cellSize, y * cellSize, cellSize - 1, cellSize - 1)
		end
	end
where cellSize is how large each cell of the board is.

User avatar
zorg
Party member
Posts: 2530
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: TicTacToe Question

Post by zorg » Thu Jan 10, 2019 12:36 pm

To be fair, the one rectangle and 2x2 internal separator lines worked perfectly fine, but it seems to me that your issue is more about how to position things in a general sense, than anything.

Use love.graphics.getDimensions to get the width and height of your window, then position everything relatively using that.
let's say you want the tic-tac-toe board centered, so you know you want a black rectangle in the middle, with a size taking up x% of the width and y% of the height, and you want to separate that into 3 parts with two lines. A little bit of math, and you now know the numbers to plug into the functions you've been using.

As for the crosses and noughts, you'd need to test for where the click happened; if it was inside the board, figure out which cell, and draw a perfectly positioned shape into it, using already stored coordinates for the circle and line functions (cross can be done with two lines, and is probably the simplest way to do it) and not just using the mouse coordinates where you clicked.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

Re: TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 9:11 pm

veethree wrote:
Thu Jan 10, 2019 11:58 am
Could use a 2d array like

Code: Select all

board = {
		{0, 0, 0},
		{0, 0, 0},
		{0, 0, 0}
	}
and draw it like

Code: Select all

for y=1, #board do
		for x=1, #board[1] do
			love.graphics.rectangle("fill", x * cellSize, y * cellSize, cellSize - 1, cellSize - 1)
		end
	end
where cellSize is how large each cell of the board is.
I actually did something like this after 3 hours of fiddling and it kept being busted. Can you explain why when I increase/change/decrease the value of the dimensions why I also end up changing how many squares there are? here's my map I created last night

Code: Select all

map = {
        {1,1,1},
        {1,1,1},
        {1,1,1}     
    }
heres the drawCell function

Code: Select all

function drawCell()
    for y=1, #map do
		for x=1, #map[y] do
			if map[y][x] == 1 then
				love.graphics.rectangle("line", y * 100, x * 100, 200, 200)
			end
		end
	end
end
I thought multiplying y and x by 100 it would just place the default area of where I
wanted the rectangles to start. (at like, 100, 100 as coords) and the 200, 200 at the end were just the dimensions of each cube/square. I must have misunderstood when I tried to do this. I found this info on the... gridlocked lua love page which was helpful in getting the general idea of what you have just shown me. But, still confused as to why mine wasn't acting the way I wanted it to. Thank you in advance if you mind explaining why mine is busted? and can you explain this line?

If i'm following this correctly, x which has been set to 1 and y which has been set to 1 are multiplied by the cell size x and y are both 100 pixels large? The subtracting 1 from each of those is another thing I am confused about. Why is this necessary? Thank you in advance.

Code: Select all

love.graphics.rectangle("fill", x * cellSize, y * cellSize, cellSize - 1, cellSize - 1)
		end

Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

Re: TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 9:16 pm

zorg wrote:
Thu Jan 10, 2019 12:36 pm
To be fair, the one rectangle and 2x2 internal separator lines worked perfectly fine, but it seems to me that your issue is more about how to position things in a general sense, than anything.

Use love.graphics.getDimensions to get the width and height of your window, then position everything relatively using that.
let's say you want the tic-tac-toe board centered, so you know you want a black rectangle in the middle, with a size taking up x% of the width and y% of the height, and you want to separate that into 3 parts with two lines. A little bit of math, and you now know the numbers to plug into the functions you've been using.

As for the crosses and noughts, you'd need to test for where the click happened; if it was inside the board, figure out which cell, and draw a perfectly positioned shape into it, using already stored coordinates for the circle and line functions (cross can be done with two lines, and is probably the simplest way to do it) and not just using the mouse coordinates where you clicked.
So my grid doesn't really matter all that much. Getting the width and the height of the window is probably a smarter way to go about positioning things. I had tried to have the mouspressed just set to coordinates that I had already found with the circle. Though, yes you're right. I need to test where the click happened not just using the coordinates. I will get back to this when I have made some improvements to my code. Thank you by the way. I was wondering how to keep my mousepresses inside of the squares. I have the coordinates written down on a piece of paper of the positions but I didn't know if using them would be a good idea.

Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

Re: TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 9:42 pm

veethree wrote:
Thu Jan 10, 2019 11:58 am
Could use a 2d array like

Code: Select all

board = {
		{0, 0, 0},
		{0, 0, 0},
		{0, 0, 0}
	}
and draw it like

Code: Select all

for y=1, #board do
		for x=1, #board[1] do
			love.graphics.rectangle("fill", x * cellSize, y * cellSize, cellSize - 1, cellSize - 1)
		end
	end
where cellSize is how large each cell of the board is.
so I ran into the problem where manipulating the cellSize does move it further on the screen than intended which make sense but is there a way to stop this?
Image

Vilent
Prole
Posts: 6
Joined: Thu Jan 10, 2019 12:51 am

Re: TicTacToe Question

Post by Vilent » Thu Jan 10, 2019 10:03 pm

Oh i figured it out here is what I have so far as the grid goes. I used both of your guys' advice with cellsize and width and height and managed to do some math to get this where I want it.

Image

I will get back to this for the mousepresses thank you all so much so far.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests