Implemented claim groups and the necessary code to properly propagate
claim groups to newly placed tiles and to existing tiles when a piecen is placed or a tile is placed that joins groups. Whee! git-svn-id: https://samskivert.googlecode.com/svn/trunk@359 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
//
|
||||
// $Id: TileGeometryTest.java,v 1.2 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: TileGeometryTest.java,v 1.3 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
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.samskivert.util.IntTuple;
|
||||
|
||||
/**
|
||||
* A simple class for testing the tile geometry specifications by drawing
|
||||
@@ -19,87 +21,18 @@ public class TileGeometryTest
|
||||
{
|
||||
public TileGeometryTest ()
|
||||
{
|
||||
ArrayList polys = new ArrayList();
|
||||
ArrayList colors = new ArrayList();
|
||||
|
||||
// create polygons from the various tile features
|
||||
for (int i = 0; i < TileUtil.TILE_FEATURES.length; i++) {
|
||||
// convert tile index into x and y coordinates (in tile
|
||||
// feature coords which will be converted to screen coords)
|
||||
int x = 4 * (i % 5), y = 4 * (i / 5);
|
||||
|
||||
// the first feature is the background color
|
||||
Object[] features = (Object[])TileUtil.TILE_FEATURES[i];
|
||||
IntTuple base = (IntTuple)features[0];
|
||||
|
||||
// add a polygon containing the whole tile colored with the
|
||||
// background color
|
||||
colors.add(COLOR_MAP[base.left]);
|
||||
Polygon poly = new Polygon();
|
||||
poly.addPoint(((x + 0) * TILE_WIDTH) / 4,
|
||||
((y + 0) * TILE_HEIGHT) / 4);
|
||||
poly.addPoint(((x + 4) * TILE_WIDTH) / 4,
|
||||
((y + 0) * TILE_HEIGHT) / 4);
|
||||
poly.addPoint(((x + 4) * TILE_WIDTH) / 4,
|
||||
((y + 4) * TILE_HEIGHT) / 4);
|
||||
poly.addPoint(((x + 0) * TILE_WIDTH) / 4,
|
||||
((y + 4) * TILE_HEIGHT) / 4);
|
||||
polys.add(poly);
|
||||
|
||||
// the remainder are tuple/coordinate pairs
|
||||
for (int f = 1; f < features.length; f += 2) {
|
||||
IntTuple type = (IntTuple)features[f];
|
||||
int[] coords = (int[])features[f+1];
|
||||
|
||||
// create a color for this polygon
|
||||
colors.add(COLOR_MAP[type.left]);
|
||||
|
||||
// if this is a road segment, we need to create a special
|
||||
// polygon
|
||||
if (type.left == ROAD) {
|
||||
poly = TileUtil.roadSegmentToPolygon(
|
||||
coords[0], coords[1], coords[2], coords[3]);
|
||||
// translate the polygon into our coordinate space
|
||||
poly.translate((x * TILE_WIDTH)/4, (y * TILE_HEIGHT)/4);
|
||||
|
||||
} else {
|
||||
// otherwise create the polygon directly from the coords
|
||||
poly = new Polygon();
|
||||
for (int c = 0; c < coords.length; c += 2) {
|
||||
// translate and scale the coords accordingly
|
||||
int fx = ((x + coords[c]) * TILE_WIDTH) / 4;
|
||||
int fy = ((y + coords[c+1]) * TILE_HEIGHT) / 4;
|
||||
poly.addPoint(fx, fy);
|
||||
}
|
||||
}
|
||||
|
||||
polys.add(poly);
|
||||
}
|
||||
for (int i = 0; i < TILE_TYPES; i++) {
|
||||
_tiles[i] = new VenisonTile(i+1, false, NORTH, i % 5, i / 5);
|
||||
}
|
||||
|
||||
// create our arrays
|
||||
_polys = new Polygon[polys.size()];
|
||||
polys.toArray(_polys);
|
||||
_colors = new Color[colors.size()];
|
||||
colors.toArray(_colors);
|
||||
}
|
||||
|
||||
public void paintComponent (Graphics g)
|
||||
{
|
||||
super.paintComponent(g);
|
||||
|
||||
// paint our polygons
|
||||
for (int i = 0; i < _polys.length; i++) {
|
||||
g.setColor(_colors[i]);
|
||||
g.fillPolygon(_polys[i]);
|
||||
}
|
||||
|
||||
// outline the tiles
|
||||
g.setColor(Color.black);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = i % 5, y = i / 5;
|
||||
g.drawRect(TILE_WIDTH * x, TILE_HEIGHT * y,
|
||||
TILE_WIDTH, TILE_HEIGHT);
|
||||
// paint our tiles
|
||||
for (int i = 0; i < _tiles.length; i++) {
|
||||
_tiles[i].paint((Graphics2D)g, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,12 +54,5 @@ public class TileGeometryTest
|
||||
frame.show();
|
||||
}
|
||||
|
||||
protected Polygon[] _polys;
|
||||
protected Color[] _colors;
|
||||
|
||||
protected static Color[] COLOR_MAP = {
|
||||
Color.red, // CITY
|
||||
Color.green, // GRASS
|
||||
Color.black // ROAD
|
||||
};
|
||||
protected VenisonTile[] _tiles = new VenisonTile[TILE_TYPES];
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//
|
||||
// $Id: AtlantiBoard.java,v 1.6 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: AtlantiBoard.java,v 1.7 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
@@ -343,7 +345,12 @@ public class VenisonBoard
|
||||
|
||||
TestDSet set = new TestDSet();
|
||||
set.addTile(new VenisonTile(CITY_TWO, false, WEST, 0, 0));
|
||||
set.addTile(new VenisonTile(CITY_FOUR, false, NORTH, 0, 1));
|
||||
set.addTile(new VenisonTile(CITY_TWO, false, WEST, -1, 1));
|
||||
set.addTile(new VenisonTile(CITY_TWO, false, WEST, -1, -1));
|
||||
set.addTile(new VenisonTile(CURVED_ROAD, false, WEST, 0, 2));
|
||||
VenisonTile target =
|
||||
new VenisonTile(DISCONNECTED_CITY_TWO, false, NORTH, 0, 1);
|
||||
set.addTile(target);
|
||||
set.addTile(new VenisonTile(CITY_THREE, false, WEST, 1, 1));
|
||||
set.addTile(new VenisonTile(CITY_THREE_ROAD, false, EAST, 1, 2));
|
||||
set.addTile(new VenisonTile(CITY_THREE, false, NORTH, -1, 0));
|
||||
@@ -353,6 +360,15 @@ public class VenisonBoard
|
||||
VenisonTile placing = new VenisonTile(CITY_TWO, false, NORTH, 0, 0);
|
||||
board.setTileToBePlaced(placing);
|
||||
|
||||
// set a feature group to test propagation
|
||||
VenisonTile[] tiles = new VenisonTile[set.size()];
|
||||
Iterator iter = set.elements();
|
||||
for (int i = 0; iter.hasNext(); i++) {
|
||||
tiles[i] = (VenisonTile)iter.next();
|
||||
}
|
||||
Arrays.sort(tiles);
|
||||
TileUtil.setFeatureGroup(tiles, target, 0, 1, 0);
|
||||
|
||||
frame.getContentPane().add(board, BorderLayout.CENTER);
|
||||
frame.pack();
|
||||
SwingUtil.centerWindow(frame);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: AtlantiTile.java,v 1.5 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: AtlantiTile.java,v 1.6 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
@@ -24,8 +24,12 @@ import com.threerings.presents.dobj.DSet;
|
||||
* Represents a single tile in play on the Venison game board.
|
||||
*/
|
||||
public class VenisonTile
|
||||
implements DSet.Element, TileCodes, Cloneable
|
||||
implements DSet.Element, TileCodes, Cloneable, Comparable
|
||||
{
|
||||
/** The starting tile. */
|
||||
public static final VenisonTile STARTING_TILE =
|
||||
new VenisonTile(CITY_ONE_ROAD_STRAIGHT, false, NORTH, 0, 0);
|
||||
|
||||
/** The tile type. */
|
||||
public int type;
|
||||
|
||||
@@ -38,6 +42,20 @@ public class VenisonTile
|
||||
/** 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 int[] claims;
|
||||
|
||||
/** A reference to our static feature descriptions. */
|
||||
public int[] features;
|
||||
|
||||
/** A reference to the piecen on this tile or null if no piecen has
|
||||
* been placed on this tile. */
|
||||
// public Piecen piecen;
|
||||
|
||||
/**
|
||||
* Constructs a tile with all of the supplied tile information.
|
||||
*/
|
||||
@@ -49,6 +67,12 @@ public class VenisonTile
|
||||
this.orientation = orientation;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// grab a reference to our feature information
|
||||
features = TileUtil.TILE_FEATURES[type-1];
|
||||
|
||||
// create our claims array
|
||||
claims = new int[features.length/2];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,6 +92,62 @@ public class VenisonTile
|
||||
// nothing doing
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 featureMask)
|
||||
{
|
||||
// translate the feature mask into our orientation
|
||||
featureMask = TileUtil.translateMask(featureMask, -orientation);
|
||||
|
||||
for (int i = 0; i < features.length; i += 2) {
|
||||
int fmask = features[i+1];
|
||||
if ((fmask & featureMask) != 0) {
|
||||
return i/2;
|
||||
}
|
||||
}
|
||||
|
||||
// no match
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 featureMask)
|
||||
{
|
||||
int fidx = getFeatureIndex(featureMask);
|
||||
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 setFeatureGroup (int featureIndex, int claimGroup)
|
||||
{
|
||||
Log.info("Setting feature group [tile=" + this +
|
||||
", fidx=" + featureIndex + ", cgroup=" + claimGroup + "].");
|
||||
claims[featureIndex] = claimGroup;
|
||||
|
||||
// TBD: update the piecen
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints this tile to the specified graphics context at its assigned
|
||||
* location, accounting for the supplied x and y offsets of the
|
||||
@@ -97,8 +177,13 @@ public class VenisonTile
|
||||
|
||||
// draw our shapes using the proper orientation
|
||||
GeneralPath[] paths = _shapes[tidx][orientation];
|
||||
IntTuple[] types = _types[tidx];
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
g.setColor(COLOR_MAP[_types[tidx][i].left]);
|
||||
if (claims[types[i].right] != 0) {
|
||||
g.setColor(CLAIMED_COLOR_MAP[types[i].left]);
|
||||
} else {
|
||||
g.setColor(COLOR_MAP[types[i].left]);
|
||||
}
|
||||
g.fill(paths[i]);
|
||||
}
|
||||
|
||||
@@ -118,6 +203,27 @@ public class VenisonTile
|
||||
return new VenisonTile(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 or to a coordinate
|
||||
// object
|
||||
if (other instanceof VenisonTile) {
|
||||
VenisonTile tile = (VenisonTile)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 {
|
||||
// who knows...
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object getKey ()
|
||||
{
|
||||
@@ -153,14 +259,12 @@ public class VenisonTile
|
||||
*/
|
||||
protected void createShapes ()
|
||||
{
|
||||
System.out.println("Creating shapes " + this + ".");
|
||||
|
||||
int tidx = type-1;
|
||||
ArrayList polys = new ArrayList();
|
||||
ArrayList types = new ArrayList();
|
||||
|
||||
// the first feature is the background color
|
||||
Object[] features = (Object[])TileUtil.TILE_FEATURES[tidx];
|
||||
Object[] features = (Object[])TileUtil.TILE_FEATURE_GEOMS[tidx];
|
||||
IntTuple base = (IntTuple)features[0];
|
||||
|
||||
// add a polygon containing the whole tile
|
||||
@@ -253,6 +357,15 @@ public class VenisonTile
|
||||
protected static Color[] COLOR_MAP = {
|
||||
Color.red, // CITY
|
||||
Color.green, // GRASS
|
||||
Color.black // ROAD
|
||||
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.black.brighter(), // ROAD
|
||||
Color.yellow.darker(), // CLOISTER
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: TileCodes.java,v 1.3 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: TileCodes.java,v 1.4 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface TileCodes
|
||||
public static final int CITY_ONE_ROAD_STRAIGHT = 13;
|
||||
|
||||
/** A cloister tile. */
|
||||
public static final int CLOISTER = 14;
|
||||
public static final int CLOISTER_PLAIN = 14;
|
||||
|
||||
/** A cloister tile with a road extending from the cloister. */
|
||||
public static final int CLOISTER_ROAD = 15;
|
||||
@@ -78,6 +78,7 @@ public interface TileCodes
|
||||
/** 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;
|
||||
@@ -98,6 +99,7 @@ public interface TileCodes
|
||||
public static final String[] ORIENT_NAMES =
|
||||
new String[] { "N", "E", "S", "W" };
|
||||
|
||||
|
||||
/** The tile image width in pixels. */
|
||||
public static int TILE_WIDTH = 90;
|
||||
|
||||
@@ -113,4 +115,44 @@ public interface TileCodes
|
||||
|
||||
/** 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;
|
||||
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: AtlantiManager.java,v 1.6 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: AtlantiManager.java,v 1.7 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class VenisonManager
|
||||
|
||||
// clear out the tile set
|
||||
_venobj.setTiles(new DSet(VenisonTile.class));
|
||||
_venobj.addToTiles(TileUtil.STARTING_TILE);
|
||||
_venobj.addToTiles(VenisonTile.STARTING_TILE);
|
||||
}
|
||||
|
||||
protected void turnWillStart ()
|
||||
@@ -101,8 +101,16 @@ public class VenisonManager
|
||||
public void handleEvent (MessageEvent event)
|
||||
{
|
||||
VenisonTile tile = (VenisonTile)event.getArgs()[0];
|
||||
// don't do no checking at present
|
||||
_venobj.addToTiles(tile);
|
||||
|
||||
// make sure this is a valid placement
|
||||
if (TileUtil.isValidPlacement(_venobj.tiles.elements(), tile)) {
|
||||
// add the tile to the tiles set
|
||||
_venobj.addToTiles(tile);
|
||||
|
||||
} else {
|
||||
Log.warning("Received invalid placement " + event + ".");
|
||||
}
|
||||
|
||||
// end the turn
|
||||
endTurn();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//
|
||||
// $Id: TileUtil.java,v 1.4 2001/10/16 01:41:55 mdb Exp $
|
||||
// $Id: TileUtil.java,v 1.5 2001/10/16 09:31:46 mdb Exp $
|
||||
|
||||
package com.threerings.venison;
|
||||
|
||||
import java.awt.Polygon;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
@@ -16,10 +17,6 @@ import com.samskivert.util.IntTuple;
|
||||
*/
|
||||
public class TileUtil implements TileCodes
|
||||
{
|
||||
/** The starting tile. */
|
||||
public static final VenisonTile STARTING_TILE =
|
||||
new VenisonTile(CITY_ONE_ROAD_STRAIGHT, false, NORTH, 0, 0);
|
||||
|
||||
/**
|
||||
* Returns a list containing the standard tile set for the Venison
|
||||
* game. The list is a clone, so it can be bent, folded and modified
|
||||
@@ -165,6 +162,212 @@ public class TileUtil implements TileCodes
|
||||
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.
|
||||
*
|
||||
* <p> 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 array 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 initClaims (VenisonTile[] tiles, VenisonTile tile)
|
||||
{
|
||||
// obtain our neighboring tiles
|
||||
VenisonTile[] neighbors = new VenisonTile[4];
|
||||
neighbors[NORTH] = findTile(tiles, tile.x, tile.y-1);
|
||||
neighbors[EAST] = findTile(tiles, tile.x+1, tile.y);
|
||||
neighbors[SOUTH] = findTile(tiles, tile.x, tile.y+1);
|
||||
neighbors[WEST] = findTile(tiles, tile.x-1, tile.y);
|
||||
|
||||
// for each feature in the tile, determine whether or not the
|
||||
// neighboring tile's matching feature is claimed
|
||||
for (int i = 0; i < tile.features.length; i += 2) {
|
||||
int ftype = tile.features[i];
|
||||
int fmask = tile.features[i+1];
|
||||
int cgroup = 0;
|
||||
|
||||
// iterate over all of the possible adjacency possibilities
|
||||
for (int c = 0; c < ADJADCENCY_MAP.length; c += 3) {
|
||||
int mask = ADJADCENCY_MAP[c];
|
||||
int dir = ADJADCENCY_MAP[c+1];
|
||||
int opp_mask = ADJADCENCY_MAP[c+2];
|
||||
|
||||
// if this feature doesn't have this edge, skip it
|
||||
if ((fmask & mask) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// translate the target direction accordingly
|
||||
dir = (dir + tile.orientation) % 4;
|
||||
|
||||
// make sure we have a neighbor in the appropriate
|
||||
// direction
|
||||
if (neighbors[dir] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// it looks like we have a match, so translate the target
|
||||
// stuff into our orientation
|
||||
mask = translateMask(mask, tile.orientation);
|
||||
opp_mask = translateMask(opp_mask, tile.orientation);
|
||||
|
||||
if (cgroup != 0) {
|
||||
// if we've already been assigned to a group, we
|
||||
// propagate our group to the opposing feature
|
||||
int fidx = neighbors[dir].getFeatureIndex(opp_mask);
|
||||
if (fidx >= 0) {
|
||||
setFeatureGroup(tiles, neighbors[dir],
|
||||
fidx, cgroup, mask);
|
||||
} else {
|
||||
Log.warning("Can't join-propagate feature " +
|
||||
"[self=" + tile +
|
||||
", target=" + neighbors[dir] +
|
||||
", fidx=" + fidx + ", cgroup=" + cgroup +
|
||||
", destEdge=" + opp_mask +
|
||||
", srcEdge=" + mask + "].");
|
||||
}
|
||||
|
||||
} else {
|
||||
// otherwise, we inherit the group of the opposing
|
||||
// feature
|
||||
cgroup = neighbors[dir].getFeatureGroup(opp_mask);
|
||||
}
|
||||
}
|
||||
|
||||
// finally initialize the feature's claim group
|
||||
tile.claims[i/2] = cgroup;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the claim group for the specified feature in this tile and
|
||||
* propagates that claim group to all connected features.
|
||||
*
|
||||
* @param tiles a sorted array 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.
|
||||
* @param entryEdgeMask the edge from which we are propagating this
|
||||
* claim group (to avoid traversing back over that edge when
|
||||
* propagating the group further).
|
||||
*/
|
||||
public static void setFeatureGroup (
|
||||
VenisonTile[] tiles, VenisonTile tile, int featureIndex,
|
||||
int claimGroup, int entryEdgeMask)
|
||||
{
|
||||
// set the claim group for this feature on this tile
|
||||
tile.setFeatureGroup(featureIndex, claimGroup);
|
||||
|
||||
// now propagate this feature to connected features
|
||||
int ftype = tile.features[featureIndex*2];
|
||||
int fmask = tile.features[featureIndex*2+1];
|
||||
|
||||
// iterate over all of the possible adjacency possibilities
|
||||
for (int c = 0; c < ADJADCENCY_MAP.length; c += 3) {
|
||||
int mask = ADJADCENCY_MAP[c];
|
||||
int dir = ADJADCENCY_MAP[c+1];
|
||||
int opp_mask = ADJADCENCY_MAP[c+2];
|
||||
VenisonTile neighbor = null;
|
||||
|
||||
// if this feature doesn't have this edge, skip it
|
||||
if ((fmask & mask) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// figure out if this would be the tile from which we
|
||||
// propagated into our current tile and skip it if so
|
||||
opp_mask = translateMask(opp_mask, tile.orientation);
|
||||
if ((opp_mask & entryEdgeMask) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure we have a neighbor in this direction
|
||||
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;
|
||||
}
|
||||
if (neighbor == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// it looks like we have a match, so translate the target mask
|
||||
// into our orientation
|
||||
mask = translateMask(mask, tile.orientation);
|
||||
|
||||
// propagate, propagate, propagate
|
||||
int fidx = neighbor.getFeatureIndex(opp_mask);
|
||||
if (fidx >= 0) {
|
||||
setFeatureGroup(tiles, neighbor, fidx, claimGroup, mask);
|
||||
|
||||
} else {
|
||||
Log.warning("Can't propagate feature [self=" + tile +
|
||||
", target=" + neighbor + ", fidx=" + fidx +
|
||||
", cgroup=" + claimGroup + ", srcEdge=" + mask +
|
||||
", destEdge=" + opp_mask + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates and returns the tile with the specified coordinates.
|
||||
*
|
||||
* @param tiles a sorted tiles array.
|
||||
*
|
||||
* @return the tile with the requested coordinates or null if no tile
|
||||
* exists at those coordinates.
|
||||
*/
|
||||
protected static VenisonTile findTile (VenisonTile[] tiles, int x, int y)
|
||||
{
|
||||
IntTuple coord = new IntTuple(x, y);
|
||||
int tidx = Arrays.binarySearch(tiles, coord);
|
||||
return (tidx >= 0) ? tiles[tidx] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the edge type for specified edge of the specified tile
|
||||
* type.
|
||||
@@ -250,6 +453,304 @@ public class TileUtil implements TileCodes
|
||||
list.add(tile);
|
||||
}
|
||||
|
||||
/** Used to figure out which edges match up to which when comparing
|
||||
* adjacent tiles. */
|
||||
protected static final int[] EDGE_MAP = new int[] {
|
||||
-1, NORTH, -1,
|
||||
WEST, -1, EAST,
|
||||
-1, SOUTH, -1
|
||||
};
|
||||
|
||||
/** A mapping from feature edge masks to tile directions and
|
||||
* corresponding feature edge masks. */
|
||||
protected static final int[] ADJADCENCY_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,
|
||||
};
|
||||
|
||||
/** Mapping table used to rotate feature facements. */
|
||||
public 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 },
|
||||
};
|
||||
|
||||
/** A table indicating which tiles have which edges. */
|
||||
protected static final int[] TILE_EDGES = new int[] {
|
||||
-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, // DISCONNECTED_CITY_TWO
|
||||
GRASS, CITY, GRASS, CITY, // DISCONNECTED_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
|
||||
};
|
||||
|
||||
/** A table describing the features of each tile and their edge
|
||||
* connectedness. */
|
||||
protected static final int[][] TILE_FEATURES = new int[][] {
|
||||
// one must offset tile type by one when indexing into this array
|
||||
|
||||
{ CITY, NORTH_F|EAST_F|SOUTH_F|WEST_F }, // CITY_FOUR
|
||||
|
||||
{ CITY, NORTH_F|EAST_F|WEST_F, // CITY_THREE
|
||||
GRASS, SOUTH_F },
|
||||
|
||||
{ CITY, NORTH_F|EAST_F|WEST_F, // CITY_THREE_ROAD
|
||||
GRASS, SSW_F,
|
||||
GRASS, SSE_F,
|
||||
ROAD, SOUTH_F },
|
||||
|
||||
{ CITY, NORTH_F|WEST_F, // CITY_TWO
|
||||
GRASS, EAST_F|SOUTH_F },
|
||||
|
||||
{ CITY, NORTH_F|WEST_F, // CITY_TWO_ROAD
|
||||
GRASS, ENE_F|SSW_F,
|
||||
GRASS, ESE_F|SSE_F,
|
||||
ROAD, EAST_F|SOUTH_F },
|
||||
|
||||
{ CITY, WEST_F|EAST_F, // CITY_TWO_ACROSS
|
||||
GRASS, NORTH_F,
|
||||
GRASS, SOUTH_F },
|
||||
|
||||
{ GRASS, WEST_F|SOUTH_F, // DISCONNECTED_CITY_TWO
|
||||
CITY, NORTH_F,
|
||||
CITY, EAST_F },
|
||||
|
||||
{ GRASS, NORTH_F|SOUTH_F, // DISCONNECTED_CITY_TWO_ACROSS
|
||||
CITY, WEST_F,
|
||||
CITY, EAST_F },
|
||||
|
||||
{ GRASS, EAST_F|SOUTH_F|WEST_F, // CITY_ONE
|
||||
CITY, NORTH_F },
|
||||
|
||||
{ GRASS, ENE_F|SSW_F|WEST_F, // CITY_ONE_ROAD_RIGHT
|
||||
GRASS, ESE_F|SSE_F,
|
||||
ROAD, EAST_F|SOUTH_F,
|
||||
CITY, NORTH_F },
|
||||
|
||||
{ GRASS, EAST_F|SSE_F, WNW_F, // CITY_ONE_ROAD_LEFT
|
||||
GRASS, SSW_F|WSW_F,
|
||||
ROAD, SOUTH_F|WEST_F,
|
||||
CITY, NORTH_F },
|
||||
|
||||
{ GRASS, ENE_F|WNW_F, // CITY_ONE_ROAD_TEE
|
||||
GRASS, ESE_F|SSE_F,
|
||||
GRASS, SSW_F|WSW_F,
|
||||
ROAD, EAST_F,
|
||||
ROAD, SOUTH_F,
|
||||
ROAD, WEST_F,
|
||||
CITY, NORTH_F },
|
||||
|
||||
{ GRASS, ENE_F|WNW_F, // CITY_ONE_ROAD_STRAIGHT
|
||||
GRASS, ESE_F, SOUTH_F, WSW_F,
|
||||
ROAD, EAST_F|WEST_F,
|
||||
CITY, NORTH_F },
|
||||
|
||||
{ GRASS, NORTH_F|EAST_F|SOUTH_F|WEST_F, // CLOISTER_PLAIN
|
||||
CLOISTER, 0},
|
||||
|
||||
{ GRASS, NORTH_F|EAST_F|WEST_F, // CLOISTER_ROAD
|
||||
CLOISTER, 0,
|
||||
ROAD, SOUTH_F },
|
||||
|
||||
{ GRASS, WNW_F|NNW_F, // FOUR_WAY_ROAD
|
||||
GRASS, NNE_F|ENE_F,
|
||||
GRASS, ESE_F|SSE_F,
|
||||
GRASS, SSW_F|WSW_F,
|
||||
ROAD, NORTH_F,
|
||||
ROAD, EAST_F,
|
||||
ROAD, SOUTH_F,
|
||||
ROAD, WEST_F },
|
||||
|
||||
{ GRASS, WNW_F|NORTH_F|ENE_F, // THREE_WAY_ROAD
|
||||
GRASS, ESE_F|SSE_F,
|
||||
GRASS, SSW_F|WSW_F,
|
||||
ROAD, EAST_F,
|
||||
ROAD, SOUTH_F,
|
||||
ROAD, WEST_F },
|
||||
|
||||
{ GRASS, NNE_F|EAST_F|SSE_F, // STRAIGHT_ROAD
|
||||
GRASS, SSW_F|WEST_F|NNW_F,
|
||||
ROAD, NORTH_F|SOUTH_F },
|
||||
|
||||
{ GRASS, WNW_F|NORTH_F|EAST_F|SSE_F, // CURVED_ROAD
|
||||
GRASS, SSW_F|WSW_F,
|
||||
ROAD, SOUTH_F|WEST_F },
|
||||
};
|
||||
|
||||
/** A table describing the geometry of the features (cities, roads,
|
||||
* etc.) of each tile. */
|
||||
protected static final Object[] TILE_FEATURE_GEOMS = new Object[] {
|
||||
// one must offset tile type by one when indexing into this array
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), }, // CITY_FOUR
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_THREE
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_THREE_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 4, 1, 3, 2, 3, 2, 4 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 2, 4, 2, 3, 3, 3, 4, 4 },
|
||||
new IntTuple(ROAD, 3),
|
||||
new int[] { 2, 3, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 4, 4, 0, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 4, 4, 0, 4, 2, 2, 4 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 2, 4, 4, 2, 4, 4 },
|
||||
new IntTuple(ROAD, 3),
|
||||
new int[] { 2, 4, 4, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ACROSS
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO
|
||||
new IntTuple(CITY, 1),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(CITY, 2),
|
||||
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO_ACROSS
|
||||
new IntTuple(CITY, 1),
|
||||
new int[] { 0, 0, 1, 1, 1, 3, 0, 4 },
|
||||
new IntTuple(CITY, 2),
|
||||
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE
|
||||
new IntTuple(CITY, 1),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_RIGHT
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 2, 2, 4, 2, 4, 4, 2, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(CITY, 3),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_LEFT
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 2, 2, 2, 2, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 0, 2, 2, 2 },
|
||||
new IntTuple(CITY, 3),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_TEE
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 2, 2, 4, 2, 4, 4, 2, 4 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 0, 2, 2, 2, 2, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 3),
|
||||
new int[] { 0, 2, 2, 2 },
|
||||
new IntTuple(ROAD, 4),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 5),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(CITY, 6),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_STRAIGHT
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 2, 4, 2, 4, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 0, 2, 4, 2 },
|
||||
new IntTuple(CITY, 3),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CLOISTER_PLAIN
|
||||
new IntTuple(CLOISTER, 1),
|
||||
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CLOISTER_ROAD
|
||||
new IntTuple(CLOISTER, 1),
|
||||
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 3, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // FOUR_WAY_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 2, 0, 4, 0, 4, 2, 2, 2 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 2, 2, 4, 2, 4, 4, 2, 4 },
|
||||
new IntTuple(GRASS, 3),
|
||||
new int[] { 0, 2, 2, 2, 2, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 4),
|
||||
new int[] { 2, 0, 2, 2 },
|
||||
new IntTuple(ROAD, 5),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 6),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 7),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // THREE_WAY_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 2, 2, 4, 2, 4, 4, 2, 4 },
|
||||
new IntTuple(GRASS, 2),
|
||||
new int[] { 0, 2, 2, 2, 2, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 3),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 4),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 5),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // STRAIGHT_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 2, 4, 2, 4, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 0, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CURVED_ROAD
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 2, 2, 2, 2, 4, 0, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
};
|
||||
|
||||
/** The standard tile set for a game of Venison. */
|
||||
protected static ArrayList TILE_SET = new ArrayList();
|
||||
|
||||
@@ -279,7 +780,7 @@ public class TileUtil implements TileCodes
|
||||
addTiles(3, TILE_SET, new VenisonTile(CITY_ONE_ROAD_TEE, false));
|
||||
addTiles(3, TILE_SET, new VenisonTile(CITY_ONE_ROAD_STRAIGHT, false));
|
||||
|
||||
addTiles(4, TILE_SET, new VenisonTile(CLOISTER, false));
|
||||
addTiles(4, TILE_SET, new VenisonTile(CLOISTER_PLAIN, false));
|
||||
addTiles(2, TILE_SET, new VenisonTile(CLOISTER_ROAD, false));
|
||||
|
||||
addTiles(1, TILE_SET, new VenisonTile(FOUR_WAY_ROAD, false));
|
||||
@@ -287,160 +788,4 @@ public class TileUtil implements TileCodes
|
||||
addTiles(8, TILE_SET, new VenisonTile(STRAIGHT_ROAD, false));
|
||||
addTiles(9, TILE_SET, new VenisonTile(CURVED_ROAD, false));
|
||||
}
|
||||
|
||||
/** Used to figure out which edges match up to which when comparing
|
||||
* adjacent tiles. */
|
||||
protected static final int[] EDGE_MAP = new int[] {
|
||||
-1, NORTH, -1,
|
||||
WEST, -1, EAST,
|
||||
-1, SOUTH, -1
|
||||
};
|
||||
|
||||
/** A table indicating which tiles have which edges. */
|
||||
protected static final int[] TILE_EDGES = new int[] {
|
||||
-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, // DISCONNECTED_CITY_TWO
|
||||
GRASS, CITY, GRASS, CITY, // DISCONNECTED_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
|
||||
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
|
||||
};
|
||||
|
||||
/** A table describing the geometry of the features (cities, roads,
|
||||
* etc.) of each tile. */
|
||||
protected static final Object[] TILE_FEATURES = new Object[] {
|
||||
// one must offset tile type by one when indexing into this array
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), }, // CITY_FOUR
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_THREE
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_THREE_ROAD
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 0, 4, 1, 3, 2, 3, 2, 4 },
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 2, 4, 2, 3, 3, 3, 4, 4 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 3, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 0, 4, 4, 0, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ROAD
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 0, 4, 4, 0, 4, 2, 2, 4 },
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 2, 4, 4, 2, 4, 4 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 4, 4, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(CITY, 0), // CITY_TWO_ACROSS
|
||||
new IntTuple(GRASS, 0),
|
||||
new int[] { 0, 4, 1, 3, 3, 3, 4, 4 },
|
||||
new IntTuple(GRASS, 1),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(CITY, 1),
|
||||
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // DISCONNECTED_CITY_TWO_ACROSS
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 1, 3, 0, 4 },
|
||||
new IntTuple(CITY, 1),
|
||||
new int[] { 4, 0, 3, 1, 3, 3, 4, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_RIGHT
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 2, 4, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_LEFT
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_TEE
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 0, 2, 2, 2 },
|
||||
new IntTuple(ROAD, 1),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CITY_ONE_ROAD_STRAIGHT
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 0, 0, 1, 1, 3, 1, 4, 0 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 0, 2, 4, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CLOISTER
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CLOISTER_ROAD
|
||||
new IntTuple(CITY, 0),
|
||||
new int[] { 1, 1, 3, 1, 3, 3, 1, 3 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 3, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // FOUR_WAY_ROAD
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 0, 2, 2 },
|
||||
new IntTuple(ROAD, 1),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 3),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // THREE_WAY_ROAD
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 0, 2, 2, 2 },
|
||||
new IntTuple(ROAD, 1),
|
||||
new int[] { 2, 2, 4, 2 },
|
||||
new IntTuple(ROAD, 2),
|
||||
new int[] { 2, 2, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // STRAIGHT_ROAD
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 0, 2, 4 }},
|
||||
|
||||
new Object[] { new IntTuple(GRASS, 0), // CURVED_ROAD
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 2, 2, 2, 4 },
|
||||
new IntTuple(ROAD, 0),
|
||||
new int[] { 0, 2, 2, 2 }},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user