Package chesstrainer

Source Code of chesstrainer.SMoveGenerator

/*
* Copyright (C) 2014 Tim Declercq <caveman1917@hotmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package chesstrainer;

import chesstrainer.util.EPiece;
import static chesstrainer.util.EPiece.BB;
import static chesstrainer.util.EPiece.BK;
import static chesstrainer.util.EPiece.BN;
import static chesstrainer.util.EPiece.BP;
import static chesstrainer.util.EPiece.BQ;
import static chesstrainer.util.EPiece.BR;
import static chesstrainer.util.EPiece.WB;
import static chesstrainer.util.EPiece.WK;
import static chesstrainer.util.EPiece.WN;
import static chesstrainer.util.EPiece.WP;
import static chesstrainer.util.EPiece.WQ;
import static chesstrainer.util.EPiece.WR;
import chesstrainer.util.ESide;
import chesstrainer.util.ESquare;
import java.util.HashSet;
import java.util.Set;

/**
*
* @author Tim Declercq <caveman1917@hotmail.com>
*/
public class SMoveGenerator {
   
    private static Set<CMove> getWhitePawnMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
       
        if (square.n() != null) {
            if (position.get(square.n()) == null) {
                if (square.getRank() != 6) {
                    moves.add(new CMove(square, square.n()));
                } else {
                    moves.add(new CMove(square, square.n(), EPiece.WN));
                    moves.add(new CMove(square, square.n(), EPiece.WB));
                    moves.add(new CMove(square, square.n(), EPiece.WR));
                    moves.add(new CMove(square, square.n(), EPiece.WQ));
                }
                if (square.getRank() == 1 && position.get(square.n().n()) == null) {
                    moves.add(new CMove(square, square.n().n()));
                }
            }
        }
       
        if (square.nw() != null) {
            if (position.get(square.nw()) != null) {
                if (position.get(square.nw()).getSide() == ESide.BLACK
                        || square.nw() == position.getEnPassantSquare()) {
                    if (square.getRank() != 6) {
                        moves.add(new CMove(square, square.nw()));
                    } else {
                        moves.add(new CMove(square, square.nw(), EPiece.WN));
                        moves.add(new CMove(square, square.nw(), EPiece.WB));
                        moves.add(new CMove(square, square.nw(), EPiece.WR));
                        moves.add(new CMove(square, square.nw(), EPiece.WQ));
                    }
                }
            }
        }
       
        if (square.ne() != null) {
            if (position.get(square.ne()) != null) {
                if (position.get(square.ne()).getSide() == ESide.BLACK
                        || square.nw() == position.getEnPassantSquare()) {
                    if (square.getRank() != 6) {
                        moves.add(new CMove(square, square.ne()));
                    } else {
                        moves.add(new CMove(square, square.ne(), EPiece.WN));
                        moves.add(new CMove(square, square.ne(), EPiece.WB));
                        moves.add(new CMove(square, square.ne(), EPiece.WR));
                        moves.add(new CMove(square, square.ne(), EPiece.WQ));
                    }
                }
            }
        }
       
