Arc Forumnew | comments | leaders | submitlogin
2 points by Darmani 6022 days ago | link | parent

A month or two ago, I wrote Sokoban in Arc, and produced a small library for multidimensional lists in the process. This function should interest you:

  ;dims needed because ((abc)) may be a two-dimensional list containing abc or 
  ;a one-dimensional list containing (abc)
  (def muldim-map (dims f lst)
    ((afn (lst)
      (if (no lst)
        nil
        (if (is dims 0)
          (f lst)
          (cons (muldim-map (- dims 1) f (car lst)) (self (cdr lst))))))
      lst))


1 point by bOR_ 6021 days ago | link

If I read it right, it is a function that for example, can grab the nth entry from a cell (or nth row / column from a matrix)?

You have the code out there somewhere? It is probably good to have some more examples of Arc out in the open, and there'll be things in it I can learn from.

-----

1 point by Darmani 6021 days ago | link

Sorry, I misunderstood your query last night.I just realized the function actually doesn't apply in this specific instance here.

It's a version of the normal map generalized to n-dimensional lists; I forgot when writing it that normal map accepts multiple lists.

However, with that added, it would be useful if you, say, had (((1 2) (3 4)) ((5 6) (7 8))) and wanted ((6 8) (10 12)); that would end up being (apply muldim-map 2 + (list (list (list 1 2) (list 3 4)) (list (list 5 6) (list 7 8))))

(I was going to download Arc's source code and use the source of the original map as a guide to writing a version of muldim-map that could handle multiple multi-dimensional lists on the spot, but I don't believe these high school computers have software that can handle tarballs.)

-----

2 points by Darmani 6021 days ago | link

However, I just realized I had another function in that library that could perform the task you described, although it would be overkill. It's called something like move-muldim-block; it takes a multi-dimensional list and returns a new multi-dimensional list with a multi-dimensional piece of that list moved elsewhere, using a combining function to determing the value of the area in which it was moved (I used it in Sokoban to simplify code that would let let me move a crate character onto a storage character and change it to the crate-on-storate character).

In other words, if lst is set to ((1 2) (3 4)) and f is some function, (move-muldim block (list 1 0) (list 1 2) (list 0 0) +) would be equivalent to (((+ 1 3) (+ 2 4)) ((f 3) (f 4))) (it moves a 1x2 block from coordinates (1 0) to coordinates (0 0)). Just take the car of the result and you have what you're looking for (in which case, we could omit the last argument and use the default value).

For this specific task, apply is a heck of a lot simpler, but I can still post the code if you're interested. I personally found it very interesting to realize that this could be done, and that muldim-move-block is a little more useful than I first thought.

-----

1 point by bOR_ 6021 days ago | link

Hmm. Right now I store the positions of my mobile piec elsewhere than in the world-list. Your function might be handy later on. I haven't yet decided if I want every actor of the world stored in the world (even if some of them might overlap), or store the mobile actors in a separate list.

Right now the thing about sokoban implementations that would interest me most is if you've done anything fancy to generate the output. Having an update of a 2d world scroll by ever so often makes it hard to track movement of a single character through this world. Did you work on that?

-----

3 points by almkglor 6021 days ago | link

Since Arc is a language targeted for the web... have you considered the possibility of generating a web page for it, with maybe next >> and << prev links?

-----

1 point by bOR_ 6021 days ago | link

That might actually work, and just autorefresh the page every second or so :)

First priorities now are finishing the wandering algorithm for the animals so that they're no longer steered but steer themselves, and generalize the code I've some more so that adding more behaviours than just biting things is easy. I'll add the visuals-through webpage idea to that list :)

-----

1 point by Darmani 6021 days ago | link

Sorry, not really. I just used a simple function to print out a 2-dimensional list and resized my terminal window so that the grid would be in the same place after every sequence of moves, which gives the illusion that the same grid is being redrawn.

-----

1 point by Darmani 6021 days ago | link

Small mistake -- the invocation would be (move-muldim block (list 1 0) (list 1 2) (list 0 0) + f) (I hope no-one thought I'd be silly enough to set the function to find the replacement-fn by looking up the global value of f...).

-----