Comments/Ratings for a Single Item
The Zillions user forum seems dead. I registered, but can't start a new topic.
I have the following move macro:
(define Mason-step ((verify (empty? $1))(create Stone) $1 add))
How do I turn this into a slide? All my attempts are generating pares errors.
For a slide, you need a loop. Since I don't know how your Mason piece moves, I'll give you an example from the Chess.zrf:
(define slide ($1 (while empty? add $1) (verify not-friend?) add))
This can be used for Bishop, Rook, or Queen moves, though it does have a special one for Rook moves that also sets an attribute for whether it can still castle to false.
The main feature that makes this a slide instead of a single-step move is the while loop. $1 is the parameter with the value of the direction to move. After moving once in this direction, it checks whether it is empty, and if it is empty, it allows the move with the add command, and it moves again in the same direction. If it reaches an occupied space or the end of the board, it breaks out of the loop, because the empty? condition is no longer met. At this point, it tests the same space with (verify not-friend?) to tell whether it is one without a piece belonging to the same player. If it's an enemy piece or empty, it will allow the move with the add command.
The Rook-slide looks like this:
(define rook-slide (
$1
(while empty? (set-attribute never-moved? false) add $1)
(verify not-friend?)
(set-attribute never-moved? false)
add
))
This uses the same method of a while loop, but in addition to allowing a move to a certain space, it makes sure that the allowed move includes the the operation of setting the attribute never-moved? to false.
I solved the Mason move by using single-step moves and add-partial.
The last piece I'm coding can push a line of pieces. This almost does what I want:
(define push ($1 (verify not-empty?) cascade (while (not-empty? $1) $1 cascade) $1 add))
But if the piece at the end of the line is at the edge of the board, I want to capture it (push it off the board). The above code disallows the move if the last piece is at the board's edge. I wonder if there is a solution using zones or dummy squares.
The piece is inspired by Nemeroth's Go Away (but it can only push one line at a time, and any effects of or on the pushed pieces are ignored).
Indeed, the whole game is inspired by Nemeroth, but on the whole, it's much simpler to code in Zillions. There is an unapproachable piece, a piece that turns the target square to stone (by a rifle-capture-like move), a piece that moves and captures as a king, a piece that lays down a line of stones, and so on. Stones do not move on their own but can be captured or pushed (a bit like ichor without the bookkeeping). Victory is by stalemate or opponent's repetition. There is no concept of compulsion or multiple-occupancy squares.
My game loses much of Nemeroth's peculiar flavor but is interesting in its own right. Pushing pieces of the board will make it complete. I will need to clean up the Zillions file and author a page.
You could test each space with on-board?
or not-on-board?
and provide a different move when the space is not on-board.
This code works perfectly with correctly defined zones:
(define push-n (n (while on-board? (if empty? add (verify false))(if (in-zone? board-edge-n) add (verify false)) cascade n))) (define push-e (e (while on-board? (if empty? add (verify false))(if (in-zone? board-edge-e) add (verify false)) cascade e))) (define push-s (s (while on-board? (if empty? add (verify false))(if (in-zone? board-edge-s) add (verify false)) cascade s))) (define push-w (w (while on-board? (if empty? add (verify false))(if (in-zone? board-edge-w) add (verify false)) cascade w)))
The (verify false)'s are essential to stop move generation when the final square is found, otherwise, Zillions crashes. I decided to use rook-wise pushes to complement the piece's bishop-like move.
Using (verify false) is a clever idea. It's sort of like using return in a function for some other language. You might have gotten the same effect by using else. For example, this might work:
(define push-n (n (while on-board? (if empty? add else (if (in-zone? board-edge-n) add else (cascade n))))))
However, it does use else twice to create an if-elseif-else structure, and breaking out with something like a return is an equally valid way to handle this.
Since the first two conditions have the same effect, this might also work:
(define push-n (n (while on-board? (if (or empty? (in-zone? board-edge-n)) add else (cascade n)))))
And let's try a general push routine without the zone:
(define push ($1 (while on-board? (if (or empty? (not-on-board? $1)) add else (cascade $1)))))
8 comments displayed
Permalink to the exact comments currently displayed.
Yes, that's what I did. We were in the same room and couldn't get it connected up in Windows 10 :p