<repo_name>skgadag1/ChessBoardChallenge<file_sep>/ChessBoradChallenge/src/service/GameOperationsService.java
package service;

import domain.ChessBoard;
import exceptionHandler.InvalidMoveException;
import exceptionHandler.InvalidPawnException;

public interface GameOperationsService {

	/*This method draws the chess board on to the console*/
	public ChessBoard drawChessBoard(String src, String dest);
	
	/*This method helps 'drawChessBoard()' method to place pawns in appropriate position*/
	public ChessBoard arrangPieces(String initColor);
	
	/*This method refresh the chess board representation each time the move is made*/
	public ChessBoard refreshChessBoard(String src, String dest) ;
	
	/*This method helps 'refreshChessBoard()' method to refresh the board depending on the players move*/
	public ChessBoard makeMove(String src, String dest, int playerNo) throws InvalidMoveException;
	
	/*This method validates the pawn name entered by the player*/
	public void validatePawn(String src, String dest, Character player) throws InvalidPawnException;
	
	/*This method validates the move made by the player*/
	public ChessBoard validateMove(String pawn, String dest, Character player) throws InvalidMoveException;
	
}
<file_sep>/ChessBoradChallenge/src/constants/Constants.java
package constants;

public class Constants {

	public static final String ALL_DRIECTION="ALL_DRIECTION";
	public static final String DIAGONAL="DIAGONAL";
	public static final String DIAGONAL_WHITE="DIAGONAL_WHITE";
	public static final String DIAGONAL_BLACK="DIAGONAL_BLACK";
	public static final String VERTICAL="VERTICAL";
	public static final String HORIZONTAL="HORIZONTAL";
	public static final String HV_DIRECTION="HV_DIRECTION";
	public static final String L_SHAPE="L_SHAPE";
	public static final String ONE_STEP="ONE_STEP";
	public static final String ONE_STEP_FORWARD="ONE_STEP_FORWARD";
	public static final String ONE_STEP_DIAGONAL="ONE_STEP_DIAGONAL";
	public static final String AQUIRE_PAWN="AQUIRE_PAWN";
	
	public static final String WHITE="WHITE";
	public static final String BLACK="BLACK";
}
<file_sep>/ChessBoradChallenge/src/service/GameOperationsServiceImpl.java
package service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.Set;

import constants.Constants;
import domain.ChessBoard;
import domain.Player;
import exceptionHandler.InvalidMoveException;
import exceptionHandler.InvalidPawnException;

public class GameOperationsServiceImpl implements GameOperationsService{

	private static ChessBoard chessBoard=new ChessBoard();
	private static List<Player> players=new ArrayList<Player>();
	private PawnMoveService pawnMoveService=new PawnMoveServiceImpl(chessBoard, players);
	private String s;
	boolean isWFirstMove=true, isBFirstMove=true;

	/*This method draws the chess board on to the console*/
	@Override
	public ChessBoard drawChessBoard(String src, String dest) {
		String key="";

		for(Integer i=0; i<9; i++) {
			for(Integer j=0; j<9; j++) {
				key=i.toString()+j.toString();
				if(i==0&&j==0) {
					s="   \t\t";
					System.out.print(s);
				}else if(i==0&&j<9&&j!=0) {
					s="  "+j+"\t  ";
					System.out.print(s);
				}else if(i>0&&i<9&&j==0) {
					s="  "+i+"\t\t";	
					System.out.print(s);
				}else {
					if(i%2!=0) {
						if(j%2!=0) {
							s="  O\t  ";
						}
						else {
							s="  *\t  ";	
						}
					}else if(i%2==0) {
						if(j%2==0) {
							s="  O\t  ";
						}
						else {
							s="  *\t  ";	
						}
					}
					if(GameOperationsServiceImpl.chessBoard.getBlackChessMen().containsKey(key)) {
						s="  "+GameOperationsServiceImpl.chessBoard.getBlackChessMen().get(key)+"\t  ";
					}else if(GameOperationsServiceImpl.chessBoard.getWhiteChessMen().containsKey(key)) {
						s="  "+GameOperationsServiceImpl.chessBoard.getWhiteChessMen().get(key)+"\t  ";
					}
					System.out.print(s);
				}

			}
			if(i==0)
				System.out.println("\n\n\t\t  Pawns Won "+GameOperationsServiceImpl.players.get(0).getPawnsWon()+"\n\t\t  "+GameOperationsServiceImpl.players.get(0).getName()+"\t\t\t\t\t\t["+(!GameOperationsServiceImpl.players.get(0).getPieceChosen().equals(Constants.WHITE)?Constants.BLACK:Constants.WHITE)+"]\n\t\t  -------------------------------------------------------------\n");
			if(i==8)
				System.out.println("\n\n\t\t  -------------------------------------------------------------\n\t\t  "+GameOperationsServiceImpl.players.get(1).getName()+"\t\t\t\t\t\t["+(!GameOperationsServiceImpl.players.get(1).getPieceChosen().equals(Constants.WHITE)?Constants.BLACK:Constants.WHITE)+"]\n\t\t  Pawns Won "+GameOperationsServiceImpl.players.get(1).getPawnsWon()+"\n");
			else if(i!=0)
				System.out.println("\n\n");
		}
		if(!src.isEmpty())
			System.out.println("[Last Move: "+src+" -> "+dest+"]");
		if((GameOperationsServiceImpl.players.get(0).getPawnsWon().contains("k")||GameOperationsServiceImpl.players.get(0).getPawnsWon().contains("K"))||(GameOperationsServiceImpl.players.get(1).getPawnsWon().contains("k")||GameOperationsServiceImpl.players.get(1).getPawnsWon().contains("K"))) {
			System.exit(0);
		}
		return GameOperationsServiceImpl.chessBoard;

	}

	/*This method helps 'drawChessBoard()' method to place pawns in appropriate position*/
	@Override
	public ChessBoard arrangPieces(String initColor) {
		GameOperationsServiceImpl.players.add(new Player("Player-1", initColor, null,new ArrayList<String>()));
		GameOperationsServiceImpl.players.add(new Player("Player-2", initColor.equals(Constants.WHITE)?Constants.BLACK:Constants.WHITE, null,new ArrayList<String>()));
		boolean isWhite=(initColor.equals(Constants.WHITE)?true:false);
		String src="";
		HashMap<String, String> whiteChessMen=new HashMap<String, String>();
		HashMap<String, String> blackChessMen=new HashMap<String, String>();
		for(Integer i=1; i<=8; i++) {
			for(Integer j=1; j<=8; j++) {
				src=((i==1||i==8)?i.toString()+j.toString():i.toString());
				switch(src) {
				case "11":	if(isWhite)
					whiteChessMen.put(src,"R1");
				else 
					blackChessMen.put(src,"r1");
				continue;
				case "12":	if(isWhite)
					whiteChessMen.put(src,"N1");
				else 
					blackChessMen.put(src,"n1");
				continue;
				case "13":	if(isWhite)
					whiteChessMen.put(src,"B1");
				else 
					blackChessMen.put(src,"b1");
				continue;
				case "14":	if(isWhite)
					whiteChessMen.put(src,"Q");
				else 
					blackChessMen.put(src,"q");
				continue;
				case "15":	if(isWhite)
					whiteChessMen.put(src,"K");
				else 
					blackChessMen.put(src,"k");
				continue;
				case "16":	if(isWhite)
					whiteChessMen.put(src,"B2");
				else 
					blackChessMen.put(src,"b2");
				continue;
				case "17":	if(isWhite)
					whiteChessMen.put(src,"N2");
				else 
					blackChessMen.put(src,"n2");
				continue;
				case "18":	if(isWhite)
					whiteChessMen.put(src,"R2");
				else 
					blackChessMen.put(src,"r2");
				continue;
				case "2":	if(isWhite)
					whiteChessMen.put(src+j,"x"+j);
				else 
					blackChessMen.put(src+j,"y"+j);
				continue;
				case "7":	if(isWhite)
					blackChessMen.put(src+j,"y"+j);
				else 
					whiteChessMen.put(src+j,"x"+j);
				continue;
				case "81":	if(isWhite)
					blackChessMen.put(src,"r1");
				else 
					whiteChessMen.put(src,"R1");
				continue;
				case "82":	if(isWhite)
					blackChessMen.put(src,"n1");
				else 
					whiteChessMen.put(src,"N1");
				continue;
				case "83":	if(isWhite)
					blackChessMen.put(src,"b1");
				else 
					whiteChessMen.put(src,"B1");
				continue;
				case "84":	if(isWhite)
					blackChessMen.put(src,"q");
				else 
					whiteChessMen.put(src,"Q");
				continue;
				case "85":	if(isWhite)
					blackChessMen.put(src,"k");
				else 
					whiteChessMen.put(src,"K");
				continue;
				case "86":	if(isWhite)
					blackChessMen.put(src,"b2");
				else 
					whiteChessMen.put(src,"B2");
				continue;
				case "87":	if(isWhite)
					blackChessMen.put(src,"n2");
				else 
					whiteChessMen.put(src,"N2");
				continue;
				case "88":	if(isWhite)
					blackChessMen.put(src,"r2");
				else 
					whiteChessMen.put(src,"R2");
				continue;
				default: 	continue;
				}
			}
			if(i==2) {
				//				color1=color2;
				i=6;
			}
		}
		GameOperationsServiceImpl.chessBoard.setBlackChessMen(blackChessMen);
		GameOperationsServiceImpl.chessBoard.setWhiteChessMen(whiteChessMen);
		return this.drawChessBoard("", "");
		

	}

