Package com.jcloisterzone.game.capability

Source Code of com.jcloisterzone.game.capability.RiverCapability

package com.jcloisterzone.game.capability;

import java.util.Map.Entry;
import java.util.Set;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.jcloisterzone.Expansion;
import com.jcloisterzone.XmlUtils;
import com.jcloisterzone.board.Location;
import com.jcloisterzone.board.Position;
import com.jcloisterzone.board.Rotation;
import com.jcloisterzone.board.Tile;
import com.jcloisterzone.board.TileGroupState;
import com.jcloisterzone.board.TilePack;
import com.jcloisterzone.board.TileSymmetry;
import com.jcloisterzone.event.TileEvent;
import com.jcloisterzone.game.Capability;
import com.jcloisterzone.game.Game;


public class RiverCapability extends Capability {

    private static final String R1_LAKE_ID = "R1.I.e";
    private static final String R2_LAKE_ID = "R2.I.v";

    public RiverCapability(Game game) {
        super(game);
    }

    @Override
    public void initTile(Tile tile, Element xml) {
        NodeList nl;
        nl = xml.getElementsByTagName("river");
        assert nl.getLength() <= 1;
        if (nl.getLength() == 1) {
            Location river = XmlUtils.union(XmlUtils.asLocation((Element) nl.item(0)));
            tile.setRiver(river);
            if (tile.getSymmetry() != TileSymmetry.NONE) {
                if (tile.getRiver().isRotationOf(Location.WE)) {
                    tile.setSymmetry(TileSymmetry.S2);
                } else {
                    tile.setSymmetry(TileSymmetry.NONE);
                }
            }
        }
    };

    private String getLakeId() {
        return game.hasExpansion(Expansion.RIVER_II) ? R2_LAKE_ID : R1_LAKE_ID;
    }

    @Override
    public void begin() {
        getTilePack().setGroupState("default", TileGroupState.WAITING);
        getTilePack().setGroupState("river-start", TileGroupState.ACTIVE);
        if (!game.hasExpansion(Expansion.RIVER_II)) {
            getTilePack().setGroupState("river", TileGroupState.ACTIVE);
        }
    }

    public void activateNonRiverTiles() {
        getTilePack().setGroupState("default", TileGroupState.ACTIVE);
        getTilePack().setGroupState("river", TileGroupState.RETIRED);
        Tile lake = getTilePack().drawTile(TilePack.INACTIVE_GROUP, getLakeId());
        getBoard().refreshAvailablePlacements(lake);
        Entry<Position, Set<Rotation>> entry = getBoard().getAvailablePlacements().entrySet().iterator().next();
        lake.setRotation(entry.getValue().iterator().next());
        getBoard().add(lake, entry.getKey());
        getBoard().mergeFeatures(lake);
        game.post(new TileEvent(TileEvent.PLACEMENT, null, lake, lake.getPosition()));
    }

    @Override
    public void turnPartCleanUp() {
        if (getTile().getRiver() == null) return;
        if (getTilePack().isEmpty()) {
            if (getTilePack().getGroupState("river") == TileGroupState.ACTIVE) {
                activateNonRiverTiles();
            } else {
                getTilePack().setGroupState("river-start", TileGroupState.RETIRED);
                getTilePack().setGroupState("river", TileGroupState.ACTIVE);
            }
        }
    }

    @Override
    public boolean isTilePlacementAllowed(Tile tile, Position p) {
        if (tile.getRiver() == null) return true;
        for (Entry<Location, Tile> e : getBoard().getAdjacentTilesMap(p).entrySet()) {

            //check river connection
            Location tileRelativePosition = e.getKey();
            Tile placedTile = e.getValue();
            if (placedTile.getRiver() == null) return false; //e.g. count of carcassone preplaced tiles
            boolean r1 = tileRelativePosition.rotateCCW(tile.getRotation()).isPartOf(tile.getRiver());
            boolean r2 = tileRelativePosition.rotateCCW(placedTile.getRotation()).rev().isPartOf(placedTile.getRiver());
            if (!(r1 & r2)) return false;

            //check U-turn
            Location continueRiver = tile.getRiver().rotateCW(tile.getRotation()).substract(tileRelativePosition);
            if (continueRiver == Location.INNER_FARM) return true; //lake
            for (Location continueSide: Location.sides()) { //split beacuse of river fork
                if (continueRiver.intersect(continueSide) == null) continue;
                Position pCheck = p.add(continueSide).add(continueSide.rotateCW(Rotation.R90));
                if (getBoard().get(pCheck) != null) return false;
                pCheck = p.add(continueSide).add(continueSide.rotateCCW(Rotation.R90));
                if (getBoard().get(pCheck) != null) return false;
                pCheck = p.add(continueSide).add(continueSide);
                if (getBoard().get(pCheck) != null) return false;
                //also forbid fork "parallel river"
                Tile next = getBoard().get(p.add(continueSide.rotateCW(Rotation.R90)));
                if (next != null && next.getRiver().rotateCW(next.getRotation()).intersect(continueSide) == continueSide) return false;
                next = getBoard().get(p.add(continueSide.rotateCCW(Rotation.R90)));
                if (next != null && next.getRiver().rotateCW(next.getRotation()).intersect(continueSide) == continueSide) return false;
            }
        }
        return true;
    }

}
TOP

Related Classes of com.jcloisterzone.game.capability.RiverCapability

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.