Richard Pattis wrote "Karel the Robot" in 1981. Karel the Robot interpreters have been written in Pascal, C, C++, Java, Scratch and Python. Since I couldn't get the version written in C for CP/M to work, I started from scratch and wrote it in tiny-c. It was quite a challenge. Karel lives in a grid of avenues and streets. Here's an example. Walls are represented by asterisks, Karel by the caret (he's facing north here) and beepers by the commercial at. S A T 9 R 8 * E 7 * * * E 6 * * ********************* T 5 @ @ ^ S 4 3 2 1 1 2 3 4 5 6 7 8 9 A B C D E F G H I A V E N U E S He can move forward a single unit. He can turn left 90. He can pick up beepers that he runs into and he can put down beepers if he has any beepers in his beeper bag. He can see walls immediately in front of him, immediately to his left or to his right. He can detect what direction he is facing in (N, S, E or W). Finally, he can tell if he's at a beeper location. His world is established via a file that has lines like this: k 5 5 N b 3 5 1 b 2 5 1 w 1 5 6 5 w 3 5 3 6 w 4 5 4 7 g 1 The first line gives the avenue and street Karel starts at and the direction he is facing. The b lines are beeper locations and the number of them at that location. The w lines are the start and end addresses of walls. The g line has how many beepers are in his bag. The starting and ending addresses of the horizontal or vertical walls are given by the addresses of the lower left corners of the cells the wall starts and ends at. Say your objective is to write a program to harvest all the beepers, place them on top of and at the end of the long horizontal wall and then return to where you started, facing in your initial direction. You should have the same number of beepers in your bag that you started with. A solution to this problem follows: /* sample program */ hurdle [ /* over, up, down */ while (front_is_clear) move turnleft while (right_is_blocked) move turnright move turnright while (front_is_clear) move turnleft ] turnright [turnleft;turnleft;turnleft] turnaround [turnleft;turnleft] main [ putbeeper /* leave marker */ turnleft while (right_is_blocked) [ move if (next_to_a_beeper) pickbeeper ] turnright move turnright i=1 while (i<=2) [hurdle; i=i+1] while (right_is_blocked) move turnaround;move while (any_beepers_in_bag) putbeeper turnaround move turnright move turnright while (not_next_to_a_beeper) move pickbeeper turnright ] Code which supports the Karel interpreter has been omitted. |