Showing posts with label hour of code. Show all posts
Showing posts with label hour of code. Show all posts

Saturday, December 6, 2014

Hour of Code 2014

Hour of Code is coming, and I'm preparing several programs that you can do in your spare time. It may not be one hour, at least for you, but it will be one hour for me. :)

I'll be using my favorite computer development platform: Petit Computer for Nintendo DSi. I do wish that I have the latest Mk 3 version that is out in Japan now, but so far, not for US.

The first program is already done: Debugger. I'll just have to write it up. Turtle Graphic is an old stand-by, but I think I'm going to implement Travelling Salesman Problem. That's right, the NP hard problem that is the sink of so many man hours of computer science researchers. There's also a re-implementation of Quicksort both recursive version (in Basic!) and non-recursive version (Merge sort!)

I'm sure I can think of a few more fun stuff to write in one hour. Hey, it's quick and easy. What are you waiting for? Download Petit Computer DSiWare for your Nintendo game device and get programming!

Friday, January 10, 2014

Petit Computer Journal #33


Quick Programs

There are many programs that can be done quickly. Suppose that you only have 15 minutes to write a computer program. What do you think you would write? Let's start a quick one. The quickest program that you can write would be a simple game. Coin flips. Heads or Tail. Or in this case, A/B buttons. The program simply checks whether or not you pushed the right buttons. It's a simple one-liner.


  1. ?"A/B?":WAIT 180:IF BUTTON(0)==16*RND(2) THEN "YOU WIN!" ELSE "YOU LOSE!"


Yes, it's that simple! There's nothing to it, is there? Let's take it a little more and do a simple Rock-Paper-Scissor game. Let's take a look at this table(A-B) (RPS=012):

B\A R P S
R 0 1 2
P -1 0 1
S -2 -1 0

Now, consider this: Looking at the diagonals, we see that the values are the same. zero means draw. one means win. two means lose. -1, -2 means lose, win. So, how about if we shift it up and set the range to modulus 3?


  1. O=(2+A-B)%3:'O=OUTCOME


The range then becomes 0-2, 0=Win,1=Lose,2=Draw, and everything is peachy! The program then clearly writes itself:


  1. CLS:CLEAR
  2. DIM T$(3)
  3. T$(0)="ROCK"
  4. T$(1)="PAPER"
  5. T$(2)="SCISSORS"
  6. ?"A=ROCK,B=PAPER,X=SCISSORS"
  7. WAIT 180
  8. B=BUTTON(0)
  9. A=0
  10. IF B AND 32 THEN A=1
  11. IF B AND 64 THEN A=2
  12. ?"YOU CHOSE ";T$(A)
  13. B=RND(3)
  14. ?"I CHOOSE ";T$(B)
  15. O=(2+A-B)%3
  16. IF O==0 THEN ?"YOU WIN" ELSE IF O==1 THEN ?"YOU LOSE" ELSE ?"DRAW"


That's all there is to it. Pretty quick to do and implement.

Let's keep moving on. How about random outcome? That's important in a game. However, there's something that you can do for a purely random device, such as dice. Here's a quick implementation of the Magic 8 Ball, although I don't bother putting in too many responses.


  1. CLS:CLEAR
  2. DIM T$(6)
  3. T$(0)="ABSOLUTELY YES"
  4. T$(1)="YES"
  5. T$(2)="MAYBE"
  6. T$(3)="NO"
  7. T$(4)="ABSOLUTELY NOT"
  8. T$(5)="NO WAY JOSE!"
  9. ?T$(RND(6))


If the example looks lean, that's because it is. The Magic 8 Ball is quite famous. Another example, using the same structure, would be Yoda's Wisdom. Quotes of Yoda from Star Wars, presented with pictures of him is a rather entertaining program. Another one would be Bingo, or lottery, or anything random. One of my stand by program is a dice roller for playing board games.

Some games requires you to roll so many dice, and they're not all six dice, either. Let's say that you want to roll 1-4 dice, ranging from D6,D10,D20. It's a simple process using the touch screen and do it. I'm doing it quick, so there's no text. You certainly want to dress it up for practical use.


  1. CLS:CLEAR
  2. DIM D(3)
  3. D[0]=6
  4. D[1]=10
  5. D[2]=20

  6. @MAIN
  7. VSYNC 1:TX=TCHX:TY=TCHY
  8. R=0
  9. FOR I=0 TO FLOOR(TX/64)
  10. R=R+RND(D[FLOOR(TY/64)])
  11. NEXT I
  12. IF TCHST THEN LOCATE 0,0:?"YOU ROLL ";R;"    "
  13. GOTO @MAIN


