chessboard

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tommy34
    New Member
    • Sep 2006
    • 2

    #1

    chessboard

    I'm new to java and any help will be appreciated. Problem is i dont know even where to start.

    I need to write a program that reads a chessboard configuration and identifies whether a king is under attack (in check). A king is in check if it is on square which can be taken by the opponent on his next move.

    White pieces will be represented by uppercase letters, and black pieces by lowercase letters. The white side will always be on the bottom of the board, with the black side always on the top.


    Pawn (p or P):

    can only move straight ahead, one square at a time. However, it takes pieces diagonally, and that is what concerns you in this problem.

    Knight (n or N)

    : has an L-shaped movement shown below. It is the only piece that can jump over other pieces.

    Bishop (b or B)

    : can move any number of squares diagonally, either forward or backward.

    Rook (r or R)

    : can move any number of squares vertically or horizontally, either forward or backward.

    Queen (q or Q)

    : can move any number of squares in any direction (diagonally, horizontally, or vertically) either forward or backward.

    King (k or K)

    : can move one square at a time in any direction (diagonally, horizontally, or vertically) either forward or backward.


    the knight is the only piece that can jump over other pieces. The pawn movement will depend on its side. If it is a black pawn, it can only move one square diagonally down the board. If it is a white pawn, it can only move one square diagonally up the board. The example above is a black pawn, described by a lowercase ``p''. We use ``move" to indicate the squares where the pawn can capture another piece.
    Input

    There will be an arbitrary number of board configurations in the input, each consisting of eight lines of eight characters each. A ``.'' denotes an empty square, while upper- and lowercase letters represent the pieces as defined above. There will be no invalid characters and no configurations where both kings are in check. You must read until you find an empty board consisting only of ``.'' characters, which should not be processed. There will be an empty line between each pair of board configurations. All boards, except for the empty one, will contain exactly one white king and one black king.
    Output

    For each board configuration read you must output one of the following answers:

    Game #d: white king is in check.

    Game #d: black king is in check.

    Game #d: no king is in check.

    where d stands for the game number starting from 1.

    Sample Input
    ..k.....
    ppp.pppp
    ........
    .R...B..
    ........
    ........
    PPPPPPPP
    K.......

    rnbqk.nr
    ppp..ppp
    ....p...
    ...p....
    .bPP....
    .....N..
    PP..PPPP
    RNBQKB.R

    ........
    ........
    ........
    ........
    ........
    ........
    ........
    ........
    Sample Output
    Game #1: black king is in check.
    Game #2: white king is in check.
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    Originally posted by tommy34
    I'm new to java and any help will be appreciated. Problem is i dont know even where to start.

    I need to write a program that reads a chessboard configuration and identifies whether a king is under attack (in check). A king is in check if it is on square which can be taken by the opponent on his next move.

    White pieces will be represented by uppercase letters, and black pieces by lowercase letters. The white side will always be on the bottom of the board, with the black side always on the top.


    Pawn (p or P):

    can only move straight ahead, one square at a time. However, it takes pieces diagonally, and that is what concerns you in this problem.

    Knight (n or N)

    : has an L-shaped movement shown below. It is the only piece that can jump over other pieces.

    Bishop (b or B)

    : can move any number of squares diagonally, either forward or backward.

    Rook (r or R)

    : can move any number of squares vertically or horizontally, either forward or backward.

    Queen (q or Q)

    : can move any number of squares in any direction (diagonally, horizontally, or vertically) either forward or backward.

    King (k or K)

    : can move one square at a time in any direction (diagonally, horizontally, or vertically) either forward or backward.


    the knight is the only piece that can jump over other pieces. The pawn movement will depend on its side. If it is a black pawn, it can only move one square diagonally down the board. If it is a white pawn, it can only move one square diagonally up the board. The example above is a black pawn, described by a lowercase ``p''. We use ``move" to indicate the squares where the pawn can capture another piece.
    Input

    There will be an arbitrary number of board configurations in the input, each consisting of eight lines of eight characters each. A ``.'' denotes an empty square, while upper- and lowercase letters represent the pieces as defined above. There will be no invalid characters and no configurations where both kings are in check. You must read until you find an empty board consisting only of ``.'' characters, which should not be processed. There will be an empty line between each pair of board configurations. All boards, except for the empty one, will contain exactly one white king and one black king.
    Output

    For each board configuration read you must output one of the following answers:

    Game #d: white king is in check.

    Game #d: black king is in check.

    Game #d: no king is in check.

    where d stands for the game number starting from 1.

    Sample Input
    ..k.....
    ppp.pppp
    ........
    .R...B..
    ........
    ........
    PPPPPPPP
    K.......

    rnbqk.nr
    ppp..ppp
    ....p...
    ...p....
    .bPP....
    .....N..
    PP..PPPP
    RNBQKB.R

    ........
    ........
    ........
    ........
    ........
    ........
    ........
    ........
    Sample Output
    Game #1: black king is in check.
    Game #2: white king is in check.
    First please confirm that the sample output you've given above does not follow from the given sample input(i.e for both games given, no king is in check). I just want to make sure I've understood your rules correctly.

    Then you'd need to address the following
    Input-Are you reading from a file or is a user going to be typing in the board configurations
    Board Representation-are you going to manipulate the board as a file, 2D array, or a Board(data structure to be designed).
    Error Handling-Did you mean from above that the program assumes correct input or that it is supposed to identify and reject incorrect input.

    Implementation-Will depend on the Board representation chosen. An initial brute force approach would be to go over each character on the board testing to see if it is attacking the opposite side's King.

    It is not as difficult as it might appear but I think making the right design decisions simplifies the program a lot

    Comment

    • D_C
      Contributor
      • Jun 2006
      • 293

      #3
      Code:
      while(!quit)
      {
         game_number++;
         Store the data in 8x8 2D array of characters
         if (the board is blank)
            quit = true;
         else
         {
            find and store the white king's position
            find and store the black kings position
            while(0 <= row < 8  && !white_check && !black_check)
              while(0 <= col < 8  && !white_check && !black_check)
               {
                  if character is uppercase
                     black_enemy = true; // or white_enemy if white means uppercase
                  switch(char_array[row][col].toLowercase())
                  {
                      case 'n' : if(black) // black knight white king
                                      white_check = KnightCheck(current row/col, white king's position));
                                    else
                                      black_check = KnightCheck(current row/col, black king's position);
                                    break;
                     ...
      Do that for each type of character. Since the Knight doesn't have to worry about obstacles, it's the easiest one to calculate.
      Code:
      KnightCheck(knight_x, knight_y, king_x, king_y)
      {
        return (abs(knight_x-king_x)+abs(knight_y-king_y))==3;
      }
      Other than avoiding obstacles, each piece is simple. Either it's limited by distance, or alignment. For example, rook must have the same x or y value as the king. For bishops, (bishop_x - bishop_y) should equal (king_x - king_y). Since two kings cannot be in check, KingCheck(black _king, white_king) should be unnecessary.

      To avoid obstacles, you need to do a loop from king to attacker. If you don't see a space, there is an object in the way. For bishops, you only need one loop since x increases/decrease as much as y since it's on the diagonal.

      The only other thing to remember is that pawns cannot travel backwards. It's also the only reason you need to know which side of the board belongs to who.

      Comment

      • tommy34
        New Member
        • Sep 2006
        • 2

        #4
        Hello,
        the problem is i keep getting ArrayIndexOutOf BoundsException and i dont know how to fix it. Any suggestions how to improve would be nice
        Code:
        import java.io.*;
        import java.io.BufferedReader;
        import java.io.InputStreamReader;
        import java.io.IOException;
        
        public class pirmaUzd {
            public static String[][] board;
            public static String[] str;
            private static String exitCode = "0 0";
             
            public static boolean RookCheck(int row,int col,String piece)
            {
                int i;
                for (i=row+1;i<8;i++)
                { 
                    if (board[i][col]!=".")
                {
                    if(board[i][col]==piece) return true;
                    else break;
                }        
                }
                for (i=row-1;i>=0;i--)
                {
                    if (board[i][col]!=".")
                    {
                        if (board[i][col]==piece) return true;
                        else break;
                    }
                }
                for (i=col+1;i<8;i++)
                {
                    if (board[row][i]!=".")
                    {
                        if (board[row][i]==piece) return true;
                        else break;
                    }
                }
                for (i=col-1;i>=0;i--)
                {
                    if (board[row][i]!=".")
                    {
                        if (board[row][i]==piece) return true;
                        else break;
                    }
                }
                return false;
            }
            
            
            
            public static boolean BishopCheck(int row,int col,String piece)
            {
                int i,j;
                
                for (i=row+1,j=col+1;i<8 && j<8; i++, j++)
                {
                    if (board[i][j]!=".")
                    {
                        if (board[i][j]==piece) return true;
                        else break;
                    }
                }
                for (i=row+1,j=col-1;i<8 && j>0; i++, j--)
                {
                    if (board[i][j]!=".")
                    {
                        if (board[i][j]==piece) return true;
                        else break;
                    }
                }
                for (i=row-1,j=col+1;i>=0 && j<8;i--,j++)
                {
                    if (board[i][j]!=".")
                    {
                        if (board[i][j]==piece) return true;
                        else break;
                    }
                }
                for (i=row-1,j=col-1;i>=0 && j>=0; i--, j--)
                {
                    if (board[i][j]!=".")
                    {
                        if (board[i][j]==piece) return true;
                        else break;
                    }
                }
                    return false;
                
            }
                
             public static boolean KnightCheck(int row, int col, String piece)
             {
                 if(board[row+1][col+2]==piece || board[row+1][col-2]==piece ||
                    board[row-1][col+2]==piece || board[row-1][col-2]==piece ||
                    board[row+2][col+1]==piece || board[row+2][col-1]==piece ||
                    board[row-2][col+1]==piece || board[row-2][col-1]==piece) return true;
                 
                 return false;
             }
             
             
             
           public static void main(String[] args) throws IOException {
          
                FileInputStream fstream = new FileInputStream( "C:/duom.txt" );
                DataInputStream ds = new DataInputStream( fstream );
                int i, j, brow, bcol, wrow, wcol, wcheck, bcheck, p;
                long q=0;
               
                brow=0; bcol=0; wrow=0; wcol=0; wcheck=0; bcheck=0; p=0;
                String[] str = new String[9];
                String[][] board = new String[9][9];
                
               
                 while ( ds.available() != 0){
                  //String str =  in.readLine();
                    for (i=0; i<8; i++)
                   
                    {
                        
                        str[i] = ds.readLine();
                        for (j=0; j<8; j++){
                            board[i][j] = String.valueOf(str[i].charAt( j ));
                            
                            if(board[i][j].equals("k")) {brow=i; bcol=j;}
                            if(board[i][j]=="K") {wrow=i; wcol=j;}
                            System.out.println(brow+ " " +bcol);
                        }
                       
                    }     
                }
                        
                
                for (i=0; i<8; i++)
                {
                    for (j=0; j<8; j++)
                    {
                        if(board[i][j]=="k") {brow=i; bcol=j;}
                        if(board[i][j]=="K") {wrow=i; wcol=j;}
                    }
                }
                
                if (board[wrow-1][wcol+1]=="p" || board[wrow-1][wcol-1]=="p") wcheck=1;
                else if (KnightCheck(wrow, wcol, "n")) wcheck=1;
                else if (RookCheck(wrow, wcol, "r")) wcheck=1;
                else if (BishopCheck(wrow, wcol, "b")) wcheck=1;
                else if (RookCheck(wrow, wcol, "q")) wcheck=1;
                else if (BishopCheck(wrow, wcol, "q")) wcheck=1;
             
               
                if (board[brow+1][bcol-1]=="P" || board[brow+1][bcol+1]=="P") bcheck=1;
                else if (KnightCheck(brow,bcol,"N")) bcheck=1;
                else if (RookCheck(brow,bcol,"R")) bcheck=1;
                else if (BishopCheck(brow,bcol,"B")) bcheck=1;
                else if (RookCheck(brow,bcol,"Q")) bcheck=1;
                else if (BishopCheck(brow,bcol,"Q")) bcheck=1;
             
                if(wcheck==1) System.out.println("Game #" + ++q + ":white king is in check");
                else if (bcheck==1) System.out.println("Game #" + ++q +":black king is in check");
                else if (wcheck==0 && bcheck==0) System.out.println("Game #" + ++q + ":no king is in check");
                
                
                }
        }

        Comment

        • r035198x
          MVP
          • Sep 2006
          • 13225

          #5
          Originally posted by tommy34
          Hello,
          the problem is i keep getting ArrayIndexOutOf BoundsException and i dont know how to fix it. Any suggestions how to improve would be nice
          Code:
          import java.io.*;
          import java.io.BufferedReader;
          import java.io.InputStreamReader;
          import java.io.IOException;
          
          public class pirmaUzd {
              public static String[][] board;
              public static String[] str;
              private static String exitCode = "0 0";
               
              public static boolean RookCheck(int row,int col,String piece)
              {
                  int i;
                  for (i=row+1;i<8;i++)
                  { 
                      if (board[i][col]!=".")
                  {
                      if(board[i][col]==piece) return true;
                      else break;
                  }        
                  }
                  for (i=row-1;i>=0;i--)
                  {
                      if (board[i][col]!=".")
                      {
                          if (board[i][col]==piece) return true;
                          else break;
                      }
                  }
                  for (i=col+1;i<8;i++)
                  {
                      if (board[row][i]!=".")
                      {
                          if (board[row][i]==piece) return true;
                          else break;
                      }
                  }
                  for (i=col-1;i>=0;i--)
                  {
                      if (board[row][i]!=".")
                      {
                          if (board[row][i]==piece) return true;
                          else break;
                      }
                  }
                  return false;
              }
              
              
              
              public static boolean BishopCheck(int row,int col,String piece)
              {
                  int i,j;
                  
                  for (i=row+1,j=col+1;i<8 && j<8; i++, j++)
                  {
                      if (board[i][j]!=".")
                      {
                          if (board[i][j]==piece) return true;
                          else break;
                      }
                  }
                  for (i=row+1,j=col-1;i<8 && j>0; i++, j--)
                  {
                      if (board[i][j]!=".")
                      {
                          if (board[i][j]==piece) return true;
                          else break;
                      }
                  }
                  for (i=row-1,j=col+1;i>=0 && j<8;i--,j++)
                  {
                      if (board[i][j]!=".")
                      {
                          if (board[i][j]==piece) return true;
                          else break;
                      }
                  }
                  for (i=row-1,j=col-1;i>=0 && j>=0; i--, j--)
                  {
                      if (board[i][j]!=".")
                      {
                          if (board[i][j]==piece) return true;
                          else break;
                      }
                  }
                      return false;
                  
              }
                  
               public static boolean KnightCheck(int row, int col, String piece)
               {
                   if(board[row+1][col+2]==piece || board[row+1][col-2]==piece ||
                      board[row-1][col+2]==piece || board[row-1][col-2]==piece ||
                      board[row+2][col+1]==piece || board[row+2][col-1]==piece ||
                      board[row-2][col+1]==piece || board[row-2][col-1]==piece) return true;
                   
                   return false;
               }
               
               
               
             public static void main(String[] args) throws IOException {
            
                  FileInputStream fstream = new FileInputStream( "C:/duom.txt" );
                  DataInputStream ds = new DataInputStream( fstream );
                  int i, j, brow, bcol, wrow, wcol, wcheck, bcheck, p;
                  long q=0;
                 
                  brow=0; bcol=0; wrow=0; wcol=0; wcheck=0; bcheck=0; p=0;
                  String[] str = new String[9];
                  String[][] board = new String[9][9];
                  
                 
                   while ( ds.available() != 0){
                    //String str =  in.readLine();
                      for (i=0; i<8; i++)
                     
                      {
                          
                          str[i] = ds.readLine();
                          for (j=0; j<8; j++){
                              board[i][j] = String.valueOf(str[i].charAt( j ));
                              
                              if(board[i][j].equals("k")) {brow=i; bcol=j;}
                              if(board[i][j]=="K") {wrow=i; wcol=j;}
                              System.out.println(brow+ " " +bcol);
                          }
                         
                      }     
                  }
                          
                  
                  for (i=0; i<8; i++)
                  {
                      for (j=0; j<8; j++)
                      {
                          if(board[i][j]=="k") {brow=i; bcol=j;}
                          if(board[i][j]=="K") {wrow=i; wcol=j;}
                      }
                  }
                  
                  if (board[wrow-1][wcol+1]=="p" || board[wrow-1][wcol-1]=="p") wcheck=1;
                  else if (KnightCheck(wrow, wcol, "n")) wcheck=1;
                  else if (RookCheck(wrow, wcol, "r")) wcheck=1;
                  else if (BishopCheck(wrow, wcol, "b")) wcheck=1;
                  else if (RookCheck(wrow, wcol, "q")) wcheck=1;
                  else if (BishopCheck(wrow, wcol, "q")) wcheck=1;
               
                 
                  if (board[brow+1][bcol-1]=="P" || board[brow+1][bcol+1]=="P") bcheck=1;
                  else if (KnightCheck(brow,bcol,"N")) bcheck=1;
                  else if (RookCheck(brow,bcol,"R")) bcheck=1;
                  else if (BishopCheck(brow,bcol,"B")) bcheck=1;
                  else if (RookCheck(brow,bcol,"Q")) bcheck=1;
                  else if (BishopCheck(brow,bcol,"Q")) bcheck=1;
               
                  if(wcheck==1) System.out.println("Game #" + ++q + ":white king is in check");
                  else if (bcheck==1) System.out.println("Game #" + ++q +":black king is in check");
                  else if (wcheck==0 && bcheck==0) System.out.println("Game #" + ++q + ":no king is in check");
                  
                  
                  }
          }
          Sorry I don't really have the time to look at the right now but if it's an ArrayIndexOutOf BoundsException you should be able to get the line number from the stack trace. If you give the line number then it will be easy to pick the error

          Comment

          • r035198x
            MVP
            • Sep 2006
            • 13225

            #6
            Now that I've looked at the code a bit, I'd say it does not look good.
            I really think you should write the Board class separately.
            All those if-elses can get terrible to maintain. Since you have decided to use a String[] instead of a char[], you need to compare using equals and !equals rather than == and !=.
            About the null pointer, like I said, what line number is occurring at?

            Comment

            • D_C
              Contributor
              • Jun 2006
              • 293

              #7
              I'm not sure what I was thinking when I told you, but I have a better idea.

              When you find a king, then search for the other player's relative to the king.

              For example, suppose the white king is at row 1, col 5. I wasn't paying attention to whether white starts at rows 0 and 1, or whether black does. Assume white does, and if I'm wrong just switch things.

              I would use a while loop for the rook/queen and bishop/queen. If statements for pawn and knight. Also, suppose the king is in a corner. You need to check if the array indices are valid. Suppose you are checking if the king can be hit by a knight. If the king is in a corner, only two of the eight possibilities are valid. That may where the ArrayIndexOutOf Bounds Exception is coming from.

              Check for black pawn. Check row 2, cols 4 and 6. You need to check that king_y < 7 and 0 < king_x < 7. If so, then test for a black pawn. Otherwise an ArrayIndexOutOf Bounds Exception will occur.
              Check for black rook/queen. Check left, right, up and down until you hit a wall or another piece. If it's a wall, he's safe, if it's his own man, he's safe. If it's a black rook, or black queen, it's checkmate.
              Check for black bishop/queen. Check up+left, up+right, down+right, down+left. Again, if you hit a wall, or your own player, the king is safe. If you hit a black bishop, or black queen, it's checkmate.
              Check for black knight. See pseudocode below.
              Code:
              if(king_x > 1) // test for knight to the left (left two, up/down 1)
              { // can go left two
                if(king_y != 0) // can go up one
                  if(game[king_y - 1][king_x - 2] == /* knight */)
                    return /* checkmate */
                if(king_y != 7) // can go down one
                  if(game[king_y + 1][king_x - 2] == /* knight */)
                    return /* checkmate */
              }
              if king_x < 6
              // test for knight to the right (right two, up/down 1)
              // same as above, just modify the constants.
              if king_y > 1
              // test for knight below (down two, left/right 1)
              if king_y < 6
              // test for knight above (up two, left/right 1)

              Comment

              Working...