18a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#!/usr/bin/env python
28a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
38a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen'''This demonstrates controlling a screen oriented application (curses).
48a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenIt starts two instances of gnuchess and then pits them against each other.
58a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen'''
68a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
78a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport pexpect
88a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport string
98a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport ANSI
108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport sys, os, time
118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenclass Chess:
138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"):
158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child = pexpect.spawn (engine)
168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.term = ANSI.ANSI ()
178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                #self.child.expect ('Chess')
198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                #if self.child.after != 'Chess':
208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                #        raise IOError, 'incompatible chess program'
218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                #self.term.process_list (self.child.before)
228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                #self.term.process_list (self.child.after)
238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.last_computer_move = ''
258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def read_until_cursor (self, r,c, e=0):
278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            '''Eventually something like this should move into the screen class or
288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            a subclass. Maybe a combination of pexpect and screen...
298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            '''
308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            fout = open ('log','a')
318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            while self.term.cur_r != r or self.term.cur_c != c:
328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                try:
338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    k = self.child.read(1, 10)
348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                except Exception, e:
358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    print 'EXCEPTION, (r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)
368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    sys.stdout.flush()
378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.term.process (k)
388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c))
398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                fout.flush()
408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                if e:
418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    sys.stdout.write (k)
428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    sys.stdout.flush()
438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                if self.term.cur_r == r and self.term.cur_c == c:
448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    fout.close()
458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    return 1
468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            print 'DIDNT EVEN HIT.'
478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            fout.close()
488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            return 1
498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def expect_region (self):
518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            '''This is another method that would be moved into the
528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            screen class.
538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            '''
548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            pass
558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def do_scan (self):
568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            fout = open ('log','a')
578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            while 1:
588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                c = self.child.read(1,10)
598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.term.process (c)
608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c))
618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                fout.flush()
628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                sys.stdout.write (c)
638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                sys.stdout.flush()
648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def do_move (self, move, e = 0):
668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                time.sleep(1)
678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.read_until_cursor (19,60, e)
688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.sendline (move)
698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def wait (self, color):
718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen            while 1:
728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                r = self.term.get_region (14,50,14,60)[0]
738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                r = r.strip()
748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                if r == color:
758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                    return
768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                time.sleep (1)
778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def parse_computer_move (self, s):
798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                i = s.find ('is: ')
808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                cm = s[i+3:i+9]
818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                return cm
828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def get_computer_move (self, e = 0):
838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                time.sleep(1)
848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.read_until_cursor (19,60, e)
858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                time.sleep(1)
868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                r = self.term.get_region (17,50,17,62)[0]
878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                cm = self.parse_computer_move (r)
888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                return cm
898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def switch (self):
918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                print 'switching'
928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.sendline ('switch')
938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def set_depth (self, depth):
958a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.sendline ('depth')
968a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.expect ('depth=')
978a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.sendline ('%d' % depth)
988a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
998a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen        def quit(self):
1008a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                self.child.sendline ('quit')
1018a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1028a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef LOG (s):
1038a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    print s
1048a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    sys.stdout.flush ()
1058a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    fout = open ('moves.log', 'a')
1068a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    fout.write (s + '\n')
1078a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    fout.close()
1088a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1098a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenprint 'Starting...'
1108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenblack = Chess()
1128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenwhite = Chess()
1138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenwhite.read_until_cursor (19,60,1)
1148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenwhite.switch()
1158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendone = 0
1178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenwhile not done:
1188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    white.wait ('Black')
1198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    move_white = white.get_computer_move(1)
1208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    LOG ( 'move white:'+ move_white )
1218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    black.do_move (move_white)
1238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    black.wait ('White')
1248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    move_black = black.get_computer_move()
1258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    LOG ( 'move black:'+ move_black )
1268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    white.do_move (move_black, 1)
1288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheng.quit()
1308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
132