diff -urN --exclude-from=kombilo05.exclude kombilo05.orig/board1.py kombilo05/board1.py
--- kombilo05.orig/board1.py	2004-07-02 21:03:56.000000000 +0300
+++ kombilo05/board1.py	2004-11-30 10:33:18.000000000 +0200
@@ -416,7 +416,16 @@
 
         return (x,y)    
 
-    def placeMark(self, pos, color, outln='', size=''):
+    def placeInfluenceMark(self, pos, color, type):
+        if type=='territory':
+            self.placeMark(pos, color="", outln=color, size="small", type="rectangle")
+        elif type=='moyo':
+            self.placeMark(pos, color="", outln=color, size="small", type="triangle")
+        elif type=='area':
+            self.placeMark(pos, color="", outln=color, size="small", type="circle")
+        
+
+    def placeMark(self, pos, color, outln='', size='', type='circle'):
         """ Place colored mark at pos. """
         x1, x2, y1, y2 = self.getPixelCoord(pos, 1)
 
@@ -426,8 +435,15 @@
         else:
             tmp1 = 2
             tmp2 = 2
-        self.create_oval(x1+tmp1, x2+tmp2, y1-tmp1, y2-tmp2, fill = color,
-                         outline = outln, tags=('marks', 'non-bg'))
+        if type=='circle':
+            self.create_oval(x1+tmp1, x2+tmp2, y1-tmp1, y2-tmp2, fill = color,
+                             outline = outln, tags=('marks', 'non-bg'))
+        elif type=='rectangle':
+            self.create_rectangle(x1+6, x2+6, y1-6, y2-6, fill = color,
+                                  outline = outln, tags=('marks','non-bg'))
+        elif type=='triangle':
+            self.create_polygon((x1+y1)/2, x2+5-5, x1+5, y2-5-5, y1-5, y2-5-5,
+                                fill = color, outline = outln, tags=('marks','non-bg'))
         self.marks[pos]=color
         self.onChange()
 
@@ -565,6 +581,24 @@
         y = int(r*math.sin((degree-90)*radPerDeg) + r)
         return (x,y)
 
+    def drawShadedStone(self, pos, color, stipple='gray50', size='normal'):
+        x1, x2, y1, y2 = self.getPixelCoord(pos, 1)
+        if size=='normal':
+            tmp1 = 0
+            tmp2 = 0
+        elif size=='medium':
+            tmp1 = 3
+            tmp2 = 3
+        elif size=='small':
+            tmp1 = 6
+            tmp2 = 6
+        elif size=='tiny':
+            tmp1 = 9
+            tmp2 = 9
+        self.create_oval(x1+tmp1, x2+tmp2, y1-tmp1, y2-tmp2,
+                         fill=color, stipple=stipple,
+                         outline='', tags=('shaded','non-bg')) 
+
     def shadedStone(self, event):
         x, y = self.getBoardCoord((event.x, event.y), 1)
         if (x,y) == self.shadedStonePos: return     # nothing changed
