163 lines
4.0 KiB
Java
163 lines
4.0 KiB
Java
/*
|
|
ZZIter.java
|
|
*
|
|
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
|
|
*
|
|
* You may use and distribute under the terms of either the GNU Lesser
|
|
* General Public License, either version 2 of the license or,
|
|
* at your choice, any later version. Alternatively, you may use and
|
|
* distribute under the terms of the XPL.
|
|
*
|
|
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
|
* the licenses.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
|
* file for more details.
|
|
*
|
|
*/
|
|
/*
|
|
* Written by Tuomas Lukka
|
|
*/
|
|
|
|
package org.gzigzag;
|
|
import java.awt.*;
|
|
import java.awt.datatransfer.*;
|
|
import java.util.*;
|
|
|
|
/** Help for iterating along ranks in various ways.
|
|
*/
|
|
|
|
public class ZZIter {
|
|
public static final String rcsid = "$Id: ZZIter.java,v 1.3 2000/11/01 00:39:06 tjl Exp $";
|
|
public static final boolean dbg = false;
|
|
static final void p(String s) { if(dbg) System.out.println(s); }
|
|
|
|
/** An callback interface for iterating along a rank with
|
|
* the cell number.
|
|
*/
|
|
public interface NIter {
|
|
/** Do whatever you like with this cell, which is the nth from
|
|
* wherever we began.
|
|
* @return True, if the iteration is to continue (in this direction).
|
|
*/
|
|
boolean go(ZZCell c, int nth);
|
|
}
|
|
|
|
/** Go along a rank, starting from a cell, interleaving alternate
|
|
* directions.
|
|
* @param c The cell to start from.
|
|
* @param included Whether the first cell is also included.
|
|
* @param d The dimension to go along.
|
|
* @param fdir The direction to take the first step in.
|
|
* @param iter The callback object.
|
|
*/
|
|
public static void alternate(ZZCell c, boolean included,
|
|
String d, int fdir, NIter iter) {
|
|
if(c == null) return;
|
|
int i = 0;
|
|
if(included)
|
|
if(!iter.go(c, 0)) return;
|
|
boolean in = true;
|
|
boolean op = true;
|
|
ZZCell inc = c;
|
|
ZZCell opc = c;
|
|
while(in || op) {
|
|
i++;
|
|
if(in) {
|
|
inc = inc.s(d, fdir);
|
|
if(inc == null)
|
|
in = false;
|
|
else
|
|
if(!iter.go(inc, fdir * i))
|
|
in = false;
|
|
}
|
|
if(op) {
|
|
opc = opc.s(d, -fdir);
|
|
if(opc == null)
|
|
op = false;
|
|
else
|
|
if(!iter.go(opc, -fdir * i))
|
|
op = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** A cell enumeration, with index.
|
|
*/
|
|
public interface NEnum {
|
|
/** Get the next cell.
|
|
*/
|
|
ZZCell nextCell();
|
|
/** Get the index of the last returned cell from nextCell.
|
|
*/
|
|
int nth();
|
|
/** Whether there are more cells.
|
|
*/
|
|
boolean more();
|
|
/** Stop advancing in the current direction.
|
|
*/
|
|
void stop();
|
|
}
|
|
|
|
/** Return an enumeration that alternates between the directions.
|
|
* @param c The cell to start from.
|
|
* @param included Whether the first cell is also included.
|
|
* @param d The dimension to go along.
|
|
* @param fdir The direction to take the first step in.
|
|
*/
|
|
public static NEnum alternate(final ZZCell c, final boolean included, final String d, final int fdir) {
|
|
return new NEnum() {
|
|
/** Next cell in p or n direction.
|
|
*/
|
|
ZZCell nextn = c.s(d, -fdir), nextp = c.s(d, fdir);
|
|
|
|
int ind = 0;
|
|
|
|
boolean started;
|
|
|
|
public ZZCell nextCell() {
|
|
if(nextn == null && nextp == null) return null;
|
|
if(!started) {
|
|
started = true;
|
|
if(included) return c;
|
|
}
|
|
// Trick: always change ind, only after see if we have something
|
|
// to return. If not, recurse and get the next one from the other side.
|
|
if(ind <= 0) {
|
|
ind = -ind;
|
|
ind ++;
|
|
if(nextp == null)
|
|
return nextCell();
|
|
ZZCell ret = nextp;
|
|
nextp = nextp.s(d, fdir);
|
|
return ret;
|
|
}
|
|
if(ind > 0) {
|
|
ind = -ind;
|
|
if(nextn == null)
|
|
return nextCell();
|
|
ZZCell ret = nextn;
|
|
nextn = nextn.s(d, -fdir);
|
|
return ret;
|
|
}
|
|
return null;
|
|
}
|
|
public int nth() {
|
|
return fdir * ind;
|
|
}
|
|
public void stop() {
|
|
if(ind >= 0) nextp = null;
|
|
else nextn = null;
|
|
}
|
|
public boolean more() {
|
|
return nextn != null || nextp != null;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
|