Package com.barrybecker4.game.twoplayer.go.board.analysis.eye

Source Code of com.barrybecker4.game.twoplayer.go.board.analysis.eye.EyeTypeAnalyzer

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

import com.barrybecker4.game.common.board.BoardPosition;
import com.barrybecker4.game.twoplayer.go.board.GoBoard;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.E1Information;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.E2Information;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.E3Information;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.EyeInformation;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.FalseEyeInformation;
import com.barrybecker4.game.twoplayer.go.board.analysis.eye.information.TerritorialEyeInformation;
import com.barrybecker4.game.twoplayer.go.board.analysis.group.GroupAnalyzer;
import com.barrybecker4.game.twoplayer.go.board.analysis.neighbor.NeighborAnalyzer;
import com.barrybecker4.game.twoplayer.go.board.analysis.neighbor.NeighborType;
import com.barrybecker4.game.twoplayer.go.board.elements.eye.IGoEye;
import com.barrybecker4.game.twoplayer.go.board.elements.group.IGoGroup;
import com.barrybecker4.game.twoplayer.go.board.elements.position.GoBoardPosition;
import com.barrybecker4.game.twoplayer.go.board.elements.position.GoBoardPositionSet;

import java.util.Set;

/**
* Determine the type of an eye on the board.
*
* @author Barry Becker
*/
public class EyeTypeAnalyzer {

    private IGoEye eye_;
    private GoBoard board_;
    private NeighborAnalyzer nbrAnalyzer_;
    private GroupAnalyzer groupAnalyzer_;


    public EyeTypeAnalyzer(IGoEye eye, GoBoard board, GroupAnalyzer analyzer) {
        eye_ = eye;
        board_ = board;
        groupAnalyzer_ = analyzer;
        nbrAnalyzer_ = new NeighborAnalyzer(board);
    }

    /**
     * @return the eye type determined based on the properties and
     *     nbrs of the positions in the spaces_ list.
     */
    public EyeInformation determineEyeInformation()
    {
        GoBoardPositionSet spaces = eye_.getMembers();
        assert (spaces != null): "spaces_ is null";
        int size = spaces.size();

        if (isFalseEye()) {
            return new FalseEyeInformation();
        }
        if ( size == 1 ) {
            return new E1Information();
        }
        if ( size == 2 ) {
            return new E2Information();
        }
        if ( size == 3 ) {
            return new E3Information();
        }
        if ( size > 3 && size < 8 ) {
            BigEyeAnalyzer bigEyeAnalyzer = new BigEyeAnalyzer(eye_);
            return bigEyeAnalyzer.determineEyeInformation();
        }
        return new TerritorialEyeInformation();
    }

    /**
     * Iterate through the spaces_ in the eye.
     * if any are determined to be a false-eye, then return false-eye for the eye type.
     * @return true if we are a false eye.
     */
    private boolean isFalseEye()  {
        GoBoardPositionSet spaces = eye_.getMembers();
        for (GoBoardPosition space : spaces) {
            if ( isFalseEye( space) ) {
                return true;
            }
        }
        return false;
    }

    /**
     * Generally if 3 or more of the nobi neighbors are friendly,
     * and 2 or more of the diagonal nbrs are not, then it is a false eye.
     * However, if against the edge or in the corner, then 2 or more friendly nobi nbrs
     * and 1 or more enemy diagonal nbrs are needed in order to call a false eye.
     * Those enemy diagonal neighbors need to be stronger otherwise they
     * should be considered too weak to cause a false eye.
     *
     * @param space check to see if this space is part of a false eye.
     * @return true if htis is a false eye.
     */
    private boolean isFalseEye( GoBoardPosition space )
    {
        IGoGroup ourGroup = eye_.getGroup();
        boolean groupP1 = ourGroup.isOwnedByPlayer1();
        Set nbrs = nbrAnalyzer_.getNobiNeighbors( space, groupP1, NeighborType.FRIEND );

        if ( nbrs.size() >= 2 ) {

            int numOppDiag = getNumOpponentDiagonals(space, groupP1);

            // now decide if false eye based on nbrs and proximity to edge.
            if ( numOppDiag >= && (nbrs.size() >= 3))
                return true;
            else if (board_.isOnEdge(space) && numOppDiag >=1) {
                return true;
            }
        }
        return false;
    }

    /**
     * Check the diagonals for > 2 of the opponents pieces.
     * there are 2 cases: both opponent pieces on the same vertical or horizontal, or
     * the opponents pieces are on the opposite diagonals
     * @return  The number of diagonal points that are occupied by opponent stones (0, 1, or 2)
     */
    private int getNumOpponentDiagonals(GoBoardPosition space, boolean groupP1) {
        int numOppDiag = 0;
        int r = space.getRow();
        int c = space.getCol();

        if (qualifiedOpponentDiagonal(-1,-1, r,c, groupP1))
            numOppDiag++;
        if (qualifiedOpponentDiagonal(-1, 1, r,c, groupP1))
            numOppDiag++;
        if (qualifiedOpponentDiagonal( 1,-1, r,c, groupP1))
            numOppDiag++;
        if (qualifiedOpponentDiagonal( 1, 1, r,c, groupP1))
            numOppDiag++;
        return numOppDiag;
    }

    /**
     *
     * @return true of the enemy piece on the diagonal is relatively strong and there are group stones adjacent.
     */
    private boolean qualifiedOpponentDiagonal(int rowOffset, int colOffset, int r, int c, boolean groupP1)
    {
        GoBoardPosition diagPos = (GoBoardPosition)board_.getPosition( r + rowOffset, c + colOffset );
        if (diagPos == null || diagPos.isUnoccupied() || diagPos.getPiece().isOwnedByPlayer1() == groupP1 )
            return false;

        BoardPosition pos1 = board_.getPosition( r + rowOffset, c );
        BoardPosition pos2 = board_.getPosition( r, c + colOffset );

        return (pos1.isOccupied() && (pos1.getPiece().isOwnedByPlayer1() == groupP1) &&
                pos2.isOccupied() && (pos2.getPiece().isOwnedByPlayer1() == groupP1) &&
                groupAnalyzer_.isTrueEnemy(diagPos));
    }
}
TOP

Related Classes of com.barrybecker4.game.twoplayer.go.board.analysis.eye.EyeTypeAnalyzer

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.