Package general

Source Code of general.Move

/*
  Copyright (C) 2010 Petri Tuononen

    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 general;
import java.util.*;

import player.Player;
import tools.Index;

/**
*
* @author Petri Tuononen
* @since 26/11/2009
*/
public class Move {

  //global variables
  private Board board;
  private HistoryOfMoves history;
 
  /**
   * Constructor
   * @param board
   */
  public Move(Board board) {
    this.board = board;
    history = new HistoryOfMoves();
  }

  private Board getBoard() {
    return board;
  }

  /**
   * Returns history of all piece moves.
   * @return HistoryOfMoves
   */
  public HistoryOfMoves getHistoryOfMoves() {
    return history;
  }
 
  /**
   * Set history of all piece moves.
   * @param history
   */
  public void setHistoryOfMoves(HistoryOfMoves history) {
    this.history=history;
  }
 
  /**
   * Move piece in selected square to destination square.
   * Returns true if the move was successful.
   * @param player
   * @param srcSq
   * @param destSq
   * @return boolean
   */
  public boolean doMove(Player player, String srcSq, String destSq) {
    //check source square notation for validity
    if (checkSqValidity(srcSq)) {
      //check destination square notation for validity
      if (checkSqValidity(destSq)) {
        //find the piece based on the source square notation.
        Piece piece = getBoard().notationToPiece(srcSq);
        //make sure the piece is owned by the player
        if (piece.getColor()==player.getSide()) {
          //get all movements that are allowed for the selected piece
          ArrayList<ArrayList<Integer>> legalMoves = possiblePieceMoves(piece, false);
          //array coordinates for new destination
          Index newLoc = getBoard().notationToIndex(destSq);
          //find out if destination location is included in the legal moves list
          ArrayList<Integer> x = legalMoves.get(0); //list of row numbers
          ArrayList<Integer> y = legalMoves.get(1); //list of column numbers
          ListIterator<Integer> xList = x.listIterator()//row iterator
          ListIterator<Integer> yList = y.listIterator()//column iterator
          int xL, yL;
          while (xList.hasNext() && yList.hasNext()) { //while lists have coordinates
            //listiterator next() method doesn't work inside if statement -> assign to variables
            xL = xList.next();
            yL = yList.next();
            if (newLoc.getX()==xL && newLoc.getY()==yL) { //legal move
              getBoard().removePiece(newLoc.getX(), newLoc.getY()); //remove captured piece from the board
              piece.setRow(newLoc.getX()); //change piece row
              piece.setCol(newLoc.getY()); //change piece column
//              board.updateGameState(); //populate the board with new location of pieces.
              //place source and destination square to history of moves
              if (player.getSide()==0) { //if white
                getHistoryOfMoves().addWhiteMove(srcSq, destSq); //add white piece move to history
              } else if (player.getSide()==1) { //if black
                getHistoryOfMoves().addBlackMove(srcSq, destSq); //add black piece move to history
              }
              //promote pawns to queens if they reach enemy's end
              getBoard().promotePawnsToQueen(player.getSide());
              return true; //move successful
            }
          }
        }
      } else {
        System.out.println("Not a valid destination square. ");
      }
    } else {
      System.out.println("Not a valid source notation.");
    }
    return false; //move failed, not own piece
  }
 
  /**
   * Checks if the given notation is valid.
   * @param sq
   * @return boolean
   */
  public boolean checkSqValidity(String sq) {
    char[] validColumns = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
    char[] validRows = {'1', '2', '3', '4', '5', '6', '7', '8'};
    if (sq.length()==2) {
      char letter = sq.charAt(0); //save 1st char from notation as a char
      char number = sq.charAt(1); //save 2nd char from notation as an integer
      for (char c : validColumns) {
        //if letter used in notation is valid
        if (c==letter) {
          for (char r : validRows) {
            //if number used in notation is valid
            if (r==number) {
              return true;
            }
          }
        }
      }     
    }
    return false;
  }
 
