📄 twogtp.py
字号:
#! /usr/bin/env python# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## This program is distributed with GNU Go, a Go program. ## ## Write gnugo@gnu.org or see http://www.gnu.org/software/gnugo/ ## for more information. ## ## Copyright 1999, 2000, 2001, 2002, 2003 and 2004 ## by the Free Software Foundation. ## ## This program is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License ## as published by the Free Software Foundation - version 2. ## ## This program is distributed in the hope that it will be ## useful, but WITHOUT ANY WARRANTY; without even the implied ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License in file COPYING ## for more details. ## ## You should have received a copy of the GNU General Public ## License along with this program; if not, write to the Free ## Software Foundation, Inc., 59 Temple Place - Suite 330, ## Boston, MA 02111, USA. ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #from getopt import *import popen2import sysimport stringimport redebug = 0 def coords_to_sgf(size, board_coords): global debug board_coords = string.lower(board_coords) if board_coords == "pass": return "" if debug: print "Coords: <" + board_coords + ">" letter = board_coords[0] digits = board_coords[1:] if letter > "i": sgffirst = chr(ord(letter) - 1) else: sgffirst = letter sgfsecond = chr(ord("a") + int(size) - int(digits)) return sgffirst + sgfsecondclass GTP_connection: # # 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" sys.exit(1) self.infile = infile self.outfile = outfile def exec_cmd(self, cmd): global debug if debug: sys.stderr.write("GTP command: " + cmd + "\n") self.outfile.write(cmd + "\n\n") self.outfile.flush() result = "" line = self.infile.readline() while line != "\n": result = result + line line = self.infile.readline() if debug: sys.stderr.write("Reply: " + line + "\n") # 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 class GTP_player: # Class members: # connection GTP_connection def __init__(self, command): self.connection = GTP_connection(command) protocol_version = self.connection.exec_cmd("protocol_version") if protocol_version[:5] != "ERROR": self.protocol_version = protocol_version else: self.protocol_version = "1" def is_known_command(self, command): return self.connection.exec_cmd("known_command " + command) == "true" def genmove(self, color): if color[0] in ["b", "B"]: command = "black" elif color[0] in ["w", "W"]: command = "white" if self.protocol_version == "1": command = "genmove_" + command else: command = "genmove " + command return self.connection.exec_cmd(command) def black(self, move): if self.protocol_version == "1": self.connection.exec_cmd("black " + move) else: self.connection.exec_cmd("play black " + move) def white(self, move): if self.protocol_version == "1": self.connection.exec_cmd("white " + move) else: self.connection.exec_cmd("play white " + move) def komi(self, komi): self.connection.exec_cmd("komi " + komi) def boardsize(self, size): self.connection.exec_cmd("boardsize " + size) if self.protocol_version != "1": self.connection.exec_cmd("clear_board") def handicap(self, handicap, handicap_type): if handicap_type == "fixed": result = self.connection.exec_cmd("fixed_handicap %d" % (handicap)) else: result = self.connection.exec_cmd("place_free_handicap %d" % (handicap)) return string.split(result, " ") def loadsgf(self, endgamefile, move_number): self.connection.exec_cmd(string.join(["loadsgf", endgamefile, str(move_number)])) def list_stones(self, color): return string.split(self.connection.exec_cmd("list_stones " + color), " ") def quit(self): return self.connection.exec_cmd("quit") def showboard(self): board = self.connection.exec_cmd("showboard") if board and (board[0] == "\n"): board = board[1:] return board def get_random_seed(self): result = self.connection.exec_cmd("get_random_seed") if result[:5] == "ERROR": return "unknown" return result def set_random_seed(self, seed): self.connection.exec_cmd("set_random_seed " + seed) def get_program_name(self): return self.connection.exec_cmd("name") + " " + \ self.connection.exec_cmd("version") def final_score(self): return self.connection.exec_cmd("final_score") def score(self): return self.final_score(self) def cputime(self): if (self.is_known_command("cputime")): return self.connection.exec_cmd("cputime") else: return "0"class GTP_game: # Class members: # whiteplayer GTP_player # blackplayer GTP_player # size int # komi float # handicap int # handicap_type string # handicap_stones int # moves list of string # resultw # resultb def __init__(self, whitecommand, blackcommand, size, komi, handicap, handicap_type, endgamefile): self.whiteplayer = GTP_player(whitecommand) self.blackplayer = GTP_player(blackcommand) self.size = size self.komi = komi self.handicap = handicap self.handicap_type = handicap_type self.endgamefile = endgamefile self.sgffilestart = "" if endgamefile != "": self.init_endgame_contest_game() else: self.sgffilestart = "" def init_endgame_contest_game(self): infile = open(self.endgamefile) if not infile: print "Couldn't read " + self.endgamefile sys.exit(2) sgflines = infile.readlines() infile.close size = re.compile("SZ\[[0-9]+\]") move = re.compile(";[BW]\[[a-z]{0,2}\]") sgf_start = [] for line in sgflines: match = size.search(line) if match: self.size = match.group()[3:-1] match = move.search(line) while match: sgf_start.append("A" + match.group()[1:]) line = line[match.end():] match = move.search(line) self.endgame_start = len(sgf_start) - endgame_start_at self.sgffilestart = ";" + string.join( sgf_start[:self.endgame_start-1], "") + "\n" if self.endgame_start % 2 == 0: self.first_to_play = "W" else: self.first_to_play = "B" def get_position_from_engine(self, engine): black_stones = engine.list_stones("black") white_stones = engine.list_stones("white") self.sgffilestart = ";" if len(black_stones) > 0: self.sgffilestart += "AB" for stone in black_stones: self.sgffilestart += "[%s]" % coords_to_sgf(self.size, stone) self.sgffilestart += "\n" if len(white_stones) > 0: self.sgffilestart += "AW" for stone in white_stones: self.sgffilestart += "[%s]" % coords_to_sgf(self.size, stone) self.sgffilestart += "\n" def writesgf(self, sgffilename): "Write the game to an SGF file after a game" size = self.size outfile = open(sgffilename, "w") if not outfile: print "Couldn't create " + sgffilename return black_name = self.blackplayer.get_program_name() white_name = self.whiteplayer.get_program_name() black_seed = self.blackplayer.get_random_seed() white_seed = self.whiteplayer.get_random_seed() handicap = self.handicap komi = self.komi result = self.resultw outfile.write("(;GM[1]FF[4]RU[Japanese]SZ[%s]HA[%s]KM[%s]RE[%s]\n" % (size, handicap, komi, result)) outfile.write("PW[%s (random seed %s)]PB[%s (random seed %s)]\n" % (white_name, white_seed, black_name, black_seed)) outfile.write(self.sgffilestart) if handicap > 1: outfile.write("AB"); for stone in self.handicap_stones: outfile.write("[%s]" %(coords_to_sgf(size, stone))) outfile.write("PL[W]\n") to_play = self.first_to_play for move in self.moves: sgfmove = coords_to_sgf(size, move) outfile.write(";%s[%s]\n" % (to_play, sgfmove)) if to_play == "B": to_play = "W" else: to_play = "B" outfile.write(")\n") outfile.close def set_handicap(self, handicap): self.handicap = handicap def swap_players(self): temp = self.whiteplayer self.whiteplayer = self.blackplayer self.blackplayer = temp def play(self, sgffile): "Play a game" global verbose if verbose >= 1: print "Setting boardsize and komi for black\n" self.blackplayer.boardsize(self.size) self.blackplayer.komi(self.komi) if verbose >= 1: print "Setting boardsize and komi for white\n" self.whiteplayer.boardsize(self.size) self.whiteplayer.komi(self.komi) self.handicap_stones = [] if self.endgamefile == "": if self.handicap < 2: self.first_to_play = "B" else: self.handicap_stones = self.blackplayer.handicap(self.handicap, self.handicap_type) for stone in self.handicap_stones: self.whiteplayer.black(stone) self.first_to_play = "W" else: self.blackplayer.loadsgf(self.endgamefile, self.endgame_start) self.blackplayer.set_random_seed("0") self.whiteplayer.loadsgf(self.endgamefile, self.endgame_start) self.whiteplayer.set_random_seed("0") if self.blackplayer.is_known_command("list_stones"): self.get_position_from_engine(self.blackplayer) elif self.whiteplayer.is_known_command("list_stones"): self.get_position_from_engine(self.whiteplayer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -