Package com.jcloisterzone.board

Source Code of com.jcloisterzone.board.Tile

package com.jcloisterzone.board;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcloisterzone.Expansion;
import com.jcloisterzone.Player;
import com.jcloisterzone.feature.Bridge;
import com.jcloisterzone.feature.City;
import com.jcloisterzone.feature.Cloister;
import com.jcloisterzone.feature.Completable;
import com.jcloisterzone.feature.Feature;
import com.jcloisterzone.feature.MultiTileFeature;
import com.jcloisterzone.feature.Scoreable;
import com.jcloisterzone.feature.Tower;
import com.jcloisterzone.feature.visitor.IsOccupied;
import com.jcloisterzone.feature.visitor.IsOccupiedOrCompleted;
import com.jcloisterzone.feature.visitor.IsOccupoedAndUncompleted;
import com.jcloisterzone.figure.Follower;
import com.jcloisterzone.game.Game;


/**
* Represents one game tile. Contains references on score objects
* which lays on tile and provides logic for tiles merging, rotating
* and placing figures.
*
* @author Roman Krejcik
*/
public class Tile /*implements Cloneable*/ {

    protected final transient Logger logger = LoggerFactory.getLogger(getClass());

    public static final String ABBEY_TILE_ID = "AM.A";

    protected Game game;
    private final Expansion origin;
    private final String id;

    private ArrayList<Feature> features;
    private Bridge bridge; //direct reference to bridge feature

    protected TileSymmetry symmetry;
    protected Position position = null;
    private Rotation rotation = Rotation.R0;

    private EdgePattern edgePattern;

    //expansions data - maybe some map instead ? but still it is only few tiles
    private TileTrigger trigger;
    private Location river;
    private Location flier;
    private Location windRose;
    private Class<? extends Feature> cornCircle;

