Behold Vilya, Ring of Air and repository for our game and virtual worldly

extensions to the distributed environment provided by Narya.


git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@1 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Michael Bayne
2006-06-23 17:58:11 +00:00
commit a4df87e52f
317 changed files with 45818 additions and 0 deletions
@@ -0,0 +1,205 @@
//
// $Id: Board.java 4191 2006-06-13 22:42:20Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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;
}
@@ -0,0 +1,77 @@
//
// $Id: BoardSummary.java 3726 2005-10-11 19:17:43Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
import com.threerings.io.SimpleStreamableObject;
/**
* Provides summarized data representing a player's board in a puzzle
* game. Board summaries are maintained by the puzzle server and are
* periodically sent to the clients to give them a view into how well
* their opponent(s) are doing. The data required to marshal a board
* summary object should be notably smaller in size than what would be
* required to marshal the entire associated {@link Board}.
*
* <p> Note all non-transient members of this and derived classes will
* automatically be serialized when the summary is sent over the wire.
*/
public abstract class BoardSummary extends SimpleStreamableObject
{
/**
* Constructs an empty board summary for use when un-serializing.
*/
public BoardSummary ()
{
// nothing for now
}
/**
* Constructs a board summary that retrieves full board information
* from the supplied board when summarizing.
*/
public BoardSummary (Board board)
{
setBoard(board);
}
/**
* Sets the board associated with this board summary, causing
* an immediate update to this summary.
*/
public void setBoard (Board board)
{
_board = board;
summarize(); // immediately summarize the new board
}
/**
* Called by the {@link
* com.threerings.puzzle.server.PuzzleManager} to refresh the
* board summary information by studying the associated board
* contents.
*/
public abstract void summarize ();
/** The board that we're summarizing. This is only valid on the
* server, and on the client only for the actual player's board. */
protected transient Board _board;
}
@@ -0,0 +1,43 @@
//
// $Id: PuzzleCodes.java 3640 2005-07-01 23:56:54Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
import com.threerings.presents.data.InvocationCodes;
/**
* Constants relating to the puzzle services.
*/
public interface PuzzleCodes extends InvocationCodes
{
/** The message bundle identifier for general puzzle messages. */
public static final String PUZZLE_MESSAGE_BUNDLE = "puzzle.general";
/** The default puzzle difficulty level. */
public static final int DEFAULT_DIFFICULTY = 2;
/** Whether to enable debug logging and assertions for puzzles. Note
* that enabling this may result in the server or client exiting
* unexpectedly if certain error conditions arise in order to
* facilitate debugging, and so this should never be enabled in any
* environment even remotely resembling production. */
public static final boolean DEBUG_PUZZLE = false;
}
@@ -0,0 +1,51 @@
//
// $Id: PuzzleConfig.java 3381 2005-03-03 19:36:34Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
import com.threerings.parlor.game.data.GameConfig;
/**
* Encapsulates the basic configuration information for a puzzle game.
*/
public abstract class PuzzleConfig extends GameConfig
implements Cloneable
{
/**
* Constructs a blank puzzle config.
*/
public PuzzleConfig ()
{
}
/**
* Returns the message bundle identifier for the bundle that should be
* used to translate the translatable strings used to describe the
* puzzle config parameters. The default implementation returns the
* base puzzle message bundle, but puzzles that have their own message
* bundle should override this method and return their puzzle-specific
* bundle identifier.
*/
public String getBundleName ()
{
return PuzzleCodes.PUZZLE_MESSAGE_BUNDLE;
}
}
@@ -0,0 +1,32 @@
//
// $Id: PuzzleGameCodes.java 4191 2006-06-13 22:42:20Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
/**
* Contains codes used by the puzzle game client implementations. This
* differs from {@link PuzzleCodes} as that is related to the puzzle
* services which span the client and the server.
*/
public interface PuzzleGameCodes
{
// Nothing at the moment.
}
@@ -0,0 +1,62 @@
//
// $Id: PuzzleGameMarshaller.java 4145 2006-05-24 01:24:24Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
import com.threerings.presents.client.Client;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.dobj.InvocationResponseEvent;
import com.threerings.puzzle.client.PuzzleGameService;
import com.threerings.puzzle.data.Board;
/**
* Provides the implementation of the {@link PuzzleGameService} interface
* that marshalls the arguments and delivers the request to the provider
* on the server. Also provides an implementation of the response listener
* interfaces that marshall the response arguments and deliver them back
* to the requesting client.
*/
public class PuzzleGameMarshaller extends InvocationMarshaller
implements PuzzleGameService
{
/** The method id used to dispatch {@link #updateProgress} requests. */
public static final int UPDATE_PROGRESS = 1;
// documentation inherited from interface
public void updateProgress (Client arg1, int arg2, int[] arg3)
{
sendRequest(arg1, UPDATE_PROGRESS, new Object[] {
Integer.valueOf(arg2), arg3
});
}
/** The method id used to dispatch {@link #updateProgressSync} requests. */
public static final int UPDATE_PROGRESS_SYNC = 2;
// documentation inherited from interface
public void updateProgressSync (Client arg1, int arg2, int[] arg3, Board[] arg4)
{
sendRequest(arg1, UPDATE_PROGRESS_SYNC, new Object[] {
Integer.valueOf(arg2), arg3, arg4
});
}
}
@@ -0,0 +1,144 @@
//
// $Id: PuzzleObject.java 4145 2006-05-24 01:24:24Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.puzzle.data;
import com.threerings.parlor.game.data.GameObject;
/**
* Extends the basic {@link GameObject} to add individual player
* status. Puzzle games typically contain numerous players that may be
* knocked out of the game while the overall game continues on, thereby
* necessitating this second level of game status.
*/
public class PuzzleObject extends GameObject
implements PuzzleCodes
{
// AUTO-GENERATED: FIELDS START
/** The field name of the <code>puzzleGameService</code> field. */
public static final String PUZZLE_GAME_SERVICE = "puzzleGameService";
/** The field name of the <code>difficulty</code> field. */
public static final String DIFFICULTY = "difficulty";
/** The field name of the <code>summaries</code> field. */
public static final String SUMMARIES = "summaries";
/** The field name of the <code>seed</code> field. */
public static final String SEED = "seed";
// AUTO-GENERATED: FIELDS END
/** Provides general puzzle game invocation services. */
public PuzzleGameMarshaller puzzleGameService;
/** The puzzle difficulty level. */
public int difficulty;
/** Summaries of the boards of all players in this puzzle (may be null
* if the puzzle doesn't support individual player boards). */
public BoardSummary[] summaries;
/** The seed used to germinate the boards. */
public long seed;
// AUTO-GENERATED: METHODS START
/**
* Requests that the <code>puzzleGameService</code> field be set to the
* specified value. The local value will be updated immediately and an
* event will be propagated through the system to notify all listeners
* that the attribute did change. Proxied copies of this object (on
* clients) will apply the value change when they received the
* attribute changed notification.
*/
public void setPuzzleGameService (PuzzleGameMarshaller value)
{
PuzzleGameMarshaller ovalue = this.puzzleGameService;
requestAttributeChange(
PUZZLE_GAME_SERVICE, value, ovalue);
this.puzzleGameService = value;
}
/**
* Requests that the <code>difficulty</code> field be set to the
* specified value. The local value will be updated immediately and an
* event will be propagated through the system to notify all listeners
* that the attribute did change. Proxied copies of this object (on
* clients) will apply the value change when they received the
* attribute changed notification.
*/
public void setDifficulty (int value)
{
int ovalue = this.difficulty;
requestAttributeChange(
DIFFICULTY, Integer.valueOf(value), Integer.valueOf(ovalue));
this.difficulty = value;
}
/**
* Requests that the <code>summaries</code> field be set to the
* specified value. The local value will be updated immediately and an
* event will be propagated through the system to notify all listeners
* that the attribute did change. Proxied copies of this object (on
* clients) will apply the value change when they received the
* attribute changed notification.
*/
public void setSummaries (BoardSummary[] value)
{
BoardSummary[] ovalue = this.summaries;
requestAttributeChange(
SUMMARIES, value, ovalue);
this.summaries = (value == null) ? null : (BoardSummary[])value.clone();
}
/**
* Requests that the <code>index</code>th element of
* <code>summaries</code> field be set to the specified value.
* The local value will be updated immediately and an event will be
* propagated through the system to notify all listeners that the
* attribute did change. Proxied copies of this object (on clients)
* will apply the value change when they received the attribute
* changed notification.
*/
public void setSummariesAt (BoardSummary value, int index)
{
BoardSummary ovalue = this.summaries[index];
requestElementUpdate(
SUMMARIES, index, value, ovalue);
this.summaries[index] = value;
}
/**
* Requests that the <code>seed</code> field be set to the
* specified value. The local value will be updated immediately and an
* event will be propagated through the system to notify all listeners
* that the attribute did change. Proxied copies of this object (on
* clients) will apply the value change when they received the
* attribute changed notification.
*/
public void setSeed (long value)
{
long ovalue = this.seed;
requestAttributeChange(
SEED, Long.valueOf(value), Long.valueOf(ovalue));
this.seed = value;
}
// AUTO-GENERATED: METHODS END
}