' Zap-a-Mole Extreme by Charles Platt ' Output pins 0, 1, 2, 3 send a 4-bit binary to a 74HC4514 decoder. ' The decoder converts binary to a high signal to one of 16 ouputs. ' The outputs are numbered 0 - 15 and connect directly to LEDs. ' PICAXE output pin 6 connects with Enable pin 23 on the decoder. ' When 6 is high, decoder output is suppressed (no visible LEDs). ' Output pin 7 drives an LCD screen which uses embedded commands ' to control text positioning. Screen statements have been placed in ' subroutines to simplify substitution of different LCD hardware. ' Input pin0 is attached to a "start" button, high when pressed. ' All input pins must be held normally low with 10K pulldown resistors. ' Input ADC0 is connected to a resistor ladder delivering varying ' voltages when buttons 0 - 15 are pressed. A 100K pullup resistor ' guarantees a voltage near Vcc when no button is pressed. ' Voltages are converted to digital values spaced at intervals of 16. ' Unused ADC input pins must be grounded through 10K pulldown resistor. ' byte variables: symbol vval = b0 ' voltage value converted by ADC symbol oldled = b1 ' previously selected LED, 0 - 15 symbol newled = b2 ' newly selected LED, 0 - 15 symbol elapsed = b3 ' counts seconds upward symbol remaining = b4 ' counts seconds downward symbol butn = b5 ' stores button number 0 - 15 symbol dreduce = b6 ' reduction in dmax each cycle ' word variables symbol dmax = w6 ' target for delay counter symbol dcount = w7 ' counts up to delay target value symbol rnum = w8 ' stores random number 0 - 65536 symbol score = w9 ' counts how many hits in this game ' constants symbol gametime = 120 ' length of game, max 255 seconds symbol dstart = 32000 ' starting value for maximum delay symbol dstep = 100 ' step to advance the delay counter symbol rstart = 150 ' start value for reduction factor setfreq m8 ' run the PICAXE at 8 MHz high 7 ' screen output must start high high 6 ' disable the decoder's LED outputs settimer t1s_8 ' set timer to count in seconds pause 12000 ' pause to initialize the screen gosub screen1 ' display the initial headline ready: high 6 ' disable the decoder's LED outputs do ' to randomize the number generator, random rnum ' choose random numbers repeatedly loop until pin0 = 1 ' while waiting for the start button gosub screen2 ' display time and hits values score = 0 ' reset the score to zero dmax = dstart ' set delay between one LED and next dreduce = rstart ' initial value for reduction factor timer = 0 ' zero the timer elapsed = 0 ' zero the elapsed time counter low 6 ' enable the decoder's LED outputs chooseled: random rnum ' store random number 0 - 65535 newled = rnum / 4096 ' convert to LED number, 0 - 16 if newled = oldled then chooseled ' disallow same LED twice oldled = newled ' memorize the new LED number outpins = newled + 128 ' use LED number as binary output dcount = 0 ' reset the delay counter if dreduce > 0 then dmax = dmax - dreduce ' reduce delay target value dreduce = dreduce - 1 ' reduce the reduction factor endif getbutton: readadc 0, vval ' convert voltage to digital value if vval < 248 then ' if a button has been pressed... butn = vval + 8 / 16 ' ...convert to button number else ' otherwise, butn = 16 ' 16 shows no button has been pressed endif if elapsed = timer then newscore ' skip this if timer hasn't ticked elapsed = elapsed + 1 ' move elapsed value one second ahead remaining = gametime - elapsed ' this is the new remaining time gosub screen3 ' update the time display if remaining = 0 then ready ' if remaining = 0 the game is over newscore: if butn <> newled then delay ' if button doesn't match, skip this score = score + 1 ' increment the score gosub screen4 ' update the score display goto chooseled ' choose another LED at random delay: dcount = dcount + dstep ' advance the delay counter if dcount < dmax then getbutton ' check buttons again goto chooseled ' max delay reached, choose new LED screen1: serout 7, T4800_8, ("?f*Zap-a-Mole Extreme*") : return screen2: serout 7, T4800_8, ("?y2?x00Remaining Time: 120") serout 7, T4800_8, ("?y3?x00Hits: 0 ") : return screen3: serout 7, T4800_8, ("?y2?x16", #remaining, " ") : return screen4: serout 7, T4800_8, ("?y3?x06", #score) : return ' Additional notes ' The outpins statement adds 128 to the binary value to keep pin7 in ' a high state. This is necessary for the LCD screen driven by pin7 ' which uses serial communication in T mode. For LCD screens using ' serial in N mode, remove the +128 value from the outpins statement. ' Each time a new LED is illuminated, the program starts counting up ' to a preset maximum value, dmax. If the user doesn't press the ' correct button during this waiting period, the program lights another ' LED instead. However, dmax gradually decreases during the game, so ' that the LEDs start changing faster and faster. ' dmax is reduced by subtracting the variable dreduce. Since a linear ' reduction in delay time would seem to have very little effect at ' first but a much larger effect toward the end of the game, the ' dreduce variable is itself reduced. Initially it is established as ' dreduce = rstart, and the value of rstart is established in the list ' of constants. Then in the "choseled:" section, you'll see the ' expression dreduce = dreduce - 1. ' To adjust the speed profile of the game, you have several options. ' These can all be chosen in the "constants" section of the program. ' To adjust game duration, you can reset "gametime" to any number ' up to a maximum of 255. The longer it lasts, the faster it gets. ' If you increase the value for dstart, the game will run more slowly ' all the way through. Reduce the value, and it runs generally faster. ' dstep is the value which the game uses to count up to the delay ' target value. Use larger steps, and the delay will be reduced. ' rstart is the starting value subtracted from the delay target dmax ' while the game is running. If rstart is larger, the rate at which ' the game speed increases will itself increase. ' PICAXE executes mathematical expressions strictly in the sequence of ' the terms in the expression. Thus vval + 8 / 16 adds 8 to vval first ' and then does the division sum. Some PICAXEs recognize parentheses ' to force execution sequence of terms in an expression, but not all. ' PICAXE does not allow negative or fractional values for variables.