Hi folks,
Here's a little puzzle to test your mental arithmetic .. resurrected from the old Pyxia forum .. :)
The code tries out a pseudo-Edit box which accepts a Return key to complete the data entry - something a normal edit box can't do without a lot of fiddling. It works by using an off-screen edit box to keep track of the data entry, and uses GetKey to detect the Return keypress.
Here's the code:
'
' EBasic Magic Square - GWS - June 2004
'
int i,j,k,n,r,g,b,mx,my,x,y,z
int test1,test2,test3,stopit,another
int groupx,groupy,sdev,col,c,d,e
int xpos,ypos,querymouse,xp,yp
int sl,st,marked,userreply,tW,tH
float pi,x1,x2,ret
pointer sprite1,spriten,spritex,sback
string aclue,a$,e$,r$
int a[10],q[10],sq[10,3]
autodefine "OFF"
pi = 4 * atan(1)
querymouse = true: ' mouse enabled
marked = 0: ' no square is marked
userreply = true: ' no reply to be displayed
if CREATESCREEN(800,600,32,&screenhandler) < 0
MESSAGEBOX 0,"Error creating screen","Error"
END
endif
Fillscreen RGB(0,0,50), FrontBuffer
FRONTPEN BackBuffer,RGB(100,100,240)
BACKPEN BackBuffer, RGB(50,50,100)
sback = CREATESPRITE(750,520,1,1)
gosub NextPuzzle
sprite1 = CREATESPRITE(80,80,1,1)
spritetobuffer sprite1
DRAWFILLEDRECT 5,5, 70, 70, RGB(50,50,100),SpriteBuffer
spriten = CREATESPRITE(100,25,1,1)
spritetobuffer spriten
Fillscreen RGB(0,0,0), SpriteBuffer
DRAWFILLEDRECT 0,0, 100, 25, RGB(50,50,100),SpriteBuffer
spritex = CREATESPRITE(100,25,1,1)
spritetobuffer spritex
Fillscreen RGB(0,0,0), SpriteBuffer
DRAWFILLEDRECT 0,0, 100, 25, RGB(50,50,100),SpriteBuffer
' create an off-screen edit control ..
CONTROL backbuffer,@edit,"",-50,-20,50,20,0,1
'----------------------------------------------------------------------
do
FILLSCREEN RGB(0,0,50)
' draw background sprite ..
DrawSpriteXY sback,25,25
' (note: set the data pointer to the beginning or this doesn't work ..)
restore squares
for i = 1 to 7 step 3
getdata squares,xp
for j = 0 to 2
getdata squares,yp
DrawSpriteXY sprite1,xp,yp
' remember the square locations ..
sq[i+j,1] = xp
sq[i+j,2] = yp
next j
next i
' place the numbers on the screen ..
k = -1
setfont BackBuffer,"Times Roman",20,600
for y = 1 to 7 step 3
k = k + 1
for z = 0 to 2
xpos = 300 + k * 82
ypos = 155 + z * 82
if q[y+z] = 30
WRITETEXT xpos, ypos, "??"
else
a$ = USING("##", q[y+z])
WRITETEXT xpos, ypos, a$
endif
next z
next y
setfont BackBuffer,"Times Roman",16,400
WRITETEXT 285, 0, " EBasic Magic Square "
setfont BackBuffer,"Times Roman",12,300
aclue = "Clue: All Rows and Columns add to the same number."
WRITETEXT 200, 480, aclue
SpriteDrawMode spriten, @TRANS
DrawSpriteXY spriten,146,560
setfont BackBuffer,"Times Roman",14,400
WRITETEXT 180, 561, "Next"
SpriteDrawMode spritex, @TRANS
DrawSpriteXY spritex,550,560
setfont BackBuffer,"Times Roman",14,400
WRITETEXT 584, 561, "Exit"
' current mouse co-ordinates and left button status ..
mx = MOUSEX()
my = MOUSEY()
test3 = mousedown(1)
' only do the next tests if the left mouse button is pressed
' and Querymouse is true ..
if querymouse and test3
' test for Next button clicked ..
test1 = mx > 146 and mx < 246
test2 = my > 560 and my < 585
if (test1 and test2) then another = 1
if another
starttimer backbuffer,500,1
another = 0
querymouse = false
gosub NextPuzzle
endif
' test for Exit button clicked ..
test1 = mx > 546 and mx < 646
test2 = my > 560 and my < 585
if (test1 and test2) then stopit = 1
' check if clicked within the squares region ..
test1 = mx > sq[1,1] and mx < sq[7,1] + 80
test2 = my > sq[1,2] and my < sq[3,2] + 80
if (test1 and test2)
' test for a '??' box clicked ..
for i = 1 to 9
if q[i] = 30 :' is it a ?? square ..
' check if the mouse is within the '??' square ..
sl = sq[i,1] : st = sq[i,2]: ' box left and top positions
test1 = (mx > sl) and (mx < sl + 80)
test2 = (my > st) and (my < st + 80)
if (test1 and test2)
' mouse clicked within '??' square 'i'..
' display the marker
DRAWRECT sq[i,1], sq[i,2], 80, 80, RGB(255,0,0)
' note which square is marked ..
marked = i
endif
endif
next i
else
' clicked outside the boxes region ..
marked = 0
setcontroltext backbuffer,1,""
endif
else
' mouse left button not down (or querymouse is false due to Next being pressed) ..
if querymouse and marked
' a '??' square is already marked ..
DRAWRECT sq[marked,1], sq[marked,2], 80, 80, RGB(255,0,0)
' get user input ..
DRAWFILLEDRECT 360, 401, 70, 23, RGB(0,50,120)
setfocus backbuffer,1
a$ = "Type the number you think it is and press Enter."
FRONTPEN BackBuffer,RGB(0,150,150)
BACKPEN BackBuffer, RGB(0,0,50)
setfont BackBuffer,"Times Roman",12,400
WRITETEXT 250, 430, a$
e$ = getkey
a$ = getcontroltext(backbuffer ,1)
setfont BackBuffer,"Times Roman",16,400
FRONTPEN BackBuffer,RGB(200,200,240)
BACKPEN BackBuffer, RGB(0,50,120)
GETTEXTSIZE backbuffer, a$, tW, tH
k = (800-tW)/2 - 5
WRITETEXT k, 401, a$
FRONTPEN BackBuffer,RGB(100,100,240)
BACKPEN BackBuffer, RGB(50,50,100)
' check for Enter pressed ..
if asc(e$) = 13
starttimer backbuffer,50,3
' is it the right answer ..
if val(a$) = a[marked]
' correct answer ..
r$ = " correct "
else
' wrong answer ..
r$ = " wrong "
endif
starttimer backbuffer,1000,2
endif
endif
endif
' show the result ..
if userreply
BACKPEN BackBuffer, RGB(0,0,50)
select r$
case " correct "
FRONTPEN BackBuffer,RGB(0,200,40)
case " wrong "
FRONTPEN BackBuffer,RGB(200,0,40)
endselect
GETTEXTSIZE backbuffer, r$, tW, tH
k = (800-tW)/2 -5
WRITETEXT k, 401, r$
FRONTPEN BackBuffer,RGB(100,100,240)
BACKPEN BackBuffer, RGB(50,50,100)
endif
FLIP
until stopit = 1
'----------------------------------------------------------------------
FREESPRITE sprite1
FREESPRITE spriten
FREESPRITE spritex
FREESPRITE sback
CLOSESCREEN
END
SUB screenhandler
select @MESSAGE
case @IDTIMER
if (@code = 1)
querymouse = true
stoptimer backbuffer,1
endif
if (@code = 2)
stoptimer backbuffer,2
if r$ = " correct " then q[marked] = a[marked]
marked = 0
userreply = false
setcontroltext backbuffer,1,""
r$ = ""
endif
if (@code = 3)
userreply = true
stoptimer backbuffer,3
endif
endselect
return
ENDSUB
sub NextPuzzle
' generate the next numbers ..
spritetobuffer sback
Fillscreen RGB(0,0,50), SpriteBuffer
' create some coloured spots fot the background ...
for i = 1 to 10
groupx = rnd(500)+100
groupy = rnd(300)+100
sdev = 30
col = rgb(rnd(200),rnd(200),rnd(200))
for j = 1 to 1000
x = splot() * sdev + groupx
y = splot() * sdev + groupy
writepixel x,y,col, SpriteBuffer
next j
next i
'generate the numbers ..
c = 1 + rand(9)
do
d = 1 + rand(9)
until d <> c
do
e = 1 + rand(9)
until (e <> c) & (e <> d)
a[1] = c + d
a[2] = c - (d + e)
a[3] = c + e
a[4] = c - d + e
a[5] = c
a[6] = c + d - e
a[7] = c - e
a[8] = c + d + e
a[9] = c - d
for i = 1 to 9
q[i] = a[i]
next i
q[c] = 30
q[d] = 30
q[e] = 30
return
endsub
sub splot(),float
' routine to give a random value from the Normal distribution ..
float x1,x2,ret
x1 = rnd(1.0)
x2 = rnd(1.0)
' catch very small (near zero) values of x1 ..
if (x1 < 1.0e-5) then x1 = 1.0e-5
' the Normal curve value ..
ret = sqrt(-2.0*log(x1)) * cos(2*pi*x2)
return ret
endsub
databegin squares
data 275,130,212,294,357,130,212,294,439,130,212,294
dataend
all the best, :)
Graham