[#144186] Re: array of object insert polices — "Pe, Botp" <botp@...>

dave [mailto:dave.m@email.it] wrote:

14 messages 2005/06/01

[#144206] Implementing a Read-Only array — Gavin Kistner <gavin@...>

Right up front, let me say that I realize that I can't prevent

14 messages 2005/06/01

[#144224] Method Chaining Issues — "aartist" <aartist@...>

try this:

28 messages 2005/06/01
[#144231] Re: Method Chaining Issues — "Phrogz" <gavin@...> 2005/06/01

This is a FAQ, though no page on the RubyGarden wiki seems to address

[#144240] Re: Method Chaining Issues — Nikolai Weibull <mailing-lists.ruby-talk@...> 2005/06/01

Phrogz wrote:

[#144230] ternary operator confusion — Belorion <belorion@...>

I don't know if this is "improper" use of the ternary operator, but I

19 messages 2005/06/01
[#144233] Re: ternary operator confusion — "Phrogz" <gavin@...> 2005/06/01

true ? a.push(1) : a.push(2)

[#144257] Re: ternary operator confusion — "Marcel Molina Jr." <marcel@...> 2005/06/01

On Thu, Jun 02, 2005 at 01:40:23AM +0900, Phrogz wrote:

[#144263] Re: ternary operator confusion — Eric Mahurin <eric_mahurin@...> 2005/06/01

--- "Marcel Molina Jr." <marcel@vernix.org> wrote:

[#144453] RubyScript2Exe and GUI toolkits — Erik Veenstra <pan@...>

13 messages 2005/06/03

[#144487] Building a business case for Ruby — Joe Van Dyk <joevandyk@...>

Hi,

29 messages 2005/06/03

[#144535] ruby-dev summary 26128-26222 — Minero Aoki <aamine@...>

Hi all,

11 messages 2005/06/04

[#144579] Package, a future replacement for setup.rb and mkmf.rb — Christian Neukirchen <chneukirchen@...>

29 messages 2005/06/04

[#144672] newbie read.scan (?) question — "Bruce D'Arcus" <bdarcus.lists@...>

Hi,

16 messages 2005/06/06

[#144691] making a duck — Eric Mahurin <eric_mahurin@...>

Regarding duck-typing... Is there an easy way make a "duck"?

27 messages 2005/06/06

[#144867] ruby-wish@ruby-lang.org mailing list — dave <dave.m@...>

19 messages 2005/06/08
[#144870] Re: [PROPOSAL] ruby-wish@ruby-lang.org mailing list — "Robert Klemme" <bob.news@...> 2005/06/08

Austin Ziegler wrote:

[#144890] RubyStuff: The Ruby Shop for Ruby Programmers — James Britt <james_b@...>

Announcing the formal grand opening of Ruby Stuff: The Ruby Shop for

36 messages 2005/06/08

[#144966] python/ruby benchmark. — "\"</script>" <groleo@...>

I took a look at

78 messages 2005/06/09
[#144967] Re: python/ruby benchmark. — gabriele renzi <surrender_it@...> 2005/06/09

"</script> ha scritto:

[#144974] Re: python/ruby benchmark. — Lothar Scholz <mailinglists@...> 2005/06/09

Hello gabriele,

[#144977] Re: python/ruby benchmark. — Kent Sibilev <ksruby@...> 2005/06/09

Java is an order of magnitude faster than Ruby. The development of a

[#144980] Re: python/ruby benchmark. — Lothar Scholz <mailinglists@...> 2005/06/09

Hello Kent,

[#144983] Re: python/ruby benchmark. — "Ryan Leavengood" <mrcode@...> 2005/06/09

Lothar Scholz said:

[#145196] Re: python/ruby benchmark(don't shoot the messenger) — ptkwt@... (Phil Tomson) 2005/06/12

In article <9e7db91105061106485b68d629@mail.gmail.com>,

[#145207] Re: python/ruby benchmark(don't shoot the messenger) — Steven Jenkins <steven.jenkins@...> 2005/06/12

Phil Tomson wrote:

[#145212] Re: python/ruby benchmark(don't shoot the messenger) — Austin Ziegler <halostatue@...> 2005/06/12

On 6/12/05, Steven Jenkins <steven.jenkins@ieee.org> wrote:

[#145219] Re: python/ruby benchmark(don't shoot the messenger) — Steven Jenkins <steven.jenkins@...> 2005/06/12

Austin Ziegler wrote:

[#145223] Re: python/ruby benchmark(don't shoot the messenger) — Austin Ziegler <halostatue@...> 2005/06/12

On 6/12/05, Steven Jenkins <steven.jenkins@ieee.org> wrote:

[#145240] Re: python/ruby benchmark(don't shoot the messenger) — Steven Jenkins <steven.jenkins@...> 2005/06/12

Austin Ziegler wrote:

[#145241] Re: python/ruby benchmark(don't shoot the messenger) — Austin Ziegler <halostatue@...> 2005/06/13

On 6/12/05, Steven Jenkins <steven.jenkins@ieee.org> wrote:

[#145000] RDoc

Hi, I have a question. When I compiled ruby-1.8.2

13 messages 2005/06/09
[#145003] Re: RDoc — Eric Hodel <drbrain@...7.net> 2005/06/09

On 09 Jun 2005, at 13:55, Jesffffas Antonio Sfffe1nchez A. wrote:

[#145238] finding Hash subsets based on key value — "ee" <erik.eide@...>

Hi

17 messages 2005/06/12

[#145304] PDF::Writer 1.0 (version 1.0.1) — Austin Ziegler <halostatue@...>

= PDF::Writer

21 messages 2005/06/13
[#145411] Re: [ANN] PDF::Writer 1.0 (version 1.0.1) — Jason Foreman <threeve.org@...> 2005/06/14

No love from PDF::Writer on Mac OS X 10.4.1. I hope to get this fixed

[#145420] Re: [ANN] PDF::Writer 1.0 (version 1.0.1) — Austin Ziegler <halostatue@...> 2005/06/14

On 6/14/05, Jason Foreman <threeve.org@gmail.com> wrote:

[#145432] Re: [ANN] PDF::Writer 1.0 (version 1.0.1) — Jamis Buck <jamis@37signals.com> 2005/06/15

On Jun 14, 2005, at 5:11 PM, Austin Ziegler wrote:

[#145339] survey: what editor do you use to hack ruby? — Lowell Kirsh <lkirsh@...>

I've been having a tough time getting emacs set up properly with ruby

62 messages 2005/06/14

[#145390] Ruby and recursion (Ackermann benchmark) — ptkwt@... (Phil Tomson)

14 messages 2005/06/14

[#145586] How to make a browser in Ruby Tk — sujeet kumar <sujeetkr@...>

Hi

13 messages 2005/06/16

[#145636] Super-scalar Optimizations — "Phrogz" <gavin@...>

I was looking over the shoulder of a C++ coworker yesterday, when he

14 messages 2005/06/16

[#145677] Truth maintenance system in Ruby — "itsme213" <itsme213@...>

Anyone know of any kind of truth-maintenance system implemented in Ruby (or,

12 messages 2005/06/17

[#145720] Frameless RDoc template ('technology preview') — ES <ruby-ml@...>

Hi!

17 messages 2005/06/17

[#145779] Newbe questions... — "Chuck Brotman" <brotman@...>

In Ruby Is there a prefered (or otherwise elegant) way to do an inner &

17 messages 2005/06/18

[#145790] GC.disable not working? — Eric Mahurin <eric_mahurin@...>

From what I can tell, GC.disable doesn't work. I'm wanting to

37 messages 2005/06/18
[#145822] Re: GC.disable not working? — ts <decoux@...> 2005/06/19

>>>>> "E" == Eric Mahurin <eric_mahurin@yahoo.com> writes:

[#146024] evaluation of ruby — "Franz Hartmann" <porschefranz@...> 2005/06/21

Hello all,

[#145830] preventing instantiation — "R. Mark Volkmann" <mark@...>

What is the recommended way in Ruby to prevent other classes from creating

13 messages 2005/06/19
[#145831] Re: preventing instantiation — Gavri Fernandez <gavri.fernandez@...> 2005/06/19

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:

[#145879] x==1 vs 1==x — Gavin Kistner <gavin@...>

I'm against _premature_ optimization in theory, but believe that a

19 messages 2005/06/20
[#145880] Re: x==1 vs 1==x — ts <decoux@...> 2005/06/20

>>>>> "G" == Gavin Kistner <gavin@refinery.com> writes:

[#145943] Chess Variants (II) (#36) — James Edward Gray II <james@...>

I don't want to spoil all the fun, in case anyone is still attempting

12 messages 2005/06/20

[#146038] 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — Michael Tan <mtan1232000@...>

Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?

47 messages 2005/06/21
[#146044] Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — "Florian Frank" <flori@...> 2005/06/21

Michael Tan wrote:

[#146047] Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — Jim Freeze <jim@...> 2005/06/21

* Florian Frank <flori@nixe.ping.de> [2005-06-22 05:40:14 +0900]:

[#146050] Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — "Ryan Leavengood" <mrcode@...> 2005/06/21

Jim Freeze said:

[#146132] Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — "Mark Thomas" <mrt@...> 2005/06/22

Florian Frank wrote:

[#146064] rubyscript2exe — Joe Van Dyk <joevandyk@...>

Hi,

14 messages 2005/06/21

[#146169] spidering a website to build a sitemap — Bill Guindon <agorilla@...>

I need to spider a site and build a sitemap for it. I've looked

17 messages 2005/06/22

[#146178] traits-0.4.0 - the coffee release — "Ara.T.Howard" <Ara.T.Howard@...>

15 messages 2005/06/22

[#146328] string to Class object — "R. Mark Volkmann" <mark@...>

How can I create a Class object from a String that contains the name of a class?

15 messages 2005/06/24

[#146380] Application-0.6.0 — Jim Freeze <jim@...>

CommandLine - Application and OptionParser

22 messages 2005/06/24

[#146391] ASP.NET vs Ruby on Rails — Stephen Kellett <snail@...>

HI Folks,

21 messages 2005/06/24
[#146457] Re: ASP.NET vs Ruby on Rails — "Dema" <demetriusnunes@...> 2005/06/25

Hi Stephen,

[#146425] speeding up Process.detach frequency — Joe Van Dyk <joevandyk@...>

Is there any way to speed up Process.detach? The ri documentation for

14 messages 2005/06/25

[#146483] I saw the beauty of Ruby Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — Michael Tan <mtan1232000@...>

22 messages 2005/06/26
[#146504] Re: I saw the beauty of Ruby Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — Brad Wilson <dotnetguy@...> 2005/06/26

For comparison, the port of your code to (less than elegant) C#.

[#146515] Re: I saw the beauty of Ruby Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — Florian Gro<florgro@...> 2005/06/26

Brad Wilson wrote:

[#146485] Re: I saw the beauty of Ruby Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds — "Florian Frank" <flori@...> 2005/06/26

Michael Tan wrote:

[#146491] What do you want to see in a Sparklines Library? — Daniel Nugent <nugend@...>

This is sort of an interest gauging/feature request poll.

17 messages 2005/06/26
[#146506] Re: What do you want to see in a Sparklines Library? — Daniel Amelang <daniel.amelang@...> 2005/06/26

See what's already been done before you get too far.

[#146517] Re: What do you want to see in a Sparklines Library? — Daniel Nugent <nugend@...> 2005/06/26

Yup, seen the stuff on RedHanded, I was planning on writing a little

[#146562] RCM - A Ruby Configuration Management System — Michael Neumann <mneumann@...>

Hi all,

22 messages 2005/06/27

[#146630] yield does not take a block — Daniel Brockman <daniel@...>

Under ruby 1.9.0 (2005-06-23) [i386-linux], irb 0.9.5(05/04/13),

48 messages 2005/06/28
[#146666] Re: yield does not take a block — Daniel Brockman <daniel@...> 2005/06/28

Yukihiro Matsumoto <matz@ruby-lang.org> writes:

[#146680] Re: yield does not take a block — Yukihiro Matsumoto <matz@...> 2005/06/28

Hi,

[#146684] Re: yield does not take a block — Eric Mahurin <eric_mahurin@...> 2005/06/28

[#146779] Re: yield does not take a block — "Adam P. Jenkins" <thorin@...> 2005/06/29

Eric Mahurin wrote:

[#146700] Anything in new Eclipse for Rubyists? — "jfry" <jeff.fry@...>

Hey there, I know that a number of folks on the list use Eclipse as

14 messages 2005/06/28

[#146773] Programmers Contest: Fit pictures on a page — hicinbothem@...

GLOSSY: The Summer Programmer Of The Month Contest is underway!

18 messages 2005/06/29

[#146815] shift vs. slice!(0) and others — Eric Mahurin <eric_mahurin@...>

I just did some benchmarking of various ways to insert/delete

12 messages 2005/06/29

[SOLUTION] Chess Variants (I) (#35)

From: Paolo Capriotti <p.capriotti@...>
Date: 2005-06-15 12:43:41 UTC
List: ruby-talk #145482
Here is my solution. It is not fully designed to support variants and
I don't know if I will have time to adapt it (it seems to me a highly
nontrivial task).

Best regards,

Paolo Capriotti

---

class Numeric
  def sign
    if self > 0
      1
    else 
      if self < 0 then -1 else 0 end
    end
  end
end

class Piece
  attr_reader :type, :color
  def initialize(color, type)
    @type = type
    @color = color
  end
  
  def type_initial
    if @type == :knight
      'n'
    else
      @type.to_s[0,1]
    end
  end
  
  def ==(other)
    return false unless other.respond_to?(:color)
    (@type == other.type and @color == other.color)
  end
end

class Vector
  attr_reader :x, :y
  def initialize(x,y)
    @x,@y = x,y
  end
  
  def +(other)
    x = @x + other[0]
    y = @y + other[1]
    Vector.new(x,y)
  end
  
  def -(other)
    x = @x - other[0]
    y = @y - other[1]
    Vector.new(x,y)
  end
  
  def *(number)
    x = @x * number
    y = @y * number
    Vector.new(x,y)
  end
  
  def ==(other)
    return false unless other.respond_to?(:[])
    @x == other[0] and @y == other[1]
  end
  
  def [](i)
    case i
    when 0
      @x
    when 1
      @y
    end
  end
  
  def clone
    Vector.new(@x,@y)
  end
end

class Board
  attr_reader :size, :turn
  attr_writer :promotion_piece
  def initialize(size_x, size_y)
    @size = Vector.new(size_x, size_y)
    @board = []
    (0...size_x).each do |x|
      @board[x] = []
    end
    @turn = :white
    @king_moved = Hash.new(false)
    @queen_rook_moved = Hash.new(false)
    @king_rook_moved = Hash.new(false)
  end
  
  def [](*position)
    position = get_pos(position)
    @board[position.x][position.y]
  end 
  
  def []=(*args)
    value = args.pop
    position = get_pos(args)
    @board[position.x][position.y] = value
    self
  end
  
  def move(from, to)
    piece = self[from]
    execute_move(from, to)
    
    case from
    when king_starting_position
      @king_moved[@turn] = true
    when king_rook_starting_position
      @king_rook_moved[@turn] = true
    when queen_rook_starting_position
      @queen_rook_moved[@turn] = true
    end
    
    if castling(from, to)
      if to.x - from.x > 0
        self[from+[1,0]] = self[king_rook_starting_position]
        self[king_rook_starting_position] = nil
      else
        self[from+[-1,0]] = self[queen_rook_starting_position]
        self[queen_rook_starting_position] = nil        
      end
    end
    
    if to == @en_passant
      self[to-[0,pawn_dir]] = nil
    end
    
    if piece.type == :pawn and (to.y - from.y) == 2
      @en_passant = to-[0,pawn_dir]
    else
      @en_passant = nil
    end
    
    switch_turn
  end
  
  def pseudolegal_move(from, to)
    return false if from == to 
    piece = self[from]
    return false unless piece
    return false unless piece.color == turn
    return false if self[to] and self[to].color == piece.color
    
    d = to - from
    case piece.type
    when :king
      if (d.x.abs <= 1 and d.y.abs <= 1)
        return true
      end
      if castling(from, to) 
        return false if @king_moved[@turn]
        if d.x > 0 # king side
          return false if @king_rook_moved[@turn]
          return false unless (self[from + [1,0]] == nil or self[from
+ [2,0]] == nil)
        else
          return false if @queen_rook_moved[@turn]
          return false unless (from + [-1,0] == nil or from + [-2,0]
== nil or from + [-3,0] == nil)
        end
        return true
      end
    when :queen
      return ((rook_slide(d) or bishop_slide(d)) and check_free_path(from, to))
    when :rook
      return (rook_slide(d) and check_free_path(from, to))
    when :bishop
      return (bishop_slide(d) and check_free_path(from, to))
    when :knight
      return knight_jump(d)
    when :pawn
      case d.x.abs
      when 1
        return (d.y == pawn_dir and ((self[to] and (not self[to].color
== piece.color)) or to == @en_passant))
      when 0
        case d.y
        when pawn_dir
          return self[to] == nil
        when pawn_dir*2
          return (from.y == rank(2) and self[from+[0,pawn_dir]] == nil
and self[to] == nil)
        else
          return false
        end
      else
        return false
      end
    end
  end
  
  def legal_move(from, to)
    return false unless pseudolegal_move(from, to)
    
    old_turn = @turn
    switch_turn
    res = check_legality(from, to, old_turn)
    @turn = old_turn

    return res
  end
  
  def is_valid(*args)
    position = get_pos(args)
    position.x >= 0 and position.x < size.x and position.y >= 0 and
position.y < size.y
  end
  
  def find_piece(piece)
    each_piece do |position, p|
      return position if piece == p
    end
    return nil
  end
  
  def each_piece
    (0...size.x).each do |x|
      (0...size.y).each do |y|
        pos = Vector.new(x,y)
        piece = self[pos]
        yield(Vector.new(x,y), self[x,y]) if self[x,y]
      end
    end
  end

  def show
    (0...@size.y).each do |y|
      (0...@size.x).each do |x|
        piece = self[x,y]
        if piece
          s = piece.type_initial
          s.upcase! if (piece.color == :white) 
          print s, ' '
        else
          print '  '
        end
      end
      print "\n"
    end
    print "\n"
  end  

  def promotion(from, to)
    to.y == rank(8) and self[from].type == :pawn
  end  
  
  def capturing(from, to)
    return true if self[to]
    self[from].type == :pawn and (not from.x == to.x)
  end
  
  def game_state
    generator = MoveGenerator.new(self)
    if generator.unstalled
      return :in_game
    else
      old_turn = @turn
      switch_turn
      if leaving_king_safe(old_turn)
        res = :stalemate
      else
        res = (@turn == :white ? :white_wins : :black_wins)
      end
      
      return res
    end
  end
  
  
  def pawn_dir
    @turn == :white ? -1 : 1
  end
  
  def rank(r)
    @turn == :white ? 8 - r : r - 1
  end
  
  def possible_starting_points(piece_type, to, capt)
    generator = MoveGenerator.new(self) do |from, dest|
      if to == dest and self[from].type == piece_type and
pseudolegal_move(from, dest) and capturing(from, to) == capt
        from
      end
    end
    generator.generate_all
  end
  
    
  def king_starting_position
    Vector.new(4, rank(1))
  end

  def king_rook_starting_position
    Vector.new(7, rank(1))
  end
  
  def queen_rook_starting_position
    Vector.new(0, rank(1))
  end  
  
private
  def check_legality(from, to, old_turn)
    if castling(from, to)
      castling_directions(from, to)+[[0,0]].each do |direction|
        return false unless leaving_position_safe(from+direction)
      end
    end
    
    old_board = []
    (0...size.x).each do |x|
      old_board[x] = @board[x].clone
    end
    
    execute_move(from, to)
    res = leaving_king_safe(old_turn)
    @board = old_board
    res
  end
  
  def check_free_path(from, to)
    d = to - from
    inc = [d.x.sign, d.y.sign]
    pos = from.clone
    while not pos == to - inc
      pos += inc
      return false if self[pos]
    end
    return true
  end

  def castling(from, to)
    from == king_starting_position and (from-to).x.abs == 2
  end
  
  def rook_slide(d)
    d.x == 0 or d.y == 0
  end
  
  def bishop_slide(d)
    d.x.abs == d.y.abs
  end
  
  def knight_jump(d)
    (d.x.abs == 2 and d.y.abs == 1) or (d.x.abs == 1 and d.y.abs == 2)
  end  
  
  def switch_turn
    @turn = (@turn == :white ? :black : :white)
  end
    
  def leaving_king_safe(old_turn)
    king_pos = find_piece(Piece.new(old_turn, :king))    
    leaving_position_safe(king_pos)
  end  
  
  def castling_directions(from, to)
    if (to.x > from.x)
      return [[1,0]]
    else
      return [[-1,0],[-2,0]]
    end
  end
  
  def leaving_position_safe(safepos)
    each_piece do |position, piece|
      if piece.color == @turn
        return false if pseudolegal_move(position, safepos)
      end
    end
  end
  
  def get_pos(v)
    case v.size
    when 1
      v[0]
    when 2
      Vector.new(v[0], v[1])
    end
  end
  
  def execute_move(from, to)
    if promotion(from, to)
      self[to] = Piece.new(@turn, @promotion_piece)
    else
      self[to] = self[from]
    end

    self[from] = nil    
  end  
end


class MoveGenerator
  def initialize(board, &valid)
    @board = board
    if block_given?
      @valid_move = valid
    else
      @valid_move = lambda do |from, to|
        if @board.is_valid(to) and @board.legal_move(from, to)
          return to
        end
      end
    end
  end
  
  def unstalled
    @fast = true
    found = catch(:move_found) do
      @board.each_piece do |position, piece|
        if piece.color == @board.turn
          can_move(position)
        end
      end
    end
    found == true
  end
  
  def generate_all
    @fast = false
    move_list = []
    @board.each_piece do |position, piece|
      if piece.color == @board.turn
        move_list += can_move(position)
      end
    end
    move_list
  end
  
  def can_move(from)
    piece = @board[from]
    move_list = []
    return [] unless piece
    
    case piece.type
    when :king
      generate_directions.each do |direction|
        move = got_move(from, from + direction)
        move_list << move if move
      end
    when :queen
      generate_directions.each do |direction|
        move_list += generate_slide(from, direction)
      end
    when :rook
      [[1,0],[-1,0],[0,1],[0,-1]].each do |direction|
        move_list += generate_slide(from, direction)
      end
    when :bishop
      [[1,1],[-1,1],[1,-1],[-1,-1]].each do |direction|
        move_list += generate_slide(from, direction)
      end      
    when :knight
      [[2,1],[2,-1],[-2,1],[-2,-1],[1,2],[1,-2],[-1,2],[-1,-2]].each do |jump|
        move = got_move(from, from + jump)
        move_list << move if move
      end
    when :pawn
      [[0,@board.pawn_dir],[0,@board.pawn_dir*2],[1,@board.pawn_dir],[-1,@board.pawn_dir]].each
do |jump|
        move = got_move(from, from + jump)
        move_list << move if move
      end
    end
    
    return move_list
  end
  
private
  
  def generate_slide(from, direction)
    move_list = []
    pos = from
    while @board.is_valid(pos += direction) do
      move = got_move(from, pos)
      move_list << move if move
    end
    move_list
  end
  
  def generate_directions
    dirs = []
    (-1..1).each do |x|
      (-1..1).each do |y|
        dirs << [x,y] unless x == 0 and y == 0
      end
    end
    return dirs
  end
  
  def got_move(from, to)
    if move = @valid_move[from, to]
      throw(:move_found, true) if @fast
      move
    else
      false
    end
  end
  
end



module UI
  def ask_move
    @promotion_piece = nil
    loop do
      print ": "
      input = gets
      raise "no move" unless input
      case input.chomp
      when /^\s*$/
        return nil
      when /^(\d)(\d)\s*(\d)(\d)$/
        return Vector.new($1.to_i, $2.to_i), Vector.new($3.to_i, $4.to_i)
      when /^([RNBQK]?)([a-h1-8]?)(x?)([a-h])([1-8])(=[RNBQK])?[#+]?$/
        piece_type = letter2piece($1)
        prom = $6
        to = Vector.new($4[0]-'a'[0], 8 - $5.to_i)
        sp = @board.possible_starting_points(piece_type, to, $3 == 'x')
        unless $2.nil? or $2 == ""
          letter = $2
          if letter =~ /[a-h]/
            check = lambda do |possible_from|
              possible_from.x == letter[0] - 'a'[0]
            end
          else
            check = lambda do |possible_from|
              possible_from.y == 8 - letter.to_i
            end
          end
          
          sp.reject! do |possible_from|
            not check[possible_from]
          end
        end
        
        case sp.size
        when 0
          say "incorrect notation"
        when 1
          from = sp.first
        else
          say "ambiguous notation"
        end

        if from
          if piece_type == :pawn and to.y == @board.rank(8)
            @promotion_piece = letter2piece($5[1,1])
          end
          
          if from
            return from, to
          end
          
        end
      when "O-O"
          pos = @board.king_starting_position
          return pos, pos + [2,0]
      when "O-O-O"
          pos = @board.queen_starting_position
          return pos, pos - [2,0]
      end
      
    end
  end
  
  def letter2piece(letter)
    case letter
    when 'R'
      return :rook
    when 'N'
      return :knight 
    when 'B'
      return :bishop
    when 'Q'
      return :queen
    when 'K'
      return :king
    else
      return :pawn
    end
  end
  
  def ask_promotion_piece
    return @promotion_piece if @promotion_piece
    print "promote to (default: queen): "
    case gets.chomp!
    when "rook" || 'r'
      return :rook
    when "knight" || 'n'
      return :knight 
    when "bishop" || 'b'
      return :bishop
    else
      return :queen || 'q'
    end
  end
  
  def say(msg)
    puts msg.to_s.gsub(/_/) { ' ' } 
  end
  
  def show_board
    say "turn : #{@board.turn.to_s}"
    (0...@board.size.y).each do |y|
      (0...@board.size.x).each do |x|
        piece = @board[x,y]
        if piece
          s = piece.type_initial
          s.upcase! if (piece.color == :white) 
          print s, ' '
        else
          print '  '
        end
      end
      print "\n"
    end
    print "\n"
  end

end


class ChessGame
  attr_reader :board
  include UI
  
  def initialize
    @board = Board.new(8,8)
    @board.promotion_piece = :queen
    
    (0...8).each do |x|
      @board[x,1] = Piece.new( :black, :pawn )
      @board[x,6] = Piece.new( :white, :pawn )
    end
    
    @board[0,0] = Piece.new( :black, :rook )
    @board[1,0] = Piece.new( :black, :knight )
    @board[2,0] = Piece.new( :black, :bishop )
    @board[3,0] = Piece.new( :black, :queen )
    @board[4,0] = Piece.new( :black, :king )
    @board[5,0] = Piece.new( :black, :bishop )
    @board[6,0] = Piece.new( :black, :knight )
    @board[7,0] = Piece.new( :black, :rook )
    
    @board[0,7] = Piece.new( :white, :rook )
    @board[1,7] = Piece.new( :white, :knight )
    @board[2,7] = Piece.new( :white, :bishop )
    @board[3,7] = Piece.new( :white, :queen )
    @board[4,7] = Piece.new( :white, :king )
    @board[5,7] = Piece.new( :white, :bishop )
    @board[6,7] = Piece.new( :white, :knight )
    @board[7,7] = Piece.new( :white, :rook )
  end
  
  def play
    while (state = @board.game_state) == :in_game
      begin
        move
      rescue RuntimeError => err
        print "\n"
        if err.message == "no move"
          say :exiting
        else
          say err.message
        end
        return
      end
    end
    show_board
    say state
  end
  
  def move
    loop do
      say ""
      show_board
      from, to = ask_move
      raise "no move" unless from
      if @board.is_valid(from) and @board.is_valid(to) and
@board.legal_move(from, to)
        if @board.promotion(from, to)
          @board.promotion_piece = ask_promotion_piece
        end
        @board.move(from, to)
        break
      else
        say :invalid_move
      end
    end    
  end
end

@game = ChessGame.new
@game.play


In This Thread

Prev Next