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