Holy crap Batman! It's the beginnings of refactoring the basic puzzle
stuff into Narya. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2876 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// $Id: Board.java,v 1.1 2003/11/26 01:42:34 mdb Exp $
|
||||
|
||||
package com.threerings.puzzle.data;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* An abstract base class for generating and storing puzzle board data.
|
||||
*/
|
||||
public abstract class Board
|
||||
implements Cloneable, Streamable
|
||||
{
|
||||
/**
|
||||
* Outputs a string representation of the board contents.
|
||||
*/
|
||||
public abstract void dump ();
|
||||
|
||||
/**
|
||||
* Outputs a string representation of the board contents, interlaced
|
||||
* with the supplied comparison board.
|
||||
*/
|
||||
public abstract void dumpAndCompare (Board other);
|
||||
|
||||
/**
|
||||
* Returns whether this board is equal to the given comparison board.
|
||||
*/
|
||||
public abstract boolean equals (Board other);
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
{
|
||||
try {
|
||||
Board board = (Board)super.clone();
|
||||
board._rando = (BoardRandom)_rando.clone();
|
||||
return board;
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException("All is wrong with universe.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the seed in the board's random number generator and calls
|
||||
* {@link #populate}.
|
||||
*/
|
||||
public void initializeSeed (long seed)
|
||||
{
|
||||
_rando = new BoardRandom(seed);
|
||||
populate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the random number generator used by the board to generate
|
||||
* random numbers for our puzzles.
|
||||
*/
|
||||
public Random getRandom ()
|
||||
{
|
||||
return _rando;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the seed is set in the board to give derived classes a
|
||||
* chance to do things like populating the board with random pieces.
|
||||
*/
|
||||
protected void populate ()
|
||||
{
|
||||
}
|
||||
|
||||
/** Used to generate random numbers. */
|
||||
protected static class BoardRandom extends Random
|
||||
implements Cloneable
|
||||
{
|
||||
public BoardRandom (long seed)
|
||||
{
|
||||
super(0L);
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public synchronized void setSeed (long seed)
|
||||
{
|
||||
_seed = (seed ^ multiplier) & mask;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
synchronized protected int next (int bits)
|
||||
{
|
||||
long nextseed = (_seed * multiplier + addend) & mask;
|
||||
_seed = nextseed;
|
||||
return (int)(nextseed >>> (48 - bits));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void nextBytes (byte[] bytes)
|
||||
{
|
||||
unimplemented();
|
||||
}
|
||||
|
||||
// not overridden: (They seemed innocent enough)
|
||||
// nextInt()
|
||||
// nextLong()
|
||||
// nextBoolean()
|
||||
// nextFloat()
|
||||
|
||||
// documentation inherited
|
||||
public int nextInt (int n)
|
||||
{
|
||||
if (n <= 0) {
|
||||
throw new IllegalArgumentException("n must be positive");
|
||||
}
|
||||
|
||||
if ((n & -n) == n) { // i.e., n is a power of 2
|
||||
return (int)((n * (long)next(31)) >> 31);
|
||||
}
|
||||
|
||||
int bits, val;
|
||||
do {
|
||||
bits = next(31);
|
||||
val = bits % n;
|
||||
} while (bits - val + (n-1) < 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public double nextDouble ()
|
||||
{
|
||||
long l = ((long)(next(26)) << 27) + next(27);
|
||||
return l / (double)(1L << 53);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public synchronized double nextGaussian ()
|
||||
{
|
||||
if (_haveNextNextGaussian) {
|
||||
_haveNextNextGaussian = false;
|
||||
return _nextNextGaussian;
|
||||
|
||||
} else {
|
||||
double v1, v2, s;
|
||||
do {
|
||||
v1 = 2 * nextDouble() - 1;
|
||||
v2 = 2 * nextDouble() - 1;
|
||||
s = v1 * v1 + v2 * v2;
|
||||
} while (s >= 1 || s == 0);
|
||||
double multiplier = Math.sqrt(-2 * Math.log(s)/s);
|
||||
_nextNextGaussian = v2 * multiplier;
|
||||
_haveNextNextGaussian = true;
|
||||
return v1 * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
{
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException("All is wrong with universe.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* I suppose I could copy all the methods from Random, then we
|
||||
* wouldn't need this..
|
||||
*/
|
||||
private final void unimplemented ()
|
||||
{
|
||||
throw new RuntimeException(
|
||||
"The Random method you attempted to call " +
|
||||
"has not been implemented by BoardRandom.");
|
||||
}
|
||||
|
||||
/** The internal state related to generating random numbers. */
|
||||
protected long _seed;
|
||||
protected double _nextNextGaussian;
|
||||
protected boolean _haveNextNextGaussian = false;
|
||||
|
||||
private final static long multiplier = 0x5DEECE66DL;
|
||||
private final static long addend = 0xBL;
|
||||
private final static long mask = (1L << 48) - 1;
|
||||
}
|
||||
|
||||
/** The object we use to generate our random numbers. */
|
||||
protected transient BoardRandom _rando;
|
||||
}
|
||||
Reference in New Issue
Block a user