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" 
> <factor-talk@lists.sourceforge.net>:
>
>> 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

Reply via email to