import string,sys,popen2 import helper,filehandling gnugocommand = "/usr/games/gnugo --mode gtp" showboard = """ = A B C D E F G 7 . . . . . . . 7 6 . . . . . . . 6 5 . . + . + . . 5 4 . . X X . . . 4 3 . . O . + . . 3 2 . . . . . . . 2 WHITE (O) has captured 0 stones 1 . . . . . . . 1 BLACK (X) has captured 0 stones A B C D E F G """ def is_int( str ): """ Is the given string an integer? """ ok = 1 try: num = int(str) except ValueError: ok = 0 return ok def showboard_to_goban_dict(showboard): """ gets a string containing the result of the 'showboard' command from gnugo --mode gtp. returns a goban dictionary . """ gobandict= {} showboardlist = string.split(showboard,'\n') while '' in showboardlist: showboardlist.remove('') #remove '=' if string.find(showboardlist[0],"=")>=0: showboardlist.remove(showboardlist[0]) #get boardsize tmplist = string.split(showboardlist[0]," ") while '' in tmplist: tmplist.remove('') boardsize = len(tmplist) #remove first A B C D ... showboardlist.remove(showboardlist[0]) #remove last A B C D ... showboardlist.remove(showboardlist[-1]) for i in range(0,boardsize): #make string to list linelist = string.split(showboardlist[i],' ') #clean list from '' entries while '' in linelist: linelist.remove('') # remove numbers for p in range(0,boardsize+1): if is_int(linelist[p]): linelist.remove(linelist[p]) #print linelist,'\n' #now fill dictionary: for j in range(0,boardsize): if (linelist[j] == ".") or (linelist[j] == "+"): gobandict[(i+1,j+1)] = 0 #empty if linelist[j] == "O": gobandict[(i+1,j+1)] = 1 #white stone if linelist[j] == "X": gobandict[(i+1,j+1)] = 2 #black stone #check for info of caputered stones: if len(linelist) > boardsize: if 'WHITE' in linelist: whitecapture = "white has captured %s stones." % linelist[-2] #print whitecapture elif 'BLACK' in linelist: blackcapture = "black has captured %s stones." % linelist[-2] gobandict["size"] = boardsize return gobandict def sgf_to_goban_dict(gobandict, filename=""): """ gets a goban dictionary and optionally a temporary filename. saves string to file, loads in gnugo, does showboard, convert showboard to gobandict. return gobandict 'lite' (just coordinates and size) """ sgf = gobandict["sgf"] #generate tmpfile if filename == "": filename = filehandling.gen_temp_file() #write sgf data to file filehandling.write_file(filename,sgf) #open connection to gnugo: conn = GTP_connection(gnugocommand) #load sgf file in gnugo result = conn.exec_cmd("loadsgf "+filename) #make move (looks like 'play black F2' result = conn.exec_cmd("showboard") #convert to goban dict ret = showboard_to_goban_dict(result) result = conn.exec_cmd("quit") return ret ### GTP_connection is based on twogtp.py packaged with gnugo. class GTP_connection: """ gets a program call string, opens an interactive session with program called with 'program'. GTP_connection.exec_cmd(command) returns result of command. # # Class members: # outfile File to write to # infile File to read from """ def __init__(self, command): try: infile, outfile = popen2.popen2(command) except: print "popen2 failed" self.infile = infile self.outfile = outfile def exec_cmd(self, cmd): self.outfile.write(cmd + "\n\n") self.outfile.flush() result = "" line = self.infile.readline() while line != "\n": result = result + line line = self.infile.readline() # Remove trailing newline from the result if result[-1] == "\n": result = result[:-1] if len(result) == 0: return "ERROR: len = 0" if (result[0] == "?"): return "ERROR: GTP Command failed: " + result[2:] if (result[0] == "="): return result[2:] return "ERROR: Unrecognized answer: " + result def is_legal(gobandict,coords,req,form): """ gets a goban dict and a (x,y) tuple. tests wether proposed move is legal. returns True or False. """ size = gobandict["size"] turn = gobandict["turn_number"] #who's turn is it? color = ["white","black"][turn % 2] #even turn: white plays, else black plays #convert given coordinates gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size) #open connection to gnugo: conn = GTP_connection(gnugocommand) result = conn.exec_cmd("is_legal "+ color +gnucoords) if result == "1": return True else: return False result = conn.exec_cmd("quit") def create_sgf_file(size, filename=""): """ gets: board size, optionally a temporary filename to use. returns the content of an empty sgf file. """ conn = GTP_connection(gnugocommand) result = conn.exec_cmd("boardsize "+str(size)) if filename == "": filename = filehandling.gen_temp_file() result = conn.exec_cmd("printsgf "+filename) ret = filehandling.read_file(filename) result = conn.exec_cmd("quit") return ret def make_move_in_sgf(req,form,gobandict,coords,filename = ""): """ gets: goban dict, (x,y) tuple for move, optionally a filename for tempfile. writes the string to a file, opens gnugo, makes the move, writes new sgf to temporary file, reads content of temporary file. returns: sgf string of new file. """ size = gobandict["size"] turn = gobandict["turn_number"] sgf = gobandict["sgf"] #convert given coordinates gnucoords = " " + helper.dict_coords_to_gnugo_coords(coords,size) # get current player #even turn: white plays, else its blacks turn color = ["white","black"][turn % 2] helper.debug(req,form,"color: %s -- turn: %s " % (color,turn)) #generate tmpfile if filename == "": filename = filehandling.gen_temp_file() #write sgf data to file filehandling.write_file(filename,sgf) #open connection to gnugo: conn = GTP_connection(gnugocommand) #load sgf file in gnugo result = conn.exec_cmd("loadsgf "+filename) #make move (looks like 'play black F2' result = conn.exec_cmd("play "+color+gnucoords) #save result to file result = conn.exec_cmd("printsgf "+filename) #read out new file sgf = filehandling.read_file(filename) result = conn.exec_cmd("quit") return sgf if __name__ == '__main__': #showboard_to_goban_dict(showboard) import popen2 conn = GTP_connection("gnugo --mode gtp") result = conn.exec_cmd("boardsize 7") result = conn.exec_cmd("genmove black") result = conn.exec_cmd("genmove white") result = conn.exec_cmd("printsgf test.sgf") result = conn.exec_cmd("quit") conn = GTP_connection("gnugo --mode gtp") result = conn.exec_cmd("loadsgf test.sgf") result = conn.exec_cmd("showboard") print result,"\n----\n" print showboard_to_goban_dict(result) print create_sgf_file(7) #loadsgf #printsgf #is_legal black F2 #dict_coords_to_gnugo_coords(coords) translates (6,6) to "F2"