UVA 10196 – Check The Check

This was a fun problem. This is a really good example of a problem where functions make your code extremely easy to read and write. I did a bit of trickery so that I could use the same functions for both white and black kings.

import java.awt.Point;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * 
 * @author Sanchit M. Bhatnagar
 * @see http://uhunt.felix-halim.net/id/74004
 * 
 */
public class P10196 {

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    PrintWriter out = new PrintWriter(System.out);

    int count = 1;
    while (sc.hasNext()) {
      char[][] grid = new char[8][8];
      Point blackKing = null;
      Point whiteKing = null;
      for (int i = 0; i < 8; i++) {
        char[] tmp = sc.next().trim().toCharArray();
        for (int j = 0; j < 8; j++) {
          grid[i][j] = tmp[j];
          if (tmp[j] == 'k') {
            blackKing = new Point(i, j);
          } else if (tmp[j] == 'K') {
            whiteKing = new Point(i, j);
          }
        }
      }
      if (blackKing == null || whiteKing == null)
        break;
      if (inCheck(blackKing, grid)) {
        out.println("Game #" + count + ": black king is in check.");
      } else if (inCheck(whiteKing, grid)) {
        out.println("Game #" + count + ": white king is in check.");
      } else {
        out.println("Game #" + count + ": no king is in check.");
      }
      count++;
    }

    out.close();
    sc.close();
  }

  private static boolean inCheck(Point king, char[][] grid) {
    // Death by queen has been incorporated into deathByRook and deathByBishop
    if (deathByPawn(king, grid) || deathByKnight(king, grid) || deathByRook(king, grid) || deathByBishop(king, grid))
      return true;
    return false;
  }

  private static boolean deathByBishop(Point king, char[][] grid) {
    int i = king.x;
    int j = king.y;
    char thing = '\u000F';
    char thing2 = '\u000F';
    if (Character.isLowerCase(grid[i][j])) {
      // Black King
      thing = 'B';
      thing2 = 'Q';
    } else {
      // White King
      thing = 'b';
      thing2 = 'q';
    }

    // NW
    int idx = i - 1;
    int idx2 = j - 1;
    while (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && grid[idx][idx2] == '.') {
      idx--;
      idx2--;
    }
    if (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && (grid[idx][idx2] == thing || grid[idx][idx2] == thing2))
      return true;

    // NE
    idx = i - 1;
    idx2 = j + 1;
    while (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && grid[idx][idx2] == '.') {
      idx--;
      idx2++;
    }
    if (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && (grid[idx][idx2] == thing || grid[idx][idx2] == thing2))
      return true;

    // SW
    idx = i + 1;
    idx2 = j - 1;
    while (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && grid[idx][idx2] == '.') {
      idx++;
      idx2--;
    }
    if (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && (grid[idx][idx2] == thing || grid[idx][idx2] == thing2))
      return true;

    // RIGHT
    idx = i + 1;
    idx2 = j + 1;
    while (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && grid[idx][idx2] == '.') {
      idx++;
      idx2++;
    }
    if (idx >= 0 && idx < 8 && idx2 >= 0 && idx2 < 8 && (grid[idx][idx2] == thing || grid[idx][idx2] == thing2))
      return true;

    return false;
  }

  private static boolean deathByRook(Point king, char[][] grid) {
    int i = king.x;
    int j = king.y;
    char thing = '\u000F';
    char thing2 = '\u000F';
    if (Character.isLowerCase(grid[i][j])) {
      // Black King
      thing = 'R';
      thing2 = 'Q';
    } else {
      // White King
      thing = 'r';
      thing2 = 'q';
    }

    // UP
    int idx = i - 1;
    while (idx >= 0 && grid[idx][j] == '.') {
      idx--;
    }
    if (idx >= 0 && idx < 8 && (grid[idx][j] == thing || grid[idx][j] == thing2))
      return true;

    // DOWN
    idx = i + 1;
    while (idx < 8 && grid[idx][j] == '.') {
      idx++;
    }
    if (idx >= 0 && idx < 8 && (grid[idx][j] == thing || grid[idx][j] == thing2))
      return true;

    // LEFT
    idx = j - 1;
    while (idx >= 0 && grid[i][idx] == '.') {
      idx--;
    }
    if (idx >= 0 && idx < 8 && (grid[i][idx] == thing || grid[i][idx] == thing2))
      return true;

    // RIGHT
    idx = j + 1;
    while (idx < 8 && grid[i][idx] == '.') {
      idx++;
    }
    if (idx >= 0 && idx < 8 && (grid[i][idx] == thing || grid[i][idx] == thing2))
      return true;

    return false;
  }

  private static boolean deathByKnight(Point king, char[][] grid) {
    int i = king.x;
    int j = king.y;
    char thing = '\u000F';
    if (Character.isLowerCase(grid[i][j])) {
      // Black King
      thing = 'N';
    } else {
      // White King
      thing = 'n';
    }
    if (i + 2 < 8) {
      if (j - 1 >= 0 && grid[i + 2][j - 1] == thing)
        return true;
      if (j + 1 < 8 && grid[i + 2][j + 1] == thing)
        return true;
    }
    if (i - 2 >= 0) {
      if (j - 1 >= 0 && grid[i - 2][j - 1] == thing)
        return true;
      if (j + 1 < 8 && grid[i - 2][j + 1] == thing)
        return true;
    }
    if (j + 2 < 8) {
      if (i - 1 >= 0 && grid[i - 1][j + 2] == thing)
        return true;
      if (i + 1 < 8 && grid[i + 1][j + 2] == thing)
        return true;
    }
    if (j - 2 >= 0) {
      if (i - 1 >= 0 && grid[i - 1][j - 2] == thing)
        return true;
      if (i + 1 < 8 && grid[i + 1][j - 2] == thing)
        return true;
    }

    return false;
  }

  private static boolean deathByPawn(Point king, char[][] grid) {
    int i = king.x;
    int j = king.y;
    char thing = '\u000F';
    if (Character.isLowerCase(grid[i][j])) {
      // Black King
      i++;
      thing = 'P';
    } else {
      // White King
      i--;
      thing = 'p';
    }
    if (i >= 0 && i < 8) {
      if (j - 1 >= 0 && grid[i][j - 1] == thing)
        return true;
      if (j + 1 < 8 && grid[i][j + 1] == thing)
        return true;
    }
    return false;
  }
}

One thought on “UVA 10196 – Check The Check”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.