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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.