Skip to content

Instantly share code, notes, and snippets.

@alalwww
Created June 21, 2013 15:22
Show Gist options
  • Save alalwww/5831940 to your computer and use it in GitHub Desktop.
Save alalwww/5831940 to your computer and use it in GitHub Desktop.
/*
* SpawnChecker
*
* (c) 2013 alalwww
* https://github.com/alalwww
*
* This mod is distributed under the terms of the Minecraft Mod Public License 1.0, or MMPL.
* Please check the contents of the license located in http://www.mod-buildcraft.com/MMPL-1.0.txt
*
* この MOD は、Minecraft Mod Public License (MMPL) 1.0 の条件のもとに配布されています。
* ライセンスの内容は次のサイトを確認してください。 http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package net.awairo.mcmod.spawnchecker.util;
/**
* 3次元空間の走査ユーティリティ.
*
* @author alalwww
*/
public class ThreeDimensionalScanningHelper
{
public static Builder build(ScanFunction function)
{
return new Builder(function);
}
public static enum ScanOrder
{
XYZ,
XZY,
YXZ,
YZX,
ZXY,
ZYX,
}
public static class Builder
{
private final ScanFunction function;
private final int options[] = { 10, 1, 10, 1, 10, 1 };
private ScanOrder flag = ScanOrder.XYZ;
private static final int RANGE_X = 0;
private static final int STEP_X = 1;
private static final int RANGE_Y = 2;
private static final int STEP_Y = 3;
private static final int RANGE_Z = 4;
private static final int STEP_Z = 5;
/**
* Constructor.
*/
private Builder(ScanFunction function)
{
this.function = function;
}
public Builder setScaningOrderTo(ScanOrder order)
{
this.flag = order;
return this;
}
public Builder setupXScanner(int range, int step)
{
options[RANGE_X] = range;
options[STEP_X] = step;
return this;
}
public Builder setupYScanner(int range, int step)
{
options[RANGE_Y] = range;
options[STEP_Y] = step;
return this;
}
public Builder setupZScanner(int range, int step)
{
options[RANGE_Z] = range;
options[STEP_Z] = step;
return this;
}
public ThreeDimensionalScanner build()
{
return new ThreeDimensionalScanner(flag, options, function);
}
}
private static abstract class LoopFunction implements ScanFunction
{
ScanFunction child;
int range = 10;
int step = 1;
@Override
public final void apply(int x, int y, int z)
{
int i = start(x, y, z);
final int end = i + range;
while (i <= end)
{
child.apply(x(i, x), y(i, y), z(i, z));
i += step;
}
}
protected abstract int start(int x, int y, int z);
protected int x(int i, int x)
{
return x;
}
protected int y(int i, int y)
{
return y;
}
protected int z(int i, int z)
{
return z;
}
}
/**
* 生成時に設定された順番と範囲で x y z 座標を走査するクラス.
*
* @author alalwww
*/
public static class ThreeDimensionalScanner
{
private final LoopFunction scanner;
private LoopFunction xScanner = new LoopFunction()
{
@Override
protected int start(int x, int y, int z)
{
return x;
}
protected int x(int i, int x)
{
return i;
};
};
private LoopFunction yScanner = new LoopFunction()
{
@Override
protected int start(int x, int y, int z)
{
return y;
}
protected int y(int i, int y)
{
return i;
};
};
private LoopFunction zScanner = new LoopFunction()
{
@Override
protected int start(int x, int y, int z)
{
return z;
}
protected int z(int i, int z)
{
return i;
};
};
/**
* Constructor.
*/
private ThreeDimensionalScanner(ScanOrder flag, int[] options, ScanFunction function)
{
switch (flag)
{
case XYZ:
scanner = xScanner;
xScanner.child = yScanner;
yScanner.child = zScanner;
zScanner.child = function;
break;
case XZY:
scanner = xScanner;
xScanner.child = zScanner;
zScanner.child = yScanner;
yScanner.child = function;
break;
case YXZ:
scanner = yScanner;
yScanner.child = xScanner;
xScanner.child = zScanner;
zScanner.child = function;
break;
case YZX:
scanner = yScanner;
yScanner.child = zScanner;
zScanner.child = xScanner;
xScanner.child = function;
break;
case ZXY:
scanner = zScanner;
zScanner.child = xScanner;
xScanner.child = yScanner;
yScanner.child = function;
break;
case ZYX:
scanner = zScanner;
zScanner.child = yScanner;
yScanner.child = xScanner;
xScanner.child = function;
break;
default:
throw new InternalError("unknown flag. " + flag);
}
int index = 0;
xScanner.range = options[index++];
xScanner.step = options[index++];
yScanner.range = options[index++];
yScanner.step = options[index++];
zScanner.range = options[index++];
zScanner.step = options[index++];
}
public ThreeDimensionalScanner setRange(int xRange, int yRange, int zRange)
{
setRangeX(xRange);
setRangeY(yRange);
setRangeZ(zRange);
return this;
}
public ThreeDimensionalScanner setStep(int xStep, int yStep, int zStep)
{
setStepX(xStep);
setStepY(yStep);
setStepZ(zStep);
return this;
}
public ThreeDimensionalScanner setRangeX(int range)
{
xScanner.range = range;
return this;
}
public ThreeDimensionalScanner setStepX(int step)
{
xScanner.step = step;
return this;
}
public ThreeDimensionalScanner setRangeY(int range)
{
yScanner.range = range;
return this;
}
public ThreeDimensionalScanner setStepY(int step)
{
yScanner.step = step;
return this;
}
public ThreeDimensionalScanner setRangeZ(int range)
{
zScanner.range = range;
return this;
}
public ThreeDimensionalScanner setStepZ(int step)
{
zScanner.step = step;
return this;
}
/**
* 引数の座標から指定した範囲の座標までを、指定した順番で走査します.
*
* @param startX
* 開始X座標
* @param startY
* 開始Y座標
* @param startZ
* 開始Z座標
*/
public void scan(int startX, int startY, int startZ)
{
scanner.apply(startX, startY, startZ);
}
}
/**
* 座標毎の処理.
*/
public static interface ScanFunction
{
/**
* 処理を行います.
*
* @param x
* x座標
* @param y
* y座標
* @param z
* z座標
*/
void apply(int x, int y, int z);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment