Select the Snake window, and use the arrow keys to control your snake. From the book’s REPL, enter the following: But if your snake crosses over its own body, you lose.īefore you start building your own snake, take a minute to try the completed version. When your snake eats an apple, it grows longer by a segment, and a new apple appears.
The Snake game features a player-controlled snake that moves around a game grid hunting for an apple. Now let’s put these models to work in designing a small but complete application. The models, and their use, are summarized in Figure 6.2. And since Clojure is built atop Java, you can also use Java’s lock-based model. You have now seen four different models for dealing with concurrency. Clojure uses the ContentHandler implementation to build an immutable Clojure structure, which then gets all the benefits of the Clojure concurrency model. The ContentHandler’s use of set! does not leak mutable data out into the rest of Clojure. Clojure permits this style as an explicit special case, and you should use it for interop purposes only. It is worth noting that this style of coding is the industry norm: objects are mutable, and programs are single-threadedly oblivious to the possibility of concurrency. (This is important primarily when inside character data, which is not shown here.)ĮndElement reverses the work of startElement by popping the *stack* and placing the top of the *stack* in *current*. The *current* is the current element, and the *state* keeps track of what kind of content is inside. The *stack* is a stack of all the elements the current element is nested inside. The callback handler updates three thread-local variables.