diff --git a/projects/atlanti/.jde-project.el b/projects/atlanti/.jde-project.el deleted file mode 100644 index ef6bdcac..00000000 --- a/projects/atlanti/.jde-project.el +++ /dev/null @@ -1,4 +0,0 @@ -(jde-set-variables - '(jde-db-source-directories (quote ("/export/local/jdk1.4/src" "/home/mdb/projects/samskivert/src/java" "/home/mdb/work/narya/src/java" "/home/mdb/projects/atlanti/src/java"))) - '(jde-global-classpath (quote ("/home/mdb/projects/samskivert/dist/classes" "/home/mdb/work/narya/dist/classes" "/home/mdb/projects/atlanti/dist/classes"))) - ) diff --git a/projects/atlanti/bin/atlclient b/projects/atlanti/bin/atlclient deleted file mode 100755 index 46143cbf..00000000 --- a/projects/atlanti/bin/atlclient +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -BINDIR=`dirname $0` -JAVA_ARGS="" -ARGS="" - -# grab the -Dinviter if it's specified -while [ ! -z "$1" ] ; do - case $1 in - -D*) - JAVA_ARGS="$JAVA_ARGS $1" - shift - ;; - *) - ARGS="$ARGS $1" - shift - ;; - esac -done - -$BINDIR/runjava $JAVA_ARGS com.threerings.micasa.client.MiCasaApp $ARGS diff --git a/projects/atlanti/bin/atlserver b/projects/atlanti/bin/atlserver deleted file mode 100755 index 5e43e32d..00000000 --- a/projects/atlanti/bin/atlserver +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -bindir=`dirname $0` -$bindir/runjava com.threerings.micasa.server.MiCasaServer $* diff --git a/projects/atlanti/bin/runjava b/projects/atlanti/bin/runjava deleted file mode 100755 index 1d245060..00000000 --- a/projects/atlanti/bin/runjava +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/perl -w - -use Getopt::Std; - -my $usage = "Usage: $0 [-p pid_file] [-r root_directory] args\n"; - -# locations of stuff -chomp($location = `dirname $0`); - -# get the server root by popping the /bin off of our parent directory -@parts = split(/\//, $location); -pop(@parts); -my $root = join("/", @parts); - -my $jhome = $ENV{"JAVA_HOME"}; - -# make sure JAVA_HOME is set -if (!defined $jhome) { - warn "$0: Error: No JAVA_HOME specified!\n"; - warn "\n"; - warn "You must set your JAVA_HOME environment variable to the\n"; - warn "the absolute path of your JDK installation. For example:\n"; - warn "\n"; - warn " % JAVA_HOME=/usr/local/jdk1.2\n"; - warn " % export JAVA_HOME\n"; - die "\n"; -} - -# make sure it's set to a directory -if (! -d $jhome) { - die "$0: Can't find a java interpreter in '$jhome'.\n"; -} - -my $java = "$jhome/bin/java"; -my $jlib = "$jhome/lib/classes.zip"; - -# put everything in our class path -my $classpath = "-classpath $root/dist/classes"; - -# add zip and jar files from our lib/ directory and the system lib/ directory -my @dirs = ( "$root/lib" ); -foreach $dir (@dirs) { - next unless (defined $dir); - if (opendir(DIR, $dir)) { - foreach $lib (grep { /.(zip|jar)/ && -f "$dir/$_" } readdir(DIR)) { - $classpath .= ":$dir/$lib"; - } - closedir DIR; - } -} - -# finally add the standard classes -$classpath = "$classpath:$jlib"; - -# specify our application root (the resource manager needs this) -my $rootarg = "-Dresource_url=file:$root/rsrc"; - -my $pid_file = undef; -my $i = 0; - -# strip out the -p and -r args (we'd use getopt() but the damned thing -# provides no way of escaping arguments so that we can pass args to -# runjava that get passed down to the JVM) -for ($i = 0; $i < @ARGV; $i++) { - my $arg = $ARGV[$i]; - - # stop when we see -- (and strip it out because Java don't dig --) - if ($arg eq "--") { - splice(@ARGV, $i, 1); - last; - } - - if ($arg eq "-p") { - $pid_file = $ARGV[$i+1]; - splice(@ARGV, $i, 2); - $i -= 1; # decrement i so that things stay in sync - - } elsif ($arg eq "-r") { - $rootarg = "-DDapplication.root=" . $ARGV[$i+1]; - splice(@ARGV, $i, 2); - $i -= 1; # decrement i so that things stay in sync - } -} - -# log the pid file if requested to do so -print `echo $$ > $pid_file` if (defined $pid_file); - -my $cmd = "$java -mx256M $classpath $rootarg " . join(" ", @ARGV); -# print "$cmd\n"; -exec($cmd); diff --git a/projects/atlanti/build.xml b/projects/atlanti/build.xml deleted file mode 100644 index 533b6bef..00000000 --- a/projects/atlanti/build.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/atlanti/lib/.cvsignore b/projects/atlanti/lib/.cvsignore deleted file mode 100644 index 0f2dd2af..00000000 --- a/projects/atlanti/lib/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -i686-Linux diff --git a/projects/atlanti/lib/README b/projects/atlanti/lib/README deleted file mode 100644 index 999910fa..00000000 --- a/projects/atlanti/lib/README +++ /dev/null @@ -1,22 +0,0 @@ -Required external libraries ---------------------------- - -The Atlantissonne code requires the following external Java libraries (JAR -files) to be placed (or symlinked) here in the lib/ directory. - -* Apache Commons Lang library (from the sanbox) - http://jakarta.apache.org/commons/index.html - -* The samskivert library: - http://www.waywardgeeks.org/code/samskivert/ - -* The Narya game development libraries; specifically: base, distrib, - media, micasa and parlor - http://www.threerings.net/code/narya/ - -Once the jar files are in place (regardless of what they are named), the -build system will automatically include them in the compile-time -classpath. - --- -$Id: README,v 1.3 2002/12/12 06:10:13 mdb Exp $ diff --git a/projects/atlanti/lib/commons-lang.jar b/projects/atlanti/lib/commons-lang.jar deleted file mode 100644 index 9963b88b..00000000 Binary files a/projects/atlanti/lib/commons-lang.jar and /dev/null differ diff --git a/projects/atlanti/lib/narya-base.jar b/projects/atlanti/lib/narya-base.jar deleted file mode 100644 index 5f0a98f6..00000000 Binary files a/projects/atlanti/lib/narya-base.jar and /dev/null differ diff --git a/projects/atlanti/lib/narya-distrib.jar b/projects/atlanti/lib/narya-distrib.jar deleted file mode 100644 index cd91e6fd..00000000 Binary files a/projects/atlanti/lib/narya-distrib.jar and /dev/null differ diff --git a/projects/atlanti/lib/narya-media.jar b/projects/atlanti/lib/narya-media.jar deleted file mode 100644 index 4da25ab2..00000000 Binary files a/projects/atlanti/lib/narya-media.jar and /dev/null differ diff --git a/projects/atlanti/lib/narya-micasa.jar b/projects/atlanti/lib/narya-micasa.jar deleted file mode 100644 index 064c0a54..00000000 Binary files a/projects/atlanti/lib/narya-micasa.jar and /dev/null differ diff --git a/projects/atlanti/lib/narya-parlor.jar b/projects/atlanti/lib/narya-parlor.jar deleted file mode 100644 index 81bbdd7f..00000000 Binary files a/projects/atlanti/lib/narya-parlor.jar and /dev/null differ diff --git a/projects/atlanti/lib/samskivert.jar b/projects/atlanti/lib/samskivert.jar deleted file mode 100644 index 71de7067..00000000 Binary files a/projects/atlanti/lib/samskivert.jar and /dev/null differ diff --git a/projects/atlanti/rsrc/config/atlanti/dbmap.properties b/projects/atlanti/rsrc/config/atlanti/dbmap.properties deleted file mode 100644 index 792de1c5..00000000 --- a/projects/atlanti/rsrc/config/atlanti/dbmap.properties +++ /dev/null @@ -1,14 +0,0 @@ -# -# $Id: dbmap.properties,v 1.3 2003/03/23 05:02:31 mdb Exp $ -# -# This provides information on the JDBC connections that are used by -# Atlantisonne server services. - -# The default database mapping. All other definitions will inherit from -# this and need only be specified in cases where they differ from the -# defaults. - -default.driver = org.gjt.mm.mysql.Driver -default.url = jdbc:mysql://DBHOST:3306/usermgmt -default.username = USERNAME -default.password = PASSWORD diff --git a/projects/atlanti/rsrc/config/atlanti/server.properties b/projects/atlanti/rsrc/config/atlanti/server.properties deleted file mode 100644 index ad4dad8f..00000000 --- a/projects/atlanti/rsrc/config/atlanti/server.properties +++ /dev/null @@ -1,4 +0,0 @@ -# -# $Id: server.properties,v 1.2 2002/12/12 05:51:53 mdb Exp $ -# -# Configuration for the Atlantissonne server diff --git a/projects/atlanti/rsrc/config/micasa/server.properties b/projects/atlanti/rsrc/config/micasa/server.properties deleted file mode 100644 index 1a0c839c..00000000 --- a/projects/atlanti/rsrc/config/micasa/server.properties +++ /dev/null @@ -1,20 +0,0 @@ -# -# $Id: server.properties,v 1.3 2002/12/12 05:51:53 mdb Exp $ -# -# Configuration for the MiCasa server - -_package = atlanti.server -_overrides = micasa.server - -# -# The list of lobby identifiers to be loaded into this server. -# -lobby_ids = atlanti - -# -# The cofiguration for the test lobby. -# -atlanti.config = com.threerings.micasa.lobby.table.TableLobbyConfig -atlanti.ugi = atlanti,board,tile,strategy -atlanti.name = Atlanti Lobby -atlanti.game_config = com.samskivert.atlanti.data.AtlantiConfig diff --git a/projects/atlanti/rsrc/i18n/atlanti.properties b/projects/atlanti/rsrc/i18n/atlanti.properties deleted file mode 100644 index 7e384cae..00000000 --- a/projects/atlanti/rsrc/i18n/atlanti.properties +++ /dev/null @@ -1,4 +0,0 @@ -# -# $Id: atlanti.properties,v 1.1 2002/05/21 04:45:09 mdb Exp $ -# -# Translation messages diff --git a/projects/atlanti/rsrc/media/piecens.png b/projects/atlanti/rsrc/media/piecens.png deleted file mode 100644 index 1e02dfc1..00000000 Binary files a/projects/atlanti/rsrc/media/piecens.png and /dev/null differ diff --git a/projects/atlanti/rsrc/media/shield.png b/projects/atlanti/rsrc/media/shield.png deleted file mode 100644 index ba99ebb2..00000000 Binary files a/projects/atlanti/rsrc/media/shield.png and /dev/null differ diff --git a/projects/atlanti/rsrc/media/tiles.png b/projects/atlanti/rsrc/media/tiles.png deleted file mode 100644 index 6bbcfd74..00000000 Binary files a/projects/atlanti/rsrc/media/tiles.png and /dev/null differ diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/Log.java b/projects/atlanti/src/java/com/samskivert/atlanti/Log.java deleted file mode 100644 index 906e53cb..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/Log.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// $Id: Log.java,v 1.3 2002/12/12 05:51:53 mdb Exp $ - -package com.samskivert.atlanti; - -/** - * A placeholder class that contains a reference to the log object used by - * this package. This is a useful pattern to use when using the samskivert - * logging facilities. One creates a top-level class like this one that - * instantiates a log object with an name that identifies log messages - * from that package and then provides static methods that generate log - * messages using that instance. Then, classes in that package need only - * import the log wrapper class and can easily use it to generate log - * messages. For example: - * - *
- * import com.samskivert.atlanti.Log;
- * // ...
- * Log.warning("All hell is breaking loose!");
- * // ...
- * 
- * - * @see com.samskivert.util.Log - */ -public class Log -{ - /** The static log instance configured for use by this package. */ - public static com.samskivert.util.Log log = - new com.samskivert.util.Log("atlanti"); - - /** Convenience function. */ - public static void debug (String message) - { - log.debug(message); - } - - /** Convenience function. */ - public static void info (String message) - { - log.info(message); - } - - /** Convenience function. */ - public static void warning (String message) - { - log.warning(message); - } - - /** Convenience function. */ - public static void logStackTrace (Throwable t) - { - log.logStackTrace(com.samskivert.util.Log.WARNING, t); - } -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/TileGeometryTest.java b/projects/atlanti/src/java/com/samskivert/atlanti/TileGeometryTest.java deleted file mode 100644 index 2b372a3b..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/TileGeometryTest.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// $Id: TileGeometryTest.java,v 1.7 2003/03/23 02:22:51 mdb Exp $ - -package com.samskivert.atlanti; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; - -import javax.swing.JFrame; -import javax.swing.JPanel; - -import com.samskivert.swing.util.SwingUtil; - -import com.threerings.media.image.ImageManager; -import com.threerings.media.tile.TileManager; -import com.threerings.resource.ResourceManager; - -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.TileCodes; -import com.samskivert.atlanti.util.PiecenUtil; - -/** - * A simple class for testing the tile geometry specifications by drawing - * them. - */ -public class TileGeometryTest extends JPanel - implements TileCodes -{ - public TileGeometryTest () - { - for (int i = 0; i < TILE_TYPES; i++) { - _tiles[i] = new AtlantiTile(i+1, true, NORTH, i % 5, i / 5); - } - } - - public void paintComponent (Graphics g) - { - super.paintComponent(g); - - // paint our tiles - for (int i = 0; i < _tiles.length; i++) { - _tiles[i].paint((Graphics2D)g, 0, 0); - } - } - - public Dimension getPreferredSize () - { - // we want to be five tiles wide by four tiles tall - return new Dimension(TILE_WIDTH * 5, TILE_HEIGHT * 4); - } - - public static void main (String[] args) - { - JFrame frame = new JFrame("Tile geometry test"); - - ResourceManager rmgr = new ResourceManager("rsrc"); - ImageManager imgr = new ImageManager(rmgr, frame); - TileManager tmgr = new TileManager(imgr); - - AtlantiTile.setManagers(imgr, tmgr); - AtlantiTile.piecenDebug = true; - PiecenUtil.init(tmgr); - - // quit if we're closed - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - TileGeometryTest panel = new TileGeometryTest(); - frame.getContentPane().add(panel); - frame.pack(); - SwingUtil.centerWindow(frame); - frame.show(); - } - - protected AtlantiTile[] _tiles = new AtlantiTile[TILE_TYPES]; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java deleted file mode 100644 index b1d89c89..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiBoard.java +++ /dev/null @@ -1,693 +0,0 @@ -// -// $Id: AtlantiBoard.java,v 1.19 2003/03/23 05:12:43 mdb Exp $ - -package com.samskivert.atlanti.client; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.util.SwingUtil; -import com.samskivert.util.CollectionUtil; - -import com.threerings.presents.dobj.DSet; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.data.AtlantiCodes; -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.Piecen; -import com.samskivert.atlanti.data.TileCodes; -import com.samskivert.atlanti.util.TileUtil; - -/** - * Displays the tiles that make up the board. - */ -public class AtlantiBoard extends JPanel - implements TileCodes, AtlantiCodes -{ - /** - * Constructs a board. - */ - public AtlantiBoard () - { - // create mouse adapters that will let us know when interesting - // mouse events happen - addMouseListener(new MouseAdapter() { - public void mouseClicked (MouseEvent evt) { - AtlantiBoard.this.mouseClicked(evt); - } - }); - addMouseMotionListener(new MouseMotionAdapter() { - public void mouseMoved (MouseEvent evt) { - AtlantiBoard.this.mouseMoved(evt); - } - }); - } - - /** - * Sets the piecen color to use when creating new piecens. - */ - public void setNewPiecenColor (int color) - { - _newPiecenColor = color; - } - - /** - * Sets the tiles to be displayed by this board. Any previous tiles - * are forgotten and the new tiles are initialized according to their - * geometry to set up initial claim groups. - * - * @param tset the set of {@link AtlantiTile} objects to be displayed - * by this board. - */ - public void setTiles (DSet tset) - { - // clear out our old tiles list - _tiles.clear(); - - // copy the tiles from the set into our local list - CollectionUtil.addAll(_tiles, tset.entries()); - - // sort the list - Collections.sort(_tiles); - - // recompute our desired dimensions and then have our parent - // adjust to our changed size - computeDimensions(); - } - - /** - * Sets the piecens to be placed on the appropriate tiles of the - * board. This should only be done when first entering the game room - * and subsequent piecen placement should be done via {@link - * #placePiecen}. - */ - public void setPiecens (DSet piecens) - { - // just iterate over the set placing each of the piecens in turn - Iterator iter = piecens.entries(); - while (iter.hasNext()) { - placePiecen((Piecen)iter.next()); - } - } - - /** - * Instructs the board to add the specified tile to the display. The - * tile will have its claims inherited accordingly. - */ - public void addTile (AtlantiTile tile) - { - Log.info("Adding tile to board " + tile + "."); - - // if we add a tile that is the same as our most recently placed - // tile, leave the placed tile. otherwise clear it out - if (!tile.equals(_placedTile)) { - _placedTile = null; - } - - // add the tile - _tiles.add(tile); - - // reference this as our most recently placed tile - _lastPlacedTile = tile; - - // resort the list - Collections.sort(_tiles); - - // have the new tile inherit its claim groups - TileUtil.inheritClaims(_tiles, tile); - - // recompute our desired dimensions and then have our parent - // adjust to our changed size - computeDimensions(); - } - - /** - * Places the specified piecen on the appropriate tile and updates - * claim groups as necessary. - */ - public void placePiecen (Piecen piecen) - { - // if we still have a placed tile, we get rid of it - _placedTile = null; - - Log.info("Placing " + piecen + "."); - - // locate the tile associated with this piecen - int tidx = _tiles.indexOf(piecen); - if (tidx != -1) { - AtlantiTile tile = (AtlantiTile)_tiles.get(tidx); - // set the piecen on the tile (supplying our tile list so that - // the necessary claim group adjustments can be made) - tile.setPiecen(piecen, _tiles); - // and repaint - repaintTile(tile); - - } else { - Log.warning("Requested to place piecen for which we could " + - "find no associated tile! [piecen=" + piecen + "]."); - } - } - - /** - * When a piecen is removed (after scoring it), this method should be - * called to update the board display. - */ - public void clearPiecen (Object key) - { - // locate the tile associated with this piecen key - int tsize = _tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)_tiles.get(i); - if (tile.getKey().equals(key)) { - // clear the piecen out of the tile - tile.clearPiecen(); - // and repaint - repaintTile(tile); - // and get on out - return; - } - } - - Log.warning("Requested to clear piecen for which we could " + - "find no associated tile! [key=" + key + "]."); - } - - /** - * Turn off the ability to place a piecen on the most recently played - * tile. This function assumes that the mouse will not be over a valid - * piecen placement at the time this function is called (it expects - * that it will be over a button of some sort that says something to - * the effect of "skip placement for this turn"). - */ - public void cancelPiecenPlacement () - { - _placingPiecen = false; - } - - /** - * If we freed up a placeable piecen that we didn't have when we - * placed our tile, this can be called to reenable piecen placement. - */ - public void enablePiecenPlacement () - { - _placingPiecen = true; - } - - /** - * Sets the tile to be placed on the board. The tile will be displayed - * in the square under the mouse cursor where it can be legally placed - * and its orientation will be determined based on the pointer's - * proximity to the edges of the target square. When the user clicks - * the mouse while the tile is in a placeable position, a - * TILE_PLACED command will be dispatched to the - * controller in scope. The coordinates and orientation of the tile - * will be available by fetching the tile back via {@link - * #getPlacedTile}. The tile provided to this method will not be - * modified. - * - * @param tile the new tile to be placed or null if no tile is to - * currently be placed. - */ - public void setTileToBePlaced (AtlantiTile tile) - { - Log.info("Setting tile to be placed [tile=" + tile + "]."); - - // make a copy of this tile so that we can play with it - _placingTile = (AtlantiTile)tile.clone();; - - // update our internal state based on this new placing tile - if (_placingTile != null) { - updatePlacingInfo(true); - } - } - - /** - * Returns the last tile placed by the user. - */ - public AtlantiTile getPlacedTile () - { - return _placedTile; - } - - // documentation inherited - public void doLayout () - { - super.doLayout(); - - // compute our translation coordinates based on our size - _tx = (getWidth() - TILE_WIDTH * _width)/2; - _ty = (getHeight() - TILE_HEIGHT * _height)/2; - } - - /** - * Causes the supplied tile to be repainted. - */ - public void repaintTile (AtlantiTile tile) - { - int offx = _tx + (tile.x + _origX) * TILE_WIDTH; - int offy = _ty + (tile.y + _origY) * TILE_HEIGHT; - repaint(offx, offy, TILE_WIDTH, TILE_HEIGHT); - } - - // documentation inherited - public void paintComponent (Graphics g) - { - super.paintComponent(g); - - Graphics2D g2 = (Graphics2D)g; - - // center the tile display if we are bigger than we need to be - g.translate(_tx, _ty); - - // iterate over our tiles, painting each of them - int tsize = _tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)_tiles.get(i); - tile.paint(g2, _origX, _origY); - } - - // if we have a placing tile, draw that one as well - if (_placingTile != null && _validPlacement) { - // if the current position is valid, draw the placing tile - _placingTile.paint(g2, _origX, _origY); - - // draw a green rectangle around the placing tile - g.setColor(Color.blue); - int sx = (_placingTile.x + _origX) * TILE_WIDTH; - int sy = (_placingTile.y + _origY) * TILE_HEIGHT; - g.drawRect(sx, sy, TILE_WIDTH-1, TILE_HEIGHT-1); - } - - // if we have a recently placed tile, draw that one as well - if (_placedTile != null) { - // draw the tile - _placedTile.paint(g2, _origX, _origY); - - // draw a white rectangle around the placed tile - g.setColor(Color.white); - int sx = (_placedTile.x + _origX) * TILE_WIDTH; - int sy = (_placedTile.y + _origY) * TILE_HEIGHT; - g.drawRect(sx, sy, TILE_WIDTH-1, TILE_HEIGHT-1); - } - - // draw a white rectangle around the last placed - if (_lastPlacedTile != null) { - g.setColor(Color.white); - int sx = (_lastPlacedTile.x + _origX) * TILE_WIDTH; - int sy = (_lastPlacedTile.y + _origY) * TILE_HEIGHT; - g.drawRect(sx, sy, TILE_WIDTH-1, TILE_HEIGHT-1); - } - - // undo our translations - g.translate(-_tx, -_ty); - } - - /** Called by our adapter when the mouse moves. */ - protected void mouseMoved (MouseEvent evt) - { - // we always want to know about our last mouse coordinates - _mouseX = evt.getX() - _tx; - _mouseY = evt.getY() - _ty; - - if (_placingTile != null) { - // if we have a tile to be placed, update its coordinates (it - // will automatically be repainted) - updatePlacingInfo(false); - - } else if (_placedTile != null && _placingPiecen) { - // if we have a recently placed tile, we're doing piecen - // placement; first convert the mouse coords into tile coords - int mx = _mouseX - (_placedTile.x + _origX) * TILE_WIDTH; - int my = _mouseY - (_placedTile.y + _origY) * TILE_HEIGHT; - boolean changed = false; - - // now see if we're inside the placing tile - if (mx >= 0 && mx < TILE_WIDTH && my >= 0 && my < TILE_HEIGHT) { - int fidx = _placedTile.getFeatureIndex(mx, my); - - // if the feature is not already claimed, we can put a - // piece there to indicate that it can be claimed - if (_placedTile.claims[fidx] == 0) { - if (_placedTile.piecen == null || - _placedTile.piecen.featureIndex != fidx) { - Piecen p = new Piecen(_newPiecenColor, 0, 0, fidx); - _placedTile.setPiecen(p, null); - changed = true; - } - - } else { - // we may need to clear out a piecen since we've moved - if (_placedTile.piecen != null) { - _placedTile.clearPiecen(); - changed = true; - } - } - - } else { - // we may need to clear out a piecen since we've moved - if (_placedTile.piecen != null) { - _placedTile.clearPiecen(); - changed = true; - } - } - - if (changed) { - repaintTile(_placedTile); - } - } - } - - /** Called by our adapter when the mouse is clicked. */ - protected void mouseClicked (MouseEvent evt) - { - int modifiers = evt.getModifiers(); - - // if this is a right button click, and we're in piecen placing - // mode, generate a PLACE_NOTHING notification instead - if (_placingPiecen && (modifiers & MouseEvent.BUTTON3_MASK) != 0) { - // stop piecen placement - _placingPiecen = false; - // clear out any placed piecen because we're placing nothing - if (_placedTile != null && _placedTile.piecen != null) { - _placedTile.piecen = null; - repaintTile(_placedTile); - } - // post the action - Controller.postAction(this, PLACE_NOTHING); - - } else { - // ignore non-button one presses other than cancel piecen - // placement - if ((modifiers & MouseEvent.BUTTON1_MASK) == 0) { - return; - } - } - - // if we have a placing tile and it's in a valid position, we want - // to dispatch an action letting the controller know that the user - // placed it - if (_placingTile != null && _validPlacement) { - // move the placing tile to the placed tile - _placedTile = _placingTile; - _placingTile = null; - - // inherit claims on the placed tile - TileUtil.inheritClaims(_tiles, _placedTile); - - // post the action - Controller.postAction(this, TILE_PLACED); - - // move into placing piecen mode - _placingPiecen = true; - - // recompute our dimensions (which will relayout or repaint) - computeDimensions(); - } - - // if we're placing a piecen and the piecen is in a valid - // position, we want to dispatch an action letting the controller - // know that the user placed it - if (_placingPiecen && _placedTile != null && - _placedTile.piecen != null) { - // clear out placing piecen mode - _placingPiecen = false; - - // post the action - Controller.postAction(this, PIECEN_PLACED); - } - } - - /** - * Updates the coordinates and orientation of the placing tile based - * on the last known coordinates of the mouse and causes it to be - * repainted. - */ - protected void updatePlacingInfo (boolean force) - { - boolean updated = false; - - // convert mouse coordinates into tile coordinates and offset them - // by the origin - int x = divFloor(_mouseX, TILE_WIDTH) - _origX; - int y = divFloor(_mouseY, TILE_HEIGHT) - _origY; - - // if these are different than the values currently in the placing - // tile, update the tile coordinates - if (_placingTile.x != x || _placingTile.y != y || force) { - // if we have a valid orientation presently, and we're moving, - // we need to clear out the old orientation - if (_validPlacement) { - repaintTile(_placingTile); - } - - // update the coordinates of the tile - _placingTile.x = x; - _placingTile.y = y; - - // make a note that we moved - updated = true; - - // we also need to recompute the valid orientations for the - // tile in this new position - _validOrients = TileUtil.computeValidOrients(_tiles, _placingTile); - - // if we've changed positions, clear out our valid placement - // flag - _validPlacement = false; - } - - // determine if we should change the orientation based on the - // position of the mouse within the tile boundaries - int rx = _mouseX % TILE_WIDTH; - int ry = _mouseY % TILE_HEIGHT; - int orient = coordToOrient(rx, ry); - - // scan for a legal orientation that is closest to our desired - // orientation - for (int i = 0; i < 4; i++) { - int candOrient = (orient+i)%4; - if (_validOrients[candOrient]) { - if (_placingTile.orientation != candOrient) { - _placingTile.orientation = candOrient; - // make a note that we moved - updated = true; - } - _validPlacement = true; - break; - } - } - - // if we now have a valid orientation and something was changed, - // we want to repaint at the new tile location - if (_validPlacement && updated) { - repaintTile(_placingTile); - } - } - - /** - * Converts mouse coordinates which are relative to a particular tile, - * into an orientation based on the position within that tile. A tile - * is divided up into four quadrants by lines connecting its four - * corners. If the tile is in a quadrant closes to an edge, it is - * converted to the orientation corresponding with that edge. - * - * @param rx the mouse coordinates modulo tile width. - * @param ry the mouse coordinates modulo tile height. - * - * @return the orientation desired for the tile in which the mouse - * resides. - */ - protected int coordToOrient (int rx, int ry) - { - if (rx > ry) { - if (rx > (TILE_HEIGHT - ry)) { - return EAST; - } else { - return NORTH; - } - } else { - if (rx > (TILE_HEIGHT - ry)) { - return SOUTH; - } else { - return WEST; - } - } - } - - /** Divides the two integers returning the floor of the divided value - * rather than its truncation. */ - protected static int divFloor (int value, int divisor) - { - return (int)Math.floor((double)value/divisor); - } - - // documentation inherited - public Dimension getPreferredSize () - { - if (_tiles.size() == 0) { - return new Dimension(100, 100); - - } else { - return new Dimension(TILE_WIDTH * _width, TILE_HEIGHT * _height); - } - } - - /** - * Determines how big we want to be based on where the tiles have been - * laid out. This will cause the component to be re-layed out if the - * dimensions change or repainted if not. - */ - protected void computeDimensions () - { - int maxX = 0, maxY = 0; - int minX = 0, minY = 0; - - // if we have a recently placed tile, start with that one - if (_placedTile != null) { - minX = maxX = _placedTile.x; - minY = maxY = _placedTile.y; - } - - // figure out what our boundaries are - int tsize = _tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)_tiles.get(i); - if (tile.x > maxX) { - maxX = tile.x; - } else if (tile.x < minX) { - minX = tile.x; - } - if (tile.y > maxY) { - maxY = tile.y; - } else if (tile.y < minY) { - minY = tile.y; - } - } - - // spread our bounds out by one - minX -= 1; minY -= 1; - maxX += 1; maxY += 1; - - // keep track of these to know if we've change dimensions - int oldOrigX = _origX, oldOrigY = _origY; - int oldWidth = _width, oldHeight = _height; - - // now we can compute our width and the origin offset - _origX = -minX; - _origY = -minY; - _width = maxX - minX + 1; - _height = maxY - minY + 1; - - if (_origX != oldOrigX || _origY != oldOrigY || - oldWidth != _width || oldHeight != _height) { - // if the dimensions changed, we need to relayout - revalidate(); - } - - // always repaint because revalidation doesn't always seem to - // result in a repaint - repaint(); - } - - /** Test code. */ - public static void main (String[] args) - { - JFrame frame = new JFrame("Board test"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - AtlantiBoard board = new AtlantiBoard(); - - TestDSet set = new TestDSet(); - set.addTile(new AtlantiTile(CITY_TWO, true, WEST, 0, 0)); - set.addTile(new AtlantiTile(CITY_TWO, false, WEST, -1, 1)); - set.addTile(new AtlantiTile(CITY_ONE, false, SOUTH, -1, -1)); - AtlantiTile zero = new AtlantiTile(CURVED_ROAD, false, WEST, 0, 2); - set.addTile(zero); - AtlantiTile one = new AtlantiTile(TWO_CITY_TWO, false, NORTH, 0, 1); - set.addTile(one); - set.addTile(new AtlantiTile(CITY_THREE, false, WEST, 1, 1)); - set.addTile(new AtlantiTile(CITY_THREE_ROAD, false, EAST, 1, 2)); - set.addTile(new AtlantiTile(CITY_THREE, false, NORTH, -1, 0)); - AtlantiTile two = new AtlantiTile(CITY_ONE, false, EAST, -2, 0); - set.addTile(two); - board.setTiles(set); - - AtlantiTile placing = new AtlantiTile(CITY_TWO, false, NORTH, 0, 0); - board.setTileToBePlaced(placing); - - // set a feature group to test propagation - List tiles = new ArrayList(); - CollectionUtil.addAll(tiles, set.entries()); - Collections.sort(tiles); - - zero.setPiecen(new Piecen(Piecen.GREEN, 0, 0, 2), tiles); - one.setPiecen(new Piecen(Piecen.BLUE, 0, 0, 0), tiles); - two.setPiecen(new Piecen(Piecen.RED, 0, 0, 1), tiles); - - Log.info("Incomplete road: " + - TileUtil.computeFeatureScore(tiles, zero, 2)); - - Log.info("Completed city: " + - TileUtil.computeFeatureScore(tiles, two, 1)); - - Log.info("Incomplete city: " + - TileUtil.computeFeatureScore(tiles, one, 2)); - - frame.getContentPane().add(board, BorderLayout.CENTER); - frame.pack(); - SwingUtil.centerWindow(frame); - frame.show(); - } - - protected static class TestDSet extends DSet - { - public void addTile (AtlantiTile tile) - { - add(tile); - } - } - - /** A reference to our tile set. */ - protected ArrayList _tiles = new ArrayList(); - - /** The tile currently being placed by the user. */ - protected AtlantiTile _placingTile; - - /** The last tile being placed by the user. */ - protected AtlantiTile _placedTile; - - /** The last tile placed on the board via {@link #addTile}. */ - protected AtlantiTile _lastPlacedTile; - - /** A flag indicating whether or not we're placing a piecen. */ - protected boolean _placingPiecen = false; - - /** Whether or not the current position and orientation of the placing - * tile is valid. */ - protected boolean _validPlacement = false; - - /** An array indicating which of the four directions are valid - * placements based on the current position of the placing tile. */ - protected boolean[] _validOrients; - - /** The color to use when creating new piecens. */ - protected int _newPiecenColor = Piecen.BLUE; - - /** Our render offset in pixels. */ - protected int _tx, _ty; - - /** The offset in tile coordinates of the origin. */ - protected int _origX, _origY; - - /** The width and height of the board in tile coordinates. */ - protected int _width, _height; - - /** The last known position of the mouse. */ - protected int _mouseX, _mouseY; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiConfigurator.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiConfigurator.java deleted file mode 100644 index 63de441b..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiConfigurator.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// $Id: AtlantiConfigurator.java,v 1.1 2002/12/12 05:51:53 mdb Exp $ - -package com.samskivert.atlanti.client; - -import com.samskivert.swing.SimpleSlider; -import com.samskivert.swing.VGroupLayout; - -import com.threerings.micasa.lobby.table.TableGameConfigurator; - -import com.samskivert.atlanti.data.AtlantiConfig; - -/** - * Provides a user interface for configuring a game. - */ -public class AtlantiConfigurator extends TableGameConfigurator -{ - // documentation inherited - protected void createConfigInterface () - { - super.createConfigInterface(); - -// _boardSize = new SimpleSlider("Board size:", 16, 48, 32); -// add(_boardSize, VGroupLayout.FIXED); -// _handSize = new SimpleSlider("Hand size:", 2, 5, 5); -// add(_handSize, VGroupLayout.FIXED); - } - - // documentation inherited - protected void gotGameConfig () - { - super.gotGameConfig(); - _vconfig = (AtlantiConfig)_config; - -// // configure our elements -// _boardSize.setValue(_vconfig.boardWidth); -// _handSize.setValue(_vconfig.handSize); - } - - // documentation inherited - protected void flushGameConfig () - { - super.flushGameConfig(); - -// // configure our elements -// _vconfig.boardWidth = _boardSize.getValue(); -// _vconfig.boardHeight = _boardSize.getValue(); -// _vconfig.handSize = _handSize.getValue(); - } - - protected AtlantiConfig _vconfig; -// protected SimpleSlider _boardSize; -// protected SimpleSlider _handSize; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java deleted file mode 100644 index 4bf6e70e..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiController.java +++ /dev/null @@ -1,223 +0,0 @@ -// -// $Id - -package com.samskivert.atlanti.client; - -import java.awt.event.ActionEvent; -import com.samskivert.util.ListUtil; -import com.threerings.util.Name; - -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.DSet; -import com.threerings.presents.dobj.EntryAddedEvent; -import com.threerings.presents.dobj.EntryRemovedEvent; -import com.threerings.presents.dobj.EntryUpdatedEvent; -import com.threerings.presents.dobj.MessageEvent; -import com.threerings.presents.dobj.SetListener; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.client.PlaceView; - -import com.threerings.parlor.game.GameController; -import com.threerings.parlor.turn.TurnGameController; -import com.threerings.parlor.turn.TurnGameControllerDelegate; -import com.threerings.parlor.util.ParlorContext; - -import com.threerings.micasa.util.MiCasaContext; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.data.AtlantiCodes; -import com.samskivert.atlanti.data.AtlantiObject; -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.Piecen; -import com.samskivert.atlanti.util.TileUtil; - -/** - * The main coordinator of user interface activities on the client-side of - * the game. - */ -public class AtlantiController extends GameController - implements TurnGameController, AtlantiCodes, SetListener -{ - /** - * Creates our controller and prepares it for operation. - */ - public AtlantiController () - { - addDelegate(_delegate = new TurnGameControllerDelegate(this)); - } - - // documentation inherited - protected void didInit () - { - super.didInit(); - - // get a handle on our body object - _self = (BodyObject)_ctx.getClient().getClientObject(); - } - - // documentation inherited - protected PlaceView createPlaceView () - { - _panel = new AtlantiPanel((MiCasaContext)_ctx, this); - return _panel; - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - super.willEnterPlace(plobj); - - // get a casted reference to our game object - _venobj = (AtlantiObject)plobj; - - // find out what our index is and use that as our piecen color - _selfIndex = ListUtil.indexOfEqual(_venobj.players, _self.username); - if (_selfIndex != -1) { - // use our player index as the piecen color directly - _panel.board.setNewPiecenColor(_selfIndex); - } - - // grab the tiles and piecens from the game object and configure - // the board with them - _panel.board.setTiles(_venobj.tiles); - _panel.board.setPiecens(_venobj.piecens); - - // if it's our turn, set the tile to be placed - if (_delegate.isOurTurn()) { - _panel.board.setTileToBePlaced(_venobj.currentTile); - } - } - - // documentation inherited - public void turnDidChange (Name turnHolder) - { - // if it's our turn, set the tile to be placed - if (turnHolder.equals(_self.username)) { - _panel.board.setTileToBePlaced(_venobj.currentTile); - } - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - super.attributeChanged(event); - - // handle the setting of the board state - if (event.getName().equals(AtlantiObject.TILES)) { - _panel.board.setTiles(_venobj.tiles); - - } else if (event.getName().equals(AtlantiObject.PIECENS)) { - _panel.board.setPiecens(_venobj.piecens); - } - } - - // documentation inherited - public void entryAdded (EntryAddedEvent event) - { - // we care about additions to TILES and PIECENS - if (event.getName().equals(AtlantiObject.TILES)) { - // a tile was added, add it to the board - AtlantiTile tile = (AtlantiTile)event.getEntry(); - _panel.board.addTile(tile); - - } else if (event.getName().equals(AtlantiObject.PIECENS)) { - // a piecen was added, place it on the board - Piecen piecen = (Piecen)event.getEntry(); - _panel.board.placePiecen(piecen); - } - } - - // documentation inherited - public void entryUpdated (EntryUpdatedEvent event) - { - } - - // documentation inherited - public void entryRemoved (EntryRemovedEvent event) - { - if (event.getName().equals(AtlantiObject.PIECENS)) { - // a piecen was removed, update the board - _panel.board.clearPiecen(event.getKey()); - } - } - - // documentation inherited - public boolean handleAction (ActionEvent action) - { - if (action.getActionCommand().equals(TILE_PLACED)) { - AtlantiTile tile = _panel.board.getPlacedTile(); - - // the user placed the tile into a valid location. grab the - // placed tile from the board and submit it to the server - Object[] args = new Object[] { tile }; - MessageEvent mevt = new MessageEvent( - _venobj.getOid(), PLACE_TILE_REQUEST, args); - _ctx.getDObjectManager().postEvent(mevt); - - // if we have no piecens to place or if there are no unclaimed - // features on the placed tile, we immediately disable piecen - // placement in the board and expect that the server will end - // our turn - int pcount = TileUtil.countPiecens(_venobj.piecens, _selfIndex); - if (pcount >= PIECENS_PER_PLAYER || !tile.hasUnclaimedFeature()) { - _panel.board.cancelPiecenPlacement(); - _panel.noplace.setEnabled(false); - - } else { - // otherwise, enable the noplace button - _panel.noplace.setEnabled(true); - } - - } else if (action.getActionCommand().equals(PIECEN_PLACED)) { - // the user placed a piecen on the tile. grab the piecen from - // the placed tile and submit it to the server - Object[] args = new Object[] { - _panel.board.getPlacedTile().piecen }; - MessageEvent mevt = new MessageEvent( - _venobj.getOid(), PLACE_PIECEN_REQUEST, args); - _ctx.getDObjectManager().postEvent(mevt); - - // disable the noplace button - _panel.noplace.setEnabled(false); - - } else if (action.getActionCommand().equals(PLACE_NOTHING)) { - // turn off piecen placement in the board - _panel.board.cancelPiecenPlacement(); - - // the user doesn't want to place anything this turn. send a - // place nothing request to the server - MessageEvent mevt = new MessageEvent( - _venobj.getOid(), PLACE_NOTHING_REQUEST, null); - _ctx.getDObjectManager().postEvent(mevt); - - // disable the noplace button - _panel.noplace.setEnabled(false); - - } else if (action.getActionCommand().equals(BACK_TO_LOBBY)) { - // bail on out - _ctx.getLocationDirector().moveBack(); - - } else { - return super.handleAction(action); - } - - return true; - } - - /** Our turn game delegate. */ - protected TurnGameControllerDelegate _delegate; - - /** A reference to our game panel. */ - protected AtlantiPanel _panel; - - /** A reference to our game panel. */ - protected AtlantiObject _venobj; - - /** A reference to our body object. */ - protected BodyObject _self; - - /** Our player index or -1 if we're not a player. */ - protected int _selfIndex; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java deleted file mode 100644 index 081491c2..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/AtlantiPanel.java +++ /dev/null @@ -1,156 +0,0 @@ -// -// $Id - -package com.samskivert.atlanti.client; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Font; -import java.awt.Frame; - -import javax.swing.*; -import javax.swing.event.AncestorEvent; -import javax.swing.event.AncestorListener; - -import com.samskivert.swing.Controller; -import com.samskivert.swing.ControllerProvider; -import com.samskivert.swing.HGroupLayout; -import com.samskivert.swing.VGroupLayout; - -import com.threerings.media.image.ImageManager; -import com.threerings.media.tile.TileManager; -import com.threerings.resource.ResourceManager; - -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.client.PlaceView; - -import com.threerings.micasa.client.ChatPanel; -import com.threerings.micasa.util.MiCasaContext; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.data.AtlantiCodes; -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.util.PiecenUtil; - -/** - * The top-level user interface component for the game display. - */ -public class AtlantiPanel extends JPanel - implements PlaceView, ControllerProvider, AtlantiCodes -{ - /** A reference to the board that is accessible to the controller. */ - public AtlantiBoard board; - - /** A reference to our _noplace button. */ - public JButton noplace; - - /** - * Constructs a new game display. - */ - public AtlantiPanel (MiCasaContext ctx, AtlantiController controller) - { - // give ourselves a wee bit of a border - setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - HGroupLayout gl = new HGroupLayout(HGroupLayout.STRETCH); - gl.setOffAxisPolicy(HGroupLayout.STRETCH); - setLayout(gl); - - // create the board - board = new AtlantiBoard(); - - // create a scroll area to contain the board - JScrollPane scrolly = new JScrollPane(board); - add(scrolly); - - // create our side panel - VGroupLayout sgl = new VGroupLayout(VGroupLayout.STRETCH); - sgl.setOffAxisPolicy(VGroupLayout.STRETCH); - sgl.setJustification(VGroupLayout.TOP); - JPanel sidePanel = new JPanel(sgl); - - // add a big fat label because we love it! - JLabel vlabel = new JLabel("Atlantissonne!"); - vlabel.setFont(new Font("Helvetica", Font.BOLD, 24)); - vlabel.setForeground(Color.black); - sidePanel.add(vlabel, VGroupLayout.FIXED); - - // add a player info view to the side panel - sidePanel.add(new JLabel("Scores:"), VGroupLayout.FIXED); - sidePanel.add(new PlayerInfoView(), VGroupLayout.FIXED); - - // add a turn indicator to the side panel - sidePanel.add(new JLabel("Current turn:"), VGroupLayout.FIXED); - sidePanel.add(new TurnIndicatorView(), VGroupLayout.FIXED); - - // add a "place nothing" button - noplace = new JButton("Place nothing"); - noplace.setEnabled(false); - noplace.setActionCommand(PLACE_NOTHING); - noplace.addActionListener(Controller.DISPATCHER); - sidePanel.add(noplace, VGroupLayout.FIXED); - - // add a chat box - ChatPanel chat = new ChatPanel(ctx); - chat.removeSendButton(); - sidePanel.add(chat); - - // add a "back" button - JButton back = new JButton("Back to lobby"); - back.setActionCommand(BACK_TO_LOBBY); - back.addActionListener(Controller.DISPATCHER); - sidePanel.add(back, VGroupLayout.FIXED); - - // add our side panel to the main display - add(sidePanel, HGroupLayout.FIXED); - - // we'll need this later to provide it - _controller = controller; - } - - // documentation inherited - public void addNotify () - { - super.addNotify(); - - // we can't create our image manager until we have access to our - // containing frame - JRootPane rpane = getRootPane(); - ImageManager imgr = new ImageManager(_rmgr, rpane); - TileManager tmgr = new TileManager(imgr); - AtlantiTile.setManagers(imgr, tmgr); - PiecenUtil.init(tmgr); - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - Log.info("Panel entered place."); - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - Log.info("Panel left place."); - } - - // documentation inherited - public Controller getController () - { - return _controller; - } - - /** A reference to our controller that we need to implement the {@link - * ControllerProvider} interface. */ - protected AtlantiController _controller; - - // this stuff is all a bit of a hack right now. by all rights, the - // MiCasa game app should set up the resource manager, because it - // knows about that sort of stuff, and make it available via the - // MiCasa context and we may have some better place for the tile - // manager to live. but it's late and i want to get this working, so - // fooey. - - /** Our resource manager. */ - protected static ResourceManager _rmgr = new ResourceManager("rsrc"); -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/PlayerInfoView.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/PlayerInfoView.java deleted file mode 100644 index 84250460..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/PlayerInfoView.java +++ /dev/null @@ -1,170 +0,0 @@ -// -// $Id: PlayerInfoView.java,v 1.5 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.client; - -import java.awt.Color; -import java.awt.GridBagLayout; -import java.awt.GridBagConstraints; - -import javax.swing.JLabel; -import javax.swing.JPanel; - -import com.threerings.util.Name; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; -import com.threerings.presents.dobj.SetListener; -import com.threerings.presents.dobj.EntryAddedEvent; -import com.threerings.presents.dobj.EntryUpdatedEvent; -import com.threerings.presents.dobj.EntryRemovedEvent; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; - -import com.samskivert.atlanti.data.AtlantiCodes; -import com.samskivert.atlanti.data.AtlantiObject; -import com.samskivert.atlanti.data.Feature; -import com.samskivert.atlanti.util.TileUtil; - -/** - * Displays each of the players in the game, their piece color and their - * score. - */ -public class PlayerInfoView - extends JPanel - implements PlaceView, AttributeChangeListener, SetListener -{ - /** - * Constructs a new player info panel, ready for insertion into the - * game panel. - */ - public PlayerInfoView () - { - setLayout(new GridBagLayout()); - - // we don't add our player info until we know how many players are - // in the game (which we find out once we enter the game room) - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - // we want to grab a reference to the game object and add - // ourselves as an attribute change listener - _atlobj = (AtlantiObject)plobj; - _atlobj.addListener(this); - - // we need score and piecen labels arrays so that we can keep - // track of per player information - _scoreLabels = new JLabel[_atlobj.players.length]; - _piecenLabels = new JLabel[_atlobj.players.length]; - - // now that we're here, we can add an entry for every player - for (int i = 0; i < _atlobj.players.length; i++) { - addPlayer(i, _atlobj.players[i]); - } - - // if we have scores, update them - if (_atlobj.scores != null) { - updateScores(); - // and the piecen count - updatePiecenCount(); - } - } - - /** - * Adds a player to the display. - */ - protected void addPlayer (int idx, Name username) - { - GridBagConstraints c = new GridBagConstraints(); - - // create a label for their username - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1.0; // use up extra space on this label - JLabel unlabel = new JLabel(username.toString()); - unlabel.setForeground(Feature.PIECEN_COLOR_MAP[idx]); - add(unlabel, c); - - // create a label for their score - c.weightx = 0.0; // size label to its preferred width - c.ipadx = 5; // 5 pixels between this label and its neighbors - c.fill = GridBagConstraints.NONE; - _scoreLabels[idx] = new JLabel("0"); - _scoreLabels[idx].setForeground(Color.black); - add(_scoreLabels[idx], c); - - // create a label for their piecen count - c.gridwidth = GridBagConstraints.REMAINDER; - c.ipadx = 0; // turn off padding - _piecenLabels[idx] = new JLabel("(0)"); - _piecenLabels[idx].setForeground(Feature.PIECEN_COLOR_MAP[idx]); - add(_piecenLabels[idx], c); - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - // remove our listening self - _atlobj.removeListener(this); - _atlobj = null; - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - // we care about the scores (which change) - if (event.getName().equals(AtlantiObject.SCORES)) { - updateScores(); - } - } - - // documentation inherited - public void entryAdded (EntryAddedEvent event) - { - updatePiecenCount(); - } - - // documentation inherited - public void entryUpdated (EntryUpdatedEvent event) - { - } - - // documentation inherited - public void entryRemoved (EntryRemovedEvent event) - { - updatePiecenCount(); - } - - /** - * Reads the scores from the game object and updates the view. - */ - protected void updateScores () - { - for (int i = 0; i < _atlobj.scores.length; i++) { - _scoreLabels[i].setText(Integer.toString(_atlobj.scores[i])); - } - } - - /** - * Updates the count of remaining piecens for all of the players. - */ - protected void updatePiecenCount () - { - for (int i = 0; i < _atlobj.scores.length; i++) { - int pcount = TileUtil.countPiecens(_atlobj.piecens, i); - int pleft = AtlantiCodes.PIECENS_PER_PLAYER - pcount; - _piecenLabels[i].setText("(" + pleft + ")"); - } - } - - /** A reference to the game object. */ - protected AtlantiObject _atlobj; - - /** References to our score label components. */ - protected JLabel[] _scoreLabels; - - /** References to our piecen label components. */ - protected JLabel[] _piecenLabels; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/TileLabel.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/TileLabel.java deleted file mode 100644 index e87b4581..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/TileLabel.java +++ /dev/null @@ -1,53 +0,0 @@ -// -// $Id: TileLabel.java,v 1.2 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.client; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; - -import javax.swing.JComponent; - -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.TileCodes; - -/** - * Displays a single tile in a Swing component. - */ -public class TileLabel extends JComponent - implements TileCodes -{ - /** - * Configures the component to display the specified tile. - * - * @param tile a reference to the tile to display or null if no tile - * should be displayed. - */ - public void setTile (AtlantiTile tile) - { - _tile = tile; - repaint(); - } - - // documentation inherited - public void paintComponent (Graphics g) - { - super.paintComponent(g); - - // simply paint the tile if we have one - if (_tile != null) { - _tile.paint((Graphics2D)g, 0, 0); - } - } - - // documentation inherited - public Dimension getPreferredSize () - { - return new Dimension(TILE_WIDTH, TILE_HEIGHT); - } - - /** The tile we are displaying. */ - protected AtlantiTile _tile; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/client/TurnIndicatorView.java b/projects/atlanti/src/java/com/samskivert/atlanti/client/TurnIndicatorView.java deleted file mode 100644 index 83cb71c1..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/client/TurnIndicatorView.java +++ /dev/null @@ -1,140 +0,0 @@ -// -// $Id: TurnIndicatorView.java,v 1.5 2002/12/12 06:07:49 mdb Exp $ - -package com.samskivert.atlanti.client; - -import javax.swing.JLabel; -import javax.swing.JPanel; - -import com.samskivert.swing.VGroupLayout; - -import com.threerings.presents.dobj.AttributeChangeListener; -import com.threerings.presents.dobj.AttributeChangedEvent; - -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.client.PlaceView; - -import com.samskivert.atlanti.data.AtlantiObject; - -/** - * Displays who the current turn holder is as well as the tile they are - * currently placing. - */ -public class TurnIndicatorView extends JPanel - implements PlaceView, AttributeChangeListener -{ - /** - * Creates a new turn indicator view which in turn creates its - * subcomponents. - */ - public TurnIndicatorView () - { - setLayout(new VGroupLayout()); - - // add our turn holder display - _whoLabel = new JLabel(); - add(_whoLabel); - - // and add our tile display - _tileLabel = new TileLabel(); - add(_tileLabel); - - // and add a tile's remaining label - _countLabel = new JLabel(); - add(_countLabel); - } - - // documentation inherited - public void willEnterPlace (PlaceObject plobj) - { - // we want to grab a reference to the game object and add - // ourselves as an attribute change listener - _atlobj = (AtlantiObject)plobj; - _atlobj.addListener(this); - - // update our displays - updateCurrentTile(); - updateGameState(); - updateTurnHolder(); - updateRemainingTiles(); - } - - // documentation inherited - public void didLeavePlace (PlaceObject plobj) - { - // remove our listening self - _atlobj.removeListener(this); - _atlobj = null; - } - - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - if (event.getName().equals(AtlantiObject.CURRENT_TILE)) { - // update the current tile display - updateCurrentTile(); - - } else if (event.getName().equals(AtlantiObject.STATE)) { - // update the game state display - updateGameState(); - // update the tiles remaining - updateRemainingTiles(); - - } else if (event.getName().equals(AtlantiObject.TURN_HOLDER)) { - // update the turn holder - updateTurnHolder(); - - // update the tiles remaining when the turn changes - updateRemainingTiles(); - } - } - - protected void updateGameState () - { - switch (_atlobj.state) { - case AtlantiObject.AWAITING_PLAYERS: - _whoLabel.setText("Awaiting players..."); - _tileLabel.setTile(null); - break; - case AtlantiObject.GAME_OVER: - _whoLabel.setText("Game over."); - _tileLabel.setTile(null); - break; - case AtlantiObject.CANCELLED: - _whoLabel.setText("Cancelled."); - _tileLabel.setTile(null); - break; - } - } - - protected void updateTurnHolder () - { - if (_atlobj.state == AtlantiObject.IN_PLAY) { - _whoLabel.setText(_atlobj.turnHolder.toString()); - } - } - - protected void updateCurrentTile () - { - // display the tile to be placed - _tileLabel.setTile(_atlobj.currentTile); - } - - protected void updateRemainingTiles () - { - _countLabel.setText("Tiles remaining: " + - Math.max(71-_atlobj.tiles.size(), 0)); - } - - /** The label displaying whose turn it is. */ - protected JLabel _whoLabel; - - /** The label displaying the tile to be placed. */ - protected TileLabel _tileLabel; - - /** The label displaying the number of tiles remaining. */ - protected JLabel _countLabel; - - /** A reference to the game object. */ - protected AtlantiObject _atlobj; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java deleted file mode 100644 index d4c733e8..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiCodes.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $Id: AtlantiCodes.java,v 1.6 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -/** - * Constants used by the Atlanti game code. - */ -public interface AtlantiCodes -{ - /** The message bundle identifier for translation messages. */ - public static final String ATLANTI_MESSAGE_BUNDLE = "atlanti"; - - /** The number of piecens provided to each player. */ - public static final int PIECENS_PER_PLAYER = 7; - - /** The name of the command posted by the {@link AtlantiBoard} when - * the user places a tile into a valid position. */ - public static final String TILE_PLACED = "tile_placed"; - - /** The name of the command posted by the {@link AtlantiBoard} when - * the user places a piecen onto an unclaimed feature. */ - public static final String PIECEN_PLACED = "piecen_placed"; - - /** The name of the command posted by the "place nothing" button in - * the side bar. */ - public static final String PLACE_NOTHING = "place_nothing"; - - /** The message submitted by the client to the server when they have - * chosen where they wish to place their tile. */ - public static final String PLACE_TILE_REQUEST = "place_tile"; - - /** The message submitted by the client to the server when they have - * chosen where they wish to place their piecen. */ - public static final String PLACE_PIECEN_REQUEST = "place_piecen"; - - /** The message submitted by the client to the server when they decide - * that they don't want to (or can't) place any piecen this turn. */ - public static final String PLACE_NOTHING_REQUEST = "place_nothing"; - - /** The name of the command posted by the "Back to lobby" button in - * the side bar. */ - public static final String BACK_TO_LOBBY = "back_to_lobby"; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java deleted file mode 100644 index 9db45c9b..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiConfig.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// $Id: AtlantiConfig.java,v 1.4 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -import java.io.IOException; - -import com.threerings.io.ObjectInputStream; -import com.threerings.io.ObjectOutputStream; - -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.game.GameConfig; - -import com.samskivert.atlanti.client.AtlantiConfigurator; -import com.samskivert.atlanti.client.AtlantiController; - -/** - * Describes the configuration parameters for the game. - */ -public class AtlantiConfig extends GameConfig - implements TableConfig -{ - // documentation inherited - public Class getControllerClass () - { - return AtlantiController.class; - } - - // documentation inherited from interface - public Class getConfiguratorClass () - { - return AtlantiConfigurator.class; - } - - // documentation inherited - public String getManagerClassName () - { - return "com.samskivert.atlanti.server.AtlantiManager"; - } - - // documentation inherited - public int getMinimumPlayers () - { - return 2; - } - - // documentation inherited - public int getMaximumPlayers () - { - return 5; - } - - // documentation inherited - public int getDesiredPlayers () - { - return _desiredPlayers; - } - - // documentation inherited - public void setDesiredPlayers (int desiredPlayers) - { - _desiredPlayers = desiredPlayers; - } - - // documentation inherited - public void writeObject (ObjectOutputStream out) - throws IOException - { - out.defaultWriteObject(); - out.writeInt(_desiredPlayers); - } - - // documentation inherited - public void readObject (ObjectInputStream in) - throws IOException, ClassNotFoundException - { - in.defaultReadObject(); - _desiredPlayers = in.readInt(); - } - - /** The desired number of players for this game or -1 if there is no - * specific desired number of players. */ - protected int _desiredPlayers; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.dobj b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.dobj deleted file mode 100644 index 106a2104..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.dobj +++ /dev/null @@ -1,53 +0,0 @@ -// -// $Id: AtlantiObject.dobj,v 1.2 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -import com.threerings.presents.dobj.DSet; -import com.threerings.util.Name; - -import com.threerings.parlor.game.GameObject; -import com.threerings.parlor.turn.TurnGameObject; - -/** - * The distributed object used to maintain state for the game. - */ -public class AtlantiObject extends GameObject - implements TurnGameObject -{ - /** The username of the current turn holder. */ - public Name turnHolder; - - /** A set containing all of the tiles that are in play in this - * game. */ - public DSet tiles = new DSet(); - - /** The tile being placed by the current turn holder. This value is - * only valid while it is someone's turn. */ - public AtlantiTile currentTile = AtlantiTile.STARTING_TILE; - - /** A set containing all of the piecens that are placed on the - * board. */ - public DSet piecens = new DSet(); - - /** The scores for each player. */ - public int[] scores; - - // documentation inherited from interface - public Name[] getPlayers () - { - return players; - } - - // documentation inherited from interface - public String getTurnHolderFieldName () - { - return TURN_HOLDER; - } - - // documentation inherited from interface - public Name getTurnHolder () - { - return turnHolder; - } -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java deleted file mode 100644 index eff24e14..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiObject.java +++ /dev/null @@ -1,216 +0,0 @@ -// -// $Id: AtlantiObject.java,v 1.10 2003/03/23 02:22:51 mdb Exp $ - -package com.samskivert.atlanti.data; - -import com.threerings.presents.dobj.DSet; -import com.threerings.util.Name; - -import com.threerings.parlor.game.GameObject; -import com.threerings.parlor.turn.TurnGameObject; - -/** - * The distributed object used to maintain state for the game. - */ -public class AtlantiObject extends GameObject - implements TurnGameObject -{ - /** The field name of the turnHolder field. */ - public static final String TURN_HOLDER = "turnHolder"; - - /** The field name of the tiles field. */ - public static final String TILES = "tiles"; - - /** The field name of the currentTile field. */ - public static final String CURRENT_TILE = "currentTile"; - - /** The field name of the piecens field. */ - public static final String PIECENS = "piecens"; - - /** The field name of the scores field. */ - public static final String SCORES = "scores"; - - /** The username of the current turn holder. */ - public Name turnHolder; - - /** A set containing all of the tiles that are in play in this - * game. */ - public DSet tiles = new DSet(); - - /** The tile being placed by the current turn holder. This value is - * only valid while it is someone's turn. */ - public AtlantiTile currentTile = AtlantiTile.STARTING_TILE; - - /** A set containing all of the piecens that are placed on the - * board. */ - public DSet piecens = new DSet(); - - /** The scores for each player. */ - public int[] scores; - - // documentation inherited from interface - public Name[] getPlayers () - { - return players; - } - - // documentation inherited from interface - public String getTurnHolderFieldName () - { - return TURN_HOLDER; - } - - // documentation inherited from interface - public Name getTurnHolder () - { - return turnHolder; - } - - /** - * Requests that the turnHolder 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 setTurnHolder (Name turnHolder) - { - requestAttributeChange(TURN_HOLDER, turnHolder); - this.turnHolder = turnHolder; - } - - /** - * Requests that the specified entry be added to the - * tiles set. The set will not change until the event is - * actually propagated through the system. - */ - public void addToTiles (DSet.Entry elem) - { - requestEntryAdd(TILES, elem); - } - - /** - * Requests that the entry matching the supplied key be removed from - * the tiles set. The set will not change until the - * event is actually propagated through the system. - */ - public void removeFromTiles (Comparable key) - { - requestEntryRemove(TILES, key); - } - - /** - * Requests that the specified entry be updated in the - * tiles set. The set will not change until the event is - * actually propagated through the system. - */ - public void updateTiles (DSet.Entry elem) - { - requestEntryUpdate(TILES, elem); - } - - /** - * Requests that the tiles field be set to the - * specified value. Generally one only adds, updates and removes - * entries of a distributed set, but certain situations call for a - * complete replacement of the set 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 setTiles (DSet tiles) - { - requestAttributeChange(TILES, tiles); - this.tiles = tiles; - } - - /** - * Requests that the currentTile 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 setCurrentTile (AtlantiTile currentTile) - { - requestAttributeChange(CURRENT_TILE, currentTile); - this.currentTile = currentTile; - } - - /** - * Requests that the specified entry be added to the - * piecens set. The set will not change until the event is - * actually propagated through the system. - */ - public void addToPiecens (DSet.Entry elem) - { - requestEntryAdd(PIECENS, elem); - } - - /** - * Requests that the entry matching the supplied key be removed from - * the piecens set. The set will not change until the - * event is actually propagated through the system. - */ - public void removeFromPiecens (Comparable key) - { - requestEntryRemove(PIECENS, key); - } - - /** - * Requests that the specified entry be updated in the - * piecens set. The set will not change until the event is - * actually propagated through the system. - */ - public void updatePiecens (DSet.Entry elem) - { - requestEntryUpdate(PIECENS, elem); - } - - /** - * Requests that the piecens field be set to the - * specified value. Generally one only adds, updates and removes - * entries of a distributed set, but certain situations call for a - * complete replacement of the set 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 setPiecens (DSet piecens) - { - requestAttributeChange(PIECENS, piecens); - this.piecens = piecens; - } - - /** - * Requests that the scores 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 setScores (int[] scores) - { - requestAttributeChange(SCORES, scores); - this.scores = scores; - } - - /** - * Requests that the indexth element of - * scores 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 setScoresAt (int value, int index) - { - requestElementUpdate(SCORES, new Integer(value), index); - this.scores[index] = value; - } -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java deleted file mode 100644 index 4aa3412e..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/AtlantiTile.java +++ /dev/null @@ -1,536 +0,0 @@ -// -// $Id: AtlantiTile.java,v 1.17 2003/03/23 02:22:51 mdb Exp $ - -package com.samskivert.atlanti.data; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Polygon; - -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; - -import java.io.IOException; - -import java.util.List; -import com.samskivert.util.IntTuple; -import com.samskivert.util.StringUtil; - -import com.threerings.media.image.ImageManager; -import com.threerings.media.tile.Tile; -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.UniformTileSet; - -import com.threerings.io.ObjectInputStream; -import com.threerings.presents.dobj.DSet; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.util.FeatureUtil; -import com.samskivert.atlanti.util.PiecenUtil; -import com.samskivert.atlanti.util.TileUtil; - -/** - * Represents a single tile in play on the game board. - * - *

Note: this should really be split into a pure data class - * and an associated visualization class in the - * atlanti.client package. - */ -public class AtlantiTile - implements DSet.Entry, TileCodes, Cloneable, Comparable -{ - /** The starting tile. */ - public static final AtlantiTile STARTING_TILE = - new AtlantiTile(CITY_ONE_ROAD_STRAIGHT, false, NORTH, 0, 0); - - /** Activate this to render a piecen on every feature (useful for the - * tile geometry test). */ - public static boolean piecenDebug = false; - - /** The tile type. */ - public int type; - - /** Whether this tile has a shield on it. */ - public boolean hasShield; - - /** The tile's orientation. */ - public int orientation; - - /** The tile's x and y coordinates. */ - public int x, y; - - /** An array of claim group values that correspond to the features of - * this tile. If a piecen has claimed a feature on this tile or that - * connects to this tile, it will be represented here by a non-zero - * claim group in the array slot that corresponds to the claimed - * feature. */ - public transient int[] claims; - - /** A reference to our static feature descriptions. */ - public transient Feature[] features; - - /** A reference to the piecen on this tile or null if no piecen has - * been placed on this tile. */ - public transient Piecen piecen; - - /** - * Constructs a tile with all of the supplied tile information. - */ - public AtlantiTile (int type, boolean hasShield, int orientation, - int x, int y) - { - this.type = type; - this.hasShield = hasShield; - this.orientation = orientation; - this.x = x; - this.y = y; - - // initialize our feature info - initFeatures(); - } - - /** - * Constructs a tile with the type information set, but in the default - * NORTH orientation and with no position. - */ - public AtlantiTile (int type, boolean hasShield) - { - this(type, hasShield, NORTH, 0, 0); - } - - /** - * Constructs a blank tile, suitable for unserialization. - */ - public AtlantiTile () - { - // nothing doing - } - - /** - * Returns true if this tile has at leats one unclaimed feature. - */ - public boolean hasUnclaimedFeature () - { - boolean unclaimed = false; - for (int i = 0; i < claims.length; i++) { - unclaimed = (unclaimed || (claims[i] == 0)); - } - return unclaimed; - } - - /** - * Looks for a feature in this tile that matches the supplied feature - * edge mask and returns the index of that feature in this tile's - * {@link #claims} array. - * - * @return the index of the matching feature or -1 if no feature - * matched. - */ - public int getFeatureIndex (int edgeMask) - { - // translate the feature mask into our orientation - edgeMask = FeatureUtil.translateMask(edgeMask, -orientation); - - // look for a feature with a matching edge mask - for (int i = 0; i < features.length; i ++) { - if ((features[i].edgeMask & edgeMask) != 0) { - return i; - } - } - - // no match - return -1; - } - - /** - * Returns the index of the feature that contains the supplied mouse - * coordinates (which will have been translated relative to the tile's - * origin). - * - * @return the index of the feature that contains the mouse - * coordinates. Some feature should always contain the mouse. - */ - public int getFeatureIndex (int mouseX, int mouseY) - { - // we search our features in reverse order because road features - // overlap grass features geometrically and are known to be - // specified after the grass features - for (int i = features.length-1; i >= 0; i--) { - if (features[i].contains(mouseX, mouseY, orientation)) { - return i; - } - } - - // something is hosed; fake it - Log.warning("Didn't find matching feature for mouse coordinates!? " + - "[tile=" + this + ", mx=" + mouseX + - ", my=" + mouseY + "]."); - return 0; - } - - /** - * Looks for a feature in this tile that matches the supplied feature - * edge mask and returns the claim group to which that feature belongs - * (which may be zero). - * - * @return the claim group to which the feature that matches the - * supplied mask belongs, or zero if no feature matched the supplied - * mask. - */ - public int getFeatureGroup (int edgeMask) - { - int fidx = getFeatureIndex(edgeMask); - return fidx < 0 ? 0 : claims[fidx]; - } - - /** - * Sets the claim group for the feature with the specified index. This - * also updates the claim group for any piecen that was placed on that - * feature as well. - * - * @param featureIndex the index of the feature to update. - * @param claimGroup the claim group to associate with the feature. - */ - public void setClaimGroup (int featureIndex, int claimGroup) - { - // update the claim group slot for this feature - claims[featureIndex] = claimGroup; - - // if we have a piecen placed on the feature identified by this - // feature index, we need to update its claim group as well - if (piecen != null && piecen.featureIndex == featureIndex) { - piecen.claimGroup = claimGroup; - } - } - - /** - * Places the specified piecen on this tile. The {@link - * Piecen#featureIndex} field is assumed to be initialized to the - * feature index of this tile on which the piecen is to be placed. - * - *

Note that this will call {@link TileUtil#setClaimGroup} to - * propagate the claiming of this feature to all neighboring tiles if - * a non-null tiles array is supplied to the function. - * - * @param piecen the piecen to place on this tile (with an - * appropriately configured feature index). - * @param tiles a sorted list of all of the tiles on the board that - * we can use to propagate our new claim group to all features - * connected to this newly claimed feature or null if propagation of - * the claim group is not desired at this time. - */ - public void setPiecen (Piecen piecen, List tiles) - { - int claimGroup = 0; - - // if we're adding a piecen to a feature that's already claimed, - // we want to inherit the claim number (this could happen when we - // show up in an in progress game) - if (claims[piecen.featureIndex] != 0) { - Log.info("Requested to add a piecen to a feature " + - "that has already been claimed [tile=" + this + - ", piecen=" + piecen + "]. Inheriting."); - claimGroup = claims[piecen.featureIndex]; - - } else { - // otherwise we generate a new claim group - claimGroup = TileUtil.nextClaimGroup(); - Log.info("Creating claim group [cgroup=" + claimGroup + - ", tile=" + this + ", fidx=" + piecen.featureIndex + "]."); - } - - // keep a reference to this piecen and configure its position - this.piecen = piecen; - piecen.x = x; - piecen.y = y; - - // assign a brand spanking new claim group to the feature and the - // piecen and propagate it to neighboring features - if (tiles != null) { - TileUtil.setClaimGroup( - tiles, this, piecen.featureIndex, claimGroup); - // update our piecen with the claim group as well - piecen.claimGroup = claimGroup; - } - } - - /** - * Clears out any piecen reference that was previously set (does not - * clear out its associated claim group, however). - */ - public void clearPiecen () - { - piecen = null; - } - - /** - * Paints this tile to the specified graphics context at its assigned - * location, accounting for the supplied x and y offsets of the - * origin. - * - * @param g the graphics context to use when painting the tile. - * @param xoff the offset (in tile units) of the origin in the x - * direction. - * @param yoff the offset (in tile units) of the origin in the y - * direction. - */ - public void paint (Graphics2D g, int xoff, int yoff) - { - int tidx = type-1; - - // obtain our tile image - if (_tileImage == null) { - _tileImage = getTileImage(type); - } - - // compute our screen coordinates - int sx = (x + xoff) * TILE_WIDTH; - int sy = (y + yoff) * TILE_HEIGHT; - - // translate to our screen coordinates - g.translate(sx, sy); - - // render our tile image - if (_tileImage != null) { - if (orientation > 0) { - g.drawImage(_tileImage, _xforms[orientation], null); - } else { - g.drawImage(_tileImage, 0, 0, null); - } - - } else { - Log.warning("No tile image!? [type=" + type + - ", img=" + _tileImage + "]."); - } - -// // render our features -// for (int i = 0; i < features.length; i++) { -// // paint the feature -// features[i].paint(g, orientation, claims[i]); -// } - - // if we have a shield, draw a square in the lower right - if (hasShield) { - Point2D sspot = FeatureUtil.getShieldSpot(orientation); - Image image = getShieldImage(); - - if (image != null) { - int iwidth = image.getWidth(null); - int iheight = image.getHeight(null); - Composite ocomp = g.getComposite(); - g.setComposite(ALPHA_PLACING); - g.drawImage(image, (int)(sspot.getX() - iwidth/2), - (int)(sspot.getY() - iheight/2), null); - g.setComposite(ocomp); - - } else { - g.setColor(Color.orange); - g.drawRect((int)(sspot.getX()-5), - (int)(sspot.getY()-5), 10, 10); - } - } - - // if we have a piecen on this tile, render it as well - if (piecen != null || piecenDebug) { - for (int i = 0; i < features.length; i++) { - if (piecenDebug) { - Image pimg = PiecenUtil.getPiecenImage(0); - features[i].paintPiecen(g, orientation, pimg, 0); - - } else if (piecen.featureIndex == i) { - Image pimg = PiecenUtil.getPiecenImage(piecen.owner); - features[i].paintPiecen( - g, orientation, pimg, piecen.claimGroup); - } - } - } - -// // draw a rectangular outline -// g.setColor(Color.black); -// g.drawRect(0, 0, TILE_WIDTH-1, TILE_HEIGHT-1); - - // translate back out - g.translate(-sx, -sy); - } - - /** - * Returns a copy of this tile object. - */ - public Object clone () - { - return new AtlantiTile(type, hasShield, orientation, x, y); - } - - /** - * Used to order tiles (which is done by board position). - */ - public int compareTo (Object other) - { - // we will either be compared to another tile, to a piecen or to a - // coordinate object (int tuple) - if (other == null) { - return -1; - - } else if (other instanceof AtlantiTile) { - AtlantiTile tile = (AtlantiTile)other; - return (tile.x == x) ? y - tile.y : x - tile.x; - - } else if (other instanceof IntTuple) { - IntTuple coord = (IntTuple)other; - return (coord.left == x) ? y - coord.right : x - coord.left; - - } else if (other instanceof Piecen) { - Piecen piecen = (Piecen)other; - return (piecen.x == x) ? y - piecen.y : x - piecen.x; - - } else { - // who knows... - return -1; - } - } - - // documentation inherited - public boolean equals (Object other) - { - return (compareTo(other) == 0); - } - - // documentation inherited - public Comparable getKey () - { - // our key is our coordinates conflated into one integer - return new Integer((x + 128) * 256 + y + 128); - } - - /** - * After we've been unserialized we have to initialize some derived - * fields. - */ - public void readObject (ObjectInputStream in) - throws IOException, ClassNotFoundException - { - in.defaultReadObject(); - initFeatures(); - } - - /** - * Initializes this tile's feature management data structures. - */ - protected void initFeatures () - { - if (type > 0) { - // grab a reference to our feature information - features = FeatureUtil.getTileFeatures(type); - - // create our claims array - claims = new int[features.length]; - - } else { - Log.warning("Requested to init features without valid type " + - this + "."); - Thread.dumpStack(); - } - } - - /** - * Generates a string representation of this tile instance. - */ - public String toString () - { - return "[type=" + type + ", shield=" + hasShield + - ", orient=" + ORIENT_NAMES[orientation] + - ", pos=" + x + "/" + y + - ", claims=" + StringUtil.toString(claims) + - ", piecen=" + piecen + "]"; - } - - /** - * Someone needs to configure this so that we can display tiles on - * screen. - */ - public static void setManagers (ImageManager imgr, TileManager tmgr) - { - _imgr = imgr; - _tmgr = tmgr; - } - - /** - * Fetches the image for the tile of the specified type. - */ - protected static Image getTileImage (int type) - { - // load up the tile set if we haven't already - if (_tset == null) { - _tset = _tmgr.loadTileSet(TILES_IMG_PATH, - TILE_WIDTH, TILE_HEIGHT); - } - - // fetch the tile - return _tset.getRawTileImage(type-1); - } - - /** - * Fetches the shield image. - */ - protected static Image getShieldImage () - { - // load up the tile set if we haven't already - if (_stset == null) { - _stset = _tmgr.loadTileSet(SHIELD_IMG_PATH, - SHIELD_SIZE, SHIELD_SIZE); - } - - // fetch the tile - return _stset.getRawTileImage(0); - } - - /** The tile image that we use to render this tile. */ - protected transient Image _tileImage; - - /** Our image manager. */ - protected static ImageManager _imgr; - - /** Our tile manager. */ - protected static TileManager _tmgr; - - /** Our tile image tileset. */ - protected static UniformTileSet _tset; - - /** Our shield image tileset. */ - protected static UniformTileSet _stset; - - /** The path to our tileset image. */ - protected static final String TILES_IMG_PATH = "media/tiles.png"; - - /** The path to our shield image. */ - protected static final String SHIELD_IMG_PATH = "media/shield.png"; - - /** The size of the shield image (width and height). */ - protected static final int SHIELD_SIZE = 17; - - /** Three affine transforms for rendering an image in three rotated - * orientations. */ - protected static AffineTransform[] _xforms; - - static { - // the first element will be left blank - _xforms = new AffineTransform[4]; - - // create our three orientation transforms - AffineTransform xform = new AffineTransform(); - for (int orient = 1; orient < 4; orient++) { - // rotate the xform into the next orientation - xform.translate(TILE_WIDTH, 0); - xform.rotate(Math.PI/2); - // and save it - _xforms[orient] = (AffineTransform)xform.clone(); - } - } - - /** For rendering shields with alpha. */ - protected static final Composite ALPHA_PLACING = - AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f); -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/Feature.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/Feature.java deleted file mode 100644 index 541c5c01..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/Feature.java +++ /dev/null @@ -1,375 +0,0 @@ -// -// $Id: Feature.java,v 1.6 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.Shape; - -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Point2D; -import java.awt.geom.RoundRectangle2D; - -import com.samskivert.util.StringUtil; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.util.FeatureUtil; -import com.samskivert.atlanti.util.TileUtil; - -/** - * Represents all of the necessary information for a particular feature of - * a particular tile. - */ -public class Feature - implements TileCodes -{ - /** Maps piecen color codes to colors. */ - public static Color[] PIECEN_COLOR_MAP = { - new Color(0x0246B7), // BLUE - new Color(0x028A12), // GREEN - new Color(0xF47A02), // ORANGE - new Color(0xC20292), // MAGENTA - new Color(0xB90202), // RED - new Color(0xFECA11), // YELLOW - }; - - /** The type of this feature. */ - public int type; - - /** The edge mask associated with this feature. */ - public int edgeMask; - - /** The location at which a piecen on this feature would be drawn (for - * each of the four tile orientations. */ - public Point2D[] piecenSpots = new Point2D[4]; - - /** The polygons used to render and hit test this feature (one for - * each orientation). */ - public GeneralPath[] polys = new GeneralPath[4]; - - /** - * Constructs a feature with a feature description array containing - * all of the necessary feature information. - */ - public Feature (int[] desc) - { - type = desc[0]; - edgeMask = desc[1]; - - // fetch our natural piecen spot, scale it and adjust for half units - int px = (desc[2] * TILE_WIDTH) / 4; - if (px < 0) { - px *= -1; - px -= TILE_WIDTH/8; - } - int py = (desc[3] * TILE_HEIGHT) / 4; - if (py < 0) { - py *= -1; - py -= TILE_HEIGHT/8; - } - // oh, just a teeny hack for aesthetic shield placement - if (type == -1) { - px += 2; py += 2; - } - piecenSpots[NORTH] = new Point2D.Float(px, py); - - // create our natural feature polygon - if (type == ROAD) { - // roads are handled specially; they are either one or two - // segment roads - if (desc.length == 8) { - polys[NORTH] = roadSegmentToPolygon( - desc[4], desc[5], desc[6], desc[7]); - - } else if (desc.length == 10) { - polys[NORTH] = roadSegmentToPolygon( - desc[4], desc[5], desc[6], desc[7], desc[8], desc[9]); - - } else { - Log.warning("Feature constructed with bogus road geometry " + - "[desc=" + StringUtil.toString(desc) + "]."); - } - - } else { - GeneralPath poly = new GeneralPath(); - for (int i = 4; i < desc.length; i += 2) { - // scale the coords accordingly - int fx = (desc[i] * TILE_WIDTH) / 4; - int fy = (desc[i+1] * TILE_HEIGHT) / 4; - if (i == 4) { - poly.moveTo(fx, fy); - } else { - poly.lineTo(fx, fy); - } - } - poly.closePath(); - polys[NORTH] = poly; - } - - // now create the three other orientations - AffineTransform xform = new AffineTransform(); - for (int orient = 1; orient < 4; orient++) { - // rotate the xform into the next orientation - xform.translate(TILE_WIDTH, 0); - xform.rotate(Math.PI/2); - - // transform the polygon - polys[orient] = (GeneralPath)polys[NORTH].clone(); - polys[orient].transform(xform); - - // transform the piecen spot - piecenSpots[orient] = new Point2D.Float(); - xform.transform(piecenSpots[NORTH], piecenSpots[orient]); - } - } - - /** - * Returns true if the feature contains the supplied mouse coordinates - * (which should be relative to the tile origin) given the supplied - * orientation information. - */ - public boolean contains (int mouseX, int mouseY, int orientation) - { - return polys[orientation].contains(mouseX, mouseY); - } - - /** - * Paints this feature to the specified graphics context with the - * specified orientation, accounting for the supplied x and y offsets - * of the origin. The graphics context is assumed to be appropriately - * translated so that we may render this feature relative to the - * origin and have it painted in the proper place. - * - * @param g the graphics context to use when painting the feature. - * @param orientation the orientation at which to paint this feature. - * @param claimGroup the claim group to which this feature belongs (or - * zero if it belongs to no claim group). - */ - public void paint (Graphics2D g, int orientation, int claimGroup) - { - // set the color according to the claim group - g.setColor(claimGroup > 0 ? CLAIMED_COLOR_MAP[type] : - COLOR_MAP[type]); - - // now render the appropriate polygon for this orientation - g.fill(polys[orientation]); - -// // paint our features for debugging (they aren't rotated and thus -// // are only valid in the natural orientation) -// int w = TILE_WIDTH, hw = w/2, qw = hw/2, tqw = 3*qw; -// int h = TILE_HEIGHT, hh = h/2, qh = hh/2, tqh = 3*qh; -// g.setColor(Color.gray); - -// if ((edgeMask & FeatureUtil.NORTH_F) != 0) { -// g.drawLine(hw, 0, hw, qh); -// } -// if ((edgeMask & FeatureUtil.EAST_F) != 0) { -// g.drawLine(tqw, hh, w, hh); -// } -// if ((edgeMask & FeatureUtil.SOUTH_F) != 0) { -// g.drawLine(hw, tqh, hw, h); -// } -// if ((edgeMask & FeatureUtil.WEST_F) != 0) { -// g.drawLine(0, hh, qw, hh); -// } - -// if ((edgeMask & FeatureUtil.NNE_F) != 0) { -// g.drawLine(tqw, 0, tqw, qh); -// } -// if ((edgeMask & FeatureUtil.NNW_F) != 0) { -// g.drawLine(qw, 0, qw, qh); -// } -// if ((edgeMask & FeatureUtil.SSE_F) != 0) { -// g.drawLine(tqw, tqh, tqw, h); -// } -// if ((edgeMask & FeatureUtil.SSW_F) != 0) { -// g.drawLine(qw, tqh, qw, h); -// } - -// if ((edgeMask & FeatureUtil.ENE_F) != 0) { -// g.drawLine(tqw, qh, w, qh); -// } -// if ((edgeMask & FeatureUtil.ESE_F) != 0) { -// g.drawLine(tqw, tqh, w, tqh); -// } -// if ((edgeMask & FeatureUtil.WNW_F) != 0) { -// g.drawLine(0, qh, qw, qh); -// } -// if ((edgeMask & FeatureUtil.WSW_F) != 0) { -// g.drawLine(0, tqh, qw, tqh); -// } - } - - /** - * Paints a piecen in a position indicating that it is placed on this - * feature. The graphics context is assumed to be appropriately - * translated so that we may render this feature relative to the - * origin and have it painted in the proper place. - * - * @param g the graphics context to use when painting the feature. - * @param orientation the orientation at which to paint this feature. - * @param image the piecen image to be painted. - * @param claimGroup the claim group to which this piecen belongs (or - * zero if it belongs to no claim group). - */ - public void paintPiecen (Graphics2D g, int orientation, Image image, - int claimGroup) - { - Point2D point = piecenSpots[orientation]; - int iwidth = image.getWidth(null); - int iheight = image.getHeight(null); - - // render the piecen image slightly transparent - Composite ocomp = g.getComposite(); - g.setComposite(ALPHA_PLACING); - g.drawImage(image, (int)(point.getX() - iwidth/2), - (int)(point.getY() - iheight/2), null); - g.setComposite(ocomp); - -// // for now, draw the claim group next to the piecen -// g.drawString(Integer.toString(claimGroup), -// (float)(point.getX() - swidth/2 + 2), -// (float)(point.getY() - sheight/2 - 2)); - } - - /** - * Massages a road segment (specified in tile feature coordinates) - * into a polygon (in screen coordinates) that can be used to render - * or hit test the road. The coordinates must obey the following - * constraints: (x1 < x2 and y1 == y2) or (x1 == x2 and y1 < y2) or - * (x1 < x2 and y1 > y2). - * - * @return a polygon representing the road segment (with origin at 0, - * 0). - */ - protected static GeneralPath roadSegmentToPolygon ( - int x1, int y1, int x2, int y2) - { - // first convert the coordinates into screen coordinates - x1 = (x1 * TILE_WIDTH) / 4; - y1 = (y1 * TILE_HEIGHT) / 4; - x2 = (x2 * TILE_WIDTH) / 4; - y2 = (y2 * TILE_HEIGHT) / 4; - - GeneralPath poly = new GeneralPath(); - int dx = 4, dy = 4; - - // figure out what sort of line segment it is - if (x1 == x2) { // vertical - // make adjustments to ensure that we stay inside the tile - // bounds - if (y1 == 0) { - y1 += dy; - } - if (y2 == TILE_HEIGHT) { - y2 -= dy; - } - poly.moveTo(x1 - dx, y1 - dy); - poly.lineTo(x1 + dx, y1 - dy); - poly.lineTo(x2 + dx, y2 + dy); - poly.lineTo(x2 - dx, y2 + dy); - - } else if (y1 == y2) { // horizontal - // make adjustments to ensure that we stay inside the tile - // bounds - if (x1 == 0) { - x1 += dx; - } - if (x2 == TILE_WIDTH) { - x2 -= dx; - } - poly.moveTo(x1 - dx, y1 - dy); - poly.lineTo(x1 - dx, y1 + dy); - poly.lineTo(x2 + dx, y2 + dy); - poly.lineTo(x2 + dx, y2 - dy); - - } else { // diagonal - poly.moveTo(x1 - dx, y1); - poly.lineTo(x1 + dx, y1); - poly.lineTo(x2, y2 + dy); - poly.lineTo(x2, y2 - dy); - } - - poly.closePath(); - return poly; - } - - /** - * Massages a road segment (specified in tile feature coordinates) - * into a polygon (in screen coordinates) that can be used to render - * or hit test the road. The coordinates must obey the following - * constraints: (y1 == y2) and (y2 > y3) and (x2 == x3). - * - * @return a polygon representing the road segment (with origin at 0, - * 0). - */ - protected static GeneralPath roadSegmentToPolygon ( - int x1, int y1, int x2, int y2, int x3, int y3) - { - // first convert the coordinates into screen coordinates - x1 = (x1 * TILE_WIDTH) / 4; - y1 = (y1 * TILE_HEIGHT) / 4; - x2 = (x2 * TILE_WIDTH) / 4; - y2 = (y2 * TILE_HEIGHT) / 4; - x3 = (x3 * TILE_WIDTH) / 4; - y3 = (y3 * TILE_HEIGHT) / 4; - - GeneralPath poly = new GeneralPath(); - int dx = 4, dy = 4; - - // figure out what sort of road segment it is - if (x1 < x2) { // left turn - poly.moveTo(x1, y1-dy); - poly.lineTo(x2+dx, y2-dy); - poly.lineTo(x3+dx, y3); - poly.lineTo(x3-dx, y3); - poly.lineTo(x2-dx, y2+dy); - poly.lineTo(x1, y1+dy); - - } else { // right turn - poly.moveTo(x1, y1-dy); - poly.lineTo(x2-dx, y2-dy); - poly.lineTo(x3-dx, y3); - poly.lineTo(x3+dx, y3); - poly.lineTo(x2+dx, y2+dy); - poly.lineTo(x1, y1+dy); - } - - poly.closePath(); - return poly; - } - - /** - * Generates a string representation of this feature. - */ - public String toString () - { - return "[type=" + FeatureUtil.typeToString(type) + - ", edgeMask=" + FeatureUtil.edgeMaskToString(edgeMask) + "]"; - } - - /** Maps feature types to colors. */ - protected static Color[] COLOR_MAP = { - Color.red, // CITY - Color.green, // GRASS - Color.black, // ROAD - Color.yellow // CLOISTER - }; - - /** Maps feature types to colors for claimed features. */ - protected static Color[] CLAIMED_COLOR_MAP = { - Color.red.darker(), // CITY - Color.green.darker(), // GRASS - Color.darkGray, // ROAD - Color.yellow.darker(), // CLOISTER - }; - - /** For rendering piecens with alpha. */ - protected static final Composite ALPHA_PLACING = - AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/Piecen.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/Piecen.java deleted file mode 100644 index 66f4692d..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/Piecen.java +++ /dev/null @@ -1,133 +0,0 @@ -// -// $Id: Piecen.java,v 1.4 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -import java.io.IOException; -import java.io.DataInputStream; -import java.io.DataOutputStream; - -import com.threerings.presents.dobj.DSet; - -/** - * A piecen is a person and a piece all rolled into one! Players can play - * a single piecen on a tile feature as a part of their turn and that - * piecen then claims that feature and all of the features that are - * connected to it forming a claim group. Once a group of features has - * been claimed, no further piecens can be placed on the group. Note, - * however, that two or more separately claimed feature groups can be - * joined by placing a tile that connects the previously disconnected - * groups together. In that case, the groups are merged into a single - * claim group and all the piecens that were part of the disparate groups - * become claimees in the new group. At scoring time, the player with the - * most piecens in a group gets the points for the group. If two or more - * players have equal numbers of piecens in a group, they each get the - * points for the group. - */ -public class Piecen - implements DSet.Entry -{ - /** A color constant. */ - public static final int RED = 0; - - /** A color constant. */ - public static final int BLACK = 1; - - /** A color constant. */ - public static final int BLUE = 2; - - /** A color constant. */ - public static final int YELLOW = 3; - - /** A color constant. */ - public static final int GREEN = 4; - - /** The owner of this piecen. */ - public int owner; - - /** The x and y coordinates of the tile on which this piecen is - * placed. */ - public int x, y; - - /** The index in the tile's feature array of the feature on which this - * piecen is placed. */ - public int featureIndex; - - /** The claim group to which this piecen belongs. */ - public int claimGroup; - - /** - * Construts a piecen with the specified configuration. - */ - public Piecen (int owner, int x, int y, int featureIndex) - { - this.owner = owner; - this.x = x; - this.y = y; - this.featureIndex = featureIndex; - } - - /** - * Constructs a blank piecen, suitable for unserialization. - */ - public Piecen () - { - } - - // documentation inherited - public Comparable getKey () - { - // our key is our coordinates conflated into one integer - return new Integer((x + 128) * 256 + y + 128); - } - - // documentation inherited - public void writeTo (DataOutputStream out) - throws IOException - { - out.writeInt(owner); - out.writeInt(x); - out.writeInt(y); - out.writeInt(featureIndex); - } - - // documentation inherited - public void readFrom (DataInputStream in) - throws IOException - { - owner = in.readInt(); - x = in.readInt(); - y = in.readInt(); - featureIndex = in.readInt(); - } - - // documentation inherited - public boolean equals (Object other) - { - // we will either be compared to a tile or to a piecen - if (other == null) { - return false; - - } else if (other instanceof AtlantiTile) { - AtlantiTile tile = (AtlantiTile)other; - return (tile.x == x) ? (y == tile.y) : false; - - } else if (other instanceof Piecen) { - Piecen piecen = (Piecen)other; - return (piecen.x == x) ? (y == piecen.y) : false; - - } else { - // who knows... - return false; - } - } - - /** - * Generates a string representation of this piecen. - */ - public String toString () - { - return "[owner=" + owner + ", pos=" + x + "/" + y + - ", feat=" + featureIndex + ", claim=" + claimGroup + "]"; - } -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java b/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java deleted file mode 100644 index c558a994..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/data/TileCodes.java +++ /dev/null @@ -1,127 +0,0 @@ -// -// $Id: TileCodes.java,v 1.10 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.data; - -/** - * A repository for constants related to the tiles that are used in the - * game of Atlantissonne. - */ -public interface TileCodes -{ - /** A four-sided city tile. */ - public static final int CITY_FOUR = 1; - - /** A three-sided city tile. */ - public static final int CITY_THREE = 2; - - /** A three-sided city tile with a road. */ - public static final int CITY_THREE_ROAD = 3; - - /** A two-sided city tile with city openings adjacent to one - * another. */ - public static final int CITY_TWO = 4; - - /** A two-sided city tile with city openings adjacent to one another - * and a road connecting the other two sides. */ - public static final int CITY_TWO_ROAD = 5; - - /** A two-sided city tile with city openings on opposite sides of the - * tile. */ - public static final int CITY_TWO_ACROSS = 6; - - /** A two-sided city tile with two separate city arcs adjacent to one - * another and not connected to each other. */ - public static final int TWO_CITY_TWO = 7; - - /** A two-sided city tile with two separate city arcs on opposite - * sides of the tile. */ - public static final int TWO_CITY_TWO_ACROSS = 8; - - /** A one-sided city tile. */ - public static final int CITY_ONE = 9; - - /** A one-sided city tile with a city arc on top and a right facing - * curved road segment beneath it. */ - public static final int CITY_ONE_ROAD_RIGHT = 10; - - /** A one-sided city tile with a city arc on top and a left facing - * curved road segment beneath it. */ - public static final int CITY_ONE_ROAD_LEFT = 11; - - /** A one-sided city tile with a city arc on top and a road tee - * beneath it. */ - public static final int CITY_ONE_ROAD_TEE = 12; - - /** A one-sided city tile with a city arc on top and straight road - * segment beneath it. */ - public static final int CITY_ONE_ROAD_STRAIGHT = 13; - - /** A cloister tile. */ - public static final int CLOISTER_PLAIN = 14; - - /** A cloister tile with a road extending from the cloister. */ - public static final int CLOISTER_ROAD = 15; - - /** A four-way road intersection. */ - public static final int FOUR_WAY_ROAD = 16; - - /** A three-way road intersection. */ - public static final int THREE_WAY_ROAD = 17; - - /** A straight road segment. */ - public static final int STRAIGHT_ROAD = 18; - - /** A curved road segment. */ - public static final int CURVED_ROAD = 19; - - /** The number of different tile types. */ - public static final int TILE_TYPES = 19; - - - /** A tile orientation constant indicating the tile is in its default - * orientation. */ - public static final int NORTH = 0; - - /** A tile orientation constant indicating the tile is rotated 90 - * degrees clockwise from its default orientation. */ - public static final int EAST = 1; - - /** A tile orientation constant indicating the tile is rotated 180 - * degrees clockwise from its default orientation. */ - public static final int SOUTH = 2; - - /** A tile orientation constant indicating the tile is rotated 270 - * degrees clockwise from its default orientation. */ - public static final int WEST = 3; - - /** A mapping from orientation codes to a string representation. */ - public static final String[] ORIENT_NAMES = { "N", "E", "S", "W" }; - - - /** The tile image width in pixels. */ - public static int TILE_WIDTH = 64; - - /** The tile image height in pixels. */ - public static int TILE_HEIGHT = 64; - - - /** A tile edge constant indicating a city edge. */ - public static final int CITY = 0; - - /** A tile edge constant indicating a grass edge. */ - public static final int GRASS = 1; - - /** A tile edge constant indicating a road edge. */ - public static final int ROAD = 2; - - /** A constant indicating a cloister. */ - public static final int CLOISTER = 3; - - /** Human readable names to go along with the feature constants. */ - public static final String[] FEATURE_NAMES = { - "island", "fishery", "boardwalk", "temple" }; - - /** A flag used to mark a tile as part of a completed city. */ - public static final int COMPLETED_CITY = 0x01; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java b/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java deleted file mode 100644 index 1570427f..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManager.java +++ /dev/null @@ -1,763 +0,0 @@ -// -// $Id: AtlantiManager.java,v 1.26 2004/08/28 02:17:06 mdb Exp $ - -package com.samskivert.atlanti.server; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import com.samskivert.util.HashIntMap; -import com.samskivert.util.StringUtil; - -import com.threerings.presents.dobj.EntryAddedEvent; -import com.threerings.presents.dobj.EntryRemovedEvent; -import com.threerings.presents.dobj.EntryUpdatedEvent; -import com.threerings.presents.dobj.DSet; -import com.threerings.presents.dobj.SetListener; -import com.threerings.presents.dobj.MessageEvent; - -import com.threerings.presents.dobj.MessageEvent; - -import com.threerings.crowd.chat.server.SpeakProvider; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.crowd.server.PlaceManager; - -import com.threerings.parlor.game.GameManager; -import com.threerings.parlor.turn.TurnGameManager; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.data.AtlantiCodes; -import com.samskivert.atlanti.data.AtlantiObject; -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.Feature; -import com.samskivert.atlanti.data.Piecen; -import com.samskivert.atlanti.data.TileCodes; -import com.samskivert.atlanti.util.FeatureUtil; -import com.samskivert.atlanti.util.TileUtil; - -/** - * The main coordinator of the Atlantissonne game on the server side. - */ -public class AtlantiManager extends GameManager - implements TurnGameManager, AtlantiCodes, SetListener -{ - public AtlantiManager () - { - addDelegate(_delegate = new AtlantiManagerDelegate(this)); - } - - // documentation inherited - protected Class getPlaceObjectClass () - { - return AtlantiObject.class; - } - - public int getTilesInBox () - { - return _tilesInBox.size(); - } - - // documentation inherited - public void didInit () - { - super.didInit(); - - // register our message handlers - registerMessageHandler(PLACE_TILE_REQUEST, new PlaceTileHandler()); - registerMessageHandler( - PLACE_PIECEN_REQUEST, new PlacePiecenHandler()); - registerMessageHandler( - PLACE_NOTHING_REQUEST, new PlaceNothingHandler()); - } - - // documentation inherited - public void didStartup () - { - super.didStartup(); - - // grab our own casted game object reference - _atlobj = (AtlantiObject)_gameobj; - } - - /** - * In preparation for starting the game, we clear out the tile set and - * put the starting tile into place. - */ - protected void gameWillStart () - { - super.gameWillStart(); - - // generate a shuffled tile list - _tilesInBox = TileUtil.getStandardTileSet(); - Collections.shuffle(_tilesInBox); - -// // shave off most of the tiles for the moment -// while (_tilesInBox.size() > 15) { -// _tilesInBox.remove(0); -// } - - // clear out our board tiles - _tiles.clear(); - - // create a claim group vector - _claimGroupVector = new int[getPlayerCount()]; - - // clear out the scores - _atlobj.setScores(new int[getPlayerCount()]); - - // clear out the tile and piecen set - _atlobj.setTiles(new DSet()); - _atlobj.setPiecens(new DSet()); - - // and add the starting tile - AtlantiTile start = TileUtil.getStartingTile(); - _atlobj.addToTiles(start); - _tiles.add(start); - } - - // documentation inherited - public void turnWillStart () - { - // let the players know what the next tile is that should be - // played - AtlantiTile tile = (AtlantiTile)_tilesInBox.remove(0); - _atlobj.setCurrentTile(tile); - } - - // documentation inherited - public void turnDidStart () - { - // nothing doing - } - - // documentation inherited - public void turnDidEnd () - { - // if there are no tiles left, we end the game - if (_tilesInBox.size() == 0) { - endGame(); - } - } - - /** - * At the end of the game, we need to compute the final scores. - */ - protected void gameDidEnd () - { - super.gameDidEnd(); - - // compute the final scores by iterating over each tile and - // scoring its features - Piecen[] piecens = getPiecens(); - Iterator iter = _atlobj.tiles.entries(); - while (iter.hasNext()) { - AtlantiTile tile = (AtlantiTile)iter.next(); - scoreFeatures(tile, piecens, true); - } - - // lastly, we have to score the farms (cue the ominous drums)... - scoreFarms(); - - // update the final scores - _atlobj.setScores(_atlobj.scores); - } - - /** - * Creates an array of piecens based on the contents of the piecens - * set in the game object, suitable for passing to {@link - * #scoreFeatures}. - */ - protected Piecen[] getPiecens () - { - // create a piecen array that we can manipulate while scoring - Piecen[] piecens = new Piecen[_atlobj.piecens.size()]; - Iterator iter = _atlobj.piecens.entries(); - for (int i = 0; iter.hasNext(); i++) { - piecens[i] = (Piecen)iter.next(); - } - return piecens; - } - - /** - * Scores the features on this tile. - * - * @param tile the tile whose features should be scored. - * @param piecens an array of the pieces on the board which we can - * manipulate directly without having to wait for entry removed - * events to be dispatched. - * @param finalTally during the final tally, we score differently and - * we don't remove piecens from the board as we score them. - */ - protected void scoreFeatures ( - AtlantiTile tile, Piecen[] piecens, boolean finalTally) - { - // potentially score all features on the tile - for (int i = 0; i < tile.features.length; i++) { - // we only need to worry about ROAD and CITY features because - // those are the only features on this tile that we might have - // completed - Feature f = tile.features[i]; - if (f.type != TileCodes.CITY && f.type != TileCodes.ROAD) { - continue; - } - - // see if any piecens are even on a feature in this group - int cgroup = tile.claims[i]; - int[] cgv = getClaimGroupVector(cgroup, piecens); - if (cgv == null) { - // if not, we don't have anything to score -// Log.info("Not scoring unclaimed feature " + -// "[ttype=" + tile.type + ", feat=" + f + -// ", cgroup=" + cgroup + "]."); - continue; - } - - // we do have something to score, so we compute the score for - // this feature - int score = TileUtil.computeFeatureScore(_tiles, tile, i); - - // if the score is positive, it's a completed feature and we - // score it regardless, we score incomplete features only - // during the final tally - if (score > 0 || finalTally) { - String qual = (score > 0) ? "Completed" : "Incomplete"; - - // convert the score into a positive value - score = Math.abs(score); - - // adjust and report the scores - StringBuffer names = new StringBuffer(); - for (int p = 0; p < cgv.length; p++) { - // adjust the score - _atlobj.scores[p] += (score * cgv[p]); - - // append the scorers name to the list - if (cgv[p] > 0) { - if (names.length() > 0) { - names.append(", "); - } - names.append(getPlayerName(p)); - } - } - - String message = qual + " " + TileCodes.FEATURE_NAMES[f.type] + - " scored " + score + " points for " + names + "."; - SpeakProvider.sendInfo( - _atlobj, ATLANTI_MESSAGE_BUNDLE, message); - - Log.info("New scores: " + StringUtil.toString(_atlobj.scores)); - - // broadcast the new scores if this isn't the final tally - if (!finalTally) { - _atlobj.setScores(_atlobj.scores); - } - - // and free up the scored piecens - removePiecens(cgroup, piecens, finalTally); - - } else { -// Log.info("Not scoring incomplete feature " + -// "[ttype=" + tile.type + ", feat=" + f + -// ", score=" + score + "]."); - } - } - - // we also may have completed a cloister, so we check that as well - for (int dx = -1; dx < 2; dx++) { - for (int dy = -1; dy < 2; dy++) { - // find our neighbor and make sure they exist - AtlantiTile neighbor = - TileUtil.findTile(_tiles, tile.x + dx, tile.y + dy); - if (neighbor == null) { - continue; - } - - // scan their features arrays for claimed cloisters - for (int i = 0; i < neighbor.features.length; i++) { - Feature f = neighbor.features[i]; - Piecen p = neighbor.piecen; - - // is a cloister - if (f.type != TileCodes.CLOISTER) { - continue; - } - - // tile has a piecen - if (p == null) { -// Log.info("Skipping non-piecen having " + -// "cloister tile [tile=" + neighbor + -// ", feat=" + f + "]."); - continue; - } - - // piecen is on cloister feature - if (neighbor.claims[i] != p.claimGroup) { -// Log.info("Skipping cloister tile with piecen on " + -// "non-cloister [tile=" + neighbor + -// ", feat=" + f + "]."); - continue; - } - - // score the cloister - int score = TileUtil.computeFeatureScore( - _tiles, neighbor, i); - - // if it's completed or if we're doing the final - // tally, we score it - if (score > 0 || finalTally) { - String qual = (score > 0) ? - "complete" : "incomplete"; - - // coerce the score into positive land - score = Math.abs(score); - - // deliver a chat notification to tell the - // players about the score - String message = getPlayerName(p.owner) + " scored " + - score + " points for " + qual + " temple."; - SpeakProvider.sendInfo( - _atlobj, ATLANTI_MESSAGE_BUNDLE, message); - - // add the score to the owning player - _atlobj.scores[p.owner] += score; - - // only broadcast the updated scores if this isn't - // the final tally - if (!finalTally) { - _atlobj.setScores(_atlobj.scores); - } - - // and clear out the piecen (only removing it from - // the piecen set if we're not in the final tally) - removePiecen(p, !finalTally); - } - } - } - } - } - - /** - * Scores the farms, which is the final act of scoring. - */ - protected void scoreFarms () - { - HashIntMap cities = new HashIntMap(); - int[] cityScores = new int[getPlayerCount()]; - - // clear out the claims for incompleted cities and claim unclaimed - // completed cities - TileUtil.prepCitiesForScoring(_tiles); - - // do the big process-ola - int tsize = _tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)_tiles.get(i); - - // iterate over all of the city features in this tile - for (int f = 0; f < tile.features.length; f++) { - // get the claim group for this feature - int cityClaim = tile.claims[f]; - - // skip unclaimed and non-city features - if (tile.features[f].type != TileCodes.CITY || - cityClaim == 0) { - continue; - } - - // get the list associated with this claim group - int[] claims = (int[])cities.get(cityClaim); - if (claims == null) { - // create a claim vector if we've not got one. if a - // city had 35 separately claimed farms around it, all - // the piecens in the game would be in play and the - // city would not have been claimed which would be an - // extremely pathological case, but we love pathology - // (especially when we don't have a resizable int list - // class handy) - claims = new int[35]; - cities.put(cityClaim, claims); - } - - // iterate over all of the grass features that are - // connected to city features on this tile and add their - // claim groups the list for this city feature - int[] grasses = FeatureUtil.CITY_GRASS_MAP[tile.type-1]; - for (int g = 0; g < grasses.length; g++) { - int farmClaim = tile.claims[grasses[g]]; - - // only worry about claimed grass regions - if (farmClaim == 0) { - Log.info("Ignoring unclaimed farm group " + - "[tile=" + tile + - ", fidx=" + grasses[g] + "]."); - continue; - } - - // and the farm claim group to the list - for (int c = 0; c < claims.length; c++) { - // don't add the farm claim twice - if (claims[c] == farmClaim) { - break; - } else if (claims[c] == 0) { - claims[c] = farmClaim; - Log.info("Noting city/farm abuttal " + - "[tile=" + tile + - ", cityClaim=" + cityClaim + - ", farmClaim=" + farmClaim + "]."); - break; - } - } - } - } - } - - // now for each city, we look to see who has the most piecens that - // are connected to the city by farms - Iterator iter = cities.keys(); - while (iter.hasNext()) { - int cityClaim = ((Integer)iter.next()).intValue(); - int[] farmClaims = (int[])cities.get(cityClaim); - int[] pcount = new int[getPlayerCount()]; - int max = 0; - - Iterator piter = _atlobj.piecens.entries(); - while (piter.hasNext()) { - Piecen p = (Piecen)piter.next(); - // see if the piecen is on any of the farms - for (int c = 0; c < farmClaims.length; c++) { - if (p.claimGroup == farmClaims[c]) { - Log.info("Counting piecen [cityClaim=" + cityClaim + - ", farmClaim=" + farmClaims[c] + - ", piecen=" + p + "]."); - // increment their count and track the max - if (max < ++pcount[p.owner]) { - max = pcount[p.owner]; - } - } - } - } - - Log.info("Counted city [cityClaim=" + cityClaim + - ", counts=" + StringUtil.toString(pcount) + "]."); - - // ignore this city if no one has any farmers nearby - if (max == 0) { - continue; - } - - // now score four points for every player that has the max - for (int i = 0; i < pcount.length; i++) { - if (pcount[i] == max) { - Log.info("Scoring city for player [cgroup=" + cityClaim + - ", player=" + getPlayerName(i) + - ", pcount=" + pcount[i] + "]."); - cityScores[i] += 4; - } - } - } - - // now report the scoring and transfer the counts to the score - // array - for (int i = 0; i < getPlayerCount(); i++) { - if (cityScores[i] > 0) { - _atlobj.scores[i] += cityScores[i]; - String message = getPlayerName(i) + " scores " + - cityScores[i] + " points for fisheries."; - SpeakProvider.sendInfo( - _atlobj, ATLANTI_MESSAGE_BUNDLE, message); - } - } - } - - /** - * Returns an int array with zeros and ones in the appropriate places - * so that a score can be multiplied by a player's position in the - * vector to determine whether or not they receive any points for the - * scoring of a particular claim group. - * - *

Note that this function returns a static (to this instance) - * vector, so it cannot be called again without overwriting values - * returned previously. - * - * @param claimGroup the claim group that we're scoring. - * @param piecens an array to use when looking for matching piecens. - * - * @return an array for the specified claim group or null if no - * players have a piecen claiming the specified claim group. - */ - protected int[] getClaimGroupVector (int claimGroup, Piecen[] piecens) - { - // clear out the vector - Arrays.fill(_claimGroupVector, 0); - - // iterate over the piecens - int max = 0; - for (int i = 0; i < piecens.length; i++) { - Piecen piecen = piecens[i]; - if (piecen == null) { - continue; - } else if (piecen.claimGroup == claimGroup) { - // color == player index... somewhat sketchy - if (++_claimGroupVector[piecen.owner] > max) { - // keep track of the highest scorer - max = _claimGroupVector[piecen.owner]; - } - } - } - - // now cut out everyone with scores less than the highest score - for (int i = 0; i < _claimGroupVector.length; i++) { - _claimGroupVector[i] = (_claimGroupVector[i] < max) ? 0 : 1; - } - - return (max == 0) ? null : _claimGroupVector; - } - - /** - * Removes piecens either from the supplied array or from the game - * object piecen set if no array is supplied. - */ - protected void removePiecens (int claimGroup, Piecen[] piecens, - boolean finalTally) - { - // we always clear the piecens from the array - for (int i = 0; i < piecens.length; i++) { - if (piecens[i] == null) { - continue; - } else if (piecens[i].claimGroup == claimGroup) { - piecens[i] = null; - } - } - - // if this isn't the final tally, we also clear 'em from the board - if (!finalTally) { - Object[] pvec = _atlobj.piecens.toArray(null); - for (int ii = 0; ii < pvec.length; ii++) { - Piecen p = (Piecen)pvec[ii]; - if (p.claimGroup == claimGroup) { - removePiecen(p, true); - } - } - } - } - - /** - * Removes the piecen from the board and optionally removes it from - * the piecen set. - * - * @param piecen the piecen to be removed. - * @param removeFromPiecens if true, the piecen will also be removed - * from the piecens set in the game object. - */ - protected void removePiecen (Piecen piecen, boolean removeFromPiecens) - { - // locate the tile that contains this piecen - int tidx = _tiles.indexOf(piecen); - if (tidx == -1) { - Log.warning("Requested to remove piecen that is not " + - "associated with any tile [piecen=" + piecen + "]."); - } else { - AtlantiTile tile = (AtlantiTile)_tiles.get(tidx); - // and clear the piecen - tile.clearPiecen(); - } - - // also remove from the piecens dset if requested - if (removeFromPiecens) { - _atlobj.removeFromPiecens(piecen.getKey()); - } - } - - // documentation inherited - public void entryAdded (EntryAddedEvent event) - { - // we react to piecen additions by potentially scoring the placed - // piecen. we allow the piecen to be added to the piecens set - // before scoring so that the players can see the piecen pop up on - // their screen and then disappear with a scoring notice rather - // than never show up at all; plus it simplifies our code - if (event.getName().equals(AtlantiObject.PIECENS)) { - Piecen piecen = (Piecen)event.getEntry(); - - // make sure this is a valid placement - AtlantiTile tile = (AtlantiTile)_atlobj.tiles.get(piecen.getKey()); - if (tile == null) { - Log.warning("Can't find tile for piecen scoring " + - piecen + "."); - - } else { - // check to see if we added the piecen to a completed - // feature, in which case we score and remove it - scoreFeatures(tile, getPiecens(), false); - } - - // now that we've scored the piecen, we can end the turn - _delegate.endTurn(); - } - } - - // documentation inherited - public void entryUpdated (EntryUpdatedEvent event) - { - } - - // documentation inherited - public void entryRemoved (EntryRemovedEvent event) - { - } - - /** - * Called when the user requests to place a tile. - */ - protected void handlePlaceTileRequest (MessageEvent event) - { - AtlantiTile tile = (AtlantiTile)event.getArgs()[0]; - int pidx = _delegate.getTurnHolderIndex(); - - // make sure it's this player's turn - if (_playerOids[pidx] != event.getSourceOid()) { - Log.warning("Requested to place tile by non-turn holder " + - "[event=" + event + - ", turnHolder=" + _atlobj.turnHolder + "]."); - - // make sure this is a valid placement - } else if (TileUtil.isValidPlacement(_tiles, tile)) { - // add the tile to the list and resort it - _tiles.add(tile); - Collections.sort(_tiles); - - // inherit its claim groups - TileUtil.inheritClaims(_tiles, tile); - - // add the tile to the tiles set - _atlobj.addToTiles(tile); - - // placing a piece may have completed road or city - // features. if it did, we score them now - scoreFeatures(tile, getPiecens(), false); - - Log.info("Placed tile " + tile + "."); - - // if the player has no free piecens or if there are no - // unclaimed features on this tile, we end their turn - // straight away - int pcount = TileUtil.countPiecens(_atlobj.piecens, pidx); - if (pcount >= PIECENS_PER_PLAYER || - !tile.hasUnclaimedFeature()) { - _delegate.endTurn(); - } - - } else { - Log.warning("Received invalid placement " + event + "."); - } - } - - /** - * Called when the user requests to place a piecen. - */ - protected void handlePlacePiecenRequest (MessageEvent event) - { - Piecen piecen = (Piecen)event.getArgs()[0]; - AtlantiTile tile = (AtlantiTile)_atlobj.tiles.get(piecen.getKey()); - int pidx = _delegate.getTurnHolderIndex(); - int pcount = TileUtil.countPiecens(_atlobj.piecens, pidx); - - // make sure it's this player's turn - if (_playerOids[pidx] != event.getSourceOid()) { - Log.warning("Requested to place piecen by non-turn holder " + - "[event=" + event + - ", turnHolder=" + _atlobj.turnHolder + "]."); - - // do some checking before we place the piecen - } else if (pcount >= PIECENS_PER_PLAYER) { - Log.warning("Requested to place piecen for player that " + - "has all of their piecens in play " + - "[event=" + event + "]."); - - } else if (tile == null) { - Log.warning("Can't find tile for requested piecen " + - "placement " + piecen + "."); - - } else if (tile.claims[piecen.featureIndex] != 0) { - Log.warning("Requested to place piecen on claimed feature " + - "[tile=" + tile + ", piecen=" + piecen + "]."); - - } else { - // otherwise stick the piece in the tile to update the - // claim groups - tile.setPiecen(piecen, _tiles); - - // and add the piecen to the game object. when we receive - // the piecen added event, we'll score it and then end the - // turn - _atlobj.addToPiecens(piecen); - } - } - - /** - * Called when the user requests to forgo their piecen placement for - * this turn. - */ - protected void handlePlaceNothingRequest (MessageEvent event) - { - int pidx = _delegate.getTurnHolderIndex(); - if (_playerOids[pidx] != event.getSourceOid()) { - Log.warning("Requested to place nothing by non-turn holder " + - "[event=" + event + - ", turnHolder=" + _atlobj.turnHolder + "]."); - - } else { - // player doesn't want to place anything, so we just end - // the turn - _delegate.endTurn(); - } - } - - /** Handles place tile requests. */ - protected class PlaceTileHandler implements MessageHandler - { - public void handleEvent (MessageEvent event, PlaceManager pmgr) - { - handlePlaceTileRequest(event); - } - } - - /** Handles place piecen requests. */ - protected class PlacePiecenHandler implements MessageHandler - { - public void handleEvent (MessageEvent event, PlaceManager pmgr) - { - handlePlacePiecenRequest(event); - } - } - - /** Handles place nothing requests. */ - protected class PlaceNothingHandler implements MessageHandler - { - public void handleEvent (MessageEvent event, PlaceManager pmgr) - { - handlePlaceNothingRequest(event); - } - } - - /** Our turn game delegate. */ - protected AtlantiManagerDelegate _delegate; - - /** A casted reference to our Atlanti game object. */ - protected AtlantiObject _atlobj; - - /** The (shuffled) list of tiles remaining to be played in this - * game. */ - protected List _tilesInBox; - - /** A sorted list of the tiles that have been placed on the board. */ - protected List _tiles = new ArrayList(); - - /** Used to score features groups. */ - protected int[] _claimGroupVector; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManagerDelegate.java b/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManagerDelegate.java deleted file mode 100644 index 75c436c5..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/server/AtlantiManagerDelegate.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $Id: AtlantiManagerDelegate.java,v 1.2 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.server; - -import com.threerings.parlor.turn.TurnGameManagerDelegate; - -import com.samskivert.atlanti.data.AtlantiCodes; - -/** - * Handles the turn-based gameplay. - */ -public class AtlantiManagerDelegate extends TurnGameManagerDelegate - implements AtlantiCodes -{ - /** - * Constructs the delegate and prepares it for operation. - */ - public AtlantiManagerDelegate (AtlantiManager vmgr) - { - super(vmgr); - _amgr = vmgr; - } - - /** - * Continue the game until we're out of tiles. - */ - protected void setNextTurnHolder () - { - // if we have tiles left, we move to the next player as normal - if (_amgr.getTilesInBox() > 0) { - super.setNextTurnHolder(); - } else { - // if we don't, we ensure that a new turn isn't started by - // setting _turnIdx to -1 - _turnIdx = -1; - } - } - - /** The manager for whom we're delegating. */ - protected AtlantiManager _amgr; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/util/FeatureUtil.java b/projects/atlanti/src/java/com/samskivert/atlanti/util/FeatureUtil.java deleted file mode 100644 index a29ea464..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/util/FeatureUtil.java +++ /dev/null @@ -1,400 +0,0 @@ -// -// $Id: FeatureUtil.java,v 1.6 2002/12/12 05:51:54 mdb Exp $ - -package com.samskivert.atlanti.util; - -import java.awt.geom.Point2D; - -import com.samskivert.atlanti.data.Feature; -import com.samskivert.atlanti.data.TileCodes; - -/** - * Feature related constants and utility functions. - */ -public class FeatureUtil implements TileCodes -{ - /** Bit mask for a north connecting feature. */ - public static final int NORTH_F = 0x1 << 0; - - /** Bit mask for an east connecting feature. */ - public static final int EAST_F = 0x1 << 1; - - /** Bit mask for a south connecting feature. */ - public static final int SOUTH_F = 0x1 << 2; - - /** Bit mask for a west connecting feature. */ - public static final int WEST_F = 0x1 << 3; - - /** Bit mask for a north by northeast connecting feature. */ - public static final int NNE_F = 0x1 << 4; - - /** Bit mask for an east by northeast connecting feature. */ - public static final int ENE_F = 0x1 << 5; - - /** Bit mask for an east by southeast connecting feature. */ - public static final int ESE_F = 0x1 << 6; - - /** Bit mask for a south by southeast connecting feature. */ - public static final int SSE_F = 0x1 << 7; - - /** Bit mask for a south by southwest connecting feature. */ - public static final int SSW_F = 0x1 << 8; - - /** Bit mask for a west by southwest connecting feature. */ - public static final int WSW_F = 0x1 << 9; - - /** Bit mask for a west by northwest connecting feature. */ - public static final int WNW_F = 0x1 << 10; - - /** Bit mask for a north by northwest connecting feature. */ - public static final int NNW_F = 0x1 << 11; - - /** A mapping from feature edge masks to tile directions and - * corresponding feature edge masks. */ - public static final int[] ADJACENCY_MAP = new int[] { - NORTH_F, NORTH, SOUTH_F, - EAST_F, EAST, WEST_F, - SOUTH_F, SOUTH, NORTH_F, - WEST_F, WEST, EAST_F, - NNW_F, NORTH, SSW_F, - NNE_F, NORTH, SSE_F, - ENE_F, EAST, WNW_F, - ESE_F, EAST, WSW_F, - SSE_F, SOUTH, NNE_F, - SSW_F, SOUTH, NNW_F, - WSW_F, WEST, ESE_F, - WNW_F, WEST, ENE_F, - }; - - /** A mapping for city tiles to the grass features that are adjacent - * to the city tiles. */ - public static final int[][] CITY_GRASS_MAP = new int[][] { - { }, - { 1 }, // CITY_THREE - { 1, 2 }, // CITY_THREE_ROAD - { 1 }, // CITY_TWO - { 1 }, // CITY_TWO_ROAD - { 1, 2 }, // CITY_TWO_ROAD_ACROSS - { 0 }, // TWO_CITY_TWO - { 0 }, // TWO_CITY_TWO_ACROSS - { 0 }, // CITY_ONE - { 0 }, // CITY_ONE_ROAD_RIGHT - { 0 }, // CITY_ONE_ROAD_LEFT - { 0 }, // CITY_ONE_ROAD_TEE - { 0 }, // CITY_ONE_ROAD_STRAIGHT - { }, - { }, - { }, - { }, - { }, - { }, - }; - - /** - * Returns the feature array for the tile of the specified type. - */ - public static Feature[] getTileFeatures (int type) - { - // create the features array - Feature[] features = new Feature[TILE_FEATURES[type-1].length]; - - // initialize it with features from the repeated feature table or - // with newly constructed features - for (int i = 0; i < features.length; i++) { - int[] desc = TILE_FEATURES[type-1][i]; - // if the description is a length one array, it is the index - // into the reused feature table of the desired feature - if (desc.length == 1) { - features[i] = _reusedFeatures[desc[0]]; - } else { - // otherwise it is the description of this unique feature - features[i] = new Feature(desc); - } - } - - return features; - } - - /** - * Returns the position of the shield on a tile of the given - * orientation. - */ - public static Point2D getShieldSpot (int orientation) - { - return _shieldFeature.piecenSpots[orientation]; - } - - /** - * Returns a string describing the supplied type code. - */ - public static String typeToString (int type) - { - return TYPE_CODES[type]; - } - - /** - * Returns a string describing the supplied edge mask. - */ - public static String edgeMaskToString (int edgeMask) - { - StringBuffer buf = new StringBuffer(); - if ((edgeMask & NORTH_F) != 0) buf.append("NORTH_F|"); - if ((edgeMask & EAST_F) != 0) buf.append("EAST_F|"); - if ((edgeMask & SOUTH_F) != 0) buf.append("SOUTH_F|"); - if ((edgeMask & WEST_F) != 0) buf.append("WEST_F|"); - if ((edgeMask & NNW_F) != 0) buf.append("NNW_F|"); - if ((edgeMask & NNE_F) != 0) buf.append("NNE_F|"); - if ((edgeMask & SSW_F) != 0) buf.append("SSW_F|"); - if ((edgeMask & SSE_F) != 0) buf.append("SSE_F|"); - if ((edgeMask & WNW_F) != 0) buf.append("WNW_F|"); - if ((edgeMask & WSW_F) != 0) buf.append("WSW_F|"); - if ((edgeMask & ENE_F) != 0) buf.append("ENE_F|"); - if ((edgeMask & ESE_F) != 0) buf.append("ESE_F|"); - // strip off the trailing bar if there is one - if (buf.length() > 0) { - buf.deleteCharAt(buf.length()-1); - } - return buf.toString(); - } - - /** - * Translates the feature edge mask into the orientation specified. - * For a forward translation, provide a positive valued orientation - * constant. For a backward translation, provide a negative valued - * orientation constant. - * - * @return the translated feature mask. - */ - public static int translateMask (int featureMask, int orientation) - { - int[] map = FEATURE_ORIENT_MAP[0]; - if ((featureMask & (NNE_F|ESE_F|SSW_F|WNW_F)) != 0) { - map = FEATURE_ORIENT_MAP[1]; - } else if ((featureMask & (ENE_F|SSE_F|WSW_F|NNW_F)) != 0) { - map = FEATURE_ORIENT_MAP[2]; - } - return xlateMask(map, featureMask, orientation); - } - - /** {@link #translateMask} helper function. */ - protected static int xlateMask ( - int[] map, int featureMask, int orientation) - { - int index = 0; - for (int i = 0; i < map.length; i++) { - if (map[i] == featureMask) { - return map[(i + 4 + orientation) % 4]; - } - } - return featureMask; - } - - /** A reused feature identifier. */ - protected static final int NESW_CITY = 0; - - /** A reused feature identifier. */ - protected static final int NEW_CITY = 1; - - /** A reused feature identifier. */ - protected static final int EW_CITY = 2; - - /** A reused feature identifier. */ - protected static final int NW_CITY = 3; - - /** A reused feature identifier. */ - protected static final int N_CITY = 4; - - /** A reused feature identifier. */ - protected static final int E_CITY = 5; - - /** A reused feature identifier. */ - protected static final int W_CITY = 6; - - /** A reused feature identifier. */ - protected static final int E_ROAD = 7; - - /** A reused feature identifier. */ - protected static final int S_ROAD = 8; - - /** A reused feature identifier. */ - protected static final int W_ROAD = 9; - - /** A reused feature identifier. */ - protected static final int S_GRASS = 10; - - /** A reused feature identifier. */ - protected static final int SE_GRASS = 11; - - /** A reused feature identifier. */ - protected static final int SW_GRASS = 12; - - /** An array of features used more than once. */ - protected static final int[][] FEATURES = new int[][] { - { CITY, NORTH_F|EAST_F|SOUTH_F|WEST_F, // NESW_CITY - 2,2, 0,0, 4,0, 4,4, 0,4 }, - { CITY, NORTH_F|EAST_F|WEST_F, // NEW_CITY - 2,2, 0,0, 4,0, 4,4, 3,3, 1,3, 0,4 }, - { CITY, EAST_F|WEST_F, // EW_CITY - 2,2, 0,0, 1,1, 3,1, 4,0, 4,4, 3,3, 1,3, 0,4 }, - { CITY, NORTH_F|WEST_F, // NW_CITY - 1,2, 0,0, 4,0, 0,4 }, - { CITY, NORTH_F, // N_CITY - 2,-1, 0,0, 1,1, 3,1, 4,0 }, - { CITY, EAST_F, // E_CITY - -4,2, 4,0, 3,1, 3,3, 4,4 }, - { CITY, WEST_F, // W_CITY - -1,2, 0,0, 1,1, 1,3, 0,4 }, - { ROAD, EAST_F, // E_ROAD - 3,2, 2,2, 4,2 }, - { ROAD, SOUTH_F, // S_ROAD - 2,3, 2,2, 2,4 }, - { ROAD, WEST_F, // W_ROAD - 1,2, 0,2, 2,2 }, - { GRASS, SOUTH_F, // S_GRASS - 2,-4, 0,4, 1,3, 3,3, 4,4 }, - { GRASS, ESE_F|SSE_F, // SE_GRASS - -4,-4, 2,2, 4,2, 4,4, 2,4 }, - { GRASS, WSW_F|SSW_F, // SW_GRASS - -1,-4, 0,2, 2,2, 2,4, 0,4 }, - }; - - /** A feature that is used to obtain the position information for - * rendering shields on city tiles that use shields. */ - protected static final int[] SHIELD_FEATURE = new int[] - { -1, NORTH_F|WEST_F, -1,-1, 0,0, 4,0, 0,4 }; - - /** A table describing the features of each tile. */ - protected static final int[][][] TILE_FEATURES = new int[][][] { - // one must offset tile type by one when indexing into this array - - { { NESW_CITY } }, // CITY_FOUR - - { { NEW_CITY }, // CITY_THREE - { S_GRASS } }, - - { { NEW_CITY }, // CITY_THREE_ROAD - { GRASS, SSW_F, 1,-4, 0,4, 1,3, 2,3, 2,4 }, - { GRASS, SSE_F, 3,-4, 2,4, 2,3, 3,3, 4,4 }, - { ROAD, SOUTH_F, 2,-4, 2,3, 2,4 } }, - - { { NW_CITY }, // CITY_TWO - { GRASS, EAST_F|SOUTH_F, 3,-4, 0,4, 4,0, 4,4 } }, - - { { NW_CITY }, // CITY_TWO_ROAD - { GRASS, ENE_F|SSW_F, -3,-2, 0,4, 4,0, 4,2, 2,4 }, - { GRASS, ESE_F|SSE_F, -4,-4, 2,4, 4,2, 4,4 }, - { ROAD, EAST_F|SOUTH_F, 3,3, 2,4, 4,2 } }, - - { { EW_CITY }, // CITY_TWO_ACROSS - { GRASS, NORTH_F, 2,-1, 0,0, 1,1, 3,1, 4,0 }, - { S_GRASS } }, - - { { GRASS, WEST_F|SOUTH_F, // TWO_CITY_TWO - -1,-3, 0,0, 4,0, 4,4, 0,4 }, - { CITY, NORTH_F, - 2,-1, 0,0, 2,1, 4,0 }, - { CITY, EAST_F, - -4,2, 4,0, 3,2, 4,4 } }, - - { { GRASS, NORTH_F|SOUTH_F, // TWO_CITY_TWO_ACROSS - 2,-4, 0,0, 4,0, 3,1, 3,3, 4,4, 0,4, 1,3, 1,1 }, - { W_CITY }, - { E_CITY } }, - - { { GRASS, EAST_F|SOUTH_F|WEST_F, // CITY_ONE - 2,-3, 0,0, 1,1, 3,1, 4,0, 4,4, 0,4 }, - { N_CITY } }, - - { { GRASS, ENE_F|SSW_F|WEST_F, // CITY_ONE_ROAD_RIGHT - 1,2, 0,0, 1,1, 3,1, 4,0, 4,2, 2,2, 2,4, 0,4 }, - { SE_GRASS }, - { ROAD, EAST_F|SOUTH_F, 3,2, 4,2, 2,2, 2,4 }, - { N_CITY } }, - - { { GRASS, EAST_F|SSE_F|WNW_F, // CITY_ONE_ROAD_LEFT - 3,2, 0,0, 1,1, 3,1, 4,0, 4,4, 2,4, 2,2, 0,2 }, - { SW_GRASS }, - { ROAD, SOUTH_F|WEST_F, 1,2, 0,2, 2,2, 2,4 }, - { N_CITY } }, - - { { GRASS, ENE_F|WNW_F, // CITY_ONE_ROAD_TEE - -1,1, 0,0, 1,1, 3,1, 4,0, 4,2, 0,2 }, - { SE_GRASS }, - { SW_GRASS }, - { E_ROAD }, - { S_ROAD }, - { W_ROAD }, - { N_CITY } }, - - { { GRASS, ENE_F|WNW_F, // CITY_ONE_ROAD_STRAIGHT - -1,1, 0,0, 1,1, 3,1, 4,0, 4,2, 0,2 }, - { GRASS, ESE_F|SOUTH_F|WSW_F, 2,3, 0,2, 4,2, 4,4, 0,4 }, - { ROAD, EAST_F|WEST_F, 2,2, 0,2, 4,2 }, - { N_CITY } }, - - { { GRASS, NORTH_F|EAST_F|SOUTH_F|WEST_F, // CLOISTER_PLAIN - -1,-1, 0,0, 4,0, 4,4, 0,4 }, - { CLOISTER, 0, 2,2, 1,1, 3,1, 3,3, 1,3 } }, - - { { GRASS, NORTH_F|EAST_F|WEST_F|SSE_F|SSW_F, // CLOISTER_ROAD - -1,-1, 0,0, 4,0, 4,4, 0,4 }, - { CLOISTER, 0, 2,2, 1,1, 3,1, 3,3, 1,3 }, - { ROAD, SOUTH_F, 2,-4, 2,3, 2,4 } }, - - { { GRASS, WNW_F|NNW_F, // FOUR_WAY_ROAD - -1,-1, 0,0, 2,0, 2,2, 0,2 }, - { GRASS, NNE_F|ENE_F, -4,-1, 2,0, 4,0, 4,2, 2,2 }, - { SE_GRASS }, - { SW_GRASS }, - { ROAD, NORTH_F, 2,1, 2,0, 2,2 }, - { E_ROAD }, - { S_ROAD }, - { W_ROAD } }, - - { { GRASS, WNW_F|NORTH_F|ENE_F, // THREE_WAY_ROAD - 2,-1, 0,0, 4,0, 4,2, 0,2 }, - { SE_GRASS }, - { SW_GRASS }, - { E_ROAD }, - { S_ROAD }, - { W_ROAD } }, - - { { GRASS, NNW_F|WEST_F|SSW_F, // STRAIGHT_ROAD - -1,2, 0,0, 2,0, 2,4, 0,4 }, - { GRASS, SSE_F|EAST_F|NNE_F, -4,2, 2,0, 4,0, 4,4, 2,4 }, - { ROAD, NORTH_F|SOUTH_F, 2,2, 2,0, 2,4 } }, - - { { GRASS, WNW_F|NORTH_F|EAST_F|SSE_F, // CURVED_ROAD - 3,1, 0,0, 4,0, 4,4, 2,4, 2,2, 0,2 }, - { SW_GRASS }, - { ROAD, SOUTH_F|WEST_F, 1,2, 0,2, 2,2, 2,4 } }, - }; - - /** Mapping table used to rotate feature facements. */ - protected static final int[][] FEATURE_ORIENT_MAP = new int[][] { - // orientations rotate through one of three four-cycles - { NORTH_F, EAST_F, SOUTH_F, WEST_F }, - { NNE_F, ESE_F, SSW_F, WNW_F }, - { ENE_F, SSE_F, WSW_F, NNW_F }, - }; - - /** String representations of the feature type codes. */ - protected static final String[] TYPE_CODES = { - "CITY", "GRASS", "ROAD", "CLOISTER" }; - - /** A table of features that are used on more than one tile. */ - protected static Feature[] _reusedFeatures; - - /** The feature that provides the location information for shield - * rendering. */ - protected static Feature _shieldFeature; - - // create our reused features table - static { - _reusedFeatures = new Feature[FEATURES.length]; - for (int i = 0; i < FEATURES.length; i++) { - _reusedFeatures[i] = new Feature(FEATURES[i]); - } - _shieldFeature = new Feature(SHIELD_FEATURE); - } -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/util/PiecenUtil.java b/projects/atlanti/src/java/com/samskivert/atlanti/util/PiecenUtil.java deleted file mode 100644 index b1a29f46..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/util/PiecenUtil.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $Id: PiecenUtil.java,v 1.4 2003/03/23 02:22:51 mdb Exp $ - -package com.samskivert.atlanti.util; - -import java.awt.Image; - -import com.threerings.media.tile.Tile; -import com.threerings.media.tile.TileManager; -import com.threerings.media.tile.UniformTileSet; - -public class PiecenUtil -{ - /** - * Loads up the piecen images using the supplied tile manager. - */ - public static void init (TileManager tmgr) - { - UniformTileSet piecenSet = tmgr.loadTileSet( - PIECEN_IMG_PATH, PIECEN_WIDTH, PIECEN_HEIGHT); - _images = new Image[PIECEN_TYPES]; - for (int i = 0; i < PIECEN_TYPES; i++) { - _images[i] = piecenSet.getRawTileImage(i); - } - } - - /** - * Returns the piecen image for the specified piecen color. - */ - public static Image getPiecenImage (int color) - { - return _images[color]; - } - - /** Our piecen images. */ - protected static Image[] _images; - - /** The number of different colors of piecen. */ - protected static final int PIECEN_TYPES = 6; - - /** The width of the piecen image in pixels. */ - protected static final int PIECEN_WIDTH = 16; - - /** The height of the piecen image in pixels. */ - protected static final int PIECEN_HEIGHT = 16; - - /** The path to the piecen image (relative to the resource - * directory). */ - protected static final String PIECEN_IMG_PATH = "media/piecens.png"; -} diff --git a/projects/atlanti/src/java/com/samskivert/atlanti/util/TileUtil.java b/projects/atlanti/src/java/com/samskivert/atlanti/util/TileUtil.java deleted file mode 100644 index 40969af8..00000000 --- a/projects/atlanti/src/java/com/samskivert/atlanti/util/TileUtil.java +++ /dev/null @@ -1,734 +0,0 @@ -// -// $Id: TileUtil.java,v 1.17 2002/12/12 05:51:55 mdb Exp $ - -package com.samskivert.atlanti.util; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import com.samskivert.util.IntTuple; - -import com.threerings.presents.dobj.DSet; - -import com.samskivert.atlanti.Log; -import com.samskivert.atlanti.data.AtlantiTile; -import com.samskivert.atlanti.data.Feature; -import com.samskivert.atlanti.data.Piecen; -import com.samskivert.atlanti.data.TileCodes; - -/** - * Utility functions relating to the Atlantissonne tiles. - */ -public class TileUtil implements TileCodes -{ - /** - * Returns an instance of the starting tile (properly cloned so that - * it can be messed with by the server). - */ - public static AtlantiTile getStartingTile () - { - return (AtlantiTile)AtlantiTile.STARTING_TILE.clone(); - } - - /** - * Returns a list containing the standard tile set for the - * Atlantissonne game. The list is a clone, so it can be bent, folded - * and modified by the caller. - */ - public static List getStandardTileSet () - { - // we need to deep copy the default tile set, so we can't just use - // clone - List tiles = new ArrayList(); - int tsize = TILE_SET.size(); - for (int i = 0; i < tsize; i++) { - tiles.add(((AtlantiTile)TILE_SET.get(i)).clone()); - } - return tiles; - } - - /** - * Scans the supplied tile set to determine which of the four - * orientations of the supplied target tile would result in a valid - * placement of that tile (valid placement meaning that all of its - * edges match up with neighboring tiles, it abuts at least one tile - * and it does not occupy the same space as any existing tile). The - * position of the target tile is assumed to be the desired placement - * position and the current orientation of the target tile is ignored. - * - * @param tiles a list of the tiles on the board. - * @param target the tile whose valid orientations we wish to compute. - * - * @return an array of boolean values indicating whether or not the - * tile can be placed in each of the cardinal directions (which match - * up with the direction constants specified in {@link TileCodes}. - */ - public static boolean[] computeValidOrients ( - List tiles, AtlantiTile target) - { - // this contains a count of tiles that match up with the candidate - // tile in each of its four orientations - int[] matches = new int[4]; - - int tsize = tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)tiles.get(i); - - // figure out where this tile is in relation to the candidate - int xdiff = tile.x - target.x; - int ydiff = tile.y - target.y; - int sum = Math.abs(xdiff) + Math.abs(ydiff); - - if (sum == 0) { - // they overlap, nothing doing - return new boolean[4]; - - } else if (sum == 1) { - // they're neighbors, we may have a match - int targetEdge = EDGE_MAP[(ydiff+1)*3 + xdiff+1]; - - // we want the edge of the placed tile that matches up - // with the tile in the candidate location, but we also - // need to take into account the orientation of the placed - // tile - int tileEdge = (targetEdge+(4-tile.orientation)+2) % 4; - - // we iterate over the four possible orientations of the - // target tile - for (int o = 0; o < 4; o++) { - // we compare the edge of the placed tile (which never - // changes) with the edge of the target tile which is - // adjusted based on the target tile's orientation - if (getEdge(tile.type, tileEdge) == - getEdge(target.type, (targetEdge+(4-o)) % 4)) { - // increment the edge matches - matches[o]++; - - } else { - // if we have a mismatch, we want to ensure that - // we screw this orientation up for good, so we - // deduct a large value from the array to ensure - // that it will remain less than zero regardless - // of which of the other three tiles match in this - // orientation - matches[o] -= 10; - } - } - } - } - - // for every orientation that we have a positive number of edge - // matches, we have a valid orientation - boolean[] orients = new boolean[4]; - for (int i = 0; i < matches.length; i++) { - orients[i] = (matches[i] > 0); - } - return orients; - } - - /** - * Returns true if the position and orientation of the target tile is - * legal given the placement of all of the existing tiles. - * - * @param tiles a list of the tiles already on the board. - * @param target the tile whose validity we want to determine. - * - * @return true if the target tile is configured with a valid position - * and orientation, false if it is not. - */ - public static boolean isValidPlacement (List tiles, AtlantiTile target) - { - boolean matchedAnEdge = false; - - int tsize = tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)tiles.get(i); - - // figure out where this tile is in relation to the candidate - int xdiff = tile.x - target.x; - int ydiff = tile.y - target.y; - int sum = Math.abs(xdiff) + Math.abs(ydiff); - - if (sum == 0) { - // they overlap, nothing doing - Log.warning("Tile overlaps another [candidate=" + target + - ", overlapped=" + tile + "]."); - return false; - - } else if (sum == 1) { - // they're neighbors, we may have a match - int targetEdge = EDGE_MAP[(ydiff+1)*3 + xdiff+1]; - - // we want the edge of the placed tile that matches up - // with the tile in the candidate location, but we also - // need to take into account the orientation of the placed - // tile - int tileEdge = (targetEdge+(4-tile.orientation)+2) % 4; - - // now rotate the target edge according to our orientation - targetEdge = ((targetEdge+(4-target.orientation)) % 4); - - // see if the edges match - if (getEdge(tile.type, tileEdge) == - getEdge(target.type, targetEdge)) { - // make a note that we matched at least one edge - matchedAnEdge = true; - - } else { - // the edges don't match, nothing doing - Log.warning("Edge mismatch [candidate=" + target + - ", tile=" + tile + - ", candidateEdge=" + targetEdge + - ", tileEdge=" + tileEdge + "]."); - return false; - } - } - } - - // if we got this far, we didn't have any mismatches, so we need - // only know that we matched at least one edge - return matchedAnEdge; - } - - /** - * When a tile is placed on the board, this method should be called on - * it to propagate existing claims to the appropriate features on this - * tile. It will determine if any city features are connected to - * cities that are already claimed, and if any road features are - * connected to roads that are already claimed and if any grassland is - * connected to grassland that is claimed. - * - *

If, in the process of initializing the claims for this tile, we - * discover that this tile connects two previously disconnected - * claims, those claims will be joined. The affected tiles and piecens - * will have their claim groups updated. - * - * @param tiles a sorted list of the tiles on the board (which need - * not include the tile whose features are being configured). - * @param tile the tile whose features should be configured. - */ - public static void inheritClaims (List tiles, AtlantiTile tile) - { - List flist = new ArrayList(); - - // for each feature in the tile, load up its claim group and make - // sure all features in that group (which will include our new - // feature) now have the same claim number - for (int i = 0; i < tile.features.length; i ++) { - int claimGroup = 0; - - // clear out the tilefeatures list before enumerating - flist.clear(); - - // enumerate the claim group for this feature - enumerateGroup(tiles, tile, i, flist); - - // find the first non-zero claim number - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - int fcg = feat.tile.claims[feat.featureIndex]; - if (fcg != 0) { - claimGroup = fcg; - break; - } - } - - // if we found no non-zero claim number, we've nothing to - // inherit - if (claimGroup == 0) { - continue; - } - - // otherwise, assign our new claim number to all members of - // the group (potentially causing some to inherit the new - // claim number) - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - // set the claim group in the tile - feat.tile.claims[feat.featureIndex] = claimGroup; - // also set the claim group on the piecen if the tile has - // an associated piecen that is on this feature - Piecen p = feat.tile.piecen; - if (p != null && p.featureIndex == feat.featureIndex) { - p.claimGroup = claimGroup; - } - } - } - } - - /** - * Sets the claim group for the specified feature in this tile and - * propagates that claim group to all connected features. - * - * @param tiles a sorted list of the tiles on the board. - * @param tile the tile that contains the feature whose claim group is - * being set. - * @param featureIndex the index of the feature. - * @param claimGroup the claim group value to set. - */ - public static void setClaimGroup ( - List tiles, AtlantiTile tile, int featureIndex, int claimGroup) - { - // load up this feature group - List flist = new ArrayList(); - enumerateGroup(tiles, tile, featureIndex, flist); - - // and assign the claim number to all features in the group - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - feat.tile.claims[feat.featureIndex] = claimGroup; - } - } - - /** - * Computes the score for the specified feature and returns it. If the - * feature is complete (has no unconnected edges), the score will be - * positive. If it is incomplete, the score will be negative. - * - * @param tiles a sorted list of the tiles on the board. - * @param tile the tile that contains the feature whose score should - * be computed. - * @param featureIndex the index of the feature in the containing - * tile. - * - * @return a positive score for a completed feature group, a negative - * score for a partial feature group. - */ - public static int computeFeatureScore ( - List tiles, AtlantiTile tile, int featureIndex) - { - Feature feature = tile.features[featureIndex]; - - if (feature.type == CLOISTER) { - // cloister's score specially - return computeCloisterScore(tiles, tile); - - } else if (feature.type == GRASS) { - // grass doesn't score - return 0; - } - - // if we're here, it's a road or city feature, which we score by - // loading up the group and counting the number of tiles in it - List flist = new ArrayList(); - boolean complete = enumerateGroup(tiles, tile, featureIndex, flist); - - // we sort the group which will order the tile feature objects by - // their tiles, ensuring that features on the same tile are next - // to one another, so that we can only count them once - Collections.sort(flist); - - // now iterate over the list, counting only unique tiles - int score = 0; - AtlantiTile lastTile = null; - int fsize = flist.size(); - for (int i = 0; i < fsize; i++) { - TileFeature feat = (TileFeature)flist.get(i); - if (feat.tile != lastTile) { - score++; - lastTile = feat.tile; - } - } - - // for city groups, we need to add a bonus of one for every tile - // that contains a shield and mutiply by two if the city is - // complete and larger than two tiles - if (feature.type == CITY) { - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - if (feat.tile.hasShield) { - score++; - } - } - if (complete && score > 2) { - score *= 2; - } - } - - // incomplete scores are reported in the negative - return complete ? score : -score; - } - - /** - * A helper function for {@link - * #computeFeatureScore(List,AtlantiTile,int)}. - */ - protected static int computeCloisterScore (List tiles, AtlantiTile tile) - { - int score = 0; - - // all we need to know are how many neighbors this guy has (we - // count ourselves as well, just for code simplicity) - for (int dx = -1; dx < 2; dx++) { - for (int dy = -1; dy < 2; dy++) { - if (findTile(tiles, tile.x + dx, tile.y + dy) != null) { - score++; - } - } - } - - // incomplete cloisters return a negative score - return (score == 9) ? 9 : -score; - } - - /** - * Clears out the claim group information for incomplete cities so - * that we can ignore them during farm scoring. Assigns new claim - * group values to any completed cities that were unclaimed. - * - * @param tiles a sorted list of tiles on the board. - */ - public static void prepCitiesForScoring (List tiles) - { - List flist = new ArrayList(); - - // iterate over the tiles, marking every city completed or not - int tsize = tiles.size(); - for (int i = 0; i < tsize; i++) { - AtlantiTile tile = (AtlantiTile)tiles.get(i); - - // iterate over each feature on this tile - for (int f = 0; f < tile.features.length; f++) { - // skip non-city features - if (tile.features[f].type != TileCodes.CITY) { - continue; - } - - // clear out the feature group list before processing - flist.clear(); - - // enumerate the features in the group with this feature - if (enumerateGroup(tiles, tile, f, flist)) { - // if it's complete, we want to ensure that all of - // these features have a claim number - if (tile.claims[f] != 0) { - // it's complete and has a claim number. move on - continue; - } - - // assign the claim number to all features in the group - int claimGroup = nextClaimGroup(); - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - feat.tile.claims[feat.featureIndex] = claimGroup; - if (t == 0) { - Log.info("Claiming complete city " + - "[claim=" + feat.tile.claims[ - feat.featureIndex] + "]."); - } - } - - } else { - // it's incomplete, so we want to clear out the claim - // number from all tiles in the group - for (int t = 0; t < flist.size(); t++) { - TileFeature feat = (TileFeature)flist.get(t); - if (t == 0) { - Log.info("Clearing incomplete city " + - "[claim=" + feat.tile.claims[ - feat.featureIndex] + "]."); - } - feat.tile.claims[feat.featureIndex] = 0; - } - } - } - } - } - - /** - * Enumerates all of the features that are in the group of which the - * specified feature is a member. - * - * @param tiles a sorted list of the tiles on the board. - * @param tile the tile that contains the feature whose group is to be - * enumerated. - * @param featureIndex the index of the feature whose group is to be - * enumerated. - * @param group the list into which instances of {@link TileFeature} - * will be placed that represent the features that are members of the - * group. - * - * @return true if the group is complete (has no unconnected - * features), false if it is not. - */ - protected static boolean enumerateGroup ( - List tiles, AtlantiTile tile, int featureIndex, List group) - { - // create a tilefeature for this feature - TileFeature feat = new TileFeature(tile, featureIndex); - - // determine whether or not this feature is already in the group - if (group.contains(feat)) { - return true; - } - - // otherwise add this feature to the group and process this - // feature's neighbors - group.add(feat); - - boolean complete = true; - int ftype = tile.features[featureIndex].type; - int fmask = tile.features[featureIndex].edgeMask; - - // iterate over all of the possible adjacency possibilities - for (int c = 0; c < FeatureUtil.ADJACENCY_MAP.length; c += 3) { - int mask = FeatureUtil.ADJACENCY_MAP[c]; - int opp_mask = FeatureUtil.ADJACENCY_MAP[c+2]; - - // if this feature doesn't have this edge, skip it - if ((fmask & mask) == 0) { - continue; - } - - // look up our neighbor - AtlantiTile neighbor = null; - int dir = FeatureUtil.ADJACENCY_MAP[c+1]; - dir = (dir + tile.orientation) % 4; - switch (dir) { - case NORTH: neighbor = findTile(tiles, tile.x, tile.y-1); break; - case EAST: neighbor = findTile(tiles, tile.x+1, tile.y); break; - case SOUTH: neighbor = findTile(tiles, tile.x, tile.y+1); break; - case WEST: neighbor = findTile(tiles, tile.x-1, tile.y); break; - } - - // make sure we have a neighbor in this direction - if (neighbor == null) { - // if we don't have a neighbor in a direction that we - // need, we're an incomplete feature. alas - complete = false; - continue; - } - - // translate the target mask into our orientation - mask = FeatureUtil.translateMask(mask, tile.orientation); - opp_mask = FeatureUtil.translateMask(opp_mask, tile.orientation); - - // obtain the index of the feature on the opposing tile - int nFeatureIndex = neighbor.getFeatureIndex(opp_mask); - if (nFeatureIndex < 0) { - Log.warning("Tile mismatch while grouping [tile=" + tile + - "featIdx=" + featureIndex + - ", neighbor=" + neighbor + - ", nFeatIdx=" + nFeatureIndex + - ", srcEdge=" + mask + - ", destEdge=" + opp_mask + "]."); - continue; - } - - // add this feature and its neighbors to the group - if (!enumerateGroup(tiles, neighbor, nFeatureIndex, group)) { - // if our neighbor was incomplete, we become incomplete. - // as dr. evil might say, "you incomplete me." - complete = false; - } - } - - return complete; - } - - /** - * Locates and returns the tile with the specified coordinates. - * - * @param tiles a sorted list of tiles. - * - * @return the tile with the requested coordinates or null if no tile - * exists at those coordinates. - */ - public static AtlantiTile findTile (List tiles, int x, int y) - { - IntTuple coord = new IntTuple(x, y); - int tidx = Collections.binarySearch(tiles, coord); - return (tidx >= 0) ? (AtlantiTile)tiles.get(tidx) : null; - } - - /** - * Returns the number of piecens on the board owned the specified - * player. This can be used when we need to count piecens and the - * server potentially hasn't gotten around to processing piecen - * removal events quite yet. - * - * @param tiles a list of the tiles on the board. - * @param playerIndex the index of the player whose piecen count is - * desired. - */ - public static int countPiecens (List tiles, int playerIndex) - { - int count = 0; - for (int i = 0; i < tiles.size(); i++) { - AtlantiTile tile = (AtlantiTile)tiles.get(i); - if (tile.piecen != null && - tile.piecen.owner == playerIndex) { - count++; - } - } - return count; - } - - /** - * Returns the number of piecens on the board owned the specified - * player. - * - * @param piecens the piecens set from the game object. - * @param playerIndex the index of the player whose piecen count is - * desired. - */ - public static int countPiecens (DSet piecens, int playerIndex) - { - int count = 0; - Iterator iter = piecens.entries(); - while (iter.hasNext()) { - if (((Piecen)iter.next()).owner == playerIndex) { - count++; - } - } - return count; - } - - /** - * Returns the edge type for specified edge of the specified tile - * type. - * - * @param tileType the type of the tile in question. - * @param edge the direction constant indicating the edge in which we - * are interested. - * - * @return the edge constant for the edge in question. - */ - public static int getEdge (int tileType, int edge) - { - return TILE_EDGES[4*tileType + edge]; - } - - /** - * Returns the next unused claim group value. - */ - public static int nextClaimGroup () - { - return ++_claimGroupCounter; - } - - /** Used to generate our standard tile set. */ - protected static void addTiles (int count, List list, AtlantiTile tile) - { - for (int i = 0; i < count; i++) { - list.add(tile); - } - } - - /** Used to keep track of actual features on tiles. */ - protected static final class TileFeature implements Comparable - { - /** The tile that contains the feature. */ - public AtlantiTile tile; - - /** The index of the feature in the tile. */ - public int featureIndex; - - /** Constructs a new tile feature. */ - public TileFeature (AtlantiTile tile, int featureIndex) - { - this.tile = tile; - this.featureIndex = featureIndex; - } - - /** Properly implement equality. */ - public boolean equals (Object other) - { - if (other == null || - !(other instanceof TileFeature)) { - return false; - - } else { - TileFeature feat = (TileFeature)other; - return (feat.tile == tile && - feat.featureIndex == featureIndex); - } - } - - /** We sort based on our tiles. */ - public int compareTo (Object other) - { - return tile.compareTo(((TileFeature)other).tile); - } - - /** Generate a string representation. */ - public String toString () - { - return "[tile=" + tile + ", fidx=" + featureIndex + "]"; - } - } - - /** Used to generate claim group values. */ - protected static int _claimGroupCounter; - - /** Used to figure out which edges match up to which when comparing - * adjacent tiles. */ - protected static final int[] EDGE_MAP = { - -1, NORTH, -1, - WEST, -1, EAST, - -1, SOUTH, -1 - }; - - /** A table indicating which tiles have which edges. */ - protected static final int[] TILE_EDGES = { - -1, -1, -1, -1, // null tile - CITY, CITY, CITY, CITY, // CITY_FOUR - CITY, CITY, GRASS, CITY, // CITY_THREE - CITY, CITY, ROAD, CITY, // CITY_THREE_ROAD - CITY, GRASS, GRASS, CITY, // CITY_TWO - CITY, ROAD, ROAD, CITY, // CITY_TWO_ROAD - GRASS, CITY, GRASS, CITY, // CITY_TWO_ACROSS - CITY, CITY, GRASS, GRASS, // TWO_CITY_TWO - GRASS, CITY, GRASS, CITY, // TWO_CITY_TWO_ACROSS - CITY, GRASS, GRASS, GRASS, // CITY_ONE - CITY, ROAD, ROAD, GRASS, // CITY_ONE_ROAD_RIGHT - CITY, GRASS, ROAD, ROAD, // CITY_ONE_ROAD_LEFT - CITY, ROAD, ROAD, ROAD, // CITY_ONE_ROAD_TEE - CITY, ROAD, GRASS, ROAD, // CITY_ONE_ROAD_STRAIGHT - GRASS, GRASS, GRASS, GRASS, // CLOISTER_PLAIN - GRASS, GRASS, ROAD, GRASS, // CLOISTER_ROAD - ROAD, ROAD, ROAD, ROAD, // FOUR_WAY_ROAD - GRASS, ROAD, ROAD, ROAD, // THREE_WAY_ROAD - ROAD, GRASS, ROAD, GRASS, // STRAIGHT_ROAD - GRASS, GRASS, ROAD, ROAD, // CURVED_ROAD - }; - - /** The standard tile set for a game of Atlantissonne. */ - protected static ArrayList TILE_SET = new ArrayList(); - - // create our standard tile set - static { - addTiles(1, TILE_SET, new AtlantiTile(CITY_FOUR, true)); - - addTiles(3, TILE_SET, new AtlantiTile(CITY_THREE, false)); - addTiles(1, TILE_SET, new AtlantiTile(CITY_THREE, true)); - addTiles(1, TILE_SET, new AtlantiTile(CITY_THREE_ROAD, false)); - addTiles(2, TILE_SET, new AtlantiTile(CITY_THREE_ROAD, true)); - - addTiles(3, TILE_SET, new AtlantiTile(CITY_TWO, false)); - addTiles(2, TILE_SET, new AtlantiTile(CITY_TWO, true)); - addTiles(3, TILE_SET, new AtlantiTile(CITY_TWO_ROAD, false)); - addTiles(2, TILE_SET, new AtlantiTile(CITY_TWO_ROAD, true)); - addTiles(1, TILE_SET, new AtlantiTile(CITY_TWO_ACROSS, false)); - addTiles(2, TILE_SET, new AtlantiTile(CITY_TWO_ACROSS, true)); - - addTiles(2, TILE_SET, new AtlantiTile(TWO_CITY_TWO, false)); - addTiles(3, TILE_SET, new AtlantiTile(TWO_CITY_TWO_ACROSS, false)); - - addTiles(5, TILE_SET, new AtlantiTile(CITY_ONE, false)); - addTiles(3, TILE_SET, new AtlantiTile(CITY_ONE_ROAD_RIGHT, false)); - addTiles(3, TILE_SET, new AtlantiTile(CITY_ONE_ROAD_LEFT, false)); - addTiles(3, TILE_SET, new AtlantiTile(CITY_ONE_ROAD_TEE, false)); - addTiles(3, TILE_SET, new AtlantiTile(CITY_ONE_ROAD_STRAIGHT, false)); - - addTiles(4, TILE_SET, new AtlantiTile(CLOISTER_PLAIN, false)); - addTiles(2, TILE_SET, new AtlantiTile(CLOISTER_ROAD, false)); - - addTiles(1, TILE_SET, new AtlantiTile(FOUR_WAY_ROAD, false)); - addTiles(4, TILE_SET, new AtlantiTile(THREE_WAY_ROAD, false)); - addTiles(8, TILE_SET, new AtlantiTile(STRAIGHT_ROAD, false)); - addTiles(9, TILE_SET, new AtlantiTile(CURVED_ROAD, false)); - } -}