I actually implemented Snake and Ladder game in less than 10 minutes. One thing that is interesting about it, is that the program really doesn't require any user input other than rolling the dice. In that sense, all the activities that you do can be boiled down into rolling the dice. We can improve this further simply by letting the computer run it straight.


  1. CLS:CLEAR
  2. A=0:B=0
  3. @MAIN
  4. ?A,B
  5. A=A+RND(2):B=B+RND(2)
  6. IF A>100 OR B>100 THEN GOTO @END
  7. GOTO @MAIN

  8. @END
  9. IF A>100 THEN ?"A WINS!"
  10. IF B>100 THEN ?"B WINS!"
  11. IF A==B THEN ?"IT'S A DRAW!"


The program will resolve the race immediately. You may find it interesting to input some kind of delay in the output, so as to make it more readable as it goes.

All of these programs can be done really quick. In fact, I do these while waiting for something. Or maybe when I was in bed, trying to sleep. Most people would take a book to read in bed. I would take a Nintendo 3DS and write programs, instead.

One more quick example of the program, and this time it's useful when you're trying to do something regarding sleep: An alarm clock.


  1. CLS
  2. AH=6:'ALARM HOUR
  3. AM=0:'ALARM MINUTE
  4. LOCATE 0,2:?AH;":";AM
  5. @MAIN
  6. WAIT 60
  7. LOCATE 0,0:?TIME$
  8. CH=VAL(LEFT$(TIME$,2))
  9. CM=VAL(MID$(TIME$,3,2))
  10. IF AH==CH AND AM==CM THEN BEEP
  11. GOTO @MAIN



Oh, one more bonus program since not one hour has passed, yet. You know how timers have lap times? Usually, there's only one room for lap times. With this, you can have as many as you want. I'm going to limit it to just 20 for simplicity. You may modify to suit.


  1. CLS
  2. I=0:T=0
  3. @MAIN
  4. VSYNC 1:T=T+1
  5. IF BTRIG() THEN I=I+1
  6. J$=RIGHT$("00"+STR$(T%60),2)
  7. S$=RIGHT$("00"+STR$(FLOOR((T/60))%60),2)
  8. M$=RIGHT$("00"+STR$(FLOOR((T/3600))%60),2)
  9. LOCATE 0,I:?I,M$;":";S$;":";J$
  10. IF I>=20 THEN END
  11. GOTO @MAIN


These programs are rough, and really, for distribution, you may want to dress them up a little. However, for something that you can doodle in 10 minutes, while waiting for something, these are perfectly suited as a pleasant time waster. Did I just do 7 programs in one hour? I guess so.

Friday, December 27, 2013

Petit Computer Journal #31



Digital Koto

A while back, I wrote a little piano program. It includes song player. It's just a little simple music player, so I used BEEP instead of MML command. However, I'm rather curious since most of the code is created for the interface. In other words, drawing the piano keys. So, I'm wondering whether or not it's simpler to just draw the keys straight. Well, what kind of musical instrument is like that? The answer is simple: Japanese Koto. In truth, different cultures have different ideas and names for what basically amounts to a bunch of strings mounted on a board.

Still, the idea of it is interesting, and it's simple enough for me to do. So, let' do it! There are several different parts, but generally speaking, once you touch the screen, you come up with a string number and beep the appropriate sound. That's just look up table. Touch screen is easy. About the only thing that's difficult is drawing the strings proportionately. A little mathematic should do it.


  1. INIT
  2. Build BEEP table
  3. Build Note table
  4. Build String table
  5. LOOP
  6. Draw Strings
  7. If Touch screen
  8. Highlight nearest string
  9. Play BEEP sound
  10. GOTO LOOP


