Package com.jcloisterzone.board

Source Code of com.jcloisterzone.board.TilePackFactory

package com.jcloisterzone.board;

import static com.jcloisterzone.XmlUtils.attributeIntValue;
import static com.jcloisterzone.XmlUtils.attributeStringValue;
import static com.jcloisterzone.XmlUtils.getTileId;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.google.common.collect.Maps;
import com.jcloisterzone.Expansion;
import com.jcloisterzone.XmlUtils;
import com.jcloisterzone.config.Config;
import com.jcloisterzone.config.Config.DebugConfig;
import com.jcloisterzone.game.CustomRule;
import com.jcloisterzone.game.Game;
import com.jcloisterzone.game.PlayerSlot;
import com.jcloisterzone.game.capability.RiverCapability;
import com.jcloisterzone.game.capability.TunnelCapability;


public class TilePackFactory {

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

    public static final String DEFAULT_TILE_GROUP = "default";

    private final TileFactory tileFactory = new TileFactory();

    protected Game game;
    protected Config config;
    protected Map<Expansion, Element> defs;

    private Set<String> usedIds = new HashSet<>(); //for assertion only


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

    public void setConfig(Config config) {
        this.config = config;
    }

    public void setExpansions(Set<Expansion> expansions) {
        defs = Maps.newLinkedHashMap();
        for (Expansion expansion : expansions) {
            defs.put(expansion, getExpansionDefinition(expansion));
        }
    }

    public int getExpansionSize(Expansion expansion) {
        Element el = getExpansionDefinition(expansion);
        NodeList nl = el.getElementsByTagName("tile");
        int size = 0;
        for (int i = 0; i < nl.getLength(); i++) {
            Element tileElement = (Element) nl.item(i);
            String tileId = getTileId(expansion, tileElement);
            if (!Tile.ABBEY_TILE_ID.equals(tileId)) {
                size += getTileCount(tileElement, tileId);
            }
        }
        return size;
    }

    protected  URL getStandardCardsConfig(Expansion expansion) {
        String fileName = "tile-definitions/"+expansion.name().toLowerCase()+".xml";
        return TilePackFactory.class.getClassLoader().getResource(fileName);
    }

    protected URL getCardsConfig(Expansion expansion) {
        DebugConfig debugConfig = config.getDebug();
        String fileName = null;
        if (debugConfig != null && debugConfig.getTile_definitions() != null) {
            fileName = debugConfig.getTile_definitions().get(expansion.name());
        }
        if (fileName == null) {
            return getStandardCardsConfig(expansion);
        } else {
            return TilePackFactory.class.getClassLoader().getResource(fileName);
        }
    }

    protected Element getExpansionDefinition(Expansion expansion) {
        return XmlUtils.parseDocument(getCardsConfig(expansion)).getDocumentElement();
    }

    protected Map<String, Integer> getDiscardTiles() {
        Map<String, Integer> discard = new HashMap<>();
        for (Element expansionDef: defs.values()) {
            NodeList nl = expansionDef.getElementsByTagName("discard");
            for (int i = 0; i < nl.getLength(); i++) {
                Element el = (Element) nl.item(i);
                String tileId = el.getAttribute("tile");
                if (discard.containsKey(tileId)) {
                    discard.put(tileId, 1 + discard.get(tileId));
                } else {
                    discard.put(tileId, 1);
                }
            }
        }
        return discard;
    }

    protected boolean isTunnelActive(Expansion expansion) {
        return expansion == Expansion.TUNNEL ||
            (game.hasCapability(TunnelCapability.class) && game.hasRule(CustomRule.TUNNELIZE_ALL_EXPANSIONS));
    }

    protected int getTileCount(Element card, String tileId) {
        if (Tile.ABBEY_TILE_ID.equals(tileId)) {
            return PlayerSlot.COUNT;
        } else {
            return attributeIntValue(card, "count", 1);
        }
    }

    protected String getTileGroup(Tile tile, Element card) {
        String group = game.getTileGroup(tile);
        if (group != null) return group;
        return attributeStringValue(card, "group", DEFAULT_TILE_GROUP);
    }

    public List<Tile> createTiles(Expansion expansion, String tileId, Element card, Map<String, Integer> discardList) {
        if (usedIds.contains(tileId)) {
            throw new IllegalArgumentException("Multiple occurences of id " + tileId + " in tile definition xml.");
        }
        usedIds.add(tileId);

        int count = getTileCount(card, tileId);

        if (discardList.containsKey(tileId)) {
            int n = discardList.get(tileId);
            count -= n;
            if (count <= 0) { //discard can be in multiple expansions and than can be nagative
                return Collections.emptyList();
            }
        }

        List<Tile> tiles = new ArrayList<Tile>(count);
        for (int j = 0; j < count; j++) {
            Tile tile = tileFactory.createTile(expansion, tileId, card, isTunnelActive(expansion));
            try {
                game.initTile(tile, card); //must be called before rotation!

                //set after full inicialization
                tile.setSymmetry(TileSymmetry.forTile(tile));
                tile.setEdgePattern(EdgePattern.forTile(tile));
                tiles.add(tile);
            } catch (RemoveTileException ex) {
                //empty
            }
        }
        return tiles;
    }

    public LinkedList<Position> getPreplacedPositions(String tileId, Element card) {
        NodeList nl = card.getElementsByTagName("position");
        if (nl.getLength() == 0) return null;

        LinkedList<Position> result = new LinkedList<Position>();
        for (int i = 0; i < nl.getLength(); i++) {
            Element posEl = (Element) nl.item(i);
            result.add(new Position(attributeIntValue(posEl, "x"), attributeIntValue(posEl, "y")));
        }
        return result;
    }

    public DefaultTilePack createTilePack() {
        DefaultTilePack tilePack = new DefaultTilePack();

        Map<String, Integer> discardList = getDiscardTiles();

        for (Entry<Expansion, Element> entry: defs.entrySet()) {
            Expansion expansion = entry.getKey();
            NodeList nl = entry.getValue().getElementsByTagName("tile");
            for (int i = 0; i < nl.getLength(); i++) {
                Element tileElement = (Element) nl.item(i);
                String tileId = getTileId(expansion, tileElement);
                LinkedList<Position> positions = getPreplacedPositions(tileId, tileElement);
                for (Tile tile : createTiles(expansion, tileId, tileElement, discardList)) {
                    tilePack.addTile(tile, getTileGroup(tile, tileElement));
                    if (positions != null && !positions.isEmpty()) {
                        Position pos = positions.removeFirst();
                        //hard coded exceptions - should be declared in pack def
                        if (game.hasExpansion(Expansion.COUNT)) {
                            if (tile.getId().equals("BA.RCr")) continue;
                            if (tile.getId().equals("R1.I.s") ||
                                tile.getId().equals("R2.I.s") ||
                                tile.getId().equals("GQ.RFI")) {
                                pos = new Position(1, 2);
                            }
                            if (tile.getId().equals("WR.CFR")) {
                                pos = new Position(-2, -2);
                            }
                        } else if (game.hasExpansion(Expansion.WIND_ROSE)) {
                            if (tile.getId().equals("BA.RCr")) continue;
                            if (game.hasCapability(RiverCapability.class)) {
                                if (tile.getId().equals("WR.CFR")) {
                                    pos = new Position(0, 1);
                                }
                            }
                        }
                        logger.info("Setting initial placement {} for {}", pos, tile);
                        tile.setPosition(pos);
                    }
                }
            }
        }
        return tilePack;
    }

    public Game getGame() {
        return game;
    }

}
TOP

Related Classes of com.jcloisterzone.board.TilePackFactory

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.