[SOLUTION] Chess Variants (II) (#36)

  • Thread starter James Edward Gray II
  • Start date
J

James Edward Gray II

I don't want to spoil all the fun, in case anyone is still attempting
this quiz, but here's my solution to four of the seven variations:

#!/usr/local/bin/ruby -w

# blackhole_chess
#
# Created by James Edward Gray II on 2005-06-20.
# Copyright 2005 Gray Productions. All rights reserved.

require "chess"

# An enhanced chess board for playing Blackhole Chess.
class BlackholeChess < Chess::Board
#
# A general purpose test to see if a _test_ square is between
_start_ and
# _finish_ squares, on a rank, file or diagonal.
#
def self.between?( start, finish, test )
test_rank, test_file = test[1, 1].to_i, test[0]
start_rank, start_file = start[1, 1].to_i, start[0]
finish_rank, finish_file = finish[1, 1].to_i, finish[0]

( test_rank == start_rank and test_rank == finish_rank and
test_file >= [start_file, finish_file].min and
test_file <= [start_file, finish_file].max ) or
( test_file == start_file and test_file == finish_file and
test_rank >= [start_rank, finish_rank].min and
test_rank <= [start_rank, finish_rank].max ) or
( (start_file - finish_file).abs == (start_rank -
finish_rank).abs and
(start_file - test_file).abs == (start_rank -
test_rank).abs and
(test_file - finish_file).abs == (test_rank -
finish_rank).abs and
test_file >= [start_file, finish_file].min and
test_file <= [start_file, finish_file].max and
test_rank >= [start_rank, finish_rank].min and
test_rank <= [start_rank, finish_rank].max )
end

# End the game if a King goes missing.
def in_checkmate?( who = @turn )
if find { |(s, pc)| pc and pc.color == who and pc.is_a?
Chess::King }
super
else
true
end
end

# Eliminate any piece moving through the blackholes.
def move( from_square, to_square, promote_to = nil )
if self.class.between?(from_square, to_square, "d5") or
self.class.between?(from_square, to_square, "f5")
@squares[from_square] = nil
next_turn
else
super
end

self
end

# Board display with two added blackholes.
def to_s( )
super.sub( /^(5\s+\|(?:[^|]+\|){3})[^|]+\|([^|]+\|)[^|]+\|/,
"\\1 * |\\2 * |" )
end
end

board = BlackholeChess.new

# insert my chess inteface code (see Summary) here, with a minor
addition to spot
# a king that falls into a blackhole

__END__

#!/usr/local/bin/ruby -w

# fairy_chess
#
# Created by James Edward Gray II on 2005-06-20.
# Copyright 2005 Gray Productions. All rights reserved.

require "chess"

#
# The container for the behavior of a chess fairy. Fairies are
simply treated
# as both a Queen and a Knight.
#
class Fairy < Chess::Queen
#
# Returns all the capturing moves for a Fairy on the provided
_board_
# at the provided _square_ of the provided _color_.
#
def self.captures( board, square, color )
captures = Chess::Queen.captures(board, square, color)
captures += Chess::Knight.captures(board, square, color)
captures.sort
end

#
# Returns all the non-capturing moves for a Fairy on the provided
# _board_ at the provided _square_ of the provided _color_.
#
def self.moves( board, square, color )
moves = Chess::Queen.moves(board, square, color)
moves += Chess::Knight.moves(board, square, color)
moves.sort
end
end

# Make the Chess::King aware of the Fairy.
class FairyAwareKing < Chess::King
# Enhance in_check? to spot special Fairy moves.
def self.in_check?( bd, sq, col )
return true if Chess::Knight.captures(bd, sq, col).any? do |
name|
bd[name].is_a?(Fairy)
end

Chess::King.in_check?( bd, sq, col )
end

# Make this piece show up as a normal King.
def to_s( )
if @color == :white then "K" else "k" end
end
end

# An enhanced chess board for playing Fairy Chess.
class FairyChess < Chess::Board
# Setup a normal board, then replace the queens with fairies.
def setup( )
super

@squares["d1"] = Fairy.new(self, "d1", :white)
@squares["d8"] = Fairy.new(self, "d8", :black)
@squares["e1"] = FairyAwareKing.new(self, "e1", :white)
@squares["e8"] = FairyAwareKing.new(self, "e8", :black)
end
end

board = FairyChess.new

# insert my chess inteface code (see Summary) here

__END__

#!/usr/local/bin/ruby -w

# fibonacci_chess
#
# Created by James Edward Gray II on 2005-06-20.
# Copyright 2005 Gray Productions. All rights reserved.

require "chess"

# An enhanced chess board for playing Fibonacci Chess.
class FibonacciBoard < Chess::Board
# Setup chess board and initialize move count sequence.
def initialize( )
super

@fib1 = nil
@fib2 = nil
@Count = 1
end

# Advance turn, as players complete moves in the Fibonacci
sequence.
def next_turn( )
if @fib1.nil?
@fib1 = 1
elsif @fib2.nil?
@fib2 = 2
next_turn if in_check?(@turn == :white ? :black : :white)
elsif @count.zero? or in_check?(@turn
== :white ? :black : :white)
@fib1, @fib2 = @fib2, @fib1 + @fib2
@Count = @fib2 - 1
else
@Count -= 1
return
end

super
end

# Return a String description of the moves remaining.
def moves_remaining( )
if @fib1.nil? or @fib2.nil? or @count.zero?
"last move"
else
"#{@count + 1} moves"
end
end
end

board = FibonacciBoard.new

# insert my chess inteface code (see Summary) here

__END__

#!/usr/local/bin/ruby -w

# gun_chess
#
# Created by James Edward Gray II on 2005-06-20.
# Copyright 2005 Gray Productions. All rights reserved.

require "chess"

# An enhanced chess board for playing Gun Chess.
class GunChess < Chess::Board
# Returns a numerical count of all the pieces on the board.
def count_pieces( )
find_all { |(square, piece)| piece }.size
end

# Make standard chess moves, save that capturing pieces do not
move.
def move( from_square, to_square, promote_to = nil )
old_count = count_pieces

super # normal chess move

if count_pieces < old_count # if it was a capture...
move(to_square, from_square) # move the piece back
next_turn # fix the extra turn change
end

self
end
end

board = GunChess.new

# insert my chess inteface code (see Summary) here, with a minor
addition to
# promote pawns on moves only, never captures

__END__

You can download the complete files here:

http://rubyquiz.com/ruby_quiz_chess.zip

I was surprised that this wasn't harder. I didn't tailor my library
to the variations and I chose random variations to solve. I expected
the library would need enhancements for some, but that didn't seem to
be the case, at least for these four variations.

James Edward Gray II
 
J

Jim Menard

James said:
I don't want to spoil all the fun, in case anyone is still attempting
this quiz, but here's my solution to four of the seven variations:

I've been working on adding checkmate detection to my Bangkok-based solution
from last week. I added check detection, which was easy. Checkmate seems
harder, unless I'm missing something. I need to figure out all possible moves
for all pieces on the checked side, then make the move and re-check the board
to see if the king is still in check. Is that what I have to do, or am I
without clue?

Jim
 
J

James Edward Gray II

I've been working on adding checkmate detection to my Bangkok-based
solution from last week. I added check detection, which was easy.
Checkmate seems harder, unless I'm missing something. I need to
figure out all possible moves for all pieces on the checked side,
then make the move and re-check the board to see if the king is
still in check. Is that what I have to do, or am I without clue?

That's how I did it. I believe that's about the best method because
you have to consider things like moving a piece in to block the check.

James Edward Gray II
 
J

Jim Van Fleet

James said:
That's how I did it. I believe that's about the best method because
you have to consider things like moving a piece in to block the check.

James Edward Gray II

It would seem that the space of "all possible moves by all possible
pieces" could be reduced greatly be examining whether or not a given
"checked" piece could possibly move to a space that blocks an attack on
the king by an attacking piece. A relatively small number of spaces
meet this criteria compared to the size of the board, and a relatively
small number of pieces are likely to meet the criteria.

If the attacking piece were a knight or fairy, the possibility of moving
a piece other than the king can be rejected out of hand, as can the case
where two checking pieces simultaneously check the king.

I could easily be missing something. Hasn't been a sharp week for me!
But wait, it's only Monday...

Cheers,

Jim
 
J

James Edward Gray II

It would seem that the space of "all possible moves by all possible
pieces" could be reduced greatly be examining whether or not a
given "checked" piece could possibly move to a space that blocks an
attack on the king by an attacking piece.

I completely agree. It's just trickier and checking all the moves is
plenty fast enough, for a two player game, so I didn't bother.

James Edward Gray II
 
G

Glenn Parker

Jim said:
If the attacking piece were a knight or fairy, the possibility of moving
a piece other than the king can be rejected out of hand, as can the case
where two checking pieces simultaneously check the king.

It's not that simple. It may be possible to capture the attacking piece
without moving the king. If two pieces are attacking, capturing one of
the pieces may block the other piece's attack.
 
J

James Edward Gray II

It's not that simple. It may be possible to capture the attacking
piece without moving the king. If two pieces are attacking,
capturing one of the pieces may block the other piece's attack.

Double check rules out everything but moving the King, so that should
be an easy enough special case to handle, if you can spot it to begin
with.

James Edward Gray II
 
G

Glenn Parker

James said:
Double check rules out everything but moving the King, so that should
be an easy enough special case to handle, if you can spot it to begin
with.

Um, no. Double check does not rule out everything but moving the king.
Read the last sentence of my original reply again.
 
J

James Edward Gray II

Um, no. Double check does not rule out everything but moving the
king. Read the last sentence of my original reply again.

I'm a tournament chess player and I assure you it's only possible to
leave double check by moving the king (in standard chess). I do
invite you to show a position that proves otherwise though... ;)

James Edward Gray II
 
M

Martin DeMello

Glenn Parker said:
Um, no. Double check does not rule out everything but moving the king.
Read the last sentence of my original reply again.

If capturing a piece blocks the other piece's attack, then the original
piece must necessarily have been blocking the other piece's attack too
(at least with the standard piece set and rules). The one loophole might
have been a pawn jumping two squares, imposing both direct and
discovered check, and being captured en passant in such a way that the
discovered check is blocked (that's the only instance where a capturing
piece doesn't occupy the square of the piece it captured), but looking
at the way the pieces move that's impossible too.

martin
 
G

Glenn Parker

James said:
I'm a tournament chess player and I assure you it's only possible to
leave double check by moving the king (in standard chess).

Well, I didn't think we were talking about (just) standard chess here.
The point of the two-part quiz was to examine the flexibility necessary
to handle chess variants. If one assumes that check situations can
always be simplified according to standard chess logic, then that seems
like a potential weakness in the system.
 
J

James Edward Gray II

Well, I didn't think we were talking about (just) standard chess here.

Very true, changing the rules of the game does complicate this.
If one assumes that check situations can always be simplified
according to standard chess logic, then that seems like a potential
weakness in the system.

On the other hand, it's impossible to plan for all the variations of
chess, so we can't let that bug us too much. Some variations do away
with check entirely (like Extinction Chess in this week's quiz).

It's probably more important to ensure that check is extendable and/
or replaceable, as needed. See my solution to Fairy Chess for an
example of this.

James Edward Gray II
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top