  /**
   * Returns true if the piece is found from the given location.
   * @param x
   * @param y
   * @return boolean
   */
  public boolean isPieceOnSquare(int x, int y) {
    Piece piece;
    for (Piece p : getBoard().getPieces()) { //pieces left
      piece = p; //get next piece
        //if piece row&col numbers match to parameters
        if (piece.getRow() == x && piece.getCol() == y) {
          return true; //piece found
        }
    }
    return false; //piece not found
  }
 
  /**
   * Returns true if the piece is found from the given location.
   * @param notation
   * @return boolean
   */
  public boolean isPieceOnSquare(String notation) {
    Index index = getBoard().notationToIndex(notation);
    Piece piece;
    for (Piece p : getBoard().getPieces()) {
        piece = p;
        if (piece.getRow() == index.getX() && piece.getCol() == index.getY()) {
          return true;
        }
    }
    return false; //piece not found
  }
 
  /**
   * Returns true if piece with defined color is found from the given location.
   * @param x
   * @param y
   * @param color
   * @return boolean
   */
  public boolean isPieceOnSquare(int x, int y, int color) {
    for (Piece p : getBoard().getPieces()) {
        if (p.getColor() == color) {
          if (p.getRow() == x && p.getCol() == y) {
            return true;
          }
        }
    }
    return false; //piece not found
  }
 
  /**
   * Check is King piece is found from the square.
   * @param x
   * @param y
   * @param color
   * @return
   */
  public boolean isKingOnSquare(int x, int y, int color) {
    for (Piece p : getBoard().getPieces()) {
        if (p.getColor() == color) {
          if (p.getRow() == x && p.getCol() == y) {
            if (p.getType()==1) {
              return true;
            }
          }
        }
    }
    return false; //piece not found
  }
 
  /**
   * Returns true if piece with defined color is found from the given location.
   * @param notation
   * @param color
   * @return boolean
   */
  public boolean isPieceOnSquare(String notation, int color) {
    Index index = getBoard().notationToIndex(notation);
    for (Piece p : getBoard().getPieces()) {
        if (p.getColor() == color) {
          if (p.getRow() == index.getX() && p.getCol() == index.getY()) {
            return true;
          }
        }
    }
    return false;
  }
 
  /**
   * On the board restriction. Checks that piece is moved
   * within the 8x8 limits. 
   * @param x
   * @param y
   * @return
   */
  private Boolean isOnBoard(int x, int y) {
    if ((x>=0 && x<=7) && (y>=0&&y<=7)) {
      return true;
    } else {
      return false;
    }
  }
 
