guile-with-graphics is a simple binding of SDL usable from Guile, useful for writing graphic applications or games in Scheme. The software is implemented in C and Scheme, and is based on turtle; however there are some significant differences: graphics is much more efficient in guile-with-graphics (but lower-level: screen refreshing must be performed manually), colors work in a different way, and there is support for SDL events such as key presses and key releases; support for other peripherals such as the mouse is easy to add.
I've implemented this program quite rapidly, hence it can't be a mature full-featured implementation; it's relatively usable, but it's only documented in comments, and some parts of the code may not be clean. I've also used some Scheme features which I have not explained in class: it's up to you to read the Guile documentation and learn them (this is the typical situation when you work with free software: you have to look for information and learn by yourself, it's always unlikely that you have followed some course teaching you everything: free software projects tend to evolve very fast.
Here's guile-with-graphics. I've written it for you students, but I seize this occasion to also release it to the general public. Have fun with it.
guile-with-graphics Copyright © 2008, 2009 Luca Saiu guile-with-graphics is free software, released under the GNU General Public License. It comes with absolutely no warranty. |
Please use the latest version if you have not started yet; if you have already started then you can safely continue to use the version you have. All changes are only in the build system; if the version you started with worked, it's ok to go on and simply ignore newer releases.
Everything should be already setup for working in the lab, with my usual hack: execute
, with optional parameters (--debug is particularly useful) and with an optional Scheme file name to execute; for example you can try the demo file scm/interactive-demo.scm with the command line:
There is no documentation: you have to learn from the provided examples and especially
from the sources; this is an important ability that you must develop.
Compared to a real-life situation, this project is very simplified; you have the author
available for any question, the code is readable and, most importantly, ridiculously short:
about 1000 lines including comments. Don't panic.
I recommend to start running the demos in the scm/ directory (see the README file), trying to understand them, and then to play with them by modifying them. The Scheme part is easier to understand than the C part.
For working with the C part read the code starting from the header files (the .h files). Note that some parts of the code are quite different from turtle.
Some of the tasks are Scheme-only, others are C-only, still others require you to use both languages; anyway if you don't know Scheme you won't get far with this project. If you don't know it yet you really have to learn the language.
You will need some documentation, in particular:
Of course you can write to the mailing list or to me if you have questions.You can choose from a list of tasks of varying difficulty. Notice that I also evaluate your coding style; make your code understandable, use reasonable identifiers and write comments where needed. And of course keep copyright and license headers correct.
You can submit any number of tasks, and of course you can and should also work at home. If you have any setup problem with guile-with-graphics or with GNU/Linux, the mailing list is the right place to ask.
Don't submit your projects to the mailing list. Send them to me personally instead. Please send me the whole modified sources, or a patch file. Don't send sources in strange formats like PDF (some students did it in the past): sources are also meant to be compiled and run, not only to be read.
Another important (and new) rule: no group projects: you have to work alone, even if this means more work for me. I have found that it's practically impossible to allow group projects while avoiding parassitism, and anyway working alone is much more instructive for you.
This is a course on free software: keep copyright headers correct when you modify something, and add a short comment near the top of a file saying who wrote what.
In any case, but particularly with difficult tasks, you have to show me that you understand what you have written; at my discretion I may ask you to come to my office for a short discussion just to convince myself that you're really the author of your project. Don't worry about that, you don't have to "study": you just have to be able to explain, in detail, what you have done.
Please don't feel offended if I have to say this, but in the past not all students have behaved like the
responsible adults they were supposed to be:
Sharing ideas with your friends is ok, submitting the same code (or very similar code) is not.
Before choosing a task you should play with the system, run the demos and try to get at least a first understanding of the source. I recommend to start reading sources from the demos (scm/*-demo.scm) and from the headers (src/*.h). You should try to understand the examples, possibly with one exception: the macro definitions in scm/utility.scm are for your convenience only; I've not talked about macros and quasiquoting in class, and you are not required to understand them. Of course you can use the macros I have defined in your tasks.
Descriptions of retired tasks are striken-thru, new task descriptions are
written in green, information added
after the initial publication of this page is written in red.
A red asterisk near a task name (*) means that I have not yet received
any correct submission for it (just to satisfy your curiosity: this time I will not give any special
bonus to the first submitter of a task solution; a student wrote in the feedback questionnaire that
such a policy encouraged a spirit of unhealthy competition among students, which I think may be true).
The bonus points shown below are for a good solution; bugs, bad coding style and wrong copyright or license headers will lower your bonus. On the other hand an exceptionally good solution may deserve an higher bonus.
Note that interactive programs such as games (I'm talking about real games with at least one player here; Life and Wireworld of course are not interactive) must run at the same speed on any computer (with a faster computer the animations may be more fluid, but objects must not move faster): you can see a clean way to do this in the demo scm/interactive-demo.scm. If your computer is slow setting tick-length to an higher value will make the system more usable (at the price of a worse fluidity).
Life from random configuration* | Implement Conway's Game of Life, starting from a random initial configuration. This is Scheme only. | |
Life from saved configuration | Implement
Conway's Game of Life,
starting from a configuration loaded from a file. You can invent the file format, but it must
be human-readable (that's easy in Scheme). This is Scheme only.
Hint: an easy way to do this is by using load... |
|
Wireworld (simple) | Write a simple
Wireworld
simulator, starting from a configuration which is read from a file (you can invent the file
format, but it must be human-readable). Don't worry about efficiency.
This is Scheme-only. |
|
+5 | Mouse support | Add mouse support (usable from Scheme) to the system, so that usable mouse events (move with coordinates, button down/button up with button identifier) are generated. This is C-only. |
at least |
Wireworld (optimized)* | Write a fast
Wireworld
simulator, starting from a configuration which is read from a file (you can invent the file
format, but it must be human-readable). The program must be reasonably efficient, but it must
be written in Scheme only (you can't use C for the simulation logic).
This is Scheme-only. |
+7 | Turtle graphics* |
Implement a simple turtle graphics system similar to
turtle, using only Scheme.
I only require that you implement move, left, right, home, go-to, pen-up, pen-down and reset: all such primitives must be compatible with turtle's version. There must be an oriented triangular cursor, but you can draw it in a style different from turtle. This is Scheme only (you're not allowed to modify the C part for this task). |
+7 | Understand interactive.scm* |
Read and understand the file scm/interactive.scm.
I (intentionally) wrote no comments for the procedures handle-all-enqueued-events and
interactive-game; explain those two procedures in every detail, in French
(or English if you prefer; the bonus is the same); in particular, I
want you to say how interactive-game allows a game to run at the same speed on
every computer.
This requires no programming, but you need to understand some relatively difficult (even if clean) code not written by you. I have just noticed (on 2009-03-25) that there are a couple of style problems in interactive-game. Instead of fixing them in the code, I will give a higher bonus to the students who correctly identify them. |
+8 | Two-player Pong | Write a simple two-player Pong game, where the two players use the same keyboard. This is Scheme-only. |
+10 (or +2 if you also submitted the two-player version) | One-player Pong | Write a simple Pong game where one player plays against the computer. This is Scheme-only. |
at least +10 | Box-and-pointer diagrams* | Write a program which reads an s-expression from the terminal (you can use read)
and then draws it on the graphic window as a box-and-pointer diagram, in a format similar to these figures from
SICP:
Figure 2.2,
Figure 2.3,
Figure 2.4.
You can do this even if you didn't implement the text support, for a lower bonus; just don't show the text. This is Scheme-only. |
at least +10 | Text support | Add support (usable from Scheme) for writing text in the graphics window. There are many possible solutions, of widely different complexity
and power. Some solutions are Scheme-only, some are C only, some involve using external libraries (you can use external libraries if you want,
but pay attention to licenses!). Another solution: you can also write a tool (in any language with a free software implementation, but different from C and Scheme if you want; I also want to see your tool's source) to translate an existing font into a new simple format invented by you, and then use the simple format from Scheme. A possible reasonable interface is a procedure write-text which takes three parameters: x and y coordinates, and a string. Of cours much more powerful interfaces are possible: for example the font name could be a parameter. But write-text as outlined above is enough if the code is clean. |
+12 | Tetris | Write a simple Tetris clone. This is Scheme-only. |
+15 | Sprite support* | Add efficient support (of course usable from Scheme) for sprites, and write a short demo program in Scheme using them. The hard part is in C, and requires you to learn some more advanced features of SDL (and possibly of Guile, depending on your solution). |
+15~20 | Arkanoid* | Write an
Arkanoid/Breakout
clone, with levels represented in a reasonable format which is easy to edit (I'm not asking for an editor program, but for
an intuitive data format; that's easy in Scheme). Of course I will give a higher bonus if you submit a more advanced and complex
solution.
Pay attention to efficiency: the software must be usable on my machine (which however is very fast, don't worry), and this task may not be completely trivial to implement in an efficient way. This is Scheme-only. |
Function plotter* |
Write a simple function plotter which displays the
graph of a given
one-argument function on the carthesian plane. The funciton must be
entered by the user (you can use read) in Lisp notation: for example
the user will write (lambda (x) (sin x)), or also simply sin, to indicate the sine function.
You should use primitive-eval to evaluate the s-expression which was given by the user and obtain a function which you can call. Don't worry about making the graphic window refresh itself when the program is waiting for user input from the terminal; it's very hard (but you get a +20 bonus if you do it (you can use C for that)). This is Scheme-only, except for the optional part worth a +20 bonus. |
|
Numeric derivative* |
You must have finished function plotter before starting this.
Modify your function plotter solution so that your program also plots an approximation of the derivative of the function, in a different color. Hint: the definition of derivative involves a limit of a quantity tending to 0: what if instead of really computing the limit you just take a very small number for the quantity? This is Scheme-only. |
|
+8 | Symbolic derivative* |
You must have finished function plotter before starting this.
The problem is similar to numeric derivative, but you must not use an approximation here: you have to compute the analythic expression of the derivative, display it on the terminal (you can use display), and then plot it. I just require you to support addition, subtraction, multiplication, division (all of them with only two parameters), sine, cosine and tangent. If lambda notation in the input bothers you, you can assume that the parameter is always called x so that, for example, that (+ x 1) means (lambda (x) (+ x 1)). Hint: this requires recursion; for example, the derivative of a sum is the sum of derivatives... But what is the derivative of a product? You can find a complete table here with much more information than you need. Remember to pay attention to the chain rule. This is Scheme-only. |
+9 (alone, without considering symbolic derivative) | Expression simplifier* |
You should (but it's just a suggestion) have done at least the non-graphic part of
symbolic derivative before starting this.
The derivative expressions you obtain from symbolic derivative are correct, but not minimal or "beautiful": for example, the expression (+ (* 0 (sin x)) (cos x)) could be written more simply as (cos x). Write an expression simplifier, taking as input an expression and returning an equivalent but simplified expression. You only have to support the expressions supported by symbolic derivative. This is Scheme-only. You can also ignore graphics here. |
+4 | complementary-color |
Write a function (in Scheme) called complementary-color and taking
one color object as parameter, which returns the
complementary
color of the given color. Your function must work for any valid color,
not only for primary or secondary colors. Your function must take a color and return another color: it must not modify its parameter. This is Scheme only. |
+7 | complement-color!* |
Add a new primitive, usable from Scheme, called complement-color! and taking
one color object as parameter. Your primitive must modify its parameter and turn it into
its complementary
color. Your primitive must work for any valid color, not only for primary or
secondary colors. It must return SCM_UNSPECIFIED. Make sure that you correctly modify the color: you have to understand how color SMOBs work from the C source code. This is C only. |
+4 | Speculate about the efficiency of complementary-color and complement-color!* |
Answer the following two questions, in French or in English (the bonus
is the same):
This task does not require any coding. |
from +2 to +10 for correct solutions | Benchmark two primitives * |
You have to compare the efficiency of draw-line and
draw-rectangle, when called with the same paramters 0 0 100 100 yellow:
Don't refresh: we don't want to measure how fast refreshing is. You can do research on the Internet for a good way to do a benchmark, and maybe you should read some benchmarking code written by others. There are many solutions, of widely varying effectiveness. |
+5 | read-pixel * |
Add a new primitive function, usable from Scheme, called read-pixel, with two
parameters, x and y, which returns the color of the graphic window
at the given coordinates. Note that you must return a color object, not just three
numbers, so you have to understand how color SMOBs work from the C source code. This is C only. |
+8 | Scaling support * |
Add a new primitive function, usable from Scheme, called draw-stretched-rectangle,
with eight parameters:
This is C only. |
+8 if you also solved Scaling support; +16 otherwise | Scaling support with overlapping rectangles * |
Exactly like Scaling support, but the primitive must not fail when rectangles
overlap: the target rectangle should just (sometimes partially) overwrite the source rectangle so that the new rectangle contains a scaled
version of the whole, original, source rectangle.
You will find this markedly more difficult than Scaling support. This is C only. |
Again, I strongly suggest all students to subscribe to the mailing list. The linked page contains all the information.