Hi Will,

Welcome to the wide world of functional programming, where data flows, and 
functions transmute without destroying their inputs.

As some others in this thread have already suggested, a general approach to 
viewing any problem space from a functional perspective is to imagine your 
problem as a pipeline of data transformations from start to finish. To the 
greatest extent possible, try to represent your data transformations as 
pure functions over immutable arguments rather than holding any global 
state in a var and mutating it at each time step.

In the context of a game program, consider depicting all of your game state 
as a single hierarchical map. Then thread this map through each function 
and return a new derived map as each output result.

```clojure
(def world-state {:flags #{}
                        :location :fancy-room
                        :inventory #{:sledgehammer :car-keys :lamp}
                        :rooms {:creepy-corridor {:name "Creepy Corridor" 
:description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw 
:troll-doll}}
                                    :fancy-room {:name "Fancy Room" 
:description "The fanciest!" :items #{:chandelier :toy-poodle 
:looking-glass}}
                                    ...}})

```
Let's imagine this is the initial world state. When your application starts 
up, it enters into the game loop (which would be a nice, friendly 
recursion, of course). In each round of the game loop, you call a sequence 
of functions to get the description of the current room, print it out, ask 
the user for the next command, process that command, and then recurse back 
to the top of the next iteration of the game loop. Although printing to 
stdout and reading from stdin are obviously side effecting functions, you 
should be able to keep your functions for retrieving the room description 
and processing the user's command as pure functions of the current 
world-state. Just make sure that the functions that process a user's 
command always return a new copy of the world-state value. When you want to 
save the game, just write out the world-state to an EDN file. By reading it 
back in again later, you can restore the game to exactly the same state it 
was in before.

In response to your specific question about having a different room 
description after some event has happened, consider this approach:

```clojure
(defn do-important-plot-changing-action [world-state]
    (-> world-state
         (update :flags conj :major-plot-point-reached)
         (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't 
nearly as fancy anymore!")))
```

That is, the function just uses assoc, assoc-in, update, and update-in to 
modify the values in the new map and return it for use in future iterations 
of the game loop. And that's pretty much all there is to it. You just pass 
the changing world state down through the stack rather than mutating it in 
place on the heap. (Ultimately, the world-state data structure is, of 
course, actually stored on the heap, and you are just passing references to 
it through the stack, but I hope you get my meaning here.)

Good luck and happy hacking!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to