So, do you think this will take you one hour to do? Time for another "Hour of Code" challenge!


  1. ACLS:CLEAR
  2. DIM BP[49]:'BEEP TABLE
  3. DIM NT$[49]:'NOTE TABLE
  4. DIM ST[16]:'STRING TABLE
  5. BREPEAT 0,60,12
  6. BREPEAT 1,60,12
  7. BREPEAT 2,60,12
  8. BREPEAT 3,60,12

  9. @INIT
  10. NSI=0
  11. P=4096/12:T$="CcDdEFfGgAaB"
  12. FOR I=-24 TO 24:J=I+24
  13. BP[J]=P*I
  14. NT$[J]=MID$(T$,(J%12),1)
  15. NEXT
  16. ST[0]=14:ST[1]=19
  17. ST[2]=21:ST[3]=22
  18. ST[4]=26:ST[5]=27
  19. ST[6]=31:ST[7]=33
  20. ST[8]=34:ST[9]=38
  21. ST[10]=39:ST[11]=43
  22. ST[12]=45:ST[13]=0
  23. ST[14]=0:ST[15]=0

  24. ACLS


That's about it for the Initialization table. I want to fiddle with the string, so I'll put in button interface so I can change the string values on the fly.


  1. @LOOP
  2. NS=13:A=256/NS:B=A/2
  3. VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
  4. IF NS<1 THEN NS=1
  5. FOR I=0 TO NS-1
  6. GLINE B+I*A,16,B+I*A,192,15
  7. LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
  8. LOCATE (B+I*A)/8,0:?NT$[ST[I]]
  9. NEXT
  10. GLINE B+TX*A,16,B+TX*A,192,8
  11. IF TCHTIME>0 THEN BEEP 20,BP[ST[TX]]
  12. GOTO @LOOP


And that's about it. 35 minutes so far, and that's because I was having trouble with the math. The truth is, had I did the math correctly beforehand, I wouldn't have had so much trouble and I wouldn't have spend the time debugging.

Oh, yeah, about the tuning on the fly. I think that it is nice to be able to change the notes. So, what I'll do is add some button interface. That's what the BREPEAT command is for. Also, I may as well throw the instrument along with it. Instead of the locked in BEEP 20, I substitute it with a variable that will allow you to choose your own instrument.

Finally, we're going to move the whole thing down to the lower screen for ease of play. What should we put on the top of the screen? I don't know. Title screen, maybe? Or some internal variables?


  1. REM DIGITAL KOTO
  2. REM BY HARRY HARDJONO
  3. REM DEC 2013

  4. ACLS:CLEAR
  5. DIM BP[49]:'BEEP TABLE
  6. DIM NT$[49]:'NOTE TABLE
  7. DIM ST[16]:'STRING TABLE
  8. BREPEAT 0,60,12
  9. BREPEAT 1,60,12
  10. BREPEAT 2,60,12
  11. BREPEAT 3,60,12
  12. PNLTYPE "OFF"

  13. @INIT
  14. NSI=0
  15. CI=16:'CURRENT INSTRUMENT
  16. P=4096/12:T$="CcDdEFfGgAaB"
  17. FOR I=-24 TO 24:J=I+24
  18. BP[J]=P*I
  19. NT$[J]=MID$(T$,(J%12),1)
  20. NEXT
  21. ST[0]=14:ST[1]=19
  22. ST[2]=21:ST[3]=22
  23. ST[4]=26:ST[5]=27
  24. ST[6]=31:ST[7]=33
  25. ST[8]=34:ST[9]=38
  26. ST[10]=39:ST[11]=43
  27. ST[12]=45:ST[13]=0
  28. ST[14]=0:ST[15]=0

  29. GPAGE 1:ACLS

  30. @LOOP
  31. NS=13:A=256/NS:B=A/2
  32. VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
  33. IF NS<1 THEN NS=1
  34. GPAGE 1,1,1
  35. FOR I=0 TO NS-1
  36. GLINE B+I*A,16,B+I*A,192,15
  37. LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
  38. LOCATE (B+I*A)/8,0:?NT$[ST[I]]
  39. NEXT
  40. GLINE B+TX*A,16,B+TX*A,192,8
  41. IF TCHTIME>0 THEN BEEP CI,BP[ST[TX]]

  42. IF BT AND 1 THEN ST[NSI]=ST[NSI]+1
  43. IF BT AND 2 THEN ST[NSI]=ST[NSI]-1
  44. IF BT AND 4 THEN NSI=NSI-1
  45. IF BT AND 8 THEN NSI=NSI+1
  46. IF BT AND 16 THEN CI=CI+1:GOSUB @DISP
  47. IF BT AND 32 THEN CI=CI-1:GOSUB @DISP
  48. NSI=(NSI+NS)%NS
  49. ST[NSI]=(ST[NSI]+49)%49
  50. CI=(CI+70)%70
  51. GOTO @LOOP

  52. @DISP
  53. ACLS
  54. ?"INST: ";CI
  55. FOR I=0 TO 15
  56. ?I,ST[I]
  57. NEXT
  58. RETURN



