Package eu.semberal.migmang.logic

Source Code of eu.semberal.migmang.logic.Referee

package eu.semberal.migmang.logic;

import eu.semberal.migmang.enums.GameColor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* Contains static methods for move validation
* @author lukas.sembera
*/
public class Referee {

    /**
     * Checks if the move is valid having the specified board. Doesn't check captured indexes!
     */
    public static boolean isValidMove(Board board, Move move, boolean isWhiteOnMove) {
        if (move.isIncorrectMove() ||
                !isSquareOnBoard(move.getFrom()) ||
                !isSquareOnBoard(move.getTo()) ||
                isWhiteOnMove && move.getColor() != GameColor.White ||
                !isWhiteOnMove && move.getColor() != GameColor.Black) {
            return false;
        }

        for (Move t : Referee.getAvailableMoves(board, move.getFrom())) {
            if (move.getTo() == t.getTo()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the game is over
     * @return GameColor if some player won or null if the game has not ended yet
     */
    public static GameColor isGameEnded(Board board) {
        if (board.getPiecesCount(GameColor.White) == 0) {
            return GameColor.Black;
        }
        if (board.getPiecesCount(GameColor.Black) == 0) {
            return GameColor.White;
        }

        return null;
    }

    /**
     * Calculates all possible moves for a specific color
     */
    public static Move[] getAllAvailableMovesForColor(Board board, GameColor color) {
        List<Move> temp = new ArrayList<Move>();
        for (int i = 0; i < 81; i++) {
            if (board.getSquare(i) != color) {
                continue;
            }
            temp.addAll(Arrays.asList(getAvailableMoves(board, i)));
        }
        return temp.toArray(new Move[temp.size()]);
    }

    /**
     * Returns all moves without jumping over possibility
     */
    private static Move[] getAvailableMovesWithoutJumpingOver(Board board, int position) {
        List<Move> temp = new ArrayList<Move>();
        int i = position + 9;
        if (areNeighbours(i, position, 1) && isSquareOnBoard(i) && board.getSquare(i) == null) {
            temp.add(new Move(position, i, board.getSquare(position)));
        }
        i = position - 9;
        if (areNeighbours(i, position, 1) && isSquareOnBoard(i) && board.getSquare(i) == null) {
            temp.add(new Move(position, i, board.getSquare(position)));
        }
        i = position + 1;
        if (areNeighbours(i, position, 1) && isSquareOnBoard(i) && board.getSquare(i) == null) {
            temp.add(new Move(position, i, board.getSquare(position)));
        }
        i = position - 1;
        if (areNeighbours(i, position, 1) && isSquareOnBoard(i) && board.getSquare(i) == null) {
            temp.add(new Move(position, i, board.getSquare(position)));
        }
        return temp.toArray(new Move[temp.size()]);
    }

    /**
     * Returns all moves where the piece from current position can move (including jumping over)
     */
    public static Move[] getAvailableMoves(Board board, int position) {
        List<Move> tempList = new ArrayList<Move>();
        tempList.addAll(Arrays.asList(getAvailableMovesWithoutJumpingOver(board, position)));

        /* In a user have only one peice left, jumping over is allowed */
        if (board.getPiecesCount(board.getSquare(position)) == 1) {
            int i = position + 18;
            if (areNeighbours(i, position, 2) && isSquareOnBoard(i) && board.getSquare(i) == null &&
                    board.getSquare(position + 9) ==
                    (board.getSquare(position) == GameColor.White ? GameColor.Black : GameColor.White)) {
                tempList.add(new Move(position, i, board.getSquare(position)));
            }
            i = position - 18;
            if (areNeighbours(i, position, 2) && isSquareOnBoard(i) && board.getSquare(i) == null &&
                    board.getSquare(position - 9) ==
                    (board.getSquare(position) == GameColor.White ? GameColor.Black : GameColor.White)) {
                tempList.add(new Move(position, i, board.getSquare(position)));
            }
            i = position + 2;
            if (areNeighbours(i, position, 2) && isSquareOnBoard(i) && board.getSquare(i) == null &&
                    board.getSquare(position + 1) ==
                    (board.getSquare(position) == GameColor.White ? GameColor.Black : GameColor.White)) {
                tempList.add(new Move(position, i, board.getSquare(position)));
            }
            i = position - 2;
            if (areNeighbours(i, position, 2) && isSquareOnBoard(i) && board.getSquare(i) == null &&
                    board.getSquare(position - 1) ==
                    (board.getSquare(position) == GameColor.White ? GameColor.Black : GameColor.White)) {
                tempList.add(new Move(position, i, board.getSquare(position)));
            }
        }

        return tempList.toArray(new Move[tempList.size()]);

    }

    /**
     * Whether two squares are neighbors on the board.
     * @param m First square
     * @param n Second square
     * @param distance Distance of the squares. If 1, it means they have to be direct neighbours, it 2, there can be one square in the middle, etc.
     */
    private static boolean areNeighbours(int m, int n, int distance) {
        if ((m % 9 == n % 9 || m / 9 == n / 9) && (Math.abs(m - n) == distance || Math.abs(m - n) == 9*distance)) {
            return true;
        }
        return false;
    }

   
    private static boolean isSquareOnBoard(int i) {
        return (i >= 0 && i <= 80);
    }

    /**
     * Adds capturing information to a move
     */
    public static void addCaptureInformationToMove(Board board, Move move) {
        GameColor color = move.getColor();
        GameColor colorForCaptures = (color == GameColor.White ? GameColor.Black : GameColor.White);
        Board s = new Board(board).addMoveWithoutCaptures(move);

        if (move.getTo() == move.getFrom() + 2) { //if distance is 2, jump over occured and is necessary to delete piece in the middle
            move.addCapturedPieceIndex(move.getFrom() + 1);
        } else if (move.getTo() == move.getFrom() - 2) {
            move.addCapturedPieceIndex(move.getFrom() - 1);
        } else if (move.getTo() == move.getFrom() + 18) {
            move.addCapturedPieceIndex(move.getFrom() + 9);
        } else if (move.getTo() == move.getFrom() - 18) {
            move.addCapturedPieceIndex(move.getFrom() - 9);
        }

        for (int i = 0; i < 81; i++) {
            if (s.getSquare(i) == colorForCaptures &&
                    Referee.getAvailableMovesWithoutJumpingOver(s, i).length == 0 &&
                    Referee.areNeighbours(move.getTo(), i, 1)) {
                move.addCapturedPieceIndex(i);

            }
        }
    }
}
TOP

Related Classes of eu.semberal.migmang.logic.Referee

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.