IO buffering problem

All,
I'm writing a chess program that has a simple text-based interface. It's
designed to be run by another program, which has a nice UI. Here's the
program as it stands now, whittled to the simplest possible use case:

i = 0
moves = ["a7a6","a6a5","a5a4","a4a3"]
$stdin.each do |command|
  if command.start_with?("protover")
    $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
  elsif command.start_with?("usermove")
    $stdout.puts "move #{moves[i]}"
    i+=1
  end
  $stdout.flush
end

The "protover" thing is needed to tell the UI program how to initialize the
protocol, and then every time a move is made, the UI program sends
"usermove <some move>" to my program, which responds with "move <my move>".

If I run this by itself, I can happily enter a few 'usermove' commands
manually, and get any number of canned moves back. However, when I run this
under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something in
the way that I'm handling IO buffering or something. If you want the nitty
gritty details, you can see them at
http://www.gnu.org/software/xboard/engine-intf.html . I'm running on
MacOSX. Any suggestions?

Hi Andrew,

All,
I'm writing a chess program that has a simple text-based interface. It's
designed to be run by another program, which has a nice UI. Here's the
program as it stands now, whittled to the simplest possible use case:

i = 0
moves = ["a7a6","a6a5","a5a4","a4a3"]
$stdin.each do |command|
   if command.start_with?("protover")
     $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
   elsif command.start_with?("usermove")
     $stdout.puts "move #{moves[i]}"
     i+=1
   end
   $stdout.flush
end

The "protover" thing is needed to tell the UI program how to initialize
the protocol, and then every time a move is made, the UI program sends
"usermove <some move>" to my program, which responds with "move <my move>".

If I run this by itself, I can happily enter a few 'usermove' commands
manually, and get any number of canned moves back. However, when I run
this under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something
in the way that I'm handling IO buffering or something. If you want the
nitty gritty details, you can see them at
Chess Engine Communication Protocol - GNU Project - Free Software Foundation . I'm running on
MacOSX. Any suggestions?

Is it possible that you aren't processing one of the commands from the program, and the program is terminating your script, perhaps after a timeout or incorrect response? I'm wondering what would show up if you added this:

else
   $stderr.print "Unknown command: '#{command}'\n"

just before the second-last line. Are you handling every incoming command as it expects?

Incidentally, you could always turn those if statements into case/when, something like:

case command
when /^protover/
...
when /^usermove/
...
else
   $stderr.print "Unknown command: '#{command}'\n"
end

This might make it easier if there are a lot of commands you need to respond to.

Cheers,
Garth

···

On 16/03/13 09:04, Andrew Wagner wrote:

At top of script

$stdout.sync = true

Cheers

robert

···

On Fri, Mar 15, 2013 at 11:34 PM, Andrew Wagner <wagner.andrew@gmail.com> wrote:

All,
I'm writing a chess program that has a simple text-based interface. It's
designed to be run by another program, which has a nice UI. Here's the
program as it stands now, whittled to the simplest possible use case:

i = 0
moves = ["a7a6","a6a5","a5a4","a4a3"]
$stdin.each do |command|
  if command.start_with?("protover")
    $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
  elsif command.start_with?("usermove")
    $stdout.puts "move #{moves[i]}"
    i+=1
  end
  $stdout.flush
end

The "protover" thing is needed to tell the UI program how to initialize the
protocol, and then every time a move is made, the UI program sends "usermove
<some move>" to my program, which responds with "move <my move>".

If I run this by itself, I can happily enter a few 'usermove' commands
manually, and get any number of canned moves back. However, when I run this
under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something in
the way that I'm handling IO buffering or something. If you want the nitty
gritty details, you can see them at
Chess Engine Communication Protocol - GNU Project - Free Software Foundation . I'm running on MacOSX.
Any suggestions?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Sorry, *third* last line.

···

On 16/03/13 11:27, Garthy D wrote:

just before the second-last line.

Thanks for the response. I really don't have to handle every incoming
response. I put in the line you suggested, and it did indeed identify a
number of commands that are "unknown". But that's ok, as far as I can tell.

As for "if" vs. "case", in my real program, I did something even more
general:
https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb .
This lets you plug in any command handlers you want. I plan on having a
library of handlers for different commands, maybe a nice DSL or something
for creating new ones, etc. Obviously, I shortened all of that to isolate
this problem.