	/*This method refresh the chess board representation each time the move is made*/
	@Override
	public ChessBoard refreshChessBoard(String src, String dest) {
		return this.drawChessBoard(src, dest);

	}

	/*This method helps 'refreshChessBoard()' method to refresh the board depending on the players move*/
	@Override
	public ChessBoard makeMove(String pawn, String dest, int playerNo) throws InvalidMoveException {
		String src="";
		Set<Entry<String, String>> entrySet=null;
		if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK))
			entrySet=GameOperationsServiceImpl.chessBoard.getBlackChessMen().entrySet();
		else
			entrySet=GameOperationsServiceImpl.chessBoard.getWhiteChessMen().entrySet();
		String aquiredPawn=this.acquirePawn(playerNo, dest);
		if(!aquiredPawn.isEmpty())
			System.out.println("Bingo! you just aquired a pawn ["+aquiredPawn+"]\n");
		for(Entry<String, String> entry : entrySet) {
			if(entry.getValue().equals(pawn)) {
				pawn=entry.getValue();
				src=entry.getKey();
				if(src.equals(dest)) {
					throw new InvalidMoveException("Can't dest the piece to the same house!\nPlease dest the pawn to appropriate cell to Win the match!\n");
				}
				if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK)) {
					GameOperationsServiceImpl.chessBoard.getBlackChessMen().remove(src);
					GameOperationsServiceImpl.chessBoard.getBlackChessMen().put(dest, pawn);					
				}
				else if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.WHITE)) {
					GameOperationsServiceImpl.chessBoard.getWhiteChessMen().remove(src);
					GameOperationsServiceImpl.chessBoard.getWhiteChessMen().put(dest, pawn);		
				}
				break;	
			}else {
				continue;
			}
		}
		return this.refreshChessBoard(pawn, dest);

	}

	/*This method validates the pawn name entered by the player*/
	@Override
	public void validatePawn(String src, String dest, Character player) throws InvalidPawnException{
		int playerNo=Integer.parseInt(player.toString())-1;
		boolean isValidPawn=false;
		Set<Entry<String, String>> entrySet=null;
		if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK))
			entrySet=GameOperationsServiceImpl.chessBoard.getBlackChessMen().entrySet();
		else
			entrySet=GameOperationsServiceImpl.chessBoard.getWhiteChessMen().entrySet();

		for(Entry<String, String> entry : entrySet) {
			if(entry.getValue().equals(src)) {
				isValidPawn=true;
				break;	
			}else {
				continue;
			}
		}
		if(isValidPawn)
			return;
		else
			throw new InvalidPawnException("The Pawn-"+src+" either doesn't belong to you or doesn't exist!\nPlease pick the valid Pawn!");
	}

	/*This method simulates acquiring the pawn*/
	private String acquirePawn(int playerNo, String dest) {
		String pawn="";
		if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK)&&GameOperationsServiceImpl.chessBoard.getWhiteChessMen().containsKey(dest)) {
			GameOperationsServiceImpl.players.get(playerNo).getPawnsWon().add(GameOperationsServiceImpl.chessBoard.getWhiteChessMen().get(dest));
			pawn=GameOperationsServiceImpl.chessBoard.getWhiteChessMen().get(dest);
			if(pawn.equals("K")) {
				System.out.println("Congratulations "+GameOperationsServiceImpl.players.get(playerNo).getName()+"! You Win!");
//				System.exit(0);
			}
			GameOperationsServiceImpl.chessBoard.getWhiteChessMen().remove(dest);
		}else if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.WHITE)&&GameOperationsServiceImpl.chessBoard.getBlackChessMen().containsKey(dest)) {
			GameOperationsServiceImpl.players.get(playerNo).getPawnsWon().add(GameOperationsServiceImpl.chessBoard.getBlackChessMen().get(dest));
			pawn=GameOperationsServiceImpl.chessBoard.getBlackChessMen().get(dest);
			if(pawn.equals("k")) {
				System.out.println("Congratulations "+GameOperationsServiceImpl.players.get(playerNo).getName()+"! You Win!");
//				System.exit(0);
			}
			GameOperationsServiceImpl.chessBoard.getBlackChessMen().remove(dest);
		}
		return pawn;
	}

	/*This method validates the move made by the player*/
	@Override
	public ChessBoard validateMove(String pawn, String dest, Character player) throws InvalidMoveException {
		if(!dest.matches("([1-8][1-8])")) {
			throw new InvalidMoveException("Can't interpret the dest!");
		}
		String src="";
		boolean isFirstMove=false;
		int playerNo=Integer.parseInt(player.toString())-1;
		Set<Entry<String, String>> entrySet=null;

		if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK))
			entrySet=GameOperationsServiceImpl.chessBoard.getBlackChessMen().entrySet();
		else
			entrySet=GameOperationsServiceImpl.chessBoard.getWhiteChessMen().entrySet();
		for(Entry<String, String> entry : entrySet) {
			if(entry.getValue().equals(pawn)) {
				pawn=entry.getValue();
				src=entry.getKey();
				break;	
			}else {
				continue;
			}
		}

		/*Condition to check whether the pawn is a 'Rook'*/
		if(pawn.matches("([rR][1-2])")) {
			if(this.pawnMoveService.moveInHVDirection(pawn,src, dest,playerNo,false)) {
				return this.makeMove(pawn, dest,playerNo);	
			}else {
				throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Rook'!\n");
			}
			
		/*Condition to check whether the pawn is a 'Knight'*/
		}else if(pawn.matches("([nN][1-2])")) {
			if(this.pawnMoveService.moveInLShape(pawn,src, dest,playerNo)) {
				return this.makeMove(pawn, dest,playerNo);	
			}else {
				throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Knight'!\n");
			}

		/*Condition to check whether the pawn is a 'Queen' or 'King'*/
		}else if(pawn.matches("([qQkK])")) {
			boolean isKing=pawn.matches("([kK])")?true:false;

			Character vp=src.charAt(0), vm=dest.charAt(0), hp=src.charAt(1), hm=dest.charAt(1);
			int row1=Integer.parseInt(vp.toString());
			int row2=Integer.parseInt(vm.toString());
			int col1=Integer.parseInt(hp.toString());
			int col2=Integer.parseInt(hm.toString());
			if(row1==row2||col1==col2) {
				if(this.pawnMoveService.moveInHVDirection(pawn,src, dest,playerNo,isKing)) {
					return this.makeMove(pawn, dest,playerNo);	
				}else {
					throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Queen'!\n");
				}	
			}else {
				if(this.pawnMoveService.moveDiagonally(pawn,src, dest, playerNo,isKing)) {
					return this.makeMove(pawn, dest,playerNo);
				}else {
					throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Queen'!\n");
				}
			}
		/*Condition to check whether the pawn is a 'Bishop'*/
		}else if(pawn.matches("([bB][1-2])")) {
			if(this.pawnMoveService.moveDiagonally(pawn,src, dest, playerNo,false)) {
				return this.makeMove(pawn, dest,playerNo);	
			}else {
				throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Bishop'!\n");
			}
		/*Condition to check whether the pawn is a 'Pawn'*/
		}else if(pawn.matches("([xXyY][1-8])")) {
			if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK)&&this.isBFirstMove) {
				entrySet=GameOperationsServiceImpl.chessBoard.getBlackChessMen().entrySet().stream().filter(x->x.getValue().startsWith("y")).collect(Collectors.toSet());
				Character c1,c2;
				for(Entry<String, String> entry : entrySet) {
					c1=entry.getValue().charAt(1);
					c2=entry.getKey().charAt(1);
					if(c1==c2) {
						continue;
					}else {
						this.isBFirstMove=false;
						break;
					}

				}
			}else if(GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.WHITE)&&this.isWFirstMove) {
				entrySet=GameOperationsServiceImpl.chessBoard.getWhiteChessMen().entrySet().stream().filter(x->x.getValue().startsWith("x")).collect(Collectors.toSet());
				Character c1,c2;
				for(Entry<String, String> entry : entrySet) {
					c1=entry.getValue().charAt(1);
					c2=entry.getKey().charAt(1);
					if(c1==c2) {
						continue;
					}else {
						this.isWFirstMove=false;
						break;
					}
				}
			}
			isFirstMove=(this.isWFirstMove?this.isWFirstMove:(this.isBFirstMove?this.isBFirstMove:false));

			if(this.pawnMoveService.moveOneSquareForward(pawn,src, dest,playerNo,isFirstMove)) {
				this.isBFirstMove=GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.BLACK)?false:this.isBFirstMove;
				this.isWFirstMove=GameOperationsServiceImpl.players.get(playerNo).getPieceChosen().equals(Constants.WHITE)?false:this.isWFirstMove;	
				return this.makeMove(pawn, dest,playerNo);	
			}else {
				throw new InvalidMoveException("Invalid Move to 'cell-"+dest+"'! Move violates restrictions imposed on 'Pawn'!\n");
			}

		}else {
			throw new InvalidMoveException("Can't interpret the dest!");
		}

	}

}
<file_sep>/README.md
# ChessBoardChallenge
This repository contains Java program to simulate the game of chess, which can be played using console/command line by 2 players.

