#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Create a Math Game

• edited November 2015 Posts: 56

I've got a new button and I have the math being randomly generated. I still don't have the buttons programmed yet. My thought is to have a variable like keypadInput with a value of 0 and have if statements for each button correlating with the variable. And the variable will be in a text() positioned in the rect. Here's my code so far

``````-- MathGame

-- Use this function to perform your initial setup
function setup()
supportedOrientations(LANDSCAPE_ANY)
--displayMode(FULLSCREEN)
noFill()
noSmooth()
noStroke()
pushStyle()
-- Sprites in variables
right=0
wrong=0
clearButton = "Project:clearButton"
backspaceButton = "Project:backspaceButton"
enterButton = "Project:enterButton"
professor = "Project:professor"
speechBubble = "Project:speechBubble"
-- List of positions for the keypad
local pos = {vec2(-250,0),vec2(-150,0),vec2(-50,0),vec2(-250,-100),vec2(-150,-100),vec2(-50,-100),vec2(-250,-200),vec2(-150,-200),vec2(-50,-200)}
pos[0]=vec2(-150,-300)

buttons={}
for i=0,9 do
buttons[i]={}
buttons[i].img="Project:button"..i
buttons[i].pos=vec2(WIDTH/2,HEIGHT/2)+pos[i]
end
end