···

On Fri, Mar 15, 2013 at 7:57 PM, Garthy D < garthy_lmkltybr@entropicsoftware.com> wrote:

Hi Andrew,

On 16/03/13 09:04, Andrew Wagner wrote:

All,
I'm writing a chess program that has a simple text-based interface. It's
designed to be run by another program, which has a nice UI. Here's the
program as it stands now, whittled to the simplest possible use case:

i = 0
moves = ["a7a6","a6a5","a5a4","a4a3"]
$stdin.each do |command|
   if command.start_with?("protover"**)
     $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
   elsif command.start_with?("usermove"**)
     $stdout.puts "move #{moves[i]}"
     i+=1
   end
   $stdout.flush
end

The "protover" thing is needed to tell the UI program how to initialize
the protocol, and then every time a move is made, the UI program sends
"usermove <some move>" to my program, which responds with "move <my
>".

If I run this by itself, I can happily enter a few 'usermove' commands
manually, and get any number of canned moves back. However, when I run
this under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something
in the way that I'm handling IO buffering or something. If you want the
nitty gritty details, you can see them at
http://www.gnu.org/software/**xboard/engine-intf.html&lt;http://www.gnu.org/software/xboard/engine-intf.html&gt;\. I'm running on
MacOSX. Any suggestions?

Is it possible that you aren't processing one of the commands from the
program, and the program is terminating your script, perhaps after a
timeout or incorrect response? I'm wondering what would show up if you
added this:

else
  $stderr.print "Unknown command: '#{command}'\n"

just before the second-last line. Are you handling every incoming command
as it expects?

Incidentally, you could always turn those if statements into case/when,
something like:

case command
when /^protover/
...
when /^usermove/
...
else
  $stderr.print "Unknown command: '#{command}'\n"
end

This might make it easier if there are a lot of commands you need to
respond to.

Cheers,
Garth

Ha, I fixed it. You were almost right, Garthy, the UI was
seemingly-randomly sending me SIGINTs. I had to tell it in the protocol
initializer not to do that. Very odd.

···

On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner <wagner.andrew@gmail.com>wrote:

Thanks for the response. I really don't have to handle every incoming
response. I put in the line you suggested, and it did indeed identify a
number of commands that are "unknown". But that's ok, as far as I can tell.

As for "if" vs. "case", in my real program, I did something even more
general:
https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb .
This lets you plug in any command handlers you want. I plan on having a
library of handlers for different commands, maybe a nice DSL or something
for creating new ones, etc. Obviously, I shortened all of that to isolate
this problem.

On Fri, Mar 15, 2013 at 7:57 PM, Garthy D < > garthy_lmkltybr@entropicsoftware.com> wrote:

Hi Andrew,

On 16/03/13 09:04, Andrew Wagner wrote:

All,
I'm writing a chess program that has a simple text-based interface. It's
designed to be run by another program, which has a nice UI. Here's the
program as it stands now, whittled to the simplest possible use case:

i = 0
moves = ["a7a6","a6a5","a5a4","a4a3"]
$stdin.each do |command|
   if command.start_with?("protover"**)
     $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
   elsif command.start_with?("usermove"**)
     $stdout.puts "move #{moves[i]}"
     i+=1
   end
   $stdout.flush
end

The "protover" thing is needed to tell the UI program how to initialize
the protocol, and then every time a move is made, the UI program sends
"usermove <some move>" to my program, which responds with "move <my
>".

If I run this by itself, I can happily enter a few 'usermove' commands
manually, and get any number of canned moves back. However, when I run
this under the UI, I get an Interrupt:

bin/winboard.rb:3:in `each': Interrupt
from bin/winboard.rb:3:in `<main>'

I know that the UI program is pretty reliable, so I'm missing something
in the way that I'm handling IO buffering or something. If you want the
nitty gritty details, you can see them at
http://www.gnu.org/software/**xboard/engine-intf.html&lt;http://www.gnu.org/software/xboard/engine-intf.html&gt;\. I'm running on
MacOSX. Any suggestions?

Is it possible that you aren't processing one of the commands from the
program, and the program is terminating your script, perhaps after a
timeout or incorrect response? I'm wondering what would show up if you
added this:

else
  $stderr.print "Unknown command: '#{command}'\n"

just before the second-last line. Are you handling every incoming command
as it expects?

