[#20675] RCR: non-bang equivalent to []= — Tobias Reif <tobiasreif@...>

Hi,

49 messages 2001/09/01
[#20774] Re: RCR: non-bang equivalent to []= — Tobias Reif <tobiasreif@...> 2001/09/03

I wrote:

[#20778] Re: RCR: non-bang equivalent to []= — Kevin Smith <kevinbsmith@...> 2001/09/03

--- Tobias Reif <tobiasreif@pinkjuice.com> wrote:

[#20715] oreilly buch von matz - website online — markus jais <info@...>

hi

43 messages 2001/09/02
[#20717] Re: OReilly Ruby book has snail on cover — ptkwt@...1.aracnet.com (Phil Tomson) 2001/09/02

Actually, thanks for posting it here. I was trying to search OReilly's

[#20922] Re: OReilly Ruby book has snail on cover — Paul Brannan <pbrannan@...> 2001/09/05

On Mon, 3 Sep 2001, Phil Tomson wrote:

[#20768] Minor cgi.rb question — "Hal E. Fulton" <hal9000@...>

I don't have much experience with

25 messages 2001/09/03

[#20770] Calling member methods from C++ — jglueck@... (Bernhard Glk)

Some quetsions have been solved for me, but my message system does not

12 messages 2001/09/03

[#20976] destructor — Frank Sonnemans <ruby@...>

Does Ruby have a destructor as in C++?

25 messages 2001/09/07

[#21218] Ruby objects <-> XML: anyone working on this? — senderista@... (Tobin Baker)

Are there any Ruby analogs of these two Python modules (xml_pickle,

13 messages 2001/09/15

[#21296] nested require files need path internally — Bob Gustafson <bobgus@...>

Version: 1.64

29 messages 2001/09/18
[#21298] Re: nested require files need path internally — David Alan Black <dblack@...> 2001/09/18

Hello --

[#21302] Re: nested require files need path internally — Bob Gustafson <bobgus@...> 2001/09/18

On Tue, 18 Sep 2001, David Alan Black wrote:

[#21303] Re: nested require files need path internally — matz@... (Yukihiro Matsumoto) 2001/09/18

Hi,

[#21306] Re: nested require files need path internally — Lars Christensen <larsch@...> 2001/09/18

On Tue, 18 Sep 2001, Yukihiro Matsumoto wrote:

[#21307] Re: nested require files need path internally — matz@... (Yukihiro Matsumoto) 2001/09/18

Hi,

[#21331] Re: nested require files need path internally — Paul Brannan <pbrannan@...> 2001/09/18

> The big difference is C++ search done in compile time, Ruby search

[#21340] Re: nested require files need path internally — matz@... (Yukihiro Matsumoto) 2001/09/18

Hi,

[#21353] Re: nested require files need path internally — Paul Brannan <pbrannan@...> 2001/09/18

On Wed, 19 Sep 2001, Yukihiro Matsumoto wrote:

[#21366] Re: nested require files need path internally — matz@... (Yukihiro Matsumoto) 2001/09/19

Hi,

[#21368] Re: nested require files need path internally — "Julian Fitzell" <julian-ml@...4.com> 2001/09/19

On 19/09/2001 at 10:12 AM matz@ruby-lang.org wrote:

[#21376] Re: nested require files need path internally — matz@... (Yukihiro Matsumoto) 2001/09/19

Hi,

[#21406] Re: nested require files need path internally — Paul Brannan <pbrannan@...> 2001/09/19

On Wed, 19 Sep 2001, Yukihiro Matsumoto wrote:

[#21315] Suggestions for new CGI lib — anders@... (Anders Johannsen)

From the comp.lang.ruby thread "Minor cgi.rb question" (2001-09-03), I

21 messages 2001/09/18

[#21413] Ruby/objects book in style of The Little Lisper — Brian Marick <marick@...>

I fell in love with Lisp in the early 80's. Back then, I read a book called

36 messages 2001/09/19
[#21420] Re: Ruby/objects book in style of The Little Lisper — Christopher Sawtell <csawtell@...> 2001/09/20

On 20 Sep 2001 06:19:44 +0900, Brian Marick wrote:

[#21479] Re: Ruby/objects book in style of The Little Lisper — Kevin Smith <kevinbsmith@...> 2001/09/21

--- Christopher Sawtell <csawtell@paradise.net.nz> wrote:

[#21491] SV: Re: Ruby/objects book in style of The Little Lisper — "Mikkel Damsgaard" <mikkel_damsgaard@...> 2001/09/21

[#21494] Re: SV: Re: Ruby/objects book in style of The Little Lisper — Kevin Smith <kevinbsmith@...> 2001/09/21

--- Mikkel Damsgaard <mikkel_damsgaard@mailme.dk> wrote:

[#21510] Re: SV: Re: Ruby/objects book in style of The Little Lisper — Todd Gillespie <toddg@...> 2001/09/22

On Sat, 22 Sep 2001, Kevin Smith wrote:

[#21514] Re: SV: Re: Ruby/objects book in style of The Little Lisper — Kevin Smith <kevinbsmith@...> 2001/09/22

--- Todd Gillespie <toddg@mail.ma.utexas.edu> wrote:

[#21535] irb — Fabio <fabio.spelta@...>

Hello. :) I'm new here, and I have not found an archive of the previous

15 messages 2001/09/22

[#21616] opening a named pipe? — "Avdi B. Grimm" <avdi@...>

I'm having trouble reading from a named pipe in linux. basicly, I'm

12 messages 2001/09/24

[#21685] manipulating "immutable" objects such as Fixnum from within callbacks & al... — Guillaume Cottenceau <gc@...>

Hello,

15 messages 2001/09/25

[#21798] Ruby internal (guide to the source) — "Benoit Cerrina" <benoit.cerrina@...>

Hi,

22 messages 2001/09/28

[ruby-talk:21673] Requesting help... small net app w/ problems

From: "Hal E. Fulton" <hal9000@...>
Date: 2001-09-25 18:18:23 UTC
List: ruby-talk #21673
Hello all...

I've been through numerous iterations with
this thing. I hope the code doesn't show it,
but I'm afraid it does.

Any help would be appreciated.

In this email:
1. overview
2. how to invoke
3. server code
4. client code

Besides net difficulties, it's likely 
there's a logic error or two.

The code *does* work on a single
machine (both Win98 and Solaris).

Thanks for any insights...
Hal Fulton

===
1. Overview
-----------------
This is a stubbed chess server that does nothing
but put clients in contact with each other so they
can play chess. The clients then talk directly and 
ignore the server. (Then one client is really a
server henceforth.)

At first I was using UDP for the initial contact, but
changed to TCP... this helped a little.

The server and each client should ideally all be
run on separate machines for good testing.

2. How to invoke
-----------------------
a. Change ChessServer constant in ch2c.rb
b. Invoke server:
        ruby ch2s.rb
c. Invoke 1st client (with any two names -- mine
    and the opponent); a colon separates the
    opponent's name from his IP name (localhost
    is the default)
        ruby ch2c.rb  Alice Bob:machine2
d. Invoke 2nd client in the corresponding way
        ruby ch2c.rb Bob Alice:machine3
e. When prompted for a move, type any arbitrary
    string... it's stubbed out.
f. In this dummy version, black always wins on
    the fourth move

3. Server code
----------------------

    require "thread"
    require "socket"
        
    PORT = 12000
    HOST = '127.0.0.1'
    
    # Exit if user presses Enter at server end
    waiter = Thread.new do
      puts "Press Enter to exit the server."
      gets
      exit
    end
        
    $mutex = Mutex.new
    $list = {}
    
    def match?(p1, p2)
      return false if !$list[p1] or !$list[p2]
    
      if ($list[p1][0] == p2 and $list[p2][0] == p1)
        true
      else
        false
      end
    end
    
    def handle_client(sess, msg, addr, port, ipname)
      $mutex.synchronize do
        cmd, player1, player2 = msg.split
        # Note: We allow user:hostname on the command line,
        # but we store it in the form user:address
        p1short = player1.dup              # Short names (i.e., 
        p2short = player2.split(":")[0]    # no ":address"
        player1 << ":#{addr}"              # Append user's IP addr
        user2, host2 = player2.split(":")
        if host2 == nil                    # No IP addr; add it
          player2 << ":127.0.0.1"
        else
          player2 = user2 + ":" + IPSocket.getaddress(host2)
        end
    
        if cmd != "login"
          puts "Protocol error: client msg was #{msg}"
        end
    
        $list[player1] = [player2, addr, port, ipname, sess]
    
print "hc: "
p $list
        if match?(player1, player2)
puts "Got a match!"
          # Note these names are "backwards" now: player2 
          # logged in first, if we got here.
          p1 = $list[player1]
          p2 = $list[player2]
          # Player ID = name:ipname:color
          # Color: 0=white, 1=black
          p1id = "#{p1short}:#{p1[3]}:1"
          p2id = "#{p2short}:#{p2[3]}:0"
          sess1 = p1[4]
          sess2 = p2[4]
          sess1.puts "#{p2id}"
          sess2.puts "#{p1id}"
          sess1.close
          sess2.close
        end 
      end
    end

    text = nil
    
    $server = TCPServer.new("127.0.0.1", PORT)
    while session = $server.accept do
      Thread.new(session) do |sess|
        text = sess.gets
        puts "recvfrom = #{text}"
        domain, port, ipname, ipaddr = sess.addr
puts "calling hc"
        handle_client sess, text, ipaddr, port, ipname
puts "called hc"
        sleep 1
      end
    end
    
    waiter.join    # Exit only if user presses Enter


4. Client
--------------

    require "socket"
    require "timeout"
        
    ChessServer     = 'localhost'
    ChessServerPort = 12000
    PeerPort        = 12001
    
    WHITE, BLACK = 0, 1
    Colors = %w[White Black]
    
    def drawBoard(board)
      puts <<-EOF
    +----------------------------------+
    | Stub! Drawing the board here...  |
    +----------------------------------+
      EOF
    end
    
    def analyzeMove(who, move, num, board)
      # Stub - black always wins on 4th move
      if who == BLACK and num == 4
        move << "  Checkmate!"
      end
      true  # Stub again - always say it's legal.
    end
    
    def myMove(who, lastmove, num, board, sock)
      ok = false
      until ok do
        print "\nYour move: "
        move = STDIN.gets.chomp
        ok = analyzeMove(who, move, num, board)
        puts "Illegal move" if not ok
      end
      sock.puts move
      move
    end
    
    def otherMove(who, move, num, board, sock)
      move = sock.gets.chomp
      puts "\nOpponent: #{move}"
      move
    end
    
    if ARGV[0]
      myself = ARGV[0]
    else
      print "Your name? "
      myself = STDIN.gets.chomp
    end
    
    if ARGV[1]
      opponentID = ARGV[1]
    else
      print "Your opponent? "
      opponentID = STDIN.gets.chomp
    end
    
    opponent = opponentID.split(":")[0]   # Remove hostname
    
    # Contact the server
    
    socket = TCPSocket.new(ChessServer, ChessServerPort)
    
    response = nil
        
puts "Sending login to server"
    socket.puts "login #{myself} #{opponentID}"
    socket.flush
puts "Waiting for response from server"
    response = socket.gets.chomp
puts "Got response #{response} from server"
    
    name, ipname, color = response.split ":"
    color = color.to_i
    
    if color == BLACK            # Other player's color
      puts "\nConnecting..."
    
      server = TCPServer.new(ipname, PeerPort)
      session = server.accept
    
      str = nil
      begin
        timeout(30) do
          str = session.gets.chomp
          if str != "ready"
            raise "Protocol error: ready-message was #{str}"
          end
        end
      rescue TimeoutError
        raise "Did not get ready-message from opponent."
      end
    
      puts "Playing #{opponent}... you are white.\n"
    
      who = WHITE
      move = nil
      board = nil      # Not really used in this dummy example
      num = 0
      drawBoard(board) # Draw the board initially for white
    
      loop do
        num += 1
        move = myMove(who, move, num, board, session)
        drawBoard(board) 
        case move
          when "resign"
            puts "\nYou've resigned. #{opponent} wins."
            break
          when /Checkmate/
            puts "\nYou have checkmated #{opponent}!"
            drawBoard(board)
            break
        end
        move = otherMove(who, move, num, board, session)
        drawBoard(board) 
        case move
          when "resign"
            puts "\n#{opponent} has resigned... you win!"
            break
          when /Checkmate/
            puts "\n#{opponent} has checkmated you."
            break
        end
      end
    else                        # We're black
      puts "\nConnecting..."
    
      socket = TCPSocket.new(ipname, PeerPort)
      socket.puts "ready"
    
      puts "Playing #{opponent}... you are black.\n"
    
      who = BLACK
      move = nil
      board = nil       # Not really used in this dummy example
      num = 0
      drawBoard(board)  # Draw board initially
    
      loop do
        num += 1
        move = otherMove(who, move, num, board, socket)
        drawBoard(board)  # Draw board after white move
        case move
          when "resign"
            puts "\n#{opponent} has resigned... you win!"
            break
          when /Checkmate/
            puts "\n#{opponent} has checkmated you."
            break
        end
        move = myMove(who, move, num, board, socket)
        drawBoard(board)  
        case move
          when "resign"
            puts "\nYou've resigned. #{opponent} wins."
            break
          when /Checkmate/
            puts "\nYou have checkmated #{opponent}!"
            break
        end
      end
      socket.close 
    end
    

In This Thread

Prev Next