DEV Community

Discussion on: Daily Challenge #181 - Is King in Check?

Collapse
 
candidateplanet profile image
lusen / they / them 🏳️‍🌈🥑

In Python.

(a) I didn't want to write a complete set of unit tests, so maybe there is a typo-style logic bug in here... but you get the idea.

(b) I changed the input to make it more readable when writing tests.

KING = '♔'
QUEEN = '♛'
BISHOP = '♝'
KNIGHT = '♞'
ROOK = '♜'
PAWN = '♟'
EMPTY = '.'

class Piece(object):
  def __init__(self, row, col):
    self.row = row
    self.col = col

def find_piece(board, symbol):
  for r in range(0, len(board)):
    for c in range(0, len(board)):
      if board[r][c] == symbol:
        return Piece(r, c)
  return None

def is_check(board):
  king = find_piece(board, KING)
  for r in range(0, len(board)):
    for c in range(0, len(board)):
      if board[r][c] == QUEEN:
        if diagonal_attack(board, Piece(r,c), king):
          return True
        if compass_attack(board, Piece(r,c), king):
          return True
      elif board[r][c] == BISHOP:
        if diagonal_attack(board, Piece(r,c), king):
          return True
      elif board[r][c] == KNIGHT:
        if knight_attack(board, Piece(r, c), king):
          return True
      elif board[r][c] == ROOK:
        if compass_attack(board, Piece(r, c), king):
          return True
      elif board[r][c] == PAWN:
        if pawn_attack(board, Piece(r, c), king):
          return True
  return False

def diagonal_attack(board, attacker, king):
  for row_incr, col_incr in [(1,1), (1,-1), (-1,1), (-1,-1)]:
    r = attacker.row+row_incr
    c = attacker.col+col_incr
    while 0 <= r < len(board) and 0 <= c < len(board):
      if r == king.row and c == king.col:
        return True
      elif board[r][c] != EMPTY:
        break
      r += row_incr
      c += col_incr
  return False

def compass_attack(board, attacker, king):
  for row_incr, col_incr in [(0,1), (0,-1), (1,0), (-1,0)]:
    r = attacker.row+row_incr
    c = attacker.col+col_incr
    while 0 <= r < len(board) and 0 <= c < len(board):
      if r == king.row and c == king.col:
        return True
      elif board[r][c] != EMPTY:
        break
      r += row_incr
      c += col_incr
  return False

def knight_attack(board, attacker, king):
  for row_incr, col_incr in [
    ( 1, 2),( 1,-2),
    (-1, 2),(-1,-2),
    ( 2, 1),( 2,-1),
    (-2, 1),(-2,-1)]:
    r = attacker.row+row_incr
    c = attacker.col+col_incr
    if r == king.row and c == king.col:
      return True
  return False

def pawn_attack(board, attacker, king):
  if attacker.row+1 == king.row:
    if attacker.col+1 == king.col or attacker.col-1 == king.col:
      return True
  return False

print(is_check([
  '........',
  '........',
  '........',
  '...♛....',
  '........',
  '.♔......',
  '........',
  '........']), True)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '...♛....',
  '.♔......',
  '........',
  '........']), False)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '...♝....',
  '.♔......',
  '........',
  '...♜....']), False)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '........',
  '.♔.....♜',
  '........',
  '........']), True)

print(is_check([
  '..♞..♞..',
  '.......♞',
  '........',
  '........',
  '........',
  '.♔......',
  '........',
  '........']), False)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '...♞....',
  '.♔......',
  '........',
  '........']), True)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '........',
  '.♔.....♟',
  '........',
  '........']), False)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '♟.......',
  '.♔......',
  '........',
  '........']), True)

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '...♟....',
  '..♔.....',
  '........',
  '........']), True)

print(is_check([
  '.......♝',
  '........',
  '........',
  '........',
  '........',
  '........',
  '........',
  '♔.......']), True);

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '........',
  '.♔......',
  '........',
  '♞.......']), True);

print(is_check([
  '........',
  '........',
  '........',
  '........',
  '...♔....',
  '........',
  '........',
  '........']), False);