Incidentally, you could always turn those if statements into case/when,
something like:

case command
when /^protover/
...
when /^usermove/
...
else
  $stderr.print "Unknown command: '#{command}'\n"
end

This might make it easier if there are a lot of commands you need to
respond to.

Cheers,
Garth

Hi Andrew,

Happy to be able to help, even if only indirectly. :slight_smile:

Also check out "trap" ("Signal.trap") if you can usefully catch and use those SIGINTs. Perhaps they're tied to certain commands like "force" in the protocol in case you need to stop "thinking" on a move? That's a wild guess based on a two-minute reading of the protocol though.

Cheers,
Garth

···

On 16/03/13 11:46, Andrew Wagner wrote:

Ha, I fixed it. You were almost right, Garthy, the UI was
seemingly-randomly sending me SIGINTs. I had to tell it in the protocol
initializer not to do that. Very odd.

On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner <wagner.andrew@gmail.com > <mailto:wagner.andrew@gmail.com>> wrote:

    Thanks for the response. I really don't have to handle every
    incoming response. I put in the line you suggested, and it did
    indeed identify a number of commands that are "unknown". But that's
    ok, as far as I can tell.

    As for "if" vs. "case", in my real program, I did something even
    more general:
    https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb .
    This lets you plug in any command handlers you want. I plan on
    having a library of handlers for different commands, maybe a nice
    DSL or something for creating new ones, etc. Obviously, I shortened
    all of that to isolate this problem.

    On Fri, Mar 15, 2013 at 7:57 PM, Garthy D > <garthy_lmkltybr@entropicsoftware.com > <mailto:garthy_lmkltybr@entropicsoftware.com>> wrote:

        Hi Andrew,

        On 16/03/13 09:04, Andrew Wagner wrote:

            All,
            I'm writing a chess program that has a simple text-based
            interface. It's
            designed to be run by another program, which has a nice UI.
            Here's the
            program as it stands now, whittled to the simplest possible
            use case:

            i = 0
            moves = ["a7a6","a6a5","a5a4","a4a3"]
            $stdin.each do |command|
                if command.start_with?("protover"__)
                  $stdout.puts "feature ping=0 setboard=1 ics=1 usermove=1"
                elsif command.start_with?("usermove"__)
                  $stdout.puts "move #{moves[i]}"
                  i+=1
                end
                $stdout.flush
            end

            The "protover" thing is needed to tell the UI program how to
            initialize
            the protocol, and then every time a move is made, the UI
            program sends
            "usermove <some move>" to my program, which responds with
            "move <my move>".

            If I run this by itself, I can happily enter a few
            'usermove' commands
            manually, and get any number of canned moves back. However,
            when I run
            this under the UI, I get an Interrupt:

            bin/winboard.rb:3:in `each': Interrupt
            from bin/winboard.rb:3:in `<main>'

            I know that the UI program is pretty reliable, so I'm
            missing something
            in the way that I'm handling IO buffering or something. If
            you want the
            nitty gritty details, you can see them at
            http://www.gnu.org/software/__xboard/engine-intf.html
            <http://www.gnu.org/software/xboard/engine-intf.html&gt; . I'm
            running on
            MacOSX. Any suggestions?

        Is it possible that you aren't processing one of the commands
        from the program, and the program is terminating your script,
        perhaps after a timeout or incorrect response? I'm wondering
        what would show up if you added this:

        else
           $stderr.print "Unknown command: '#{command}'\n"

        just before the second-last line. Are you handling every
        incoming command as it expects?

        Incidentally, you could always turn those if statements into
        case/when, something like:

        case command
        when /^protover/
        ...
        when /^usermove/
        ...
        else
           $stderr.print "Unknown command: '#{command}'\n"
        end

        This might make it easier if there are a lot of commands you
        need to respond to.

        Cheers,
        Garth

Yep, I think you're dead-on right. Thanks again.

···

On Fri, Mar 15, 2013 at 8:23 PM, Garthy D < garthy_lmkltybr@entropicsoftware.com> wrote:

Hi Andrew,

Happy to be able to help, even if only indirectly. :slight_smile:

Also check out "trap" ("Signal.trap") if you can usefully catch and use
those SIGINTs. Perhaps they're tied to certain commands like "force" in the
protocol in case you need to stop "thinking" on a move? That's a wild guess
based on a two-minute reading of the protocol though.

