Package com.jcloisterzone.game.phase

Source Code of com.jcloisterzone.game.phase.CornCirclePhase

package com.jcloisterzone.game.phase;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.jcloisterzone.Player;
import com.jcloisterzone.action.MeepleAction;
import com.jcloisterzone.action.PlayerAction;
import com.jcloisterzone.action.UndeployAction;
import com.jcloisterzone.board.Location;
import com.jcloisterzone.board.Position;
import com.jcloisterzone.board.Tile;
import com.jcloisterzone.board.pointer.FeaturePointer;
import com.jcloisterzone.board.pointer.MeeplePointer;
import com.jcloisterzone.event.CornCircleSelectOptionEvent;
import com.jcloisterzone.event.SelectActionEvent;
import com.jcloisterzone.feature.City;
import com.jcloisterzone.feature.Farm;
import com.jcloisterzone.feature.Feature;
import com.jcloisterzone.figure.BigFollower;
import com.jcloisterzone.figure.Follower;
import com.jcloisterzone.figure.Mayor;
import com.jcloisterzone.figure.Meeple;
import com.jcloisterzone.figure.Phantom;
import com.jcloisterzone.figure.SmallFollower;
import com.jcloisterzone.figure.Wagon;
import com.jcloisterzone.game.Game;
import com.jcloisterzone.game.Snapshot;
import com.jcloisterzone.game.capability.CornCircleCapability;
import com.jcloisterzone.game.capability.CornCircleCapability.CornCicleOption;

public class CornCirclePhase extends Phase {

    private final CornCircleCapability cornCircleCap;

    public CornCirclePhase(Game game) {
        super(game);
        cornCircleCap = game.getCapability(CornCircleCapability.class);
    }

    @Override
    public boolean isActive() {
        return game.hasCapability(CornCircleCapability.class);
    }

    @Override
    public Player getActivePlayer() {
        Player player = cornCircleCap.getCornCirclePlayer();
        if (player == null) return super.getActivePlayer();
        return player;
    }

    @Override
    public void enter() {
        if (getTile().getCornCircle() == null) {
            next();
            return;
        }
        game.post(new CornCircleSelectOptionEvent(getActivePlayer(), getTile().getPosition()));
    }

    private void nextCornPlayer() {
        Player active = getActivePlayer();
        if (active == game.getTurnPlayer()) {
            cornCircleCap.setCornCirclePlayer(null);
            cornCircleCap.setCornCircleOption(null);
            next();
        } else {
            Player cornPlayer = game.getNextPlayer(active);
            cornCircleCap.setCornCirclePlayer(cornPlayer);
            prepareCornAction();
        }
    }

    @Override
    public void cornCiclesRemoveOrDeploy(boolean remove) {
        if (remove) {
            cornCircleCap.setCornCircleOption(CornCicleOption.REMOVAL);
        } else {
            cornCircleCap.setCornCircleOption(CornCicleOption.DEPLOYMENT);
        }
        Player cornPlayer = game.getNextPlayer(getActivePlayer());
        cornCircleCap.setCornCirclePlayer(cornPlayer);
        prepareCornAction();
    }

    private void prepareCornAction() {
        List<PlayerAction<?>> actions;
        Class<? extends Feature> cornType = getTile().getCornCircle();
        if (cornCircleCap.getCornCircleOption() == CornCicleOption.REMOVAL) {
            actions = prepareRemovalAction(cornType);
        } else {
            actions = prepareDeploymentAction(cornType);
        }
        if (actions.isEmpty()) {
            nextCornPlayer();
        } else {
            boolean passAllowed = cornCircleCap.getCornCircleOption() == CornCicleOption.DEPLOYMENT;
            game.post(new SelectActionEvent(getActivePlayer(), actions, passAllowed));
        }
    }

    private List<PlayerAction<?>> prepareDeploymentAction(Class<? extends Feature> cornType) {
        List<FeaturePointer> pointers = new ArrayList<>();
        for (Meeple m : game.getDeployedMeeples()) {
            if (!(m instanceof Follower)) continue;
            if (m.getPlayer() != getActivePlayer()) continue;
            if (!cornType.isInstance(m.getFeature())) continue;
            pointers.add(new FeaturePointer(m.getPosition(), m.getLocation()));
        }
        if (pointers.isEmpty()) return Collections.emptyList();

        List<PlayerAction<?>> actions = new ArrayList<>();
        //TODO nice to do this in generic way independently on particular followers enumeration
        if (getActivePlayer().hasFollower(SmallFollower.class)) {
            actions.add(new MeepleAction(SmallFollower.class).addAll(pointers));
        }
        if (getActivePlayer().hasFollower(BigFollower.class)) {
            actions.add(new MeepleAction(BigFollower.class).addAll(pointers));
        }
        if (getActivePlayer().hasFollower(Phantom.class)) {
            actions.add(new MeepleAction(Phantom.class).addAll(pointers));
        }
        if (cornType.equals(City.class) && getActivePlayer().hasFollower(Mayor.class)) {
            actions.add(new MeepleAction(Mayor.class).addAll(pointers));
        }
        if (!cornType.equals(Farm.class) && getActivePlayer().hasFollower(Wagon.class)) {
            actions.add(new MeepleAction(Wagon.class).addAll(pointers));
        }
        return actions;
    }

    private List<PlayerAction<?>> prepareRemovalAction(Class<? extends Feature> cornType) {
      UndeployAction action = null;
        for (Meeple m : game.getDeployedMeeples()) {
            if (!(m instanceof Follower)) continue;
            if (m.getPlayer() != getActivePlayer()) continue;
            if (!cornType.isInstance(m.getFeature())) continue;
            if (action == null) {
                action = new UndeployAction("undeploy");
            }
            action.add(new MeeplePointer(m));
        }
        if (action == null) return Collections.emptyList();
        return Collections.<PlayerAction<?>>singletonList(action);
    }

    @Override
    public void undeployMeeple(Position p, Location loc, Class<? extends Meeple> meepleType, Integer meepleOwner) {
        if (cornCircleCap.getCornCircleOption() != CornCicleOption.REMOVAL) {
            logger.error("Removal not selected as corn options.");
            return;
        }
        Meeple m = game.getMeeple(p, loc, meepleType, game.getPlayer(meepleOwner));
        Class<? extends Feature> cornType = getTile().getCornCircle();
        if (!cornType.isInstance(m.getFeature())) {
            logger.error("Improper feature type");
            return;
        }
        m.undeploy();
        nextCornPlayer();
    }

    @Override
    public void deployMeeple(Position p, Location loc, Class<? extends Meeple> meepleType) {
        if (cornCircleCap.getCornCircleOption() != CornCicleOption.DEPLOYMENT) {
            logger.error("Deployment wasn't selected as corn options.");
            return;
        }
        List<Meeple> meeples = getBoard().get(p).getFeature(loc).getMeeples();
        if (meeples.isEmpty()) {
            logger.error("Feature must be occupied");
            return;
        }
        if (meeples.get(0).getPlayer() != getActivePlayer()) {
            logger.error("Feature must be occupies with own follower");
            return;
        }

        Meeple m = getActivePlayer().getMeepleFromSupply(meepleType);
        Tile tile = getBoard().get(p);
        m.deploy(tile, loc);
        nextCornPlayer();
    }

    @Override
    public void pass() {
        if (cornCircleCap.getCornCircleOption() == CornCicleOption.REMOVAL) {
            logger.error("Removal cannot be passed");
            return;
        }
        nextCornPlayer();
    }

    @Override
    public void loadGame(Snapshot snapshot) {
        setEntered(true); //avoid call enter on load phase to this phase switch
        if (cornCircleCap.getCornCircleOption() == null) {
            game.post(new CornCircleSelectOptionEvent(game.getActivePlayer(), getTile().getPosition()));
        } else {
            prepareCornAction();
        }
    }
}
TOP

Related Classes of com.jcloisterzone.game.phase.CornCirclePhase

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.