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!
A blogspot journal showcasing computer programming, personal development, and other hobbies. Featuring Raspberry Pi, Petit Computer, and miscellaneous How-To.
Showing posts with label hour of code. Show all posts
Showing posts with label hour of code. Show all posts
Saturday, December 6, 2014
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.
- ?"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?
- 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:
- CLS:CLEAR
- DIM T$(3)
- T$(0)="ROCK"
- T$(1)="PAPER"
- T$(2)="SCISSORS"
- ?"A=ROCK,B=PAPER,X=SCISSORS"
- WAIT 180
- B=BUTTON(0)
- A=0
- IF B AND 32 THEN A=1
- IF B AND 64 THEN A=2
- ?"YOU CHOSE ";T$(A)
- B=RND(3)
- ?"I CHOOSE ";T$(B)
- O=(2+A-B)%3
- 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.
- CLS:CLEAR
- DIM T$(6)
- T$(0)="ABSOLUTELY YES"
- T$(1)="YES"
- T$(2)="MAYBE"
- T$(3)="NO"
- T$(4)="ABSOLUTELY NOT"
- T$(5)="NO WAY JOSE!"
- ?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.
- CLS:CLEAR
- DIM D(3)
- D[0]=6
- D[1]=10
- D[2]=20
- @MAIN
- VSYNC 1:TX=TCHX:TY=TCHY
- R=0
- FOR I=0 TO FLOOR(TX/64)
- R=R+RND(D[FLOOR(TY/64)])
- NEXT I
- IF TCHST THEN LOCATE 0,0:?"YOU ROLL ";R;" "
- 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.
- CLS:CLEAR
- A=0:B=0
- @MAIN
- ?A,B
- A=A+RND(2):B=B+RND(2)
- IF A>100 OR B>100 THEN GOTO @END
- GOTO @MAIN
- @END
- IF A>100 THEN ?"A WINS!"
- IF B>100 THEN ?"B WINS!"
- 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.
- CLS
- AH=6:'ALARM HOUR
- AM=0:'ALARM MINUTE
- LOCATE 0,2:?AH;":";AM
- @MAIN
- WAIT 60
- LOCATE 0,0:?TIME$
- CH=VAL(LEFT$(TIME$,2))
- CM=VAL(MID$(TIME$,3,2))
- IF AH==CH AND AM==CM THEN BEEP
- 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.
- CLS
- I=0:T=0
- @MAIN
- VSYNC 1:T=T+1
- IF BTRIG() THEN I=I+1
- J$=RIGHT$("00"+STR$(T%60),2)
- S$=RIGHT$("00"+STR$(FLOOR((T/60))%60),2)
- M$=RIGHT$("00"+STR$(FLOOR((T/3600))%60),2)
- LOCATE 0,I:?I,M$;":";S$;":";J$
- IF I>=20 THEN END
- 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.
- INIT
- Build BEEP table
- Build Note table
- Build String table
- LOOP
- Draw Strings
- If Touch screen
- Highlight nearest string
- Play BEEP sound
- GOTO LOOP
So, do you think this will take you one hour to do? Time for another "Hour of Code" challenge!
- ACLS:CLEAR
- DIM BP[49]:'BEEP TABLE
- DIM NT$[49]:'NOTE TABLE
- DIM ST[16]:'STRING TABLE
- BREPEAT 0,60,12
- BREPEAT 1,60,12
- BREPEAT 2,60,12
- BREPEAT 3,60,12
- @INIT
- NSI=0
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1)
- NEXT
- ST[0]=14:ST[1]=19
- ST[2]=21:ST[3]=22
- ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33
- ST[8]=34:ST[9]=38
- ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0
- ST[14]=0:ST[15]=0
- 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.
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
- IF NS<1 THEN NS=1
- FOR I=0 TO NS-1
- GLINE B+I*A,16,B+I*A,192,15
- LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
- LOCATE (B+I*A)/8,0:?NT$[ST[I]]
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- IF TCHTIME>0 THEN BEEP 20,BP[ST[TX]]
- 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?
- REM DIGITAL KOTO
- REM BY HARRY HARDJONO
- REM DEC 2013
- ACLS:CLEAR
- DIM BP[49]:'BEEP TABLE
- DIM NT$[49]:'NOTE TABLE
- DIM ST[16]:'STRING TABLE
- BREPEAT 0,60,12
- BREPEAT 1,60,12
- BREPEAT 2,60,12
- BREPEAT 3,60,12
- PNLTYPE "OFF"
- @INIT
- NSI=0
- CI=16:'CURRENT INSTRUMENT
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1)
- NEXT
- ST[0]=14:ST[1]=19
- ST[2]=21:ST[3]=22
- ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33
- ST[8]=34:ST[9]=38
- ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0
- ST[14]=0:ST[15]=0
- GPAGE 1:ACLS
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:BT=BTRIG():TX=FLOOR(TCHX*NS/256)
- IF NS<1 THEN NS=1
- GPAGE 1,1,1
- FOR I=0 TO NS-1
- GLINE B+I*A,16,B+I*A,192,15
- LOCATE (B+I*A)/8,0:?FLOOR(ST[I]/12)
- LOCATE (B+I*A)/8,0:?NT$[ST[I]]
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- IF TCHTIME>0 THEN BEEP CI,BP[ST[TX]]
- IF BT AND 1 THEN ST[NSI]=ST[NSI]+1
- IF BT AND 2 THEN ST[NSI]=ST[NSI]-1
- IF BT AND 4 THEN NSI=NSI-1
- IF BT AND 8 THEN NSI=NSI+1
- IF BT AND 16 THEN CI=CI+1:GOSUB @DISP
- IF BT AND 32 THEN CI=CI-1:GOSUB @DISP
- NSI=(NSI+NS)%NS
- ST[NSI]=(ST[NSI]+49)%49
- CI=(CI+70)%70
- GOTO @LOOP
- @DISP
- ACLS
- ?"INST: ";CI
- FOR I=0 TO 15
- ?I,ST[I]
- NEXT
- 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!
- REM DIGITAL KOTO
- REM BY HARRY HARDJONO
- ACLS:CLEAR:DIM BP[49]
- DIM NT$[49]:DIM ST[16]
- P=4096/12:T$="CcDdEFfGgAaB"
- FOR I=-24 TO 24:J=I+24
- BP[J]=P*I
- NT$[J]=MID$(T$,(J%12),1):NEXT
- ST[0]=14:ST[1]=19:ST[2]=21
- ST[3]=22:ST[4]=26:ST[5]=27
- ST[6]=31:ST[7]=33:ST[8]=34
- ST[9]=38:ST[10]=39:ST[11]=43
- ST[12]=45:ST[13]=0:ST[14]=0
- @LOOP
- NS=13:A=256/NS:B=A/2
- VSYNC 1:TX=FLOOR(TCHX*NS/256)
- GPAGE 1,1,1:FOR I=0 TO NS-1
- GLINE B+I*A,0,B+I*A,192,15
- NEXT
- GLINE B+TX*A,16,B+TX*A,192,8
- SD=BP[ST[TX]]
- IF TCHTIME>0 THEN BEEP 16,SD
- GOTO @LOOP
Labels:
31,
challenge,
computer,
digital,
hour of code,
Journal,
koto,
music,
Petit,
screen,
single,
tutorial
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.
- ACLS:CLEAR
- @INIT
- C$="":'COMMAND STRING
- N=0:'COMMAND PARAMETER
- X0=128:Y0=96:'TURTLE POSITION
- X1=0:Y1=0:'TURTLE DESTINATION
- A=0:'ANGLE
- D=0:'DISTANCE
- C=0:'PEN COLOR
- SPSET 1,139,0,0,0,0:SPOFS 1,X0,Y0
- @MAIN
- 'CLASSIC RECTANGLE
- C$="F35R90F35R90F35R90F35R90"
- GOSUB @TURTLE
- WAIT 300
- @END
- BEEP 6
- END
- @TURTLE
- IF LEN(C$)<3 THEN RETURN
- TC$=LEFT$(C$,3)
- N=VAL(RIGHT$(TC$,2))
- TC$=LEFT$(C$,1)
- C$=RIGHT$(C$,LEN(C$)-3)
- ?TC$;" ",N;" ":WAIT 60
- 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
- TN=INSTR("FLRCP",TC$)
- ?TC$,TN,N:WAIT 60
- ON TN GOTO @TTF,@TTL,@TTR,@TTC,@TTP
- GOTO @TURTLE
- @TTF
- GOTO @TURTLE
- @TTL
- GOTO @TURTLE
- @TTR
- GOTO @TURTLE
- @TTC
- C=N:GCOLOR C
- GOTO @TURTLE
- @TTP
- IF N==0 THEN GPAINT X0,Y0,C ELSE GPAINT X0,Y0,N
- 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:
- @TEST
- FOR A=0 to 360 STEP 360/12
- GOSUB @ROTATE:WAIT 60
- NEXT
- @ROTATE
- A=A%360
- SPANGLE 1,A,6
- 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:
- @TTL
- A=A-N:'TURN LEFT
- GOSUB @ROTATE
- @TTR
- A=A+N:'TURN RIGHT
- 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!
- @TEST
- FOR A=0 to 360 STEP 360/12
- SPOFS 1,128,96:GOSUB @ROTATE
- X1=50*SIN(RAD(A)):'RSINTHETA
- Y1=50*COS(RAD(A)):'RCOSTHETA
- SPOFS 1,128+X1,96+Y1,50:'50 IS THE DISTANCE
- WAIT 60
- 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!
- @TTF
- D=N
- X1=D*SIN(RAD(A))
- Y1=(-1*D)*COS(RAD(A))
- SPOFS 1,X0+X1,Y0+Y1,D
- @TTF1
- SPREAD(1),TTFX,TTFY:'GOSUB @WRAP
- IF C!=0 THEN GPSET TTFX,TTFY,C
- IF SPCHK(1)!=0 GOTO @TTF1
- 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:
- IF C!=0 THEN GPSET ((TTFX+256)%256),((TTFY+192)%192),C
- IF SPCHK(1)!=0 GOTO @TTF1
- X0=((X0+X1+256)%256):Y0=((Y0+Y1+192)%192)
- 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!
- @WRAP
- SPOFS 2,((TTFX+256)%256),((TTFY+192)%192)
- SPANGLE 2,A,0
- 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"!
- REM TURTLE GRAPHIC
- REM BY HARRY HARDJONO
- REM DEC 2013
- ACLS:CLEAR
- @INIT
- WRAP=1
- C$="":'COMMAND STRING
- N=0:'COMMAND PARAMETER
- X0=128:Y0=96:'TURTLE POSITION
- X1=0:Y1=0:'TURTLE DESTINATION
- A=0:'ANGLE
- D=0:'DISTANCE
- C=0:'PEN COLOR
- SPSET 1,139,0,0,0,0:SPOFS 1,X0,Y0
- SPHOME 1,8,8
- SPSET 2,139,0,0,0,0:SPOFS 1,-255,-255
- SPHOME 2,8,8
- @MAIN
- 'GOSUB @TEST
- 'CLASSIC RECTANGLE
- FOR I=1 TO 8
- C$="F35R90F35R90F35R90F35R90"
- GOSUB @TURTLE
- NEXT
- @END
- BEEP 6:WAIT 600
- END
- @TURTLE
- IF LEN(C$)<3 THEN RETURN
- TC$=LEFT$(C$,3)
- N=VAL(RIGHT$(TC$,2))
- TC$=LEFT$(C$,1)
- C$=RIGHT$(C$,LEN(C$)-3)
- TN=INSTR("FLRCP",TC$)
- ON TN GOTO @TTF,@TTL,@TTR,@TTC,@TTP
- GOTO @TURTLE
- @TTF
- D=N
- X1=D*SIN(RAD(A))
- Y1=(-1*D)*COS(RAD(A))
- SPOFS 1,X0+X1,Y0+Y1,D
- @TTF1
- SPREAD(1),TTFX,TTFY:IF WRAP THEN GOSUB @WRAP
- IF C!=0 AND WRAP==1 THEN GPSET ((TTFX+256)%256),((TTFY+192)%102),C
- IF C!=0 AND WRAP==0 THEN GPSET TTFX,TTFY,C
- IF SPCHK(1)!=0 GOTO @TTF1
- IF WRAP==1 THEN X0=((X0+X1+256)%256:Y0=((Y0+Y1+192)%192):SPOFS1,X0,Y0
- IF WRAP==0 THEN X0=X0+X1:Y0=Y0+Y1
- GOTO @TURTLE
- @TTL
- A=A-N:'TURN LEFT
- GOSUB @ROTATE
- GOTO @TURTLE
- @TTR
- A=A+N:'TURN RIGHT
- GOSUB @ROTATE
- GOTO @TURTLE
- @TTC
- C=N:GCOLOR C
- GOTO @TURTLE
- @TTP
- IF N==0 THEN GPAINT X0,Y0,C ELSE GPAINT X0,Y0,N
- GOTO @TURTLE
- @TEST
- WRAP=1:'0 OR 1
- FOR SP=0 TO 150 STEP 3
- V=SP:LOCATE 0,0:?SP
- @LINER
- IF V>99 THEN C$="F99":GOSUB @TURTLE:V=V-99:GOTO @LINER
- L1$=RIGHT$(("000"+STR$(V)),2)
- C$="F"+L1$+"R70C"+L1$:GOSUB @TURTLE
- NEXT
- RETURN
- @ROTATE
- IF A<0 THEN A=A+360:GOTO @ROTATE
- A=A%360:SPANGLE 1,A,6
- RETURN
- @WRAP
- SPOFS 2,((TTFX+256)%256),((TTFY+192)%192)
- SPANGLE 2,A,0
- RETURN
Labels:
100 lines,
30,
algorithm,
challenge,
code,
computer,
coordinates,
degree,
graphic,
hour of code,
Journal,
LOGO,
Petit,
polar,
programming,
radian,
source,
turtle
Subscribe to:
Posts (Atom)