Cheers,
Garth

On 16/03/13 11:46, Andrew Wagner wrote:

Ha, I fixed it. You were almost right, Garthy, the UI was
seemingly-randomly sending me SIGINTs. I had to tell it in the protocol
initializer not to do that. Very odd.

On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner <wagner.andrew@gmail.com >> <mailto:wagner.andrew@gmail.**com <wagner.andrew@gmail.com>>> wrote:

    Thanks for the response. I really don't have to handle every
    incoming response. I put in the line you suggested, and it did
    indeed identify a number of commands that are "unknown". But that's
    ok, as far as I can tell.

    As for "if" vs. "case", in my real program, I did something even
    more general:
    https://github.com/arwagner/**tdchess/blob/master/lib/**
tdchess/runner.rb<https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb&gt;\.
    This lets you plug in any command handlers you want. I plan on
    having a library of handlers for different commands, maybe a nice
    DSL or something for creating new ones, etc. Obviously, I shortened
    all of that to isolate this problem.

    On Fri, Mar 15, 2013 at 7:57 PM, Garthy D >> <garthy_lmkltybr@**entropicsoftware.com<garthy_lmkltybr@entropicsoftware.com> >> <mailto:garthy_lmkltybr@**entropicsoftware.com<garthy_lmkltybr@entropicsoftware.com>>> >> wrote:

        Hi Andrew,

        On 16/03/13 09:04, Andrew Wagner wrote:

            All,
            I'm writing a chess program that has a simple text-based
            interface. It's
            designed to be run by another program, which has a nice UI.
            Here's the
            program as it stands now, whittled to the simplest possible
            use case:

            i = 0
            moves = ["a7a6","a6a5","a5a4","a4a3"]
            $stdin.each do |command|
                if command.start_with?("protover"**__)

                  $stdout.puts "feature ping=0 setboard=1 ics=1
usermove=1"
                elsif command.start_with?("usermove"**__)

                  $stdout.puts "move #{moves[i]}"
                  i+=1
                end
                $stdout.flush
            end

            The "protover" thing is needed to tell the UI program how to
            initialize
            the protocol, and then every time a move is made, the UI
            program sends
            "usermove <some move>" to my program, which responds with
            "move <my move>".

            If I run this by itself, I can happily enter a few
            'usermove' commands
            manually, and get any number of canned moves back. However,
            when I run
            this under the UI, I get an Interrupt:

            bin/winboard.rb:3:in `each': Interrupt
            from bin/winboard.rb:3:in `<main>'

            I know that the UI program is pretty reliable, so I'm
            missing something
            in the way that I'm handling IO buffering or something. If
            you want the
            nitty gritty details, you can see them at
            http://www.gnu.org/software/__**xboard/engine-intf.html&lt;http://www.gnu.org/software/__xboard/engine-intf.html&gt;

            <http://www.gnu.org/software/**xboard/engine-intf.html&lt;http://www.gnu.org/software/xboard/engine-intf.html&gt;&gt;
. I'm
            running on
            MacOSX. Any suggestions?

        Is it possible that you aren't processing one of the commands
        from the program, and the program is terminating your script,
        perhaps after a timeout or incorrect response? I'm wondering
        what would show up if you added this:

        else
           $stderr.print "Unknown command: '#{command}'\n"

        just before the second-last line. Are you handling every
        incoming command as it expects?

        Incidentally, you could always turn those if statements into
        case/when, something like:

        case command
        when /^protover/
        ...
        when /^usermove/
        ...
        else
           $stderr.print "Unknown command: '#{command}'\n"
        end

        This might make it easier if there are a lot of commands you
        need to respond to.

        Cheers,
        Garth

Hi Andrew,

No problem at all. :slight_smile: I hope to have the opportunity to be utterly annihilated by your completed program in chess some day. :wink:

Cheers,
Garth

···

On 16/03/13 12:03, Andrew Wagner wrote:

Yep, I think you're dead-on right. Thanks again.

