Thanks! On Friday, March 30, 2018 at 11:12:04 AM UTC-7, Karsten Schmidt wrote: > > Hi Will, > > have a look at this workshop repository, in which we developed a > simple text adventure framework: > https://github.com/learn-postspectacular/resonate-workshop-2014 > > Hth! K. > > On 30 March 2018 at 16:01, Gary Johnson <lambda...@gmail.com <javascript:>> > wrote: > > 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 clo...@googlegroups.com > <javascript:> > > Note that posts from new members are moderated - please be patient with > your > > first post. > > To unsubscribe from this group, send email to > > clojure+u...@googlegroups.com <javascript:> > > 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+u...@googlegroups.com <javascript:>. > > For more options, visit https://groups.google.com/d/optout. > > > > -- > Karsten Schmidt > http://postspectacular.com | http://thi.ng | http://toxiclibs.org > > On 30 March 2018 at 16:01, Gary Johnson <lambda...@gmail.com <javascript:>> > wrote: > > 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 clo...@googlegroups.com > <javascript:> > > Note that posts from new members are moderated - please be patient with > your > > first post. > > To unsubscribe from this group, send email to > > clojure+u...@googlegroups.com <javascript:> > > 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+u...@googlegroups.com <javascript:>. > > For more options, visit https://groups.google.com/d/optout. > > > > -- > Karsten Schmidt > http://thi.ng >
-- 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.