Package com.barrybecker4.game.twoplayer.pente

Source Code of com.barrybecker4.game.twoplayer.pente.PenteMoveGenerator

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

import com.barrybecker4.common.geometry.Location;
import com.barrybecker4.game.common.Move;
import com.barrybecker4.game.common.MoveList;
import com.barrybecker4.game.common.board.GamePiece;
import com.barrybecker4.game.twoplayer.common.BestMoveFinder;
import com.barrybecker4.game.twoplayer.common.TwoPlayerMove;
import com.barrybecker4.optimization.parameter.ParameterArray;

import static com.barrybecker4.game.twoplayer.common.search.strategy.SearchStrategy.WINNING_VALUE;

/**
* Responsible for determining a set of reasonable next moves.
*
* @author Barry Becker
*/
final class PenteMoveGenerator {

    private PenteSearchable searchable_;

    /**
     * Constructor.
     */
    public PenteMoveGenerator(PenteSearchable searchable) {
        searchable_ = searchable;
    }

    /**
     * @return all reasonably good next moves.
     */
    public final MoveList generateMoves(TwoPlayerMove lastMove, ParameterArray weights) {
        MoveList moveList = new MoveList();

        PenteBoard pb = searchable_.getBoard();
        pb.determineCandidateMoves();

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

        int ncols = pb.getNumCols();
        int nrows = pb.getNumRows();

        for (int i = 1; i <= ncols; i++ ) {
            for (int j = 1; j <= nrows; j++ ) {
                if ( pb.isCandidateMove( j, i )) {
                    TwoPlayerMove m;
                    if (lastMove == null)
                       m = TwoPlayerMove.createMove( j, i, 0, new GamePiece(player1));
                    else
                       m = TwoPlayerMove.createMove( j, i, lastMove.getValue(), new GamePiece(player1));
                    searchable_.makeInternalMove( m );
                    m.setValue(searchable_.worth( m, weights));
                    // now revert the board
                    searchable_.undoInternalMove( m );
                    moveList.add( m );
                }
            }
        }
        BestMoveFinder finder = new BestMoveFinder(searchable_.getSearchOptions().getBestMovesSearchOptions());
        return finder.getBestMoves( player1, moveList);
    }

    /**
     * @return a list of urgent moves (i.e positions that can result in a win for either player.
     */
    public MoveList generateUrgentMoves(TwoPlayerMove lastMove, ParameterArray weights) {
        // no urgent moves at start of game.
        if (lastMove == null)  {
            return new MoveList();
        }
         MoveList allMoves =
             findMovesForBothPlayers(lastMove, weights);

        // now keep only those that result in a win or loss.
        MoveList urgentMoves = new MoveList();
        boolean currentPlayer = !lastMove.isPlayer1();

        for (Move m : allMoves) {
            TwoPlayerMove move = (TwoPlayerMove) m;
            // if its not a winning move or we already have it, then skip
            if ( Math.abs(move.getValue()) >= WINNING_VALUE  && !contains(move, urgentMoves) ) {
                move.setUrgent(true);
                move.setPlayer1(currentPlayer);
                move.setPiece(new GamePiece(currentPlayer));
                urgentMoves.add(move);
            }
        }
        return urgentMoves;
    }

    /**
     * Consider both our moves and opponent moves.
     * @return Set of all next moves.
     */
    private MoveList findMovesForBothPlayers(TwoPlayerMove lastMove, ParameterArray weights) {
        MoveList allMoves = new MoveList();

        MoveList moves = generateMoves(lastMove, weights);
        allMoves.addAll(moves);

        // unlike go, I don't know if we need this
        TwoPlayerMove oppLastMove = lastMove.copy();
        oppLastMove.setPlayer1(!lastMove.isPlayer1());
        MoveList opponentMoves =
                generateMoves(oppLastMove, weights);
        for (Move m : opponentMoves){
            TwoPlayerMove move = (TwoPlayerMove) m;
            allMoves.add(move);
        }

        return allMoves;
    }

    /**
     * @return true of the {@link MoveList} contains the specified move.
     */
    private boolean contains(TwoPlayerMove move, MoveList moves) {
        for (Move m : moves) {
            Location moveLocation = ((TwoPlayerMove)m).getToLocation();
            if (moveLocation.equals(move.getToLocation())) {
                return true;
            }
        }
        return false;
    }
}
TOP

Related Classes of com.barrybecker4.game.twoplayer.pente.PenteMoveGenerator

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.