Oh, by the way. The actual problem is so simple, that you can actually fit the minimalistic version of the program into one screen. That's right. It's another single screen challenge program!


  1. REM DIGITAL KOTO
  2. REM BY HARRY HARDJONO
  3. ACLS:CLEAR:DIM BP[49]
  4. DIM NT$[49]:DIM ST[16]
  5. P=4096/12:T$="CcDdEFfGgAaB"
  6. FOR I=-24 TO 24:J=I+24
  7. BP[J]=P*I
  8. NT$[J]=MID$(T$,(J%12),1):NEXT
  9. ST[0]=14:ST[1]=19:ST[2]=21
  10. ST[3]=22:ST[4]=26:ST[5]=27
  11. ST[6]=31:ST[7]=33:ST[8]=34
  12. ST[9]=38:ST[10]=39:ST[11]=43
  13. ST[12]=45:ST[13]=0:ST[14]=0
  14. @LOOP
  15. NS=13:A=256/NS:B=A/2
  16. VSYNC 1:TX=FLOOR(TCHX*NS/256)
  17. GPAGE 1,1,1:FOR I=0 TO NS-1
  18. GLINE B+I*A,0,B+I*A,192,15
  19. NEXT
  20. GLINE B+TX*A,16,B+TX*A,192,8
  21. SD=BP[ST[TX]]
  22. IF TCHTIME>0 THEN BEEP 16,SD
  23. GOTO @LOOP


Friday, December 20, 2013

Petit Computer Journal #30


Programming Turtle Graphic

It somewhat annoys me when people are teaching turtle graphic as the basis of learning computer programming. It's not that turtle graphic is bad, as I do believe that the thought process does indeed teach programming. It is that the turtle is presented as a module. A black box, if you will.

I think it's more appropriate, especially for computer programming students to learn how simple and easy it can be to write their own turtle module. Therefore, I propose that instead of turtle graphic module, it should be a turtle graphic routines. Instead of a mysterious black box, it should be a transparent wrapper.

Done as a function call, especially interested students can take a peek into the function and see exactly how easy it can be to write a useful program such as turtle graphic.

In fact, I believe that it can be done in one hour. Turtle Graphic algorithm as an "Hour of Code" challenge? Bring it on!

First, what is involved in a turtle graphic program? Well, there's turtle and there's graphic. What are the commands necessary? Forward, Left, Right, and Pen. Each of those commands are followed by a number. We'll call that Number variable. Well, well. There are only 4 commands, are they? Would you believe that they are doable in about one hour? Why not?

If you are familiar with Object Oriented methodology, those are called "methods". What about variables? There's the position of the turtle, X0 and Y0. There's the destination of the turtle, X1 and Y1. There's Angle and Distance. And there's Pen Color. Is that 8 variables total? Are you saying coding these 8 variables into 4 commands is a great challenge? I don't think so!

Of course, we're skipping a lot of things. Namely, the LOGO language. LOGO is a programming language and if you are learning LOGO, you are learning computer programming language. The first turtle graphic and LOGO make effective combination. Most people incorrectly assume that turtle graphic must involve LOGO somewhat. Yet, Turtle graphic is just the graphical component of it. As for the language, we'll use Petit Computer Smile Basic.

That's all there is to it. So, let's set the timer and begin. 1 hour is all that takes. For simplicity, I will assume that commands are given in Strings and consist of 3 characters: A letter command, followed by 2 digit number. If the string has more than 3 characters, then the program will extract the first three characters only. If the string is less than 3 characters, it will be ignored. Also, Color 0 means Pen Up, which means moving the turtle without drawing the line. And perhaps, we should expand the language so we can do GPAINT command for colorful final image. With that in mind, let's begin!

