require 'tagua/core'def crazyhouse_initrepo(loader) repo = Tagua::Repository.new chess = loader.get_repository 'chess' or return repo.proxy = chess repo.state_factory = state_class State repo.animator_factory = animator_factory do |api, namer| Tagua::DropAnimator.new(chess.animator_factory.create(api, namer), api, namer, $white, $black) end repo.move_serializer.each do |key, s| repo.get(key).wrap_with MoveSerializer end repo.validator.wrap_with Validator $pawn = chess.type.pawnendclass State delegate_to :state attr_accessor :pools def initialize(state) @state = state @pools = Tagua::PoolCollection.new end def clone res = self.class.new(state.clone) res.pools = pools.clone res end def move(m) if m.drop captured = board.get(m.dst) set(m.dst, m.drop) pools.pool(m.drop.color).remove(m.drop.type) # handle capturing by drop: some variants could use it pools.pool(opponent(captured.color)).add(captured.type) if captured switchTurn else state.move(m) if (m.promotion) promoted = board.get(m.to) promoted.promoted = true board.set(m.to, promoted) end end endendclass Validator delegate_to :validator def initialize(validator) @validator = validator end def pseudolegal(state, move) # add drop information to move, if missing if not move.drop and move.pool and move.index != -1 move.drop = state.pools.pool(move.pool).get(move.index) end dropped = move.drop # use wrapped validator for nondrop moves return validator.pseudolegal(move) unless dropped # dropping on a valid square return false unless state.board.valid(move.to) # cannot drop on occupied squares return false if state.board(move.to) # cannot drop pawns in first or eighth rank return false if dropped.type == $pawn and (move.to.y == state.rank(0, $white) or move.to.y == state.promotion(state.board.size.y - 1, $white)) return true end def mover(state, move) if move.drop return move.drop.color; else return validator.mover(move); end endendclass MoveSerializer delegate_to :serializer def initialize(serializer) @serializer = serializer end def serialize(move, ref) if move.drop res = if serializer.type == 'decorated' "{#{move.drop.type.name}}" else serializer.symbol(move.drop.type).upcase end "#{res}@#{move.to.toString(ref.board.size.y)}#{serializer.suffix(move, ref)}" else serializer.serialize move end endend