Re: [Factor-talk] Recourse to Composure
Thanks Alex! Ill try to setup a draft website it can be viewed from when its almost done or I've at least done a first pass to eliminate any errors I've missed. As for your solution, I was not aware of the Cartesian words. That's a much tidier solution than mine. I'll have to try messing with it more when I work on the game this weekend. Fantastic solution. The second approach is also interesting but I definitely prefer the former. Jack Original Message On Jun 6, 2019, 3:47 PM, Alexander Ilin wrote: > Hi, Jack! > > I think what you are doing is really cool, and I would love to read the book > one day! > > 06.06.2019, 15:16, "Jack Lucas via Factor-talk" > : > >> Yesterday I was trying to create this adjacency system for one of the games >> I'm working on. I have no idea if this will stay like this, but, at the >> time, it sure felt like I was trying to jam first class words into Factor, >> and I'd like to know if there's a better method. >> >> The goal of this snippet of code is to take some originating coordinates on >> the stack like 40 40 and convert it into the adjacent square coordinates in >> my grid. So from 40 40 we might get a sequence back like { { 0 0 } { 80 0 } >> { 0 80 } { 80 80 } } describing the coordinates of squares adjacent ( in the >> corner going diagonally ). I obviously didn't want to rewrite adjacent 4 >> times with a different combination of +'s and -'s so I instead wrote it as >> you see here. > > Thinking in terms of sequences and matrices, this is the solution I came up > with for you: > > : adjacent-diagonals ( pos step -- seq ) >{ - + } [ execute( x y -- n ) ] with cartesian-map >first2 cartesian-product concat ; > > Test code: > > IN: scratchpad { 40 40 } 40 adjacent-diagonals . > { { 0 0 } { 0 80 } { 80 0 } { 80 80 } } > > Correspondingly, if the player is facing "left", you could pick the > necessary pair of coordinates by doing something like > > : left-squares ( square -- seq ) >grid-size get adjacent-diagonals { 0 2 } swap nths ; > > or, generalizing over the directions, > > : player-direction-squares ( -- seq ) >{ >{ "down" { 0 1 } } >{ "up"{ 2 3 } } >{ "left" { 0 2 } } >{ "right" { 1 3 } } >} player-sym get direction>> of ; > > : adjacent-squares ( pos -- seq ) >grid-size get adjacent-diagonals player-direction-squares swap nths ; > > What do you think? > > Another approach could revolve around the following definition, I think you > can figure out the rest of the details: > > : player-direction-squares ( -- seq ) >{ >{ "down" { { + - } { - - } } } >{ "up"{ { + + } { - + } } } >{ "left" { { - - } { - + } } } >{ "right" { { + - } { + + } } } >} player-sym get direction>> of ; > >> >> >>> :: adjacent ( x y ex ex2 -- quot ) >>> [ x grid-size get ex execute , >>> y grid-size get ex2 execute , ] { } make ; inline >>> >>> : upper-left ( x y -- seq ) >>> \ - \ - adjacent ; >>> >>> : upper-right ( x y -- seq ) >>> \ + \ - adjacent ; >>> >>> : bottom-left ( x y -- seq ) >>> \ - \ + adjacent ; >>> >>> : bottom-right ( x y -- seq ) >>> \ + \ + adjacent ; >>> >>> ! player-sym is just a tuple holding the players state >>> ! Whatever direction the player is facing is the side >>> ! we want him to be able to grab items from. >>> : player-direction-squares ( -- squares ) >>> player-sym get direction>> >>> { >>> { "left" [ { bottom-left upper-left } ] } >>> { "right" [ { bottom-right upper-right } ] } >>> } case ; >>> >>> ! square-coordinates ( square -- x y ) >>> >>> : adjacent-squares ( square -- list ) >>> square-coordinates [ rot execute( x y -- seq ) ] 2curry >>> player-direction-squares >>> swap map ; inline >> >> In this way, depending on which direction the player is facing, finding the >> adjacent squares is literally a matter of mapping over the words themselves >> rather than the data. Since it would look like... >> >>> { "bottom-left" "upper-left" } [ x y rot execute( x y -- seq ) ] map >> >> The question for me becomes, is this an over-complicated way of achieving a >> simple effect? I wonder if there's a way to do it like lisp-macros where I >> can just syntactically insert the words I want without evaluating them. In >> any case, I'm mostly posting this to see if I'm going off the deep end of >> only having a problem because I'm thinking about the issue the wrong way or >> if this genuinely is the right direction to go in trying to solve a problem >> like this in Factor. Either way it was fun to try to make without repeating >> myself 4 times. >> >> Copiously Caffeinated, > > Sequentially Coordinated, > > ---=--- > Александр___ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk
Re: [Factor-talk] Recourse to Composure
Hi, Jack! I think what you are doing is really cool, and I would love to read the book one day! 06.06.2019, 15:16, "Jack Lucas via Factor-talk" :Yesterday I was trying to create this adjacency system for one of the games I'm working on. I have no idea if this will stay like this, but, at the time, it sure felt like I was trying to jam first class words into Factor, and I'd like to know if there's a better method. The goal of this snippet of code is to take some originating coordinates on the stack like 40 40 and convert it into the adjacent square coordinates in my grid. So from 40 40 we might get a sequence back like { { 0 0 } { 80 0 } { 0 80 } { 80 80 } } describing the coordinates of squares adjacent ( in the corner going diagonally ). I obviously didn't want to rewrite adjacent 4 times with a different combination of +'s and -'s so I instead wrote it as you see here. Thinking in terms of sequences and matrices, this is the solution I came up with for you: : adjacent-diagonals ( pos step -- seq ) { - + } [ execute( x y -- n ) ] with cartesian-map first2 cartesian-product concat ; Test code:IN: scratchpad { 40 40 } 40 adjacent-diagonals .{ { 0 0 } { 0 80 } { 80 0 } { 80 80 } } Correspondingly, if the player is facing "left", you could pick the necessary pair of coordinates by doing something like : left-squares ( square -- seq ) grid-size get adjacent-diagonals { 0 2 } swap nths ; or, generalizing over the directions, : player-direction-squares ( -- seq ) { { "down" { 0 1 } } { "up" { 2 3 } } { "left" { 0 2 } } { "right" { 1 3 } } } player-sym get direction>> of ; : adjacent-squares ( pos -- seq ) grid-size get adjacent-diagonals player-direction-squares swap nths ; What do you think? Another approach could revolve around the following definition, I think you can figure out the rest of the details: : player-direction-squares ( -- seq ) { { "down" { { + - } { - - } } } { "up" { { + + } { - + } } } { "left" { { - - } { - + } } } { "right" { { + - } { + + } } } } player-sym get direction>> of ; :: adjacent ( x y ex ex2 -- quot ) [ x grid-size get ex execute , y grid-size get ex2 execute , ] { } make ; inline : upper-left ( x y -- seq ) \ - \ - adjacent ; : upper-right ( x y -- seq ) \ + \ - adjacent ; : bottom-left ( x y -- seq ) \ - \ + adjacent ; : bottom-right ( x y -- seq ) \ + \ + adjacent ; ! player-sym is just a tuple holding the players state! Whatever direction the player is facing is the side! we want him to be able to grab items from.: player-direction-squares ( -- squares ) player-sym get direction>> { { "left" [ { bottom-left upper-left } ] } { "right" [ { bottom-right upper-right } ] } } case ; ! square-coordinates ( square -- x y ) : adjacent-squares ( square -- list ) square-coordinates [ rot execute( x y -- seq ) ] 2curry player-direction-squares swap map ; inline In this way, depending on which direction the player is facing, finding the adjacent squares is literally a matter of mapping over the words themselves rather than the data. Since it would look like... { "bottom-left" "upper-left" } [ x y rot execute( x y -- seq ) ] map The question for me becomes, is this an over-complicated way of achieving a simple effect? I wonder if there's a way to do it like lisp-macros where I can just syntactically insert the words I want without evaluating them. In any case, I'm mostly posting this to see if I'm going off the deep end of only having a problem because I'm thinking about the issue the wrong way or if this genuinely is the right direction to go in trying to solve a problem like this in Factor. Either way it was fun to try to make without repeating myself 4 times. Copiously Caffeinated, Sequentially Coordinated, ---=---Александр ___ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk
Re: [Factor-talk] Recourse to Composure
> 2019/06/06 21:15、Jack Lucas via Factor-talk > のメール: > > (Fourth) Logic programming and basic AI. I'll probably have to make a port > of mini-kanren into Factor. Hi, I'm interested in Factor miniKanren. I am porting microKanren for Factor, but the work is interrupted with some difficulties. I'm starting to think that it would be better to port Prolog to Factor. :-) -- KUSUMOTO Norio ___ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk
[Factor-talk] Recourse to Composure
Hi all! Yesterday I was trying to create this adjacency system for one of the games I'm working on. I have no idea if this will stay like this, but, at the time, it sure felt like I was trying to jam first class words into Factor, and I'd like to know if there's a better method. The goal of this snippet of code is to take some originating coordinates on the stack like 40 40 and convert it into the adjacent square coordinates in my grid. So from 40 40 we might get a sequence back like { { 0 0 } { 80 0 } { 0 80 } { 80 80 } } describing the coordinates of squares adjacent ( in the corner going diagonally ). I obviously didn't want to rewrite adjacent 4 times with a different combination of +'s and -'s so I instead wrote it as you see here. > :: adjacent ( x y ex ex2 -- quot ) > [ x grid-size get ex execute , > y grid-size get ex2 execute , ] { } make ; inline > > : upper-left ( x y -- seq ) > \ - \ - adjacent ; > > : upper-right ( x y -- seq ) > \ + \ - adjacent ; > > : bottom-left ( x y -- seq ) > \ - \ + adjacent ; > > : bottom-right ( x y -- seq ) > \ + \ + adjacent ; > > ! player-sym is just a tuple holding the players state > ! Whatever direction the player is facing is the side > ! we want him to be able to grab items from. > : player-direction-squares ( -- squares ) > player-sym get direction>> > { > { "left" [ { bottom-left upper-left } ] } > { "right" [ { bottom-right upper-right } ] } > } case ; > > ! square-coordinates ( square -- x y ) > > : adjacent-squares ( square -- list ) > square-coordinates [ rot execute( x y -- seq ) ] 2curry > player-direction-squares > swap map ; inline In this way, depending on which direction the player is facing, finding the adjacent squares is literally a matter of mapping over the words themselves rather than the data. Since it would look like... > { "bottom-left" "upper-left" } [ x y rot execute( x y -- seq ) ] map The question for me becomes, is this an over-complicated way of achieving a simple effect? I wonder if there's a way to do it like lisp-macros where I can just syntactically insert the words I want without evaluating them. In any case, I'm mostly posting this to see if I'm going off the deep end of only having a problem because I'm thinking about the issue the wrong way or if this genuinely is the right direction to go in trying to solve a problem like this in Factor. Either way it was fun to try to make without repeating myself 4 times. I'm working on a Factor/Raylib book right now (132 pages/36k words ATM) using games in the likeness of Realm of Racket or Land of Lisp in order to teach the use of Factor and accrue general dominance upon the phonetically entangled (lispers). This one is called Fields of Factor and tells the story of a journey through a rather surreal field, filled with emotional centurions, wise tortoises, and anti-Platonic chickens. There is also a touching first hand discourse on the violent oppression of poets in 19th century London as related by a dream. With this backdrop to help excite the readers imagination, there be 4 games we make, and I'm on the second one right now. Their order is somewhat laid out like the following. - (First game) Primitive, no OOP, a variety of different methods illustrated like recursion, combinators, and use of the hash-table/assoc. Another game based on this game is made by the reader through a guided exercise; this game is much simpler than the one explained in the book but has many of the same elements. - (Second) OOP and Macros with some focus on solving one of the core problems using sets. Takes some code from the first game and builds on it. - (Third) Hopefully, 3D and physics based. Introduces less new concepts from Factor itself to focus on game design. - (Fourth) Logic programming and basic AI. I'll probably have to make a port of mini-kanren into Factor. I do intend, in some manner, that it act as a newbie guide built by a newbie himself. In that regard I've adopted the presentation of some philosophy in the book regarding the iterative process of design in action. That is, I want the reader to appreciate the fancier tools Factor provides by first starting with the more primitive and working upwards. It's been a lot of fun so far since there is a loose story contained in the book and I love writing creatively. Perhaps I'm not the most qualified to write it, but I have learned a lot so far by having to drudge through documentation and experiment. It'd be a shame not to try to eliminate that for others trying to learn the language. Copiously Caffeinated, Jack___ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk