Package com.barrybecker4.puzzle.tantrix.model

Source Code of com.barrybecker4.puzzle.tantrix.model.BorderFinder

// Copyright by Barry G. Becker, 2012. Licensed under MIT License: http://www.opensource.org/licenses/MIT
package com.barrybecker4.puzzle.tantrix.model;

import com.barrybecker4.common.geometry.Box;
import com.barrybecker4.common.geometry.Location;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import static com.barrybecker4.puzzle.tantrix.model.HexTile.NUM_SIDES;

/**
* Finds the set of moves on the border of the current 'tantrix'.
* The 'tantrix' is the set of currently played consistent tiles.
*
* @author Barry Becker
*/
public class BorderFinder {

    private Tantrix tantrix;
    private PathColor primaryColor;
    private Set<Location> visited;
    private int maxHalfPathLength;
    private Box boundingBox;

    /**
     * Constructor
     */
    public BorderFinder(Tantrix tantrix, int numTiles, PathColor primaryColor) {
        this.tantrix = tantrix;
        this.primaryColor = primaryColor;
        this.maxHalfPathLength = (numTiles + 1)/2;
        boundingBox = tantrix.getBoundingBox();
    }

    /**
     * Travel the primary path in both directions, adding all adjacent empty placements
     * as long as they do not push either boundingBox dimension beyond maxHalfPathLength.
     * @return list of legal next placements
     */
    public Set<Location> findBorderPositions() {
        Set<Location> positions = new LinkedHashSet<Location>();
        visited = new HashSet<Location>();

        TilePlacement lastPlaced = tantrix.getLastTile();

        Queue<TilePlacement> searchQueue = new TilePlacementList();
        searchQueue.add(lastPlaced);
        visited.add(lastPlaced.getLocation());

        while (!searchQueue.isEmpty()) {
            TilePlacement placement = searchQueue.remove();
            positions.addAll(findEmptyNeighborLocations(placement));
            searchQueue.addAll(findPrimaryPathNeighbors(placement));
        }

        return positions;
    }

    /**
     * @return all the empty neighbor positions next to the specified placement
     */
    private List<Location> findEmptyNeighborLocations(TilePlacement placement) {
        List<Location> emptyNbrLocations = new LinkedList<Location>();
        for (byte i=0; i< NUM_SIDES; i++) {

            Location nbrLoc = HexUtil.getNeighborLocation(placement.getLocation(), i);
            if (tantrix.get(nbrLoc) == null) {
                Box newBox = new Box(boundingBox, nbrLoc);
                if (newBox.getMaxDimension() <= maxHalfPathLength) {
                    emptyNbrLocations.add(nbrLoc);
                    boundingBox = newBox;
                }
            }
        }
        return emptyNbrLocations;
    }

    /**
     * @return the one or two neighbors that can be found by following the primary path.
     */
    private TilePlacementList findPrimaryPathNeighbors(TilePlacement previous) {

        TilePlacementList pathNbrs = new TilePlacementList();
        for (byte i=0; i< NUM_SIDES; i++) {
            PathColor color = previous.getPathColor(i);
            if (color == primaryColor) {
                TilePlacement nbr = tantrix.getNeighbor(previous, i);
                if (nbr != null && !visited.contains(nbr.getLocation())) {
                    Box newBox = new Box(boundingBox, nbr.getLocation());
                    if (newBox.getMaxDimension() < maxHalfPathLength) {
                        pathNbrs.add(nbr);
                        visited.add(nbr.getLocation());
                        boundingBox = newBox;
                    }
                }
            }
        }
        return pathNbrs;
    }
}
TOP

Related Classes of com.barrybecker4.puzzle.tantrix.model.BorderFinder

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.