    public Tile(Expansion origin, String id) {
        this.origin = origin;
        this.id = id;
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    public EdgePattern getEdgePattern() {
        return edgePattern;
    }

    public void setEdgePattern(EdgePattern edgePattern) {
        this.edgePattern = edgePattern;
    }

    public char getEdge(Location side) {
        return getEdgePattern().at(side, rotation);
    }

    public String getId() {
        return id;
    }

    public Expansion getOrigin() {
        return origin;
    }

    protected boolean check(Tile tile, Location rel, Board board) {
        return getEdge(rel) == tile.getEdge(rel.rev());
    }

    public void setFeatures(ArrayList<Feature> features) {
        assert this.features == null;
        this.features = features;
    }

    public List<Feature> getFeatures() {
        return features;
    }

    public Feature getFeature(Location loc) {
        if (loc == Location.ABBOT) loc = Location.CLOISTER;
        for (Feature p : features) {
            if (p.getLocation().equals(loc)) return p;
        }
        return null;
    }

    public Feature getFeaturePartOf(Location loc) {
        if (loc == Location.ABBOT) loc = Location.CLOISTER;
        for (Feature p : features) {
            if (loc.isPartOf(p.getLocation())) {
                return p;
            }
        }
        return null;
    }

    /** merge this to another tile - method argument is tile placed before */
    protected void merge(Tile tile, Location loc) {
        //if (logger.isDebugEnabled()) logger.debug("Merging " + id + " with " + tile.getId());
        Location oppositeLoc = loc.rev();
        MultiTileFeature oppositePiece = (MultiTileFeature) tile.getFeaturePartOf(oppositeLoc);
        if (oppositePiece != null) {
            if (isAbbeyTile()) {
                oppositePiece.setAbbeyEdge(oppositeLoc);
            } else {
                MultiTileFeature thisPiece = (MultiTileFeature) getFeaturePartOf(loc);
                oppositePiece.setEdge(oppositeLoc, thisPiece);
                thisPiece.setEdge(loc, oppositePiece);
            }
        }
        for (int i = 0; i < 2; i++) {
            Location halfSide = i == 0 ? loc.getLeftFarm() : loc.getRightFarm();
            Location oppositeHalfSide = halfSide.rev();
            oppositePiece = (MultiTileFeature) tile.getFeaturePartOf(oppositeHalfSide);
            if (oppositePiece != null) {
                if (isAbbeyTile()) {
                    oppositePiece.setAbbeyEdge(oppositeHalfSide);
                } else {
                    MultiTileFeature thisPiece = (MultiTileFeature) getFeaturePartOf(halfSide);
                    oppositePiece.setEdge(oppositeHalfSide, thisPiece);
                    thisPiece.setEdge(halfSide, oppositePiece);
                }
            }
        }
    }

    protected void unmerge(Tile tile, Location loc) {
        Location oppositeLoc = loc.rev();
        MultiTileFeature oppositePiece = (MultiTileFeature) tile.getFeaturePartOf(oppositeLoc);
        if (oppositePiece != null) {
            oppositePiece.setEdge(oppositeLoc, null);
            if (!isAbbeyTile()) {
                MultiTileFeature thisPiece = (MultiTileFeature) getFeaturePartOf(loc);
                thisPiece.setEdge(loc, null);
            }
        }
        for (int i = 0; i < 2; i++) {
            Location halfSide = i == 0 ? loc.getLeftFarm() : loc.getRightFarm();
            Location oppositeHalfSide = halfSide.rev();
            oppositePiece = (MultiTileFeature) tile.getFeaturePartOf(oppositeHalfSide);
            if (oppositePiece != null) {
                oppositePiece.setEdge(oppositeHalfSide, null);
                if (!isAbbeyTile()) {
                    MultiTileFeature thisPiece = (MultiTileFeature) getFeaturePartOf(halfSide);
                    thisPiece.setEdge(halfSide, null);
                }
            }
        }
    }

    protected void rotate() {
        rotation = rotation.next();
    }

    public void setRotation(Rotation rotation) {
        assert rotation != null;
        this.rotation =  rotation;
    }

    public Rotation getRotation() {
        return rotation;
    }

    public TileSymmetry getSymmetry() {
        return symmetry;
    }

    public void setSymmetry(TileSymmetry symmetry) {
        this.symmetry = symmetry;
    }

    public boolean isAbbeyTile() {
        return id.equals(ABBEY_TILE_ID);
    }

    public boolean hasCloister() {
        return getFeature(Location.CLOISTER) != null;
    }


    public Cloister getCloister() {
        return (Cloister) getFeature(Location.CLOISTER);
    }

    public Tower getTower() {
        return (Tower) getFeature(Location.TOWER);
    }

    public Game getGame() {
        return game;
    }

    public void setGame(Game game) {
        this.game = game;
    }


    public void setPosition(Position p) {
        position = p;
    }

    public Position getPosition() {
        return position;
    }


    public Bridge getBridge() {
        return bridge;
    }

    public void placeBridge(Location bridgeLoc) {
        assert bridge == null && bridgeLoc != null; //TODO AI support - remove bridge from tile
        Location normalizedLoc = bridgeLoc.rotateCCW(rotation);
        bridge = new Bridge();
        bridge.setId(game.idSequnceNextVal());
        bridge.setTile(this);
        bridge.setLocation(normalizedLoc);
        features.add(bridge);
        edgePattern = edgePattern.getBridgePattern(normalizedLoc);
    }

    public Set<Location> getUnoccupiedScoreables(boolean excludeCompleted) {
        Set<Location> locations = new HashSet<>();
        for (Feature f : features) {
            //if (f instanceof Farm && !game.hasCapability(Capability.FARM_PLACEMENT)) continue;
            if (f instanceof Scoreable) {
                IsOccupied visitor;
                if (excludeCompleted && f instanceof Completable) {
                    visitor = new IsOccupiedOrCompleted();
                } else {
                    visitor = new IsOccupied();
                }
                if (f.walk(visitor)) continue;
                locations.add(f.getLocation());
            }
        }
        return locations;
    }

    public Set<Location> getPlayerFeatures(Player player, Class<? extends Feature> featureClass) {
        return getPlayerFeatures(player, featureClass, false);
    }

    public Set<Location> getPlayerUncompletedFeatures(Player player, Class<? extends Feature> featureClass) {
        return getPlayerFeatures(player, featureClass, true);
    }


    private Set<Location> getPlayerFeatures(Player player, Class<? extends Feature> featureClass, boolean uncompletedOnly)  {
        Set<Location> locations = new HashSet<>();
        for (Feature f : features) {
            if (!featureClass.isInstance(f)) continue;
            IsOccupied visitor = uncompletedOnly ? new IsOccupoedAndUncompleted() : new IsOccupied();
            if (f.walk(visitor.with(player).with(Follower.class))) {
                locations.add(f.getLocation());
            }
        }
        return locations;
    }

    @Override
    public String toString() {
        return getId() + '(' + getRotation() + ')';
    }

    public TileTrigger getTrigger() {
        return trigger;
    }

    public void setTrigger(TileTrigger trigger) {
        this.trigger = trigger;
    }

    public boolean hasTrigger(TileTrigger trigger) {
        return trigger == this.trigger;
    }

    public Class<? extends Feature> getCornCircle() {
        return cornCircle;
    }

    public void setCornCircle(Class<? extends Feature> cornCircle) {
        this.cornCircle = cornCircle;
    }

    public City getCityWithPrincess() {
        for (Feature p : features) {
            if (p instanceof City ) {
                City cp = (City) p;
                if (cp.isPricenss()) {
                    return cp;
                }
            }
        }
        return null;
    }


    public Location getRiver() {
        return river;
    }

    public void setRiver(Location river) {
        this.river = river;
    }


    public Location getFlier() {
        return flier;
    }

    public void setFlier(Location flier) {
        this.flier = flier;
    }

    public Location getWindRose() {
        return windRose;
    }

    public void setWindRose(Location windRose) {
        this.windRose = windRose;
    }

    public boolean isBridgeAllowed(Location bridgeLoc) {
        if (origin == Expansion.COUNT || getBridge() != null) return false;
        return edgePattern.isBridgeAllowed(bridgeLoc, rotation);
    }

}
TOP

Related Classes of com.jcloisterzone.board.Tile

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.