views:

84

answers:

2

I modified the source code from Fred Lundh's Python Standard Library. The original source uses popen2 to communicate to subprocess, but I changed it to use subprocess.Popen() as follows.

import subprocess
import string

class Chess:
    "Interface class for chesstool-compatible programs"

    def __init__(self, engine = "/opt/local/bin/gnuchess"):
        proc=subprocess.Popen([engine],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
        self.fin, self.fout = proc.stdin, proc.stdout

        s = self.fout.readline() <--
        print s
        if not s.startswith("GNU Chess"):
            raise IOError, "incompatible chess program"

    def move(self, move):
        ...
        my = self.fout.readline() <--
        ...

    def quit(self):
        self.fin.write("quit\n")
        self.fin.flush()

g = Chess()
print g.move("a2a4")
print g.move("b2b3")
g.quit()

It seems to run OK, but the gnuchess prints out multiple lines of messages as follows, but with self.fout.readline() it only shows one line.

Thinking...
... 
R N B Q K B N R 

How do I get multiple lines of message? readlines() method doesn't seem to work.

ADDED

I tested the code from movieyoda, but it doesn't work. I think it's just correct that only readline() should work, not readlines() and read(), as one doesn't know when to stop reading except for the readline().

+1  A: 

I would just read it's output as it arrives. When the process dies, the subprocess module will take care of cleaning things up for you. You could do something like this -

l = list()
while True:
    data = proc.stdout.read(4096)
    if not data:
        break
    l.append(data)
file_data = ''.join(l)

All of this is a replacement for self.fout.readline(). Have not tried it. But should handle multiple lines.

MovieYoda
+2  A: 

To interact with gnuchess, I'd use pexpect.

import pexpect
import sys
game = pexpect.spawn('/usr/games/gnuchess')
# Echo output to stdout
game.logfile = sys.stdout
game.expect('White')
game.sendline('a2a4')
game.expect('White')
game.sendline('b2b3')
game.expect('White')
game.sendline('quit')
unutbu