In 15 minutes, I got the initial framework already.


  1. ACLS:CLEAR

  2. @INIT
  3. C$="":'COMMAND STRING
  4. N=0:'COMMAND PARAMETER
  5. X0=128:Y0=96:'TURTLE POSITION
  6. X1=0:Y1=0:'TURTLE DESTINATION
  7. A=0:'ANGLE
  8. D=0:'DISTANCE
  9. C=0:'PEN COLOR
  10. SPSET 1,139,0,0,0,0:SPOFS 1,X0,Y0

  11. @MAIN
  12. 'CLASSIC RECTANGLE
  13. C$="F35R90F35R90F35R90F35R90"
  14. GOSUB @TURTLE
  15. WAIT 300

  16. @END
  17. BEEP 6
  18. END

  19. @TURTLE
  20. IF LEN(C$)<3 THEN RETURN
  21. TC$=LEFT$(C$,3)
  22. N=VAL(RIGHT$(TC$,2))
  23. TC$=LEFT$(C$,1)
  24. C$=RIGHT$(C$,LEN(C$)-3)
  25. ?TC$;" ",N;"  ":WAIT 60

  26. GOTO @TURTLE


If you look at the code, there is nothing much there. It's simply the structure to pass on the command for the turtle. We can use IF-THEN ladder structure, or we can use ON-GOTO command structure. Depending on TC$, which contains the actual command. We can actually skip TC$, and specify LEFT$(C$,1) instead, but using that extra variable clarifies things for now.

I decided to do the easy thing first and implement Paint and Color command. Change C$ to "C01P00C02P00C03P00C04P00" for now. Also, we'll use ON-GOTO. This requires a numeric variable, so we'll do this


  1. TN=INSTR("FLRCP",TC$)
  2. ?TC$,TN,N:WAIT 60

  3. ON TN GOTO @TTF,@TTL,@TTR,@TTC,@TTP
  4. GOTO @TURTLE
  5. @TTF
  6. GOTO @TURTLE
  7. @TTL
  8. GOTO @TURTLE
  9. @TTR
  10. GOTO @TURTLE
  11. @TTC
  12. C=N:GCOLOR C
  13. GOTO @TURTLE
  14. @TTP
  15. IF N==0 THEN GPAINT X0,Y0,C ELSE GPAINT X0,Y0,N
  16. GOTO @TURTLE


Wow, that was easy! Of course, the hard part is coming up. Specifically, we're going to talk a bit about polar coordinates. We need it to draw the turtle. But first, we're going to just set the angle. That's not too difficult. All we have to do is adjust the angle variable just like we did with color. About the only thing that we have to do is to convert the angle to radians.

A bit of caution here. Mostly, we can just to "L180" to do a turn-about movement. However, since we decided to limit the numeric portion to just 2 digits, the most we can do is quarter turn. If we want to have turn-about the turtle, then we have to do it twice, with "L90L90" command.

Another thing. We want to rotate the turtle to the appropriate angle. So far, all we did was display the sprite. Now we want to set the angle and have the turtle facing in the right direction. So, there are two steps. First, we want to convert degrees to radians, and second, we want to orient the sprite accordingly.

There is a complication here. That is, computers have 0,0 coordinate on the top-left corner of the screen, unlike math with their 0,0 coordinate on the bottom-left of the screen. We'll have to fudge the math a bit, and the best way to do it is to just experiment. So, we're going to set up a new subroutine @ROTATE which will rotate the sprites according to angles. That is, given the value of A in degree, set the direction accordingly. All we have to do then, is decide which values goes which direction. I think 0 degree should point up. With that in mind, do this real quick:


  1. @TEST
  2. FOR A=0 to 360 STEP 360/12
  3. GOSUB @ROTATE:WAIT 60
  4. NEXT

  5. @ROTATE
  6. A=A%360
  7. SPANGLE 1,A,6
  8. RETURN



We discovered a weakness in our program in that the rotation is not centered on the sprite. We fix it by adding this line on the @INIT subroutine.

SPHOME 1,8,8

Then we simply add these lines to the LEFT and RIGHT portion of the code:


  1. @TTL
  2. A=A-N:'TURN LEFT
  3. GOSUB @ROTATE

  4. @TTR
  5. A=A+N:'TURN RIGHT
  6. GOSUB @ROTATE



And there you go! Just one more function and that's all there is to it! Who says turtle graphic programming is hard? Haha, joking aside, we have been delaying the inevitable. Not only we have to convert degree to radians, but we also have to make sure that the turtle is facing the right way. Fortunately, there are functions RAD(),SIN() and COS() that makes it simple. There is something else that we have to worry about, but we'll defer that until later. For now, let's draw!


  1. @TEST
  2. FOR A=0 to 360 STEP 360/12
  3. SPOFS 1,128,96:GOSUB @ROTATE
  4. X1=50*SIN(RAD(A)):'RSINTHETA
  5. Y1=50*COS(RAD(A)):'RCOSTHETA
  6. SPOFS 1,128+X1,96+Y1,50:'50 IS THE DISTANCE
  7. WAIT 60
  8. NEXT


