So I recently purchased the draw library on Touch Lua! I've started trying to make a simple Tic Tac Toe game. I'm using a simple setup they used to detect clicks on the NumPad default program, so the buttons should work.
The problem is that when you tap a square, the O fills into seemingly-random squares, sometimes more than 1, up to 4+ squares may get filled.
I suspect the problem is the function Picked, which sets the title to X/O and then updates the board.
local Turn = nil
local Move = "O"
local Mode = nil
::ModePick::
print("1 player mode? (y/n)")
local plrs = io.read()
if plrs == "y" then
Mode = 1
goto TurnChoice
elseif plrs == "n" then
Mode = 2
goto Game
else
goto ModePick
end
::TurnChoice::
print("Would you like to go first? (Be O) (y/n)")
do
local pick = io.read()
if pick == "y" then
Turn = 1
elseif pick == "n" then
Turn = 2
else
goto TurnChoice
end
end
::Game::
local Buttons = {}
draw.setscreen(1)
draw.settitle("Tic Tac Toe")
draw.clear()
width, height = draw.getport()
function Picked(b)
for i,v in pairs(Buttons) do
if v == b then
b.title = Move
UpdateBoard()
end
end
--Fill in X/O details
--Detect if there's a tic/tac/toe
--Set winning screen
if Move == "O" then
--Compute Move (1 player)
--Move = "X" (2 player)
else
Move = "O"
end
end
function DrawButton(b)
draw.setfont('Helvetica', 50)
draw.setlinestyle(2, 'butt')
local x1, y1 = b.x, b.y
local x2, y2 = x1+b.width, y1+b.height
draw.rect(x1, y1, x2, y2, b.color)
local w, h = draw.stringsize(b.title)
local x = b.x + (b.width - w)/2
local y = b.y + (b.height - h)/2
draw.string(b.title, x, y, draw.black)
return b
end
function Button(x, y, x2, y2, title, color, action)
local action = action or function() end
local button = {x = x, y = y, width = x2, height = y2, color = color, title = title, action = action}
table.insert(Buttons, button)
return button
end
function LookUpButton(x, y)
for i = 1, #Buttons do
local b = Buttons[i]
if x > b.x and x < b.x+b.width and y > b.y and y < b.y+b.height then
return b
end
end
return nil
end
function TouchBegan(x, y)
local b = LookUpButton(x, y)
if b then
b.action(b)
end
end
function TouchMoved(x, y)
end
function TouchEnded(x, y)
end
draw.tracktouches(TouchBegan, TouchMoved, TouchEnded)
function CreateButton(x,y,x2,y2,txt,col,func)
return DrawButton(Button(x, y, x2, y2, txt, col, func))
end
function UpdateBoard()
draw.clear()
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[i + ii].title, draw.blue, Picked)
end
end
end
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, "", draw.blue, Picked)
end
end
while true do
draw.doevents()
sleep(1)
end
Note: Sorry if the indention came out wrong, I pasted all this code in on my iPod, so I had to manually put in 4 spaces starting each line.
If anybody could help me out with this small setback I have, I'd love the help, if there's anything I'm missing I'd gladly edit it in just reply in the comments :D
EDIT: I've modified some of the code to fix how the table keeps getting new buttons, this is the code I have now, same problem, buttons are added in wrong place (and getting removed now):
function Button(x, y, x2, y2, title, color, action, prev)
local action = action or function() end
local button = {x = x, y = y, width = x2, height = y2, color = color, title = title, action = action}
if prev then
for i,v in pairs(Buttons) do
if v == prev then
table.remove(Buttons, i)
end
end
end
table.insert(Buttons, button)
return button
end
function CreateButton(x,y,x2,y2,txt,col,func, prev)
return DrawButton(Button(x, y, x2, y2, txt, col, func, prev))
end
function UpdateBoard()
draw.clear()
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[i + ii].title, draw.blue, Picked, Buttons[i + ii])
end
end
end
EDIT: Thanks to Etan I've fixed UpdateBoard, squares are still random:
function UpdateBoard()
draw.clear()
local n = 1
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons[n].title, draw.blue, Picked, Buttons[n])
n = n + 1
end
end
end
It's been a while since I've got around to post the finished code, but this is what it looks like:
function UpdateBoard(ended)
local ended = ended or false
local Act = nil
if ended == true then
Act = function() end
else
Act = Picked
end
draw.clear()
local Buttons2 = {}
for i,v in pairs(Buttons) do
Buttons2[i] = v
end
Buttons = {}
local n = 1
for i = 1,3 do
for ii = 1,3 do
CreateButton(100 * (ii - 1) + 7.5, 100 * (i - 1) + 75, 100, 100, Buttons2[n].title, draw.blue, Act, Buttons2[n], i, ii)
n = n + 1
end
end
OpenButtons = {}
ClosedButtons = {}
for i,v in pairs(Buttons) do
if v.title == "" then
table.insert(OpenButtons, v)
else
table.insert(ClosedButtons, v)
end
end
end
It may seem a bit complicated for the question, but this is the code after multiple other things.
The main difference you should note here, is that it's recreating the table of buttons, so it does not recount new buttons, and it uses n to count up, instead of using i and ii.