Package com.barrybecker4.game.twoplayer.blockade.board.move

Source Code of com.barrybecker4.game.twoplayer.blockade.board.move.MoveGenerator

/** Copyright by Barry G. Becker, 2000-2011. Licensed under MIT License: http://www.opensource.org/licenses/MIT  */
package com.barrybecker4.game.twoplayer.blockade.board.move;

import com.barrybecker4.game.common.GameContext;
import com.barrybecker4.game.common.MoveList;
import com.barrybecker4.game.common.board.BoardPosition;
import com.barrybecker4.game.twoplayer.blockade.board.BlockadeBoard;
import com.barrybecker4.game.twoplayer.blockade.board.BlockadeBoardPosition;
import com.barrybecker4.game.twoplayer.blockade.board.move.wall.WallPlacementFinder;
import com.barrybecker4.game.twoplayer.blockade.board.path.Path;
import com.barrybecker4.game.twoplayer.blockade.board.path.PathList;
import com.barrybecker4.game.twoplayer.common.TwoPlayerMove;
import com.barrybecker4.optimization.parameter.ParameterArray;

import java.util.LinkedList;
import java.util.List;

/**
* Generates candidate next moves for a game of Blockade given a current board state.
*
* @author Barry Becker
*/
public class MoveGenerator {

    private BlockadeBoard board;
    private ParameterArray weights_;

    /** Constructor */
    public MoveGenerator(ParameterArray weights, BlockadeBoard board) {

        this.board = board;
        weights_ = weights;
    }

    /**
     * First find the opponent's shortest paths.
     * Then For each piece of the current player's NUM_HOME pieces, add a move that represents a step along
     * its shortest paths to the opponent homes and all reasonable wall placements.
     * To limit the number of wall placements we will restrict possibilities to those positions which
     * effect one of the *opponents* shortest paths.
     * @param lastMove last move that was made on the board
     * @return list of generated moves.
     */
    public MoveList generateMoves(TwoPlayerMove lastMove) {

        MoveList moveList = new MoveList();
        boolean player1 = (lastMove == null) || !lastMove.isPlayer1();

        // There is one path from every piece to every opponent home (i.e. n*NUM_HOMES)
        PathList opponentPaths = board.findAllOpponentShortestPaths(player1);

        List<BoardPosition> pawnLocations = new LinkedList<BoardPosition>();
        for ( int row = 1; row <= board.getNumRows(); row++ ) {
            for ( int col = 1; col <= board.getNumCols(); col++ ) {
                BoardPosition p = board.getPosition( row, col );
                if ( p.isOccupied() && p.getPiece().isOwnedByPlayer1() == player1 ) {
                    pawnLocations.add(p);
                    addMoves( p, moveList, opponentPaths, weights_ );
                }
            }
        }
        if (moveList.isEmpty())
            GameContext.log(1, "There aren't any moves to consider for lastMove=" + lastMove
                    + " Complete movelist =" + board.getMoveList() + " \nThe pieces are at:" + pawnLocations);

        return moveList;
    }

    /**
     * Find all the moves a piece can make from position p, and insert them into moveList.
     *
     * @param position the piece to check from its new location.
     * @param moveList add the potential moves to this existing list.
     * @param weights to use.
     * @return the number of moves added.
     */
    private int addMoves( BoardPosition position, MoveList moveList, PathList opponentPaths, ParameterArray weights) {
        int numMovesAdded = 0;

        // first find the NUM_HOMES shortest paths for p.
        PathList paths = board.findShortestPaths((BlockadeBoardPosition)position);

        WallPlacementFinder wallFinder = new WallPlacementFinder(board, opponentPaths, weights);

        // for each of these paths, add possible wall positions.
        // Take the first move from each shortest path and add the wall positions to it.
        for (Path path : paths) {
            if (path.getLength() > 0) {
                 numMovesAdded += addPotentialMoves(moveList, wallFinder, path);
            }
            else {
                GameContext.log(1, "one of the paths was empty : " + paths);
            }
        }

        return numMovesAdded;
    }

    /**
     * Add reasonable next moves.
     * @return the number of moves added.
     */
    private int addPotentialMoves(MoveList moveList, WallPlacementFinder wallFinder, Path path) {

        BlockadeMove firstStep = path.get(0);
        // make the move
        board.makeMove(firstStep);

        // after making the first move, the shortest paths may have changed somewhat.
        // unfortunately, I think we need to recalculate them.
        BlockadeBoardPosition newPos =
                board.getPosition(firstStep.getToRow(), firstStep.getToCol());
        PathList ourPaths = board.findShortestPaths(newPos);

        List<BlockadeMove> wallMoves = wallFinder.findWallPlacementsForMove(firstStep, ourPaths);
        GameContext.log(2, "num wall placements for Move = " + wallMoves.size());
        board.undoMove();

        // iterate through the wallMoves and add only the ones that are not there already
        for (BlockadeMove wallMove : wallMoves) {
            if (!moveList.contains(wallMove)) {
                moveList.add(wallMove);
            }
        }
        return wallMoves.size();
    }
}
TOP

Related Classes of com.barrybecker4.game.twoplayer.blockade.board.move.MoveGenerator

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.