From: Andrew Wagner Date: 2013-03-16T10:09:38+09:00 Subject: Re: IO buffering problem --20cf307f382cc6e57704d80068a6 Content-Type: text/plain; charset=UTF-8 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 " to my program, which responds with "move > 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 `
' >> >> 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? >> > > 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 > > --20cf307f382cc6e57704d80068a6 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Thanks for the response. I really don't have to handle= every incoming response. I put in the line you suggested, and it did indee= d identify a number of commands that are "unknown". But that'= s ok, as far as I can tell.=C2=A0

As for "if" vs. "case", in my real= program, I did something even more general:=C2=A0https://github.com= /arwagner/tdchess/blob/master/lib/tdchess/runner.rb . This lets you plu= g 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@ent= ropicsoftware.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&= #39;s
designed to be run by another program, which has a nice UI. Here's the<= br> program as it stands now, whittled to the simplest possible use case:

i =3D 0
moves =3D ["a7a6","a6a5","a5a4","a4a3&qu= ot;]
$stdin.each do |command|
=C2=A0 =C2=A0if command.start_with?("protover")
=C2=A0 =C2=A0 =C2=A0$stdout.puts "feature ping=3D0 setboard=3D1 ics=3D= 1 usermove=3D1"
=C2=A0 =C2=A0elsif command.start_with?("usermove")
=C2=A0 =C2=A0 =C2=A0$stdout.puts "move #{moves[i]}"
=C2=A0 =C2=A0 =C2=A0i+=3D1
=C2=A0 =C2=A0end
=C2=A0 =C2=A0$stdout.flush
end

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

If I run this by itself, I can happily enter a few 'usermove' comma= nds
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&#= 39;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 timeou= t or incorrect response? I'm wondering what would show up if you added = this:

else
=C2=A0 $stderr.print "Unknown command: '#{command}'\n"
just before the second-last line. Are you handling every incoming command a= s it expects?

Incidentally, you could always turn those if statements into case/when, som= ething like:

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

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

Cheers,
Garth


--20cf307f382cc6e57704d80068a6--