If you run this code, you will see that the whole thing breaks up. You see that the sprite and the movement do not match. We want to see the sprites to move in a clock-wise pattern. The problem now is how to fix it? Remember that the coordinate is centered at top-left? That's the problem! To the math savvy among you, it may interest you to come up with the solution yourself. Otherwise, here's the fix!

Y1=-50*COS(RAD(A)):'RCOSTHETA

Yes, it's that easy! Simply turn R into negative R, and that's all there is to it. Really. Now, all we have to do is do the @TTF subroutine and we'll be done!


  1. @TTF
  2. D=N
  3. X1=D*SIN(RAD(A))
  4. Y1=(-1*D)*COS(RAD(A))
  5. SPOFS 1,X0+X1,Y0+Y1,D
  6. @TTF1
  7. SPREAD(1),TTFX,TTFY:'GOSUB @WRAP
  8. IF C!=0 THEN GPSET TTFX,TTFY,C
  9. IF SPCHK(1)!=0 GOTO @TTF1
  10. X0=X0+X1:Y0=Y0+Y1


And that's it! You're probably wondering why we're doing interval D on SPOFS. The reason for it is so that we can retrieve sprite coordinates TTFX,TTFY along the way, and plot the points with color C. That's a pretty neat trick. Otherwise, we'd have to mess around with line drawing algorithm. Not that coming up with line drawing algorithm is bad, just that it's an unnecessary complexity if all that we want is a simple subroutine.

Oh, one more thing: Suppose we want to do a wrap around? What should we do? Well, I don't like to mess with the current code, but basically, what we want to do is adjust the sprite location and update the target accordingly. So, we need to check whether TTFX or TTFY is below zero and if so, shift everything by the screenful. Trivial, had we did our own line drawing algorithm. Not so much if we're dependent upon internal routines, just like we did.

What exactly do we need to implement coordinate wrapping, anyway? Well, we need the start and stop coordinates, which are X0,y0 and X1,Y1. We also need a coordinate that specifies the current location going there. And we want to be able to reset the coordinates from the sprites.

So, we can do a bunch of calculation, but basically, we want to handle these 2 lines:

SPOFS 1,NEWX,NEWY
SPOFS 1,ADJX,ADJY,TIMELEFT

So, we need 5 variables to be set. To the math savvy among you, I suggest that you work it out yourself.

Time left is easy. We have already have D. For the new D, all we have to do is calculate the distance of the current position with the target coordinate. TIMELEFT=SQR((X1-TTFX)^2+(Y1-TTFY)^2) The old distance formula standby. NEWX and NEWY is simply OLDX=OLDX+256 and OLDY=OLDy+192. Basically, screen width and height. Same thing with ADJX and ADJY.

There's nothing to it, is there? We need to add WRAP=1 and replace the commented 'GOSUB @WRAP with IF WRAP THEN GOSUB @WRAP.

Before we do a bunch of complicated math, though, I'll point out to you something very interesting. The fact that there is only one GPSET makes it easy. If we don't care about drawing the point where the turtle is, and just worry about wrap, we can easily modify the line to this:


  1. IF C!=0 THEN GPSET ((TTFX+256)%256),((TTFY+192)%192),C
  2. IF SPCHK(1)!=0 GOTO @TTF1
  3. X0=((X0+X1+256)%256):Y0=((Y0+Y1+192)%192)
  4. SPOFS 1,XO,YO


That's something to think about. Do we want to write some complicated routines or do we just want to get the job done? With that in mind, instead of doing a bunch of mathematics, we can simply create a secondary sprite and put it into the current point set whenever the original turtle is out of bound! Simple, yet effective!


  1. @WRAP
  2. SPOFS 2,((TTFX+256)%256),((TTFY+192)%192)
  3. SPANGLE 2,A,0
  4. RETURN


And that's all there is to it! We can easily implement this within one hour. With wrap function, we're pushing it into the hour, depending on how fast you can type with the stylus. Regardless, we're only typing less than 100 lines program, with testing subroutine. What's the test? Well, remember that we're limiting the data to only 2 digits? That helps when we're doing wrapping test cases. But how about when we want to do large drawings? The test subroutine is used throughout the development process in order to try out subroutines outside the main program.

