Skip to content

jahankhan/chessinal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chessinal

This is a chess app you can play in your terminal!

How to Play

  • Download the code from this repository
  • Navigate to the chess folder and run ruby game.rb
  • You will be prompted whether you want to play single or multiplayer
  • Enter an option (1 for singleplayer, 0 for multiplayer)
  • Move with either the arrow keys and WASD keys and select squares with the space bar
  • Enjoy the game!

The AI in this program is implemented by using the Negamax algorithm with alpha-beta pruning. Since chess is a zero-sum gain we can take advantage of the fact that max(a, b) = -min(-a, -b) and abstract away the need for two cases. Here is a snippet from the algorithm.

def negamax(board, depth, a, b, color)
  if depth == 0
    return color * board.evaluate()
  end
  get_color = color == 1 ? :W : :BLK
  moves = get_computer_moves(board, get_color)
  best_val = -100000
  best_move = nil
  moves.each do |move|
    new_board = board.dup
    new_board.move_piece(move[0], move[1])
    value = -negamax(new_board, depth - 1, -b, -a, -color)
    a = [a, value].max
    return a if a >= b
    if value > best_val
      best_move = move
      best_val = value
    end
  end
  return best_val
end

I also took advantage ruby's polymorphic associations by creating two modules that each piece inherited from

module SlidingPiece

  include SteppingPiece

  def moves(move_dirs_arr)
    output = []
    starting_pos = pos
    move_dirs_arr.each do |dir|
      while true
        newpos= get_new_pos(starting_pos, dir)
        if board.validate!(starting_pos,newpos)
          output.push(newpos)
          starting_pos = newpos
        else
          if is_enemy?(newpos)
            output.push(newpos)
          end
          starting_pos=pos
          break
        end
      end
    end
    return output
  end
end
module SteppingPiece

  def moves(move_dirs_arr)
    output = []
    starting_pos = pos
    move_dirs_arr.each do |dir|
      newpos= get_new_pos(starting_pos, dir)
      if board.validate!(starting_pos,newpos)
        output.push(newpos)
      else
        if is_enemy?(newpos)
          output.push(newpos)
        end
      end
    end
    output
  end

  def get_new_pos(pos, dir)
    pos.map.with_index do |el, i|
      el + dir[i]
    end
  end

  def is_enemy?(pos)
    board.valid_pos?(pos) && board[pos].color != self.color
  end
end

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages