mirror of
https://github.com/SleepingInsomniac/lx_chess_cr
synced 2024-11-16 19:49:34 +01:00
Move terminal game into own class
This commit is contained in:
parent
1608aa7b90
commit
90a5683236
2 changed files with 158 additions and 113 deletions
117
src/lx_chess.cr
117
src/lx_chess.cr
|
@ -5,6 +5,7 @@ require "./lx_chess/term_board"
|
|||
require "./lx_chess/game"
|
||||
require "./lx_chess/fen"
|
||||
require "./lx_chess/notation"
|
||||
require "./lx_chess/term_game"
|
||||
|
||||
require "option_parser"
|
||||
|
||||
|
@ -38,128 +39,18 @@ OptionParser.parse do |parser|
|
|||
end
|
||||
end
|
||||
|
||||
log = [] of String
|
||||
fen = LxChess::Fen.parse(options["fen_string"]? || "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
|
||||
|
||||
player_white = LxChess::Player.new
|
||||
player_black = LxChess::Player.new
|
||||
|
||||
game = LxChess::Game.new(board: fen.board, players: [player_white, player_black])
|
||||
game.set_fen_attributes(fen)
|
||||
|
||||
gb = LxChess::TermBoard.new(game.board)
|
||||
game = LxChess::TermGame.new(fen: fen)
|
||||
|
||||
if theme = options["theme"]?
|
||||
if LxChess::TermBoard::THEMES[theme]?
|
||||
gb.board_theme = theme
|
||||
game.gb.board_theme = theme
|
||||
else
|
||||
STDERR.puts "No theme #{theme}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
term = LxChess::Terminal.new
|
||||
|
||||
term.clear
|
||||
term.clear_scroll
|
||||
|
||||
loop do
|
||||
term.move 0, 0
|
||||
print fen.to_s
|
||||
term.trunc
|
||||
term.move x: 0, y: 3
|
||||
gb.draw
|
||||
|
||||
game.pgn.strings.each_with_index do |m, i|
|
||||
term.move game.board.width * 2 + 10, y: 3 + i
|
||||
print m
|
||||
end
|
||||
|
||||
term.move x: 0, y: game.board.height + 5
|
||||
if game.turn == 0
|
||||
print " #{game.full_moves + 1}. "
|
||||
else
|
||||
print " #{game.full_moves + 1}. ... "
|
||||
end
|
||||
term.trunc
|
||||
input = gets
|
||||
case input
|
||||
when /moves\s+([a-z]\d)/i
|
||||
next unless input
|
||||
if matches = input.match(/[a-z]\d/i)
|
||||
if square = matches[0]?
|
||||
if index = game.board.index(square)
|
||||
if set = game.moves(index)
|
||||
gb.highlight(set.moves, "blue")
|
||||
from = "#{set.piece.fen_symbol}#{game.board.cord(index)}: "
|
||||
to = set.moves.map { |m| game.board.cord(m) }.join(", ")
|
||||
log.unshift from + to
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
when /moves/i
|
||||
pieces = game.board.select do |piece|
|
||||
next if piece.nil?
|
||||
game.turn == 0 ? piece.white? : piece.black?
|
||||
end
|
||||
|
||||
move_sets = pieces.map do |piece|
|
||||
next unless piece
|
||||
game.moves(piece.index.as(Int16))
|
||||
end
|
||||
|
||||
move_string = move_sets.map do |set|
|
||||
next unless set
|
||||
next if set.moves.empty?
|
||||
gb.highlight(set.moves, "blue")
|
||||
from = "#{set.piece.fen_symbol}#{game.board.cord(set.origin)}: "
|
||||
to = set.moves.map { |m| game.board.cord(m) }.join(", ")
|
||||
from + to
|
||||
end.compact.join(" | ")
|
||||
log.unshift move_string
|
||||
when /\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i
|
||||
if input
|
||||
if matches = input.downcase.match(/\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i)
|
||||
from = matches[1]
|
||||
to = matches[2]
|
||||
promo = if matches[3]?
|
||||
matches[3][0]
|
||||
end
|
||||
if from && to
|
||||
gb.clear
|
||||
san = game.make_move(from, to)
|
||||
gb.highlight([game.board.index(from), game.board.index(to)])
|
||||
log.unshift "#{san.to_s}: #{from} => #{to}"
|
||||
end
|
||||
end
|
||||
end
|
||||
when nil
|
||||
else
|
||||
if input
|
||||
notation = LxChess::Notation.new(input)
|
||||
from, to = game.parse_san(notation)
|
||||
if from && to
|
||||
gb.clear
|
||||
san = game.make_move(from, to)
|
||||
gb.highlight([from.to_i16, to.to_i16])
|
||||
log.unshift "#{san.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fen.update(game)
|
||||
rescue e : LxChess::Notation::InvalidNotation | LxChess::Game::SanError | LxChess::Game::IllegalMove
|
||||
if msg = e.message
|
||||
log.unshift msg
|
||||
end
|
||||
ensure
|
||||
puts
|
||||
log.each { |l| print l; term.trunc; puts }
|
||||
until log.size < 8
|
||||
log.pop
|
||||
end
|
||||
game.tick
|
||||
end
|
||||
|
||||
# gb.flip!
|
||||
# gb.draw
|
||||
# puts
|
||||
|
|
154
src/lx_chess/term_game.cr
Normal file
154
src/lx_chess/term_game.cr
Normal file
|
@ -0,0 +1,154 @@
|
|||
require "./fen"
|
||||
require "./game"
|
||||
require "./player"
|
||||
require "./terminal"
|
||||
require "./term_board"
|
||||
|
||||
module LxChess
|
||||
class TermGame
|
||||
property gb : TermBoard
|
||||
getter log
|
||||
|
||||
def initialize(@fen : Fen, players = [Player.new, Player.new])
|
||||
@term = Terminal.new
|
||||
@game = Game.new(board: @fen.board, players: players)
|
||||
@game.set_fen_attributes(fen)
|
||||
@gb = TermBoard.new(@game.board)
|
||||
@log = [] of String
|
||||
clear_screen
|
||||
end
|
||||
|
||||
def update
|
||||
input = gets || ""
|
||||
|
||||
case input
|
||||
when /moves\s+([a-z]\d)/i
|
||||
if matches = input.match(/[a-z]\d/i)
|
||||
if square = matches[0]?
|
||||
if index = @game.board.index(square)
|
||||
if set = @game.moves(index)
|
||||
@gb.highlight(set.moves, "blue")
|
||||
from = "#{set.piece.fen_symbol}#{@game.board.cord(index)}: "
|
||||
to = set.moves.map { |m| @game.board.cord(m) }.join(", ")
|
||||
@log.unshift from + to
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
when /moves/i
|
||||
pieces = @game.board.select do |piece|
|
||||
next if piece.nil?
|
||||
@game.turn == 0 ? piece.white? : piece.black?
|
||||
end
|
||||
|
||||
move_sets = pieces.map do |piece|
|
||||
next unless piece
|
||||
@game.moves(piece.index.as(Int16))
|
||||
end
|
||||
|
||||
move_string = move_sets.map do |set|
|
||||
next unless set
|
||||
next if set.moves.empty?
|
||||
@gb.highlight(set.moves, "blue")
|
||||
from = "#{set.piece.fen_symbol}#{@game.board.cord(set.origin)}: "
|
||||
to = set.moves.map { |m| @game.board.cord(m) }.join(", ")
|
||||
from + to
|
||||
end.compact.join(" | ")
|
||||
@log.unshift move_string
|
||||
when /\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i
|
||||
if input
|
||||
if matches = input.downcase.match(/\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i)
|
||||
from = matches[1]
|
||||
to = matches[2]
|
||||
promo = if matches[3]?
|
||||
matches[3][0]
|
||||
end
|
||||
if from && to
|
||||
@gb.clear
|
||||
san = @game.make_move(from, to)
|
||||
@gb.highlight([@game.board.index(from), @game.board.index(to)])
|
||||
@log.unshift "#{san.to_s}: #{from} => #{to}"
|
||||
end
|
||||
end
|
||||
end
|
||||
when nil
|
||||
else
|
||||
if input
|
||||
notation = Notation.new(input)
|
||||
from, to = @game.parse_san(notation)
|
||||
if from && to
|
||||
@gb.clear
|
||||
san = @game.make_move(from, to)
|
||||
@gb.highlight([from.to_i16, to.to_i16])
|
||||
@log.unshift "#{san.to_s}: #{@game.board.cord(from)} => #{@game.board.cord(to)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@fen.update(@game)
|
||||
rescue e : LxChess::Notation::InvalidNotation | LxChess::Game::SanError | LxChess::Game::IllegalMove
|
||||
if msg = e.message
|
||||
@log.unshift msg
|
||||
end
|
||||
ensure
|
||||
until log.size < 8
|
||||
log.pop
|
||||
end
|
||||
end
|
||||
|
||||
def draw
|
||||
draw_fen
|
||||
draw_board
|
||||
draw_pgn
|
||||
draw_log
|
||||
draw_prompt
|
||||
end
|
||||
|
||||
def tick
|
||||
draw
|
||||
update
|
||||
end
|
||||
|
||||
# ===================
|
||||
# = Drawing methods =
|
||||
# ===================
|
||||
|
||||
private def clear_screen
|
||||
@term.clear
|
||||
@term.clear_scroll
|
||||
end
|
||||
|
||||
private def draw_fen
|
||||
@term.move 0, 0
|
||||
print @fen.to_s
|
||||
@term.trunc
|
||||
end
|
||||
|
||||
private def draw_board
|
||||
@term.move x: 0, y: 3
|
||||
@gb.draw
|
||||
end
|
||||
|
||||
private def draw_pgn
|
||||
@game.pgn.strings.each_with_index do |m, i|
|
||||
@term.move @game.board.width * 2 + 10, y: 3 + i
|
||||
print m
|
||||
end
|
||||
end
|
||||
|
||||
private def draw_log
|
||||
@term.move x: 0, y: @game.board.height + 7
|
||||
@log.each { |l| print l; @term.trunc; puts }
|
||||
end
|
||||
|
||||
private def draw_prompt
|
||||
@term.move x: 0, y: @game.board.height + 5
|
||||
if @game.turn == 0
|
||||
print " #{@game.full_moves + 1}. "
|
||||
else
|
||||
print " #{@game.full_moves + 1}. ... "
|
||||
end
|
||||
@term.trunc
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue