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.

Reply via email to