Environment Setup to run java
-------------------------------
1. Download JDK 1.8 (https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
2. Install the JDK on your machine (installing in 'C:\Program Files\' folder is recommended)
3. Add below 2 environment variables 
   Variable Name : JAVA_HOME
   Variable Value : C:\Program Files\Java\jdk1.8.0_31

   Variable Name : PATH 
   Variable Value : %JAVA_HOME%\bin

Environment Setup to run Unit test using JUnit4
-------------------------------------------------
1. Download JUnit4 (https://search.maven.org/remotecontent?filepath=junit/junit/4.13-beta-3/junit-4.13-beta-3.jar)
2. Copy/Move the downloaded jar to 'C:\Program Files\JUnit'
3. Add below 2 environment variables 
   Variable Name : JUNIT_HOME
   Variable Value : C:\Program Files\JUnit
   
   Variable Name : CLASSPATH
   Variable Value : %CLASSPATH%;%JUNIT_HOME%\junit-4.13-beta-3.jar;.;

Steps to run the program
--------------------------
1. Open the project 'ChessBoardChallenge' in an IDE such Eclipse, IntelliJ, etc.
2. Right click on the /ChessBoradChallenge/src/StartTheGame.java -> Run As -> Java Application
3. Once the application is run, a set of instructions will be given.
4. Follow the instructions for better experience.

Steps to run the Unit tests
--------------------------
1. Open the project 'ChessBoardChallenge' in an IDE such Eclipse, IntelliJ, etc.
2. Right click on the /ChessBoradChallenge/src/test/TestRunner.java -> Run As -> Java Application
3. The above file will start executing unit test cases one by one with the dealy of 1.5 sec.

***Note: When application/test is run, maximize the console so that chess board representation can be seen better.

Following are the instructions and guide lines to play chess using command line
---------------------------------------------------------------------------------
1. This is a standard 8x8 Chess Board representation with following notations used:
	-> '*' -> a black square/cell
	-> 'O' -> a white square/cell
	-> 'R' -> white Rook    &  'r' -> black Rook
	-> 'N' -> white Knight  &  'n' -> black Knight
	-> 'B' -> white Bishop  &  'b' -> black Bishop
	-> 'Q' -> white Queen   &  'q' -> black Queen
	-> 'K' -> white King    &  'k' -> black King
	-> 'x' -> white Pawn    &  'y' -> black Pawn

2. To move the pawn enter the 'pawn name' as shown in the representation and 
   enter the square no. where you wnat the pawn to be moved

	In the below example given, 'move' is combination of 'Row no.'(3) and 'Col no.'(6)
	ex: pawn: N2
	    move:36

3. Apart from the above notations, rest of the notations used are self-explanatory

***Note: This is game is designed according to rules and standards of real world Chess, so always try to make valid moves,
	you will end up getting exceptions otherwise!

![alt text](https://raw.githubusercontent.com/skgadag1/ChessBoardChallenge/master/c001.PNG)
![alt text](https://raw.githubusercontent.com/skgadag1/ChessBoardChallenge/master/c002.PNG)
![alt text](https://raw.githubusercontent.com/skgadag1/ChessBoardChallenge/master/c003.PNG)
![alt text](https://raw.githubusercontent.com/skgadag1/ChessBoardChallenge/master/c004.PNG)
![alt text](https://raw.githubusercontent.com/skgadag1/ChessBoardChallenge/master/c005.PNG)