        return moves;
       
    }
   
    private static Set<CMove> getBlackPawnMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
       
        if (square.s() != null) {
            if (position.get(square.s()) == null) {
                if (square.getRank() != 1) {
                    moves.add(new CMove(square, square.s()));
                } else {
                    moves.add(new CMove(square, square.s(), EPiece.BN));
                    moves.add(new CMove(square, square.s(), EPiece.BB));
                    moves.add(new CMove(square, square.s(), EPiece.BR));
                    moves.add(new CMove(square, square.s(), EPiece.BQ));
                }
                if (square.getRank() == 6 && position.get(square.s().s()) == null) {
                    moves.add(new CMove(square, square.s().s()));
                }
            }
        }
       
        if (square.sw() != null) {
            if (position.get(square.sw()) != null) {
                if (position.get(square.sw()).getSide() == ESide.WHITE
                        || square.nw() == position.getEnPassantSquare()) {
                    if (square.getRank() != 1) {
                        moves.add(new CMove(square, square.sw()));
                    } else {
                        moves.add(new CMove(square, square.sw(), EPiece.BN));
                        moves.add(new CMove(square, square.sw(), EPiece.BB));
                        moves.add(new CMove(square, square.sw(), EPiece.BR));
                        moves.add(new CMove(square, square.sw(), EPiece.BQ));
                    }
                }
            }
        }
       
        if (square.se() != null) {
            if (position.get(square.se()) != null) {
                if (position.get(square.se()).getSide() == ESide.WHITE
                        || square.nw() == position.getEnPassantSquare()) {
                    if (square.getRank() != 1) {
                        moves.add(new CMove(square, square.se()));
                    } else {
                        moves.add(new CMove(square, square.se(), EPiece.BN));
                        moves.add(new CMove(square, square.se(), EPiece.BB));
                        moves.add(new CMove(square, square.se(), EPiece.BR));
                        moves.add(new CMove(square, square.se(), EPiece.BQ));
                    }
                }
            }
        }
       
        return moves;
       
    }
   
    private static Set<CMove> getKnightMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
        ESide side = position.get(square).getSide();
       
        for (ESquare s : new ESquare[]{square.knight1(), square.knight2(),
            square.knight3(), square.knight4(), square.knight5(), square.knight6(),
            square.knight7(), square.knight8()}) {
           
            if (s != null) {
                if (position.get(s) == null) {
                    moves.add(new CMove(square, s));
                } else if (position.get(s).getSide() != side) {
                    moves.add(new CMove(square, s));
                }
            }
           
        }
       
        return moves;
    }
   
    private static Set<CMove> getBishopMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
        ESide side = position.get(square).getSide();
        ESquare s;
       
        s = square;
        while (s.nw() != null) {
            s = s.nw();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.ne() != null) {
            s = s.ne();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.se() != null) {
            s = s.se();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.sw() != null) {
            s = s.sw();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        return moves;
    }
   
    private static Set<CMove> getRookMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
        ESide side = position.get(square).getSide();
        ESquare s;
       
        s = square;
        while (s.n() != null) {
            s = s.n();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.e() != null) {
            s = s.e();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.s() != null) {
            s = s.s();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        s = square;
        while (s.w() != null) {
            s = s.w();
            if (position.get(s) == null) {
                moves.add(new CMove(square, s));
            } else if (position.get(s).getSide() != side) {
                moves.add(new CMove(square, s));
                break;
            } else {
                break;
            }
        }
       
        return moves;
    }
   
    private static Set<CMove> getQueenMoves(CPosition position, ESquare square) {
        Set<CMove> moves = getBishopMoves(position, square);
        moves.addAll(getRookMoves(position, square));
        return moves;
    }
   
    private static Set<CMove> getKingMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
        ESide side = position.get(square).getSide();
       
        for (ESquare s : new ESquare[]{square.n(), square.ne(), square.e()
            , square.se(), square.s(), square.sw(), square.w(), square.nw()}) {
           
            if (s != null) {
                if (position.get(s) == null) {
                    moves.add(new CMove(square, s));
                } else if (position.get(s).getSide() != side) {
                    moves.add(new CMove(square, s));
                }
            }
        }
       
        if (side == ESide.WHITE && square == ESquare.e1) {
           
            if (position.isWhiteCastleShort()) {
                if (position.get(ESquare.f1) == null
                        && position.get(ESquare.g1) == null) {
                    if (!isInCheck(position)
                            && !isAttackedBy(position, ESquare.f1, ESide.BLACK)) {
                        moves.add(new CMove(ESquare.e1, ESquare.g1));
                    }
                }
            }
           
            if (position.isWhiteCastleLong()) {
                if (position.get(ESquare.d1) == null
                        && position.get(ESquare.c1) == null
                        && position.get(ESquare.b1) == null) {
                    if (!isInCheck(position)
                            && !isAttackedBy(position, ESquare.d1, ESide.BLACK)) {
                        moves.add(new CMove(ESquare.e1, ESquare.c1));
                    }
                }
            }
        }
       
        if (side == ESide.BLACK && square == ESquare.e8) {
           
            if (position.isBlackCastleShort()) {
                if (position.get(ESquare.f8) == null
                        && position.get(ESquare.g8) == null) {
                    if (!isInCheck(position)
                            && !isAttackedBy(position, ESquare.f8, ESide.WHITE)) {
                        moves.add(new CMove(ESquare.e8, ESquare.g8));
                    }
                }
            }
           
            if (position.isBlackCastleLong()) {
                if (position.get(ESquare.d8) == null
                        && position.get(ESquare.c8) == null
                        && position.get(ESquare.b8) == null) {
                    if (!isInCheck(position)
                            && !isAttackedBy(position, ESquare.d8, ESide.WHITE)) {
                        moves.add(new CMove(ESquare.e8, ESquare.c8));
                    }
                }
            }
        }
       
        return moves;
    }
   
    private static Set<CMove> getMoves(CPosition position, ESquare square) {
        Set<CMove> moves = new HashSet<>();
       
        if (square == null) {
            return moves;
        }
        if (position.get(square) == null) {
            return moves;
        }
       
        switch (position.get(square)) {
            case WP: moves.addAll(getWhitePawnMoves(position, square)); break;
            case BP: moves.addAll(getBlackPawnMoves(position, square)); break;
            case WN:
            case BN: moves.addAll(getKnightMoves(position, square)); break;
            case WB:
            case BB: moves.addAll(getBishopMoves(position, square)); break;
            case WR:
            case BR: moves.addAll(getRookMoves(position, square)); break;
            case WQ:
            case BQ: moves.addAll(getQueenMoves(position, square)); break;
            case WK:
            case BK: moves.addAll(getKingMoves(position, square)); break;
        }
       
        return moves;
    }
   
    private static Set<CMove> getPseudoLegalMoves(CPosition position, ESide side) {
        Set<CMove> moves = new HashSet<>();
       
        for (ESquare square : position.getPosition().keySet()) {
           
            if (position.get(square).getSide() == side) {
                moves.addAll(getMoves(position, square));
            }
        }
       
        return moves;
    }
   
    private static Set<CMove> getPseudoLegalMoves(CPosition position) {
        return getPseudoLegalMoves(position, position.getSideToMove());
    }
   
    private static Set<CMove> retainLegalMoves(CPosition position, Set<CMove> moves) {
       
        CPosition pos;
        Set<CMove> legalMoves = new HashSet<>();
        ESide side = position.getSideToMove();
       
        for (CMove move : moves) {
            if (side != position.getPosition().get(move.getFrom()).getSide()) {
                continue;
            }
            pos = position.copy();
            pos.makeMove(move);
            if (!isInCheck(pos)) {
                legalMoves.add(move);
            }
        }
       
        return legalMoves;
    }
   
    public static Set<CMove> getLegalMoves(CPosition position) {
        return retainLegalMoves(position, getPseudoLegalMoves(position));
    }
   
    public static Set<CMove> getLegalMoves(CPosition position, ESquare square) {
        return retainLegalMoves(position, getMoves(position, square));
    }
   
    public static boolean isLegalMove(CPosition position, CMove move) {
        Set<CMove> legalMoves = getLegalMoves(position, move.getFrom());
        for (CMove legalMove : legalMoves) {
            if (move.equals(legalMove)) {
                return true;
            }
        }
        return false;
    }
   
    public static boolean isAttackedBy(CPosition position, ESquare square, ESide side) {
       
        if (side == ESide.WHITE) {
            if (position.get(square.sw()) == EPiece.WP) {
                return true;
            }
            if (position.get(square.se()) == EPiece.WP) {
                return true;
            }
           
            if (position.get(square.n()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.ne()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.e()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.se()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.s()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.sw()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.w()) == EPiece.WK) {
                return true;
            }
            if (position.get(square.nw()) == EPiece.WK) {
                return true;
            }
           
            if (position.get(square.knight1()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight2()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight3()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight4()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight5()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight6()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight7()) == EPiece.WN) {
                return true;
            }
            if (position.get(square.knight8()) == EPiece.WN) {
                return true;
            }
           
            ESquare s = square;
            while (s.nw() != null && position.get(s.nw()) == null) {
                s = s.nw();
            }
            if (position.get(s.nw()) == EPiece.WB
                    || position.get(s.nw()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.ne() != null && position.get(s.ne()) == null) {
                s = s.ne();
            }
            if (position.get(s.ne()) == EPiece.WB
                    || position.get(s.ne()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.se() != null && position.get(s.se()) == null) {
                s = s.se();
            }
            if (position.get(s.se()) == EPiece.WB
                    || position.get(s.se()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.sw() != null && position.get(s.sw()) == null) {
                s = s.sw();
            }
            if (position.get(s.sw()) == EPiece.WB
                    || position.get(s.sw()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.n() != null && position.get(s.n()) == null) {
                s = s.n();
            }
            if (position.get(s.n()) == EPiece.WR
                    || position.get(s.n()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.e() != null && position.get(s.e()) == null) {
                s = s.e();
            }
            if (position.get(s.e()) == EPiece.WR
                    || position.get(s.e()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.s() != null && position.get(s.s()) == null) {
                s = s.s();
            }
            if (position.get(s.s()) == EPiece.WR
                    || position.get(s.s()) == EPiece.WQ) {
                return true;
            }
           
            s = square;
            while (s.w() != null && position.get(s.w()) == null) {
                s = s.w();
            }
            if (position.get(s.w()) == EPiece.WR
                    || position.get(s.w()) == EPiece.WQ) {
                return true;
            }
        } else {
            if (position.get(square.nw()) == EPiece.BP) {
                return true;
            }
            if (position.get(square.ne()) == EPiece.BP) {
                return true;
            }
           
            if (position.get(square.n()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.ne()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.e()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.se()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.s()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.sw()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.w()) == EPiece.BK) {
                return true;
            }
            if (position.get(square.nw()) == EPiece.BK) {
                return true;
            }
           
            if (position.get(square.knight1()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight2()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight3()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight4()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight5()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight6()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight7()) == EPiece.BN) {
                return true;
            }
            if (position.get(square.knight8()) == EPiece.BN) {
                return true;
            }
           
            ESquare s = square;
            while (s.nw() != null && position.get(s.nw()) == null) {
                s = s.nw();
            }
            if (position.get(s.nw()) == EPiece.BB
                    || position.get(s.nw()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.ne() != null && position.get(s.ne()) == null) {
                s = s.ne();
            }
            if (position.get(s.ne()) == EPiece.BB
                    || position.get(s.ne()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.se() != null && position.get(s.se()) == null) {
                s = s.se();
            }
            if (position.get(s.se()) == EPiece.BB
                    || position.get(s.se()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.sw() != null && position.get(s.sw()) == null) {
                s = s.sw();
            }
            if (position.get(s.sw()) == EPiece.BB
                    || position.get(s.sw()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.n() != null && position.get(s.n()) == null) {
                s = s.n();
            }
            if (position.get(s.n()) == EPiece.BR
                    || position.get(s.n()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.e() != null && position.get(s.e()) == null) {
                s = s.e();
            }
            if (position.get(s.e()) == EPiece.BR
                    || position.get(s.e()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.s() != null && position.get(s.s()) == null) {
                s = s.s();
            }
            if (position.get(s.s()) == EPiece.BR
                    || position.get(s.s()) == EPiece.BQ) {
                return true;
            }
           
            s = square;
            while (s.w() != null && position.get(s.w()) == null) {
                s = s.w();
            }
            if (position.get(s.w()) == EPiece.BR
                    || position.get(s.w()) == EPiece.BQ) {
                return true;
            }
        }
        return false;
    }
   
    public static boolean isInCheck(CPosition position) {
        ESquare kingSquare = null;
        ESide side = position.getSideToMove();
       
        for (ESquare s : position.getPosition().keySet()) {
            if (side == ESide.BLACK && position.get(s) == EPiece.WK) {
                kingSquare = s;
                break;
            }
            if (side == ESide.WHITE && position.get(s) == EPiece.BK) {
                kingSquare = s;
                break;
            }
        }
       
        return isAttackedBy(position, kingSquare, side);
    }
   
}
TOP

Related Classes of chesstrainer.SMoveGenerator

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.