/** Called when an entry is added to {@link AtlantiObject#TILES}. */ public void tilesAdded(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(); }
/** * 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); } }
/** Test code. */ public static void main(String[] args) { JFrame frame = new JFrame("Board test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); AtlantiBoardView board = new AtlantiBoardView(null); 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.tilesChanged(set); AtlantiTile placing = new AtlantiTile(CITY_TWO, false, NORTH, 0, 0); board.setTileToBePlaced(placing); // set a feature group to test propagation List<AtlantiTile> tiles = new ArrayList<AtlantiTile>(); CollectionUtil.addAll(tiles, set.iterator()); 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.setVisible(true); }
/** 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); } // tell the controller we're done _ctrl.placeNothing(); } 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 _ctrl.tilePlaced(_placedTile); // 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 let the controller know that the user placed it if (_placingPiecen && _placedTile != null && _placedTile.piecen != null) { _ctrl.piecenPlaced(_placedTile.piecen); // clear out placing piecen mode _placingPiecen = false; } }