diff -urN --exclude-from=kombilo05.exclude kombilo05.orig/gtp.py kombilo05/gtp.py
--- kombilo05.orig/gtp.py	1970-01-01 02:00:00.000000000 +0200
+++ kombilo05/gtp.py	2004-12-01 06:47:11.000000000 +0200
@@ -0,0 +1,277 @@
+#! /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.                                        #
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+# some comments (like above) and
+# lots of code copied from twogtp.py from gnugo-3.6-pre4
+# additions/changes by Aloril 2004
+
+
+import popen2
+import sys
+import string
+import time
+import os
+
+debug = 1
+
+def coords_to_sgf(size, board_coords):
+    global debug
+    
+    board_coords = string.lower(board_coords)
+    if board_coords == "pass":
+        return ""
+    if debug>1:
+        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 + sgfsecond
+
+
+def sgf_to_coords(size, sgf_coords):
+    print sgf_coords
+    letter = string.upper(sgf_coords[0])
+    if letter>="I":
+        letter = chr(ord(letter)+1)
+    digit = str(ord('a') + int(size) - ord(sgf_coords[1]))
+    return letter+digit
+
+
+class 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
+
+        for i in range(100):
+            log_name = "gtp%03i.log" % i
+            if not os.path.exists(log_name):
+                break
+        self.log_fp = open(log_name, "w")
+        self.log_fp.write(command+"\n")
+        self.log_fp.flush()
+        
+    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()
+        if self.log_fp:
+            self.log_fp.write("Time: %f\n" % time.time())
+            self.log_fp.write(cmd + "\n\n")
+            self.log_fp.flush()
+        result = ""
+        line = self.infile.readline()
+        if self.log_fp:
+            self.log_fp.write(line)
+            self.log_fp.flush()
+        while line != "\n":
+            result = result + line
+            line = self.infile.readline()
+            if self.log_fp:
+                self.log_fp.write(line)
+                self.log_fp.flush()
+        if debug:
+            sys.stderr.write("Reply: " + result + "\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):
+        if self.connection.log_fp:
+            self.connection.log_fp.write(open(endgamefile).read())
+            self.connection.log_fp.flush()
+        return 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 experimental_score(self, color):
+        self.showboard()
+        return self.connection.exec_cmd("experimental_score " + color)
+
+    def all_move_values(self):
+        moves = string.split(self.connection.exec_cmd("all_move_values"))
+        result = []
+        for i in range(0, len(moves), 2):
+            result.append((moves[i], float(moves[i+1])))
+        return result
+
+    def dragon_stones_and_status(self):
+        dragon_status = {}
+        for line in string.split(self.connection.exec_cmd("dragon_status"), "\n"):
+            lst = string.split(line)
+            stone = lst[0][:-1]
+            status = lst[1]
+            dragon_status[stone] = status
+        result = []
+        for line in string.split(self.connection.exec_cmd("dragon_stones"), "\n"):
+            stone_lst = string.split(line)
+            for stone in stone_lst:
+                if dragon_status.has_key(stone):
+                    key_stone = stone
+                    break
+            else:
+                key_stone = ""
+            for stone in stone_lst:
+                status = dragon_status.get(key_stone, "unknown")
+                result.append((stone, status))
+        return result
+
+    def influence_regions(self, color):
+        result = []
+        data = self.connection.exec_cmd("initial_influence " + color + " influence_regions")
+        for line in string.split(data, "\n"):
+            result.append(map(int, string.split(line)))
+        return result
+            
+
+    def set_board(self, black_stones, white_stones):
+        self.connection.exec_cmd("clear_board")
+        for color, stone_lst in (("black", black_stones), ("white", white_stones)):
+            for stone in stone_lst:
+                self.connection.exec_cmd("play " + color + " " + stone)
+        self.showboard()
+
+    def cputime(self):
+        if (self.is_known_command("cputime")):
+            return self.connection.exec_cmd("cputime")
+        else:
+            return "0"
diff -urN --exclude-from=kombilo05.exclude kombilo05.orig/kombilo.py kombilo05/kombilo.py
--- kombilo05.orig/kombilo.py	2004-07-02 21:03:56.000000000 +0300
+++ kombilo05/kombilo.py	2004-12-02 05:13:34.455451728 +0200
@@ -65,6 +65,16 @@
 
 from board1 import *
 import v
+from gtp import GTP_player
+
+analyze_engine_command = "/usr/local/src/gnugo-3.6/interface/gnugo --mode gtp --chinese-rules --never-resign"
+analyze_engine_command = "/usr/local/src/gnugo-3.6/interface/gnugo --mode gtp --chinese-rules --never-resign"
+#for i in range(100):
+#    engine_sgf_name = "engine%03i.sgf" % i
+#    if not os.path.exists(engine_sgf_name):
+#        break
+#play_engine_command = "/usr/local/src/gnugo-3.4/interface/gnugo --mode gtp --chinese-rules --never-resign -o " + engine_sgf_name
+play_engine_command = "/usr/local/src/gnugo-3.4/interface/gnugo --mode gtp --chinese-rules --never-resign"
 
 try:
     from sgfpars import Node, Cursor, SGFError, SGFescape
@@ -5979,6 +5989,8 @@
         except IOError:
             showwarning('IOError', 'Could not write kombilo.def')
 
+        self.analyze_engine.quit()
+        self.play_engine.quit()
         self.master.quit()
         
 
@@ -6780,6 +6792,13 @@
         self.currentSearchPattern = None
         self.balloonHelp()
 
+        self.analyze_engine = GTP_player(analyze_engine_command)
+        print "Analyze:", self.analyze_engine.get_program_name()
+        self.play_engine = GTP_player(play_engine_command)
+        self.play_engine.get_random_seed()
+        #self.play_engine.handicap(2, "fixed")
+        print "Opponent:", self.play_engine.get_program_name()
+
 
 # ---------------------------------------------------------------------------------------
 
diff -urN --exclude-from=kombilo05.exclude kombilo05.orig/v.py kombilo05/v.py
--- kombilo05.orig/v.py	2004-07-02 21:03:56.000000000 +0300
+++ kombilo05/v.py	2004-12-02 05:13:33.896536696 +0200
@@ -50,6 +50,8 @@
     from sgfparser import Node, Cursor, SGFError, SGFescape
 from board1 import *
 
+import gtp
+
 # ---------------------------------------------------------------------------------------
 
 class BunchTkVar:
@@ -1523,6 +1525,159 @@
             pass
 
         return 0
+
+    def getCurrentPosAsSGFstring(self):
+        n = self.cursor.currentN
+        result = []
+        while n:
+            result.append(n.SGFstring)
+            n = n.previous
+        result.reverse()
+        return "(" + join(result, "") + ")\n"
+
+    def analyzePosition(self):
+        class AnalyseInfo: pass
+        pos_as_sgf = self.getCurrentPosAsSGFstring()
+        if not hasattr(self, "analyze_cache"): self.analyze_cache = {}
+        if self.analyze_cache.has_key(pos_as_sgf):
+            print "Cached"
+            print pos_as_sgf
+            analyse_info = self.analyze_cache[pos_as_sgf]
+            color = analyse_info.color
+            move = analyse_info.move
+            score = analyse_info.score
+            moves = analyse_info.moves
+            dragon_stone_status = analyse_info.dragon_stone_status
+            influence = analyse_info.influence
+        else:
+            self.analyze_cache[pos_as_sgf] = analyse_info = AnalyseInfo()
+            gtp_sgf = "gtp.sgf"
+            fp = open(gtp_sgf, "w")
+            fp.write(pos_as_sgf)
+            fp.close()
+            analyse_info.color = color = self.analyze_engine.loadsgf(gtp_sgf, "")
+            self.analyze_engine.showboard()
+            node_count0 = int(self.analyze_engine.connection.exec_cmd("get_trymove_counter"))
+            analyse_info.move = move = self.analyze_engine.connection.exec_cmd("reg_genmove "+ color)
+            print move
+            score = self.analyze_engine.connection.exec_cmd("estimate_score " + color)
+            #score1 = self.analyze_engine.experimental_score(color)
+            #score = score0 + " | " + score1
+            node_count1 = int(self.analyze_engine.connection.exec_cmd("get_trymove_counter"))
+            tmp = node_count = node_count1-node_count0
+            node_count_str = ""
+            if not node_count:
+                node_count_str = "0"
+            else:
+                while tmp:
+                    tmp, tmp_rem = divmod(tmp, 1000)
+                    if node_count_str: node_count_str = ","+node_count_str
+                    if tmp:
+                        node_count_str = ("%03i" % tmp_rem) + node_count_str
+                    else:
+                        node_count_str = str(tmp_rem) + node_count_str
+            score += "  ("+node_count_str+" nodes)"
+            print "!:", score
+            analyse_info.score = score
+
+            #Moves candidates
+            if move!="PASS":
+                #moves = split(self.analyze_engine.connection.exec_cmd("top_moves"))
+                analyse_info.moves = moves = self.analyze_engine.all_move_values()
+            else:
+                analyse_info.moves = moves = []
+
+            #Dragons
+            if self.analyze_engine.connection.exec_cmd("list_stones black") or \
+               self.analyze_engine.connection.exec_cmd("list_stones white"):
+                #dragon_data = self.analyze_engine.connection.exec_cmd("dragon_data")
+                analyse_info.dragon_stone_status = dragon_stone_status = \
+                                                   self.analyze_engine.dragon_stones_and_status()
+            else:
+                analyse_info.dragon_stone_status = dragon_stone_status = []
+
+            #Influence
+            analyse_info.influence = influence = self.analyze_engine.influence_regions(color)
+
+        #Display results
+        self.scoreVar.set(score)
+        #Move candidates
+        for pos, value in moves:
+            #print pos, move, pos==move
+            if pos==move: postfix = "!"
+            else: postfix = ""
+            pos = self.convCoord(gtp.coords_to_sgf(self.board.boardSize, pos))
+            if value<1.0:
+                value = "<1"
+            else:
+                value = str(int(value))
+            self.board.placeLabel(pos, "LB", value + postfix)
+        #Dragon status
+        for stone, status in dragon_stone_status:
+            #print stone, status
+            if status=="critical":
+                label = "!"
+            elif status=="dead":
+                label = "x"
+            else:
+                label = ""
+            if label:
+                pos = self.convCoord(gtp.coords_to_sgf(self.board.boardSize, stone))
+                self.board.placeLabel(pos, "LB", label)
+        #Influence
+        for j in range(len(influence)):
+            for i in range(len(influence[j])):
+                inf = influence[j][i]
+                pos = i+1, j+1
+                if inf==3:
+                    self.board.placeInfluenceMark(pos, "green", "territory")
+                elif inf==2:
+                    self.board.placeInfluenceMark(pos, "#00C000", "moyo")
+                elif inf==1:
+                    self.board.placeInfluenceMark(pos, "#007000", "area")
+                elif inf==-3:
+                    self.board.placeInfluenceMark(pos, "red", "territory")
+                elif inf==-2:
+                    self.board.placeInfluenceMark(pos, "#C00000", "moyo")
+                elif inf==-1:
+                    self.board.placeInfluenceMark(pos, "#700000", "area")
+        
+
+    def playCurrentMoveInEngine(self):
+        n = self.cursor.currentNode()
+        print n
+        pos_as_sgf = self.getCurrentPosAsSGFstring()
+        if len(n)==1:
+            if hasattr(self, "lastEnginePos"):
+                if self.lastEnginePos[:-2] + self.cursor.currentN.SGFstring + self.lastEnginePos[-2:]!=pos_as_sgf:
+                    print "Position not ok!"
+                    return
+            gtp_move = gtp.sgf_to_coords(self.board.boardSize, n.values()[0][0])
+            print gtp_move
+            if n.keys()[0]=="B":
+                self.play_engine.black(gtp_move)
+                next_color = "white"
+            else:
+                self.play_engine.white(gtp_move)
+                next_color = "black"
+            move = self.play_engine.genmove(next_color)
+            print move
+            pos = self.convCoord(gtp.coords_to_sgf(self.board.boardSize, move))
+            self.nextMove(pos)
+            pos_as_sgf = self.getCurrentPosAsSGFstring()
+            #x1,y1,x2,y2 = self.board.getPixelCoord(pos)
+            #print pos, x1,y1,x2,y2
+            #class Ev: pass
+            #ev = Ev()
+            #ev.x = (x1+x2)/2
+            #ev.y = (y1+y2)/2
+            #self.cursor.onButton1(ev)
+            #self.board.play(self.convCoord(gtp.coords_to_sgf(self.board.boardSize, move)))
+            #self.board.currentColor = self.board.invert(self.board.currentColor)
+            self.play_engine.showboard()
+        self.play_engine.connection.log_fp.write(pos_as_sgf)
+        print pos_as_sgf
+        self.lastEnginePos = pos_as_sgf
         
 
     def gotoMove(self, event):
@@ -2739,6 +2894,40 @@
             self.dataWindow.updateGameInfo(self.cursor)
 
 
+    def showRestOfGame(self):
+        n = self.cursor.currentN
+        count = 0
+        while n:
+            n = n.next
+            if not n: break
+            count += 1
+            if count<=2:
+                stipple = 'gray75'
+            elif count<=10:
+                stipple = 'gray50'
+            elif count<=30:
+                stipple = 'gray25'
+            else:
+                stipple = 'gray12'
+            if count<=50:
+                size = 'normal'
+            elif count<=100:
+                size = 'medium'
+            elif count<=150:
+                size = 'small'
+            else:
+                size = 'tiny'
+            d = n.getData()
+            pos = None
+            if d.has_key("B"):
+                pos = self.convCoord(d["B"][0])
+                color = "black"
+            if d.has_key("W"):
+                pos = self.convCoord(d["W"][0])
+                color = "white"
+            #self.board.placeLabel(pos, "LB", str(count), color)
+            self.board.drawShadedStone(pos, color, stipple, size)
+
     def toggleDatawindow(self):
         if self.options.datawindowVisible.get():
             self.dataWindow.window.deiconify()
@@ -2846,7 +3035,14 @@
         self.options.datawindowVisible.set(1)
         self.datawindowButton = Checkbutton(navFrame, text='DATA', variable = self.options.datawindowVisible,
                                             command = self.toggleDatawindow, indicatoron=0)
-        
+
+        self.analyzeButton = Button(navFrame, text='Analyze', command = self.analyzePosition)
+        self.boardFrame.bind('<a>', lambda e, s = self.analyzeButton: s.invoke())
+        self.playCurrentButton = Button(navFrame, text='Play', command = self.playCurrentMoveInEngine)
+        #self.boardFrame.bind('<p>', lambda e, s = self.playCurrentButton: s.invoke())
+        self.showRestOfGameButton = Button(navFrame, text='Rest', command = self.showRestOfGame)
+        self.boardFrame.bind('<r>', lambda e, s = self.showRestOfGameButton: s.invoke())
+
         # try to load icons for navigation buttons
 
         if sys.path[0].endswith('library.zip'): SYSPATH = os.path.split(sys.path[0])[0]
@@ -2878,6 +3074,9 @@
         self.passButton.grid(row=0, column=10)
         self.gameinfoButton.grid(row=0, column=11)
         self.datawindowButton.grid(row=0, column=12)
+        self.analyzeButton.grid(row=0, column=13)
+        self.playCurrentButton.grid(row=0, column=14)
+        self.showRestOfGameButton.grid(row=0, column=15)
         
         self.modeVar = StringVar()
         self.modeVar.set('blackwhite')
@@ -2936,11 +3135,16 @@
         self.capLabel = Label(labelFrame, height=1, width=15, relief=SUNKEN, justify=LEFT,
                               textvariable=self.capVar)
 
+        self.scoreVar = StringVar()
+        self.scoreLabel = Label(labelFrame, height=1, width=53, relief=SUNKEN, justify=LEFT,
+                              textvariable=self.scoreVar)
+
         # pack everything
 
         self.gameNameLabel.pack(expand=NO, fill=X, side=LEFT, padx = 5)
         self.movenoLabel.pack(expand=NO, fill=X, side=LEFT, padx=5)
         self.capLabel.pack(expand=NO, fill=X, side=LEFT, padx=5)
+        self.scoreLabel.pack(expand=NO, fill=X, side=LEFT, padx=5)
 
 
     def balloonHelp(self):
@@ -2954,6 +3158,8 @@
         self.balloon.bind(self.passButton, 'Pass')
         self.balloon.bind(self.gameinfoButton, 'Edit game info')
         self.balloon.bind(self.datawindowButton, 'Open/withdraw data window')
+        self.balloon.bind(self.analyzeButton, 'Analyze position with GnuGo')
+        self.balloon.bind(self.playCurrentButton, 'Play current move on board against engine/something else using gtp')
 
         self.balloon.bind(self.BWbutton, 'Play black/white stones')
         self.balloon.bind(self.WBbutton, 'Play white/black stones')