function create()
a={}
ans={}
str={}
choice=math.random(4)
c=math.random(4)    -- + - x /
for z=1,4 do
a[z]=vec2(math.random(99),math.random(99))
if c==1 then
str[z]=string.format("%d + %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x+a[z].y)
elseif c==2 then
str[z]=string.format("%d - %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x-a[z].y)
elseif c==3 then
str[z]=string.format("%d x %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x*a[z].y)
elseif c==4 then
str[z]=string.format("%d / %d = ",a[z].x,a[z].y)
ans[z]=a[z].x/a[z].y
end
end
end

-- This function gets called once every frame
function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
return
print("touch") --just a test to see if it registers the touch
end
end
end
end

-- This function gets called once every frame
function draw()

-- This sets a dark background color
background(40, 40, 50)

-- This displays the 0-9 keypad
for i=0,9 do
sprite(buttons[i].img,buttons[i].pos.x,buttons[i].pos.y,75)
end

-- This displays the input rectangle correlating with the keypad
rect(WIDTH/2-100, HEIGHT/2-300)

-- This displays the backspace, clear button and enter button
sprite(clearButton, WIDTH/2-250, HEIGHT/2-300, 75)
sprite(backspaceButton, WIDTH/2-50, HEIGHT/2-300, 75)
sprite(enterButton, WIDTH/2+50, HEIGHT/2+130, 75)

-- This displays the "Right" and "Wrong" at the top of the screen and the increments
fill(255)
fontSize(48)
text("Right "..right,WIDTH/2-100,HEIGHT-50) -- "Right 0"
text("Wrong "..wrong,WIDTH/2+100,HEIGHT-50) -- "Wrong 0"
rect(WIDTH/2-300, HEIGHT/2+100, 300, 50) -- Input bar

-- This displays the professor sprite and his speech bubble
sprite(professor, WIDTH/2+225,HEIGHT/2-100, 350, 600)
sprite(speechBubble, WIDTH/2+75, HEIGHT/2+225, 250, 150)

fill(0, 0, 0, 255)
text(str[choice],WIDTH/2+75,HEIGHT/2+230)
end
``````
• Mod
Posts: 8,943

@CodingIsLife It's hard to look at code that has images that can't be seen. When I tried to run your code, I got an error. Apparently the function create() isn't being executed. The picture above looks good.

• Mod
Posts: 8,943

@CodingIsLife I replaced your images with my own and fixed the error so the code runs.

• Mod
Posts: 8,943

@CodingIsLife Find these lines of code in your program. Make the changes I indicated with `moved here` or `added`. This should give you some help.

``````supportedOrientations(LANDSCAPE_ANY)    -- moved here
displayMode(FULLSCREEN)     -- moved here

-- Use this function to perform your initial setup
function setup()
noFill()
noSmooth()
noStroke()
pushStyle()
``````
``````function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
return
end
end
end
end
``````
``````    text("Wrong "..wrong,WIDTH/2+100,HEIGHT-50) -- "Wrong 0"
rect(WIDTH/2-300, HEIGHT/2+100, 300, 50) -- Input bar

-- This displays the professor sprite and his speech bubble
sprite(professor, WIDTH/2+225,HEIGHT/2-100, 350, 600)
sprite(speechBubble, WIDTH/2+75, HEIGHT/2+225, 250, 150)
``````
• Posts: 56

@dave1707 Wow! You're the best. Honestly this has helped so much. This program is almost there!

• Posts: 56

Now the clear and backspace buttons need to be programmed and the correlation between the value and answer of the question. Time to get back at it

• Posts: 18

@dave1707 The emojii are a cool feature. I knew I could add print and add them with Unicode, but just picking them from the keyboard ... Forehead smack ... Of course.

Using the text function to implicitly convert the value ... SMACK again ... I was thinking of building the string ... But it's a number ... Make that work for you!

@CodingIsLife. I think we have covered all the roadblocks. I'm interested in your final implementation.. I think there is a lot to said for dave1707's implementation of the state machine with a button class and an array mapped onto buttons, and using the state to calculate the value is way more maintainable than testing for the value. This saves a lot of effort and maintainable.

• Posts: 56

I'm probably going to continue this later on in the week due to my busy school schedule. I'll definitely be popping in asking questions. I believe I have enough information to do the rest, but I'm sure I'll be back asking questions :P Thanks to everyone who wrote in this post.

• edited November 2015 Posts: 56

@dave1707 Ugh I can't seem to figure out the clear and backspace button mechanism. I understand that the value has to go back to 0 o for backspace value=value//10 but it just gives me errors. I know the code must go under the touch function but it isn't working. It just gets confusing because all the keypad numbers are in a list and have their own chunk of code in the touch function that I don't know what to do for the clear, backspace and enter button. This is my touch function, still the same.

``````function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
value=value*10+i
return
end
end
end
end
``````
• Mod
Posts: 8,943

@CodingIsLife Try this. You'll have to add code for the enter key to compare with your calculated answer and do what you need to do if correct or not.

``````function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
value=value*10+i
return
end
end
if touch:dist(vec2(WIDTH/2-250,HEIGHT/2-300))<75 then   -- clear
value=0
end
if touch:dist(vec2(WIDTH/2-50,HEIGHT/2-300))<75 then    -- backspace
value=value//10
end
if touch:dist(vec2(WIDTH/2+50,HEIGHT/2+130))<75 then    -- enter
-- compare value with answer then move 0 to value
value=0
end

end
end
``````
• Mod
Posts: 5,396

Dave's solution is good, but in the interest of neatness, you can store button values for clear, backspace, etc, just as you did with the number keys, eg

``````buttons["clear"].pos=vec2(WIDTH/2-250, HEIGHT/2-300, 75)
buttons["clear"].img="Project:clearButton"
``````

You see that a table can mix numbered items (0-9) with (text) named items.

Then in draw, you can alter your code slightly to draw all your buttons in one loop. This version of a for loop will handle a mixture of number (0-9) and text (eg "clear") items.

``````for i,b in pairs (buttons) do
sprite(b.img,b.pos.x,b.pos.y,75)
end
``````

In touch, you can then modify dave's code to use the table items

``````if touch:dist(buttons["clear"].pos)<75 then   -- clear
value=0
end
``````

The benefit of doing this is that all your key positions are defined in one place, and in one table, in setup, and not duplicated in draw, touch, etc. This makes it much easier to make changes. For example, if you wanted to move your whole keypad 10 pixels to the left for some reason, you could (say) define a variable offset in setup

``````offset=vec2(-10,0)
``````

and then use it to modify the draw function, this easily

``````for i,b in pairs (buttons) do
local p=b.pos-offset
sprite(b.img, p.x, p.y, 75)
end
``````

• edited November 2015 Posts: 56

@dave1707 @Ignatz Thanks for the quick reply. I'm going to be adding the code in shortly. @Ignatz the line of code you said:

``````buttons["clear"].pos=vec2(WIDTH/2-250, HEIGHT/2-300, 75)
buttons["clear"].img="Project:clearButton"
``````

is only for the clear button, correct? If so, then I'd need to repeat the process with the other two buttons, right?

• Mod
edited November 2015 Posts: 5,396

Yes, do the other buttons too

• Mod
Posts: 8,943

@CodingIsLife Playing your program, I noticed that you still need to prevent negative answers and answers with a decimal point. So far it's looking good.

• edited November 2015 Posts: 56

@Ignatz Thanks @dave1707 Yeah I was debating whether to implement a decimal button and a negative/minus button. It really all depends on how easy it would be to accomplish to be honest. I suppose it's a possibility, but I'd rather prevent them. Another thing to figure out.

• Posts: 56

@Ignatz Also would I put

``````buttons["clear"].pos=vec2(WIDTH/2-250, HEIGHT/2-300, 75)
buttons["clear"].img="Project:clearButton"
``````

Under/in the

``````buttons={}
for i=0,9 do
buttons[i]={}
buttons[i].img="Project:button"..i
buttons[i].pos=vec2(WIDTH/2,HEIGHT/2)+pos[i]
end
``````

Code?

• Mod
Posts: 5,396

Yes, put it under that loop (NOT inside it)

• edited November 2015 Posts: 56

@Ignatz Okay well I've done the clear and backspace button but I get an error on line 73

error: attempt to index a nil value (field 'clear')

Line 73:
value=value*10+i

My touch function

``````function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
value=value*10+i
return
end

if touch:dist(buttons["clear"].pos)<75 then   -- clear
value=0
end

if touch:dist(buttons["backspace"].pos)<75 then   -- backspace
value=value//10
end
end
end
end
``````
• Posts: 56

Here is the other code

``````buttons={}
for i=0,9 do
buttons[i]={}
buttons[i].img="Project:button"..i
buttons[i].pos=vec2(WIDTH/2,HEIGHT/2)+pos[i]
end
end
-- List of positions for the clear, backspace and enter buttons
buttons["clear"].pos=vec2(WIDTH/2-250, HEIGHT/2-300, 75)
buttons["clear"].img="Project:clearButton"
buttons["backspace"].pos=vec2(WIDTH/2-50, HEIGHT-300, 75)
buttons["backspace"].img="Project:backspaceButton"
buttons["enter"].pos=vec2(WIDTH/2+50, HEIGHT+150, 75)
buttons["enter"].img="Project:enterButton"
``````
• Mod
Posts: 5,396

Try putting this line before you set all the positions for these buttons

``````buttons["clear"],buttons["backspace"],buttons["enter"]={},{},{}
``````
• Posts: 56

@Ignatz That only gets rid of everything on the screen

• edited November 2015 Posts: 56
`````` -- MathGame

supportedOrientations(LANDSCAPE_ANY)
--displayMode(FULLSCREEN)

-- Use this function to perform your initial setup
function setup()
value = 0
create()
noFill()
noSmooth()
noStroke()
pushStyle()
-- Sprites in variables
right=0
wrong=0
clearButton = "Project:clearButton"
backspaceButton = "Project:backspaceButton"
enterButton = "Project:enterButton"
professor = "Project:professor"
speechBubble = "Project:speechBubble"
-- List of positions for the keypad
local pos =   {vec2(-250,0),vec2(-150,0),vec2(-50,0),vec2(-250,-100),vec2(-150,-100),ve  c2(-50,-100),vec2(-250,-200),vec2(-150,-200),vec2(-50,-200)}
pos[0]=vec2(-150,-300)

buttons["clear"],buttons["backspace"],buttons["enter"]={},{},{}

buttons={}
for i=0,9 do
buttons[i]={}
buttons[i].img="Project:button"..i
buttons[i].pos=vec2(WIDTH/2,HEIGHT/2)+pos[i]
end

end
-- List of positions for the clear, backspace and enter buttons
buttons["clear"].pos=vec2(WIDTH/2-250, HEIGHT/2-300, 75)
buttons["clear"].img="Project:clearButton"
buttons["backspace"].pos=vec2(WIDTH/2-50, HEIGHT-300, 75)
buttons["backspace"].img="Project:backspaceButton"
buttons["enter"].pos=vec2(WIDTH/2+50, HEIGHT+150, 75)
buttons["enter"].img="Project:enterButton"

function create()
a={}
ans={}
str={}
choice=math.random(4)
c=math.random(4)    -- + - x /
for z=1,4 do
a[z]=vec2(math.random(99),math.random(99))
if c==1 then
str[z]=string.format("%d + %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x+a[z].y)
elseif c==2 then
str[z]=string.format("%d - %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x-a[z].y)
elseif c==3 then
str[z]=string.format("%d x %d = ",a[z].x,a[z].y)
ans[z]=math.tointeger(a[z].x*a[z].y)
elseif c==4 then
str[z]=string.format("%d / %d = ",a[z].x,a[z].y)
ans[z]=a[z].x/a[z].y
end
end
end

-- This function gets called once every frame
function touched(t)
if t.state==ENDED then --wait for touch to end
local touch=vec2(t.x,t.y)
for i=0,9 do
if touch:dist(buttons[i].pos)<75 then
keyTouched=i
value=value*10+i
return
end

if touch:dist(buttons["clear"].pos)<75 then   -- clear
value=0
end

if touch:dist(buttons["backspace"].pos)<75 then   -- backspace
value=value//10
end
end
end
end

-- This function gets called once every frame
function draw()

-- This sets a dark background color
background(40, 40, 50)

-- This displays the 0-9 keypad
for i=0,9 do
sprite(buttons[i].img,buttons[i].pos.x,buttons[i].pos.y,75)
end

-- This displays the input rectangle correlating with the keypad
rect(WIDTH/2-100, HEIGHT/2-300)

-- This displays the backspace, clear button and enter button
sprite(clearButton, WIDTH/2-250, HEIGHT/2-300, 75)
sprite(backspaceButton, WIDTH/2-50, HEIGHT/2-300, 75)
sprite(enterButton, WIDTH/2+50, HEIGHT/2+130, 75)

-- This displays the "Right" and "Wrong" at the top of the screen and the increments
fill(255)
fontSize(48)
text("Right "..right,WIDTH/2-100,HEIGHT-50) -- "Right 0"
text("Wrong "..wrong,WIDTH/2+100,HEIGHT-50) -- "Wrong 0"
rect(WIDTH/2-300, HEIGHT/2+100, 300, 50) -- Input bar

for i,b in pairs (buttons) do
sprite(b.img,b.pos.x,b.pos.y,75)
end

fill(0)
text(value, WIDTH/2-150, HEIGHT/2+120)

-- This displays the professor sprite and his speech bubble
sprite(professor, WIDTH/2+225,HEIGHT/2-100, 350, 600)
sprite(speechBubble, WIDTH/2+75, HEIGHT/2+225, 250, 150)

fill(0, 0, 0, 255)
text(str[choice],WIDTH/2+75,HEIGHT/2+230)
end
``````
• Mod
Posts: 5,396

There are at least two problems

1. the line you just added should be just before you define the clear button position. You have added it just before the line buttons={}, which will cancel the line you have just added

2. you have the end of the setup function in the wrong place, after the loop that sets the number buttons, and before you set the clear button

• Posts: 56

I'm going to try and fix the problems. Well problem #2 was a mistake on here rather than in the code. (Indenting issue in my comment)

• Mod
Posts: 8,943

Sometimes neatness isn't the best way. Getting the program to work, #1. Understanding everything that's happening, #2. Rewriting the code to make it better or smaller, #3.

• Mod
Posts: 5,396

yes, but refactoring should be happening as you go, not just at the end

• Posts: 56

I think instead of stressing over how to fix the errors I'm just going to use Dave's code. Neatness is not my main priority now. Thanks anyways @Ignatz

• Posts: 56

This is just a small assignment and I just want to complete it. As long as it runs properly that's all that matters.

• Mod
Posts: 8,943

That's where I disagree. When the program works and you understand everything that's happening, then you have a better idea of what needs to be changed and how to change it to make it better and smaller.

• Mod
Posts: 5,396

I understand you want to limit the time you spend on it.

But if you plan to write any longer programs, you need to learn how to make your code tighter and smaller. That's why so many beginners get into trouble.

• Mod
Posts: 8,943

Everyone has their own style. Mine is to get the program working, then optimize it.

• Posts: 56

I think I'm just going to complete it and submit it and then post the code onto here and later on I'll go in and simplify it.

• Mod
Posts: 5,396

That's fine, I think you've done well so far

• Posts: 56

In case anyone is still following this post, the program is still under development and in near completion!

• Posts: 18

@codingislife. Please post your finished code using pastebin, Dropbox, or git. I thought about a change to your program using levels yesterday. An interesting skills drill might be to have the program iterate through addition, subtraction, multiplication, and division. You couldn't proceed to the next level until you reached a certain level of proficiency on the current level. With the right U.I. Enhancements I bet you could get teachers to buy that on the App Store.

• Posts: 56

@nfgdayton That is an interesting idea. Although this is just a small assignment for my Computer Science class. Oddly enough I actually am doing a math game as well for my final app project (with a group) which will be put onto the App Store. But I'd love to work on this program after I submit it as well.

• Posts: 18

To get you thinking look at a post called " the power of openurl." I am going to look at sending myself emails ... But this looks like it's definitely possible. It is a small step to have a teacher send themselves reports from classroom activity using the iPad. Then your calc app moves from a practice app to a diagnostic app.

• edited November 2015 Posts: 56

Okay! So I've completed what I wanted to accomplish. This is just a small assignment but I may come back to this code and make it much better. I've uploaded the code to Github and Pastebin. Open the links & copy/paste the code on your iOS device or else the code will not work (for the ones you must go to; it uses emojis as buttons)

Github: https://github.com/CodingIsLyfe/MathGame (This is my own code using my own iPad images)

https://github.com/CodingIsLyfe/Math-Game (GO TO THIS ONE)

Pastebin: http://pastebin.com/hbuX1pNf (This is mine)

http://pastebin.com/4FyXKe3j(GO TO THIS ONE)

Let me know if you run into any problems or have any suggestions. This was a fun project and it really helped me understand Codea. Big thanks to everyone who helped me. @dave1707 @Ignatz @nfgdayton and @quezadav

• Mod
Posts: 5,396

Don't stop now.

There's so much more you can do with Codea.

• edited November 2015 Posts: 56

Oh I know. This is...hm...let's say v1.0

I'm actually quite interesting in making the game look cleaner and more organized (etc). That's just the code that works fine in my opinion and I'm happy with it. Also, that code will be what I'm submitting for my assignment but I'll find time to make it better.

I'll definitely come back and do more.

• Posts: 18

@codingislife Thanks for posting the version that uses CODEA native images. The "Go to this one" link in Pastebin is the same as your code, but I went to github and got the "native" version.

I am very jealous of your visual design skills. The cloud above the character boy is a great way to present the problem.

I am going to show this program to a teacher friend of mine and see what they think about using this program to evaluate student's grasp of math facts. If I write that program I will post it on this thread.

This is very nice work. It is amazing what you can do in Codea in under 150 lines of code.

• edited November 2015 Posts: 56

@nfgdayton Thank you for pointing that out. The new link is http://pastebin.com/4FyXKe3j

Also thanks for the compliment. I find my artistic skills play a major role in my other courses and it definitely helps.

Sounds good. Whenever I complete my course's final app project I'll make a post on here as well. The game will be similar to this but instead it gives you the solution and you must determine whether it is correct or incorrect.

Codea is so fun

• Posts: 18

Yes. I'm exploring the tables to string/ string to tables threads right now. I'm surprised these don't come up more often. Easy to convert a table to a string. [http://codea.io/talk/discussion/2850/table-to-string](String to table) is a little harder. I tried to go generic and got caught up in string handling problems. Problem is handling tables containing tables.

Formatting permanent data in terms other. Than key-value seems to be a sticking point for Codea ON THE IPAD.

• Posts: 56

You do whatever you want with my code @nfgdayton

• Mod
Posts: 8,943

@nfgdayton See the Codea functions json.encode and json.decode .

• Posts: 56

Hey, y'all. I've got a question about the touch function. I didn't want to make a whole new discussion because that could get annoying.

So in my programming class, we've been creating an app in groups. I have a question about how I'd go about making a store. Well, I've got the code checking if the user has enough currency to actually buy the item and their amount of currency goes down. However, I want the user to be able to buy backgrounds for a scene where they are displayed with a math problem. Here http://imgur.com/a/lZQui you can see the pictures of some scenes. I have it when the user presses the small squares in the store, a preview of the background will show up. I'd like it if I could check if the user has held it for a certain amount of time and then maybe the square changes colour or something (checkmark) and then the user pressed the buy button. This is the code for the store scene http://pastebin.com/2M2T6txf. We have this chunk of code we use in class to make coding easier which is why the store scene code looks a bit different from normal LUA if you will. This is the said chunk of code http://pastebin.com/c004LDSi which is put in a 'Blank File'.

• Mod
edited January 2016 Posts: 5,396

HahaHa - I love the reference in the code to the scene manager being from Brainfox on the Codea forum. If Briarfox was still around, he would ROFL.

• Mod
Posts: 5,396

You already have code for touches.

When a touch is made on one of the menu squares, and the touch state is `BEGAN`, set an indicator variable, eg `startTime = ElapsedTime`

When the touch ends (touch state is ENDED), check if startTime was set, and if it was, calculate the time it was held = `ElapsedTime - startTime`

• edited January 2016 Posts: 56

@Ignatz Would the

``````if (touch.state == BEGAN
``````

``````and backgroundPreviewRed.selected == true) then
startTime = ElapsedTime
end
``````

or have I misinterpreted your comment?

• Mod
Posts: 8,943

Try this.

``````displayMode(FULLSCREEN)

function setup()
tchStart=0
end

function draw()
background(40, 40, 50)
fill(255)
if tchStart~=0 then
text("Screen touched for "..((ElapsedTime-tchStart)//1).." seconds.",WIDTH/2,HEIGHT/2)
end
text("touch the screen",WIDTH/2,HEIGHT-100)
end

function touched(t)
if t.state==BEGAN then
tchStart=ElapsedTime
end
if t.state==ENDED then
tchStart=0
end
end
``````