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