I commented out the test subroutine in the final program, but it's a good example on how you can use it in your program, so I'm leaving it there. The total time that it takes to do this program is:

15 min Initial Framework
10 min C and P command
10 min Rotation
15 min TTF drawing
10 min Wrap option

Total Development time? 1 hour, including screen wrap function. Now that's what I call "Hour of Code"!





  1. REM TURTLE GRAPHIC
  2. REM BY HARRY HARDJONO
  3. REM DEC 2013

  4. ACLS:CLEAR

  5. @INIT
  6. WRAP=1
  7. C$="":'COMMAND STRING
  8. N=0:'COMMAND PARAMETER
  9. X0=128:Y0=96:'TURTLE POSITION
  10. X1=0:Y1=0:'TURTLE DESTINATION
  11. A=0:'ANGLE
  12. D=0:'DISTANCE
  13. C=0:'PEN COLOR
  14. SPSET 1,139,0,0,0,0:SPOFS 1,X0,Y0
  15. SPHOME 1,8,8
  16. SPSET 2,139,0,0,0,0:SPOFS 1,-255,-255
  17. SPHOME 2,8,8

  18. @MAIN
  19. 'GOSUB @TEST
  20. 'CLASSIC RECTANGLE
  21. FOR I=1 TO 8
  22. C$="F35R90F35R90F35R90F35R90"
  23. GOSUB @TURTLE
  24. NEXT

  25. @END
  26. BEEP 6:WAIT 600
  27. END

  28. @TURTLE
  29. IF LEN(C$)<3 THEN RETURN
  30. TC$=LEFT$(C$,3)
  31. N=VAL(RIGHT$(TC$,2))
  32. TC$=LEFT$(C$,1)
  33. C$=RIGHT$(C$,LEN(C$)-3)
  34. TN=INSTR("FLRCP",TC$)
  35. ON TN GOTO @TTF,@TTL,@TTR,@TTC,@TTP
  36. GOTO @TURTLE
  37. @TTF
  38. D=N
  39. X1=D*SIN(RAD(A))
  40. Y1=(-1*D)*COS(RAD(A))
  41. SPOFS 1,X0+X1,Y0+Y1,D
  42. @TTF1
  43. SPREAD(1),TTFX,TTFY:IF WRAP THEN GOSUB @WRAP
  44. IF C!=0 AND WRAP==1 THEN GPSET ((TTFX+256)%256),((TTFY+192)%102),C
  45. IF C!=0 AND WRAP==0 THEN GPSET TTFX,TTFY,C
  46. IF SPCHK(1)!=0 GOTO @TTF1
  47. IF WRAP==1 THEN X0=((X0+X1+256)%256:Y0=((Y0+Y1+192)%192):SPOFS1,X0,Y0
  48. IF WRAP==0 THEN X0=X0+X1:Y0=Y0+Y1
  49. GOTO @TURTLE

  50. @TTL
  51. A=A-N:'TURN LEFT
  52. GOSUB @ROTATE
  53. GOTO @TURTLE
  54. @TTR
  55. A=A+N:'TURN RIGHT
  56. GOSUB @ROTATE
  57. GOTO @TURTLE
  58. @TTC
  59. C=N:GCOLOR C
  60. GOTO @TURTLE
  61. @TTP
  62. IF N==0 THEN GPAINT X0,Y0,C ELSE GPAINT X0,Y0,N
  63. GOTO @TURTLE

  64. @TEST
  65. WRAP=1:'0 OR 1
  66. FOR SP=0 TO 150 STEP 3
  67. V=SP:LOCATE 0,0:?SP
  68. @LINER
  69. IF V>99 THEN C$="F99":GOSUB @TURTLE:V=V-99:GOTO @LINER
  70. L1$=RIGHT$(("000"+STR$(V)),2)
  71. C$="F"+L1$+"R70C"+L1$:GOSUB @TURTLE
  72. NEXT
  73. RETURN

  74. @ROTATE
  75. IF A<0 THEN A=A+360:GOTO @ROTATE
  76. A=A%360:SPANGLE 1,A,6
  77. RETURN

  78. @WRAP
  79. SPOFS 2,((TTFX+256)%256),((TTFY+192)%192)
  80. SPANGLE 2,A,0
  81. RETURN