On Fri, Mar 15, 2013 at 8:23 PM, Garthy D > <garthy_lmkltybr@entropicsoftware.com > <mailto:garthy_lmkltybr@entropicsoftware.com>> wrote:

    Hi Andrew,

    Happy to be able to help, even if only indirectly. :slight_smile:

    Also check out "trap" ("Signal.trap") if you can usefully catch and
    use those SIGINTs. Perhaps they're tied to certain commands like
    "force" in the protocol in case you need to stop "thinking" on a
    move? That's a wild guess based on a two-minute reading of the
    protocol though.

    Cheers,
    Garth

    On 16/03/13 11:46, Andrew Wagner wrote:

        Ha, I fixed it. You were almost right, Garthy, the UI was
        seemingly-randomly sending me SIGINTs. I had to tell it in the
        protocol
        initializer not to do that. Very odd.

        On Fri, Mar 15, 2013 at 8:09 PM, Andrew Wagner > <wagner.andrew@gmail.com <mailto:wagner.andrew@gmail.com> > <mailto:wagner.andrew@gmail.__com > <mailto:wagner.andrew@gmail.com>>> wrote:

             Thanks for the response. I really don't have to handle every
             incoming response. I put in the line you suggested, and it did
             indeed identify a number of commands that are "unknown".
        But that's
             ok, as far as I can tell.

             As for "if" vs. "case", in my real program, I did something
        even
             more general:
        https://github.com/arwagner/__tdchess/blob/master/lib/__tdchess/runner.rb
        <https://github.com/arwagner/tdchess/blob/master/lib/tdchess/runner.rb&gt;
        .
             This lets you plug in any command handlers you want. I plan on
             having a library of handlers for different commands, maybe
        a nice
             DSL or something for creating new ones, etc. Obviously, I
        shortened
             all of that to isolate this problem.

             On Fri, Mar 15, 2013 at 7:57 PM, Garthy D > <garthy_lmkltybr@__entropicsoftware.com > <mailto:garthy_lmkltybr@entropicsoftware.com> > <mailto:garthy_lmkltybr@__entropicsoftware.com > <mailto:garthy_lmkltybr@entropicsoftware.com>>> wrote:

                 Hi Andrew,

                 On 16/03/13 09:04, Andrew Wagner wrote:

                     All,
                     I'm writing a chess program that has a simple
        text-based
                     interface. It's
                     designed to be run by another program, which has a
        nice UI.
                     Here's the
                     program as it stands now, whittled to the simplest
        possible
                     use case:

                     i = 0
                     moves = ["a7a6","a6a5","a5a4","a4a3"]
                     $stdin.each do |command|
                         if command.start_with?("protover"____)

                           $stdout.puts "feature ping=0 setboard=1 ics=1
        usermove=1"
                         elsif command.start_with?("usermove"____)

                           $stdout.puts "move #{moves[i]}"
                           i+=1
                         end
                         $stdout.flush
                     end

                     The "protover" thing is needed to tell the UI
        program how to
                     initialize
                     the protocol, and then every time a move is made,
        the UI
                     program sends
        "usermove <some move>" to my program, which responds with
        "move <my move>".

                     If I run this by itself, I can happily enter a few
        'usermove' commands
                     manually, and get any number of canned moves back.
        However,
                     when I run
                     this under the UI, I get an Interrupt:

                     bin/winboard.rb:3:in `each': Interrupt
                     from bin/winboard.rb:3:in `<main>'

                     I know that the UI program is pretty reliable, so I'm
                     missing something
                     in the way that I'm handling IO buffering or
        something. If
                     you want the
                     nitty gritty details, you can see them at
        http://www.gnu.org/software/____xboard/engine-intf.html
        <http://www.gnu.org/software/__xboard/engine-intf.html&gt;

        <http://www.gnu.org/software/__xboard/engine-intf.html
        <http://www.gnu.org/software/xboard/engine-intf.html&gt;&gt; . I'm
                     running on
                     MacOSX. Any suggestions?

                 Is it possible that you aren't processing one of the
        commands
                 from the program, and the program is terminating your
        script,
                 perhaps after a timeout or incorrect response? I'm
        wondering
                 what would show up if you added this:

                 else
                    $stderr.print "Unknown command: '#{command}'\n"

                 just before the second-last line. Are you handling every
                 incoming command as it expects?

                 Incidentally, you could always turn those if statements
        into
                 case/when, something like:

                 case command
                 when /^protover/
                 ...
                 when /^usermove/
                 ...
                 else
                    $stderr.print "Unknown command: '#{command}'\n"
                 end

                 This might make it easier if there are a lot of
        commands you
                 need to respond to.

                 Cheers,
                 Garth