  /**
   * Get all possible movements for the bishop piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists.
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possibleBishopMvmts(Piece piece, boolean kingCapture) {
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                         //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    //arraylist containing x&y arraylists
    ArrayList<ArrayList<Integer>> xAndY = new ArrayList<ArrayList<Integer>>();
    int x = piece.getRow();
    int y = piece.getCol();
    int color = piece.getColor();
    int opponentColor;
    if (color==0) {
      opponentColor=1;
    } else {
      opponentColor=0;
    }
    /*
     * 4 diagonal directions
      -up-right 
      -up-left  
      -down-right
      -down-left
     */
    //up-right
    int i=x, j=y;
    i--; j++;
    while (i>=0 && j<=7) {
      //if own piece on the square
      if (isPieceOnSquare(i, j, color)) { //break, don't add coordinates
        break;       
      //if opponent's piece on the square 
      } else if (isPieceOnSquare(i, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(j)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, j, opponentColor)) {
            mvmtX.add(i); mvmtY.add(j)
          }
        }
        break;       
      } else { //add coordinates
        mvmtX.add(i); mvmtY.add(j)
      }
      i--; j++;
    }
    //up-left
    i=x;
    j=y;
    i--; j--;
    while (i>=0 && j>=0) {
      //if own piece on the square
      if (isPieceOnSquare(i, j, color)) { //break, don't add coordinates
        break;       
      //if opponent's piece on the square 
      } else if (isPieceOnSquare(i, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(j)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, j, opponentColor)) {
            mvmtX.add(i); mvmtY.add(j)
          }
        }
        break;       
      } else { //add coordinates
        mvmtX.add(i); mvmtY.add(j);       
      }
      i--; j--;
    }
    //down-right
    i=x;
    j=y;
    i++; j++;
    while (i<=7 && j<=7) {
      //if own piece on the square
      if (isPieceOnSquare(i, j, color)) { //break, don't add coordinates
        break;       
      //if opponent's piece on the square 
      } else if (isPieceOnSquare(i, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(j)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, j, opponentColor)) {
            mvmtX.add(i); mvmtY.add(j)
          }
        }
        break;       
      } else { //add coordinates
        mvmtX.add(i); mvmtY.add(j);       
      }
      i++; j++;
    }
    //down-left
    i=x;
    j=y;
    i++; j--;
    while (i<=7 && j>=0) {
      //if own piece on the square
      if (isPieceOnSquare(i, j, color)) { //break, don't add coordinates
        break;       
      //if opponent's piece on the square 
      } else if (isPieceOnSquare(i, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(j);
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, j, opponentColor)) {
            mvmtX.add(i); mvmtY.add(j)
          }
        }
        break;       
      } else { //add coordinates
        mvmtX.add(i); mvmtY.add(j);       
      }
      i++; j--;
    }
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
  }
 
  /**
   * Get all possible movements for the rook piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists.
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possibleRookMvmts(Piece piece, boolean kingCapture) {
    //possible movements horizontal and vertical within board 8x8 limits
    //(i, 0<=j<8) horizontal
    //(0<=i<8, j) vertical
    /*
     * 4 directions
     * up
     * right
     * down
     * left
     */
    int x = piece.getRow();
    int y = piece.getCol();
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                     //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    //arraylist containing x&y arraylists
    ArrayList<ArrayList<Integer>> xAndY = new ArrayList<ArrayList<Integer>>();
    int opponentColor;
    if (piece.getColor()==0) {
      opponentColor=1;
    } else {
      opponentColor=0;
    }
    int i, j;
    //up
    i=x;
    i--;
    while (i>=0) {
      //if own piece on the square
      if (isPieceOnSquare(i, y, piece.getColor())) { //break, don't add coordinates
        break
      //if opponent's piece on the square
      } else if (isPieceOnSquare(i, y, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(y)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, y, opponentColor)) {
            mvmtX.add(i); mvmtY.add(y)
          }
        }
        break;   
      } else {
        mvmtX.add(i); mvmtY.add(y)
      }
      i--;
    }
    //down
    i=x;
    i++;
    while (i<=7) {
      //if own piece on the square
      if (isPieceOnSquare(i, y, piece.getColor())) { //break, don't add coordinates
        break
      //if opponent's piece on the square
      } else if (isPieceOnSquare(i, y, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(i); mvmtY.add(y)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(i, y, opponentColor)) {
            mvmtX.add(i); mvmtY.add(y)
          }
        }
        break;   
      } else {
        mvmtX.add(i); mvmtY.add(y)
      }
      i++;
    }
    //right
    j=y;
    j++;
    while (j<=7) {
      //if own piece on the square
      if (isPieceOnSquare(x, j, piece.getColor())) { //break, don't add coordinates
        break
      //if opponent's piece on the square
      } else if (isPieceOnSquare(x, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(x); mvmtY.add(j)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x, j, opponentColor)) {
            mvmtX.add(x); mvmtY.add(j)
          }
        }
        break;   
      } else {
        mvmtX.add(x); mvmtY.add(j)
      }
      j++;
    }
    //left
    j=y;
    j--;
    while (j>=0) {
      //if own piece on the square
      if (isPieceOnSquare(x, j, piece.getColor())) { //break, don't add coordinates
        break
      //if opponent's piece on the square
      } else if (isPieceOnSquare(x, j, opponentColor)) { //add coordinates and break
        if (kingCapture) {
          mvmtX.add(x); mvmtY.add(j)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x, j, opponentColor)) {
            mvmtX.add(x); mvmtY.add(j)
          }
        }
        break;   
      } else {
        mvmtX.add(x); mvmtY.add(j)
      }
      j--;
    }
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
  }
 
  /**
   * Get all possible movements for the knight piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists.
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possibleKnightMvmts(Piece piece, boolean kingCapture) {
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                     //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    //arraylist containing x&y arraylists
    ArrayList<ArrayList<Integer>> xAndY = new ArrayList<ArrayList<Integer>>();
    int x = piece.getRow();
    int y = piece.getCol();
    //get opponent color
    int opponentColor;
    if (piece.getColor()==0) {
      opponentColor=1;
    } else {
      opponentColor=0;
    }
    //possible movements for the knight piece.
    //up-right
    //1 up, 2 right (x+2, y-1)
    if (isOnBoard(x+2, y-1)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x+2, y-1, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x+2); mvmtY.add(y-1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+2, y-1, opponentColor)) {
            mvmtX.add(x+2); mvmtY.add(y-1)
          }
        }
      }
    }
    //2 up, 1 right (x+1, y-2)
    if (isOnBoard(x+1, y-2)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x+1, y-2, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x+1); mvmtY.add(y-2);
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+1, y-2, opponentColor)) {
            mvmtX.add(x+1); mvmtY.add(y-2);
          }
        }
      }
    }
    //up-left
    //1 up, 2 left (x-2, y-1)
    if (isOnBoard(x-2, y-1)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x-2, y-1, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x-2); mvmtY.add(y-1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-2, y-1, opponentColor)) {
            mvmtX.add(x-2); mvmtY.add(y-1)
          }
        }
      }
    }
    //2 up, 1 left (x-1, y-2)
    if (isOnBoard(x-1, y-2)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x-1, y-2, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x-1); mvmtY.add(y-2)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-1, y-2, opponentColor)) {
            mvmtX.add(x-1); mvmtY.add(y-2)
          }
        }
      }
    }
    //down-right
    //1 down, 2 right (x+2, y+1)
    if (isOnBoard(x+2, y+1)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x+2, y+1, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x+2); mvmtY.add(y+1);
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+2, y+1, opponentColor)) {
            mvmtX.add(x+2); mvmtY.add(y+1)
          }
        }
      }
    }
    //2 down, 1 right (x+1, y+2)
    if (isOnBoard(x+1, y+2)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x+1, y+2, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x+1); mvmtY.add(y+2)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+1, y+2, opponentColor)) {
            mvmtX.add(x+1); mvmtY.add(y+2)
          }
        }
      }
    }
    //down-left
    //1 down, 2 left (x-2, y+1)
    if (isOnBoard(x-2, y+1)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x-2, y+1, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x-2); mvmtY.add(y+1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-2, y+1, opponentColor)) {
            mvmtX.add(x-2); mvmtY.add(y+1)
          }
        }
      }
    }
    //2 down, 1 left (x-1, y+2)
    if (isOnBoard(x-1, y+2)) {
      //if no own piece on the square
      if (!isPieceOnSquare(x-1, y+2, piece.getColor())) {
        if (kingCapture) {
          mvmtX.add(x-1); mvmtY.add(y+2)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-1, y+2, opponentColor)) {
            mvmtX.add(x-1); mvmtY.add(y+2)
          }
        }
      }
    }
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
  }
 
  /**
   * Get all possible movements for the knight piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists.
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possiblePawnMvmts(Piece piece, boolean kingCapture) {
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                     //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    //arraylist containing x&y arraylists
    ArrayList<ArrayList<Integer>> xAndY = new ArrayList<ArrayList<Integer>>();
    int x = piece.getRow();
    int y = piece.getCol();
    //can only move forwards or diagonally forwards when
    //capturing other piece.
    //At start the 2nd row pawn can move 1 or 2 squares forward,
    //otherwise only 1 as long as there's no obstructing pieces.
    int opponentColor;
    if (piece.getColor()==0) {
      opponentColor = 1;
    } else {
      opponentColor = 0;
    }
    if (piece.getType()==6 && piece.getColor()==0) { //white pawn
      if (x==6) { //can move 1 or 2 squares forward
        if (!isPieceOnSquare(x-1, y)) { //if no obstructing piece
          mvmtX.add(x-1); mvmtY.add(y); //1 square forward
          if (!isPieceOnSquare(x-2, y)) { //if no obstructing piece
            mvmtX.add(x-2); mvmtY.add(y); //2 squares forward
          }
        }
      } else { //can move 1 square forward
        if (x-1>=0 && !isPieceOnSquare(x-1, y)) { //if no obstructing piece
          mvmtX.add(x-1); mvmtY.add(y)
        }
      }
      //diagonal moves if opponent's piece can be captured
      //up-right if opponent's piece on the square
      if (isPieceOnSquare(x-1, y+1, opponentColor)) {
        if (kingCapture) {
          mvmtX.add(x-1); mvmtY.add(y+1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-1, y+1, opponentColor)) {
            mvmtX.add(x-1); mvmtY.add(y+1)
          }
        }
      }
      //up-left if opponent's piece on the square
      if (isPieceOnSquare(x-1, y-1, opponentColor)) {
        if (kingCapture) {
          mvmtX.add(x-1); mvmtY.add(y-1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x-1, y-1, opponentColor)) {
            mvmtX.add(x-1); mvmtY.add(y-1)
          }
        }
      }
    } else if (piece.getType()==6 && piece.getColor()==1) { //black pawn
      if (x==1) { //can move 1 or 2 squares forward
        if (!isPieceOnSquare(x+1, y)) { //if no obstructing piece
          mvmtX.add(x+1); mvmtY.add(y); //1 square forward           
          if (!isPieceOnSquare(x+2, y)) { //if no obstructing piece
            mvmtX.add(x+2); mvmtY.add(y); //2 squares forward             
          }
        }
      } else { //can move 1 square forward
        if (x+1<8 && !isPieceOnSquare(x+1, y)) { //if no obstructing piece
          mvmtX.add(x+1); mvmtY.add(y);           
        }
      }
      //diagonal moves if opponent's piece can be captured
      //if opponent's piece on the square
      if (isPieceOnSquare(x+1, y+1, opponentColor)) {
        if (kingCapture) {
          mvmtX.add(x+1); mvmtY.add(y+1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+1, y+1, opponentColor)) {
            mvmtX.add(x+1); mvmtY.add(y+1)
          }
        }
      }
      //if opponent's piece on the square
      if (isPieceOnSquare(x+1, y-1, opponentColor)) {
        if (kingCapture) {
          mvmtX.add(x+1); mvmtY.add(y-1)
        } else {
          //if enemy king is not on the square
          if (!isKingOnSquare(x+1, y-1, opponentColor)) {
            mvmtX.add(x+1); mvmtY.add(y-1)
          }
        }
      }
    }
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
 
 
  /**
   * Get all possible movements for the king piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possibleKingMvmts(Piece piece, boolean kingCapture) {
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                        //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    //arraylist containing x&y arraylists
    ArrayList<ArrayList<Integer>> xAndY = new ArrayList<ArrayList<Integer>>();
    int x = piece.getRow();
    int y = piece.getCol();
    int color = piece.getColor();
    int opponentColor;
    if (color==0) {
      opponentColor=1;
    } else {
      opponentColor=0;
    }
    //possible horizontal and lateral movements
    //horizontal
    //check that piece stays on the board and there's no own piece blocking the way
    if (isOnBoard(x, y+1) && !isPieceOnSquare(x, y+1, color)) { //right
      if (kingCapture) {
        mvmtX.add(x); mvmtY.add(y+1); //(x, y+1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x, y+1, opponentColor)) {
          mvmtX.add(x); mvmtY.add(y+1); //(x, y+1)
        }
      }
    }
    if (isOnBoard(x, y-1) && !isPieceOnSquare(x, y-1, color)) { //left
      if (kingCapture) {
        mvmtX.add(x); mvmtY.add(y-1); //(x, y-1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x, y-1, opponentColor)) {
          mvmtX.add(x); mvmtY.add(y-1); //(x, y-1)
        }
      }
    }
    //vertical
    if (isOnBoard(x-1, y) && !isPieceOnSquare(x-1, y, color)) { //up
      if (kingCapture) {
        mvmtX.add(x-1); mvmtY.add(y); //(x-1, y)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x-1, y, opponentColor)) {
          mvmtX.add(x-1); mvmtY.add(y); //(x-1, y)
        }
      }
    }
    if (isOnBoard(x+1, y) && !isPieceOnSquare(x+1, y, color)) { //down
      if (kingCapture) {
        mvmtX.add(x+1); mvmtY.add(y); //(x+1, y)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x+1, y, opponentColor)) {
          mvmtX.add(x+1); mvmtY.add(y); //(x+1, y)
        }
      }
    }
    //possible diagonal movements
    //up-right
    if (isOnBoard(x-1, y+1) && !isPieceOnSquare(x-1, y+1, color)) {
      if (kingCapture) {
        mvmtX.add(x-1); mvmtY.add(y+1); //(x-1, y+1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x-1, y+1, opponentColor)) {
          mvmtX.add(x-1); mvmtY.add(y+1); //(x-1, y+1)
       
      }
    }
    //up-left
    if (isOnBoard(x-1, y-1) && !isPieceOnSquare(x-1, y-1, color)) {
      if (kingCapture) {
        mvmtX.add(x-1); mvmtY.add(y-1); //(x-1, y-1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x-1, y-1, opponentColor)) {
          mvmtX.add(x-1); mvmtY.add(y-1); //(x-1, y-1)
        }
      }
    }
    //down-right
    if (isOnBoard(x+1, y+1) && !isPieceOnSquare(x+1, y+1, color)) {
      if (kingCapture) {
        mvmtX.add(x+1); mvmtY.add(y+1); //(x+1, y+1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x+1, y+1, opponentColor)) {
          mvmtX.add(x+1); mvmtY.add(y+1); //(x+1, y+1)
        }
      }
    }
    //down-left
    if (isOnBoard(x+1, y-1) && !isPieceOnSquare(x+1, y-1, color)) {
      if (kingCapture) {
        mvmtX.add(x+1); mvmtY.add(y-1); //(x+1, y-1)
      } else {
        //if enemy king is not on the square
        if (!isKingOnSquare(x+1, y-1, opponentColor)) {
          mvmtX.add(x+1); mvmtY.add(y-1); //(x+1, y-1)
        }
      }
    }
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
  }
 
  /**
   * Get all possible movements for the queen piece.
   * X and Y coordinates are saved in separate arraylists.
   * Returns an arraylist containing x&y arraylists
   * @param piece
   * @return
   */
  private ArrayList<ArrayList<Integer>> possibleQueenMvmts(Piece piece, boolean kingCapture) {
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                      //for possible movements
    mvmtX = new ArrayList<Integer>(); //list for x coordinates
    mvmtY = new ArrayList<Integer>(); //list for y coordinates
    ArrayList<ArrayList<Integer>> bishopXAndY, rookXAndY, xAndY;
    //arraylist containing x&y arraylists
    xAndY = new ArrayList<ArrayList<Integer>>();
    //combined bishop & rook movements
    //get bishop movement possibilities
    bishopXAndY = possibleBishopMvmts(piece, kingCapture);
    mvmtX.addAll(bishopXAndY.get(0));
    mvmtY.addAll(bishopXAndY.get(1));
    //get rook movement possibilities
    rookXAndY = possibleRookMvmts(piece, kingCapture);
    mvmtX.addAll(rookXAndY.get(0));
    mvmtY.addAll(rookXAndY.get(1));
    xAndY.add(mvmtX);
    xAndY.add(mvmtY);
    return xAndY;
  }
 
  /**
   * Returns an arraylist containing two arraylists for possible
   * coordinates the selected piece can move.
   * @param piece
   * @return ArrayList<ArrayList<Integer>>
   */
  public ArrayList<ArrayList<Integer>> possiblePieceMoves(Piece piece, boolean kingCapture) {
    int type;
    ArrayList<Integer> mvmtX, mvmtY; //lists for x&y coordinates
                       //for possible movements
    ArrayList<ArrayList<Integer>> kingXAndY, queenXAndY,
      bishopXAndY, rookXAndY, knightXAndY, pawnXAndY;
    //arraylist containing x&y arraylists for possible piece movement coordinates
    ArrayList<ArrayList<Integer>> mvmtXAndY = new ArrayList<ArrayList<Integer>>();
    //get x & y from the Piece object
    type = piece.getType(); //piece type
    mvmtX = new ArrayList<Integer>();
    mvmtY = new ArrayList<Integer>();
    switch(type) {
    case 1: //king
      //get king movement possibilities
      kingXAndY = possibleKingMvmts(piece, kingCapture); //get arraylist containing
                         //2 arraylists
      mvmtX = kingXAndY.get(0); //arraylist of x coordinates
      mvmtY = kingXAndY.get(1); //arraylist of y coordinates
      break;
    case 2: //queen
      //get queen movement possibilities
      queenXAndY = possibleQueenMvmts(piece, kingCapture);
      mvmtX = queenXAndY.get(0); //arraylist of x coordinates
      mvmtY = queenXAndY.get(1); //arraylist of y coordinates
      break;
    case 3: //rook
      rookXAndY = possibleRookMvmts(piece, kingCapture);
      mvmtX = rookXAndY.get(0); //arraylist of x coordinates
      mvmtY = rookXAndY.get(1); //arraylist of y coordinates
      break;
    case 4: //knight
      knightXAndY = possibleKnightMvmts(piece, kingCapture);
      mvmtX = knightXAndY.get(0); //arraylist of x coordinates
      mvmtY = knightXAndY.get(1); //arraylist of y coordinates
      break;
    case 5: //bishop
      bishopXAndY = possibleBishopMvmts(piece, kingCapture);
      mvmtX = bishopXAndY.get(0); //arraylist of x coordinates
      mvmtY = bishopXAndY.get(1); //arraylist of y coordinates
      break;
    case 6: //pawn
      pawnXAndY = possiblePawnMvmts(piece, kingCapture);
      mvmtX = pawnXAndY.get(0); //arraylist of x coordinates
      mvmtY = pawnXAndY.get(1); //arraylist of y coordinates
      break;
    default:
      break;
    }
    mvmtXAndY.add(mvmtX);
    mvmtXAndY.add(mvmtY);
    return mvmtXAndY;
  }
 
  /**
   * Check if King can move.
   * @param color
   * @return boolean
   */
  public boolean canKingMove(int color) {
    //get all pieces
    ArrayList<Piece> pieces = getBoard().getPieces();
    ArrayList<ArrayList<Integer>> kingMvmts = new ArrayList<ArrayList<Integer>>();
    for (Piece p : pieces) {
      if (p.getType() == 1 && p.getColor() == color) {
        kingMvmts = possibleKingMvmts(p, false);
        break;
      }
    }
    //check if any movements
    ArrayList<Integer> mvmtX = kingMvmts.get(0); //x coordinates
    //if list is empty
    if (mvmtX.isEmpty()) {
      return false;
    } else { //list not empty
      return true;
    }
  }
 
}
TOP

Related Classes of general.Move

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.