Skip to content

Instantly share code, notes, and snippets.

@andkerosine
Created August 24, 2012 21:30
Show Gist options
  • Save andkerosine/3455827 to your computer and use it in GitHub Desktop.
Save andkerosine/3455827 to your computer and use it in GitHub Desktop.
FEN Move Validator
def side piece
piece == ' ' ? -1 : piece =~ /[a-z]/
end
fen = File.read ARGV.shift
board = [*'1'..'8'].reverse.product [*'a'..'h']
from, to = *ARGV.map { |a| board.index a.reverse.split // }
raise 'Wat.' if from == to
board, act, _ = fen.split
board.gsub!(/(\d|\/)/) { ' ' * $1.to_i }
raise 'No piece.' if board[from] == ' '
raise 'Not your turn.' if side board[from] != side(act.tr 'w', 'W')
raise 'Mutiny!' if side(board[from]) == side(board[to])
a, b = [from, to].minmax
dir = [*7..9].find { |n| (b - a) % n == 0 } || 1
clear = (a + dir...b).step(dir).map { |s| board [s] }.join.strip.empty?
rook = ([*-7..7] + (-56..56).step(8).to_a).include? to
bishop = [7, 9].include? dir
queen = clear and rook or bishop
pawn = [*7..9, 16]
puts case board[from]
when /r/i then clear and rook
when /b/i then clear and bishop
when /q/i then queen
when /k/i then queen and [1, *7..9].include?(b - a)
when /n/i then [6, 10, 15, 17].include?(b - a)
when /p/i then
pawn.map!(&:-@) if $~[0] == 'P'
pawn.select! { |s| board[from + s].send s.odd? ? :!= : :==, ' ' }
pawn.pop unless [*8..15, *47..55].include? from
pawn.map { |s| from + s }.include? to
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment