diff --git a/lib/goban.py b/lib/goban.py
index 1a1fd5a..5273cf3 100644
--- a/lib/goban.py
+++ b/lib/goban.py
@@ -5,8 +5,11 @@ class Goban:
EMPTY=0
WHITE=1
BLACK=2
- # GRAY_WHITE=3
- # GRAY_BLACK=4
+ SCORE_BLACK=3
+ SCORE_WHITE=4
+ SCORE_DAME=5
+ SCORING=6
+
def __init__(self, board_size=19):
# Build the board intersections
@@ -109,7 +112,6 @@ class Goban:
- # fixme: need to handle post-game stuff here... scoring code
def pass_move(self, color=None):
if color is None:
color = self.to_move
@@ -122,6 +124,9 @@ class Goban:
if self.passed_last:
self.to_move = Goban.EMPTY
+ self.winner = Goban.SCORING
+ self.auto_score()
+ return range(len(self.board))
else:
self.to_move = self._other_color(color)
self.passed_last = True
@@ -294,8 +299,9 @@ class Goban:
return None
point = self.board[pos]
+ code = None
- if point == Goban.EMPTY:
+ if point == Goban.EMPTY or point == Goban.SCORE_DAME:
code = self.def_draw_codes[pos]
elif point == Goban.BLACK:
code = 'b'
@@ -305,6 +311,10 @@ class Goban:
code = 'w'
if pos == self.last_move:
code += 'Cb'
+ elif point == Goban.SCORE_WHITE:
+ code = self.def_draw_codes[pos] + 'ws'
+ elif point == Goban.SCORE_BLACK:
+ code = self.def_draw_codes[pos] + 'bs'
if pos == self.ko:
code += 'S'
@@ -312,6 +322,51 @@ class Goban:
return code
+ def auto_score(self):
+ '''
+ Detects regions and assigns them to the appropriate player
+ This may not always guess correctly, so we also have API that
+ can manually change these things.
+
+ After calling this function, the entire board should be redrawn.
+ '''
+ for i in range(len(self.board)):
+ if self.board[i] == Goban.EMPTY:
+ bs = self.board_size * self.board_size
+ checked = set()
+ score = self._score_space(i, checked)
+
+ for c in checked:
+ self.board[c] = score
+
+
+
+ def _score_space(self, pos, checked):
+ if pos in checked:
+ return None
+
+ if self.board[pos] == Goban.BLACK:
+ return Goban.SCORE_BLACK
+ elif self.board[pos] == Goban.WHITE:
+ return Goban.SCORE_WHITE
+
+ checked.add(pos)
+
+ possible = set()
+ for i in self._neighbors(pos):
+ score = self._score_space(i, checked)
+ possible.add(score)
+
+ if Goban.SCORE_DAME in possible or (Goban.SCORE_BLACK in possible and Goban.SCORE_WHITE in possible):
+ return Goban.SCORE_DAME
+ elif Goban.SCORE_BLACK in possible:
+ return Goban.SCORE_BLACK
+ elif Goban.SCORE_WHITE in possible:
+ return Goban.SCORE_WHITE
+ else:
+ return None
+
+
def _make_default_draw_codes(self):
ret = []
diff --git a/pygo.py b/pygo.py
index 9010821..75280b1 100755
--- a/pygo.py
+++ b/pygo.py
@@ -62,6 +62,8 @@ class Pygo():
self.games.append_page(game, gtk.Label('Local Game'))
self.games.set_tab_reorderable(game, True)
game.show_all()
+ game.winner_box.hide()
+
def on_net_direct(self, widget):
diff --git a/ui/default.glade b/ui/default.glade
index a2a056b..95e58f5 100644
--- a/ui/default.glade
+++ b/ui/default.glade
@@ -128,29 +128,6 @@
-
-
-
- True
- label1
- False
- False
- GTK_JUSTIFY_LEFT
- False
- False
- 0.5
- 0.5
- 0
- 0
- PANGO_ELLIPSIZE_NONE
- -1
- False
- 0
-
-
- tab
-
-
0
diff --git a/ui/res/go_bs.png b/ui/res/go_bs.png
new file mode 100644
index 0000000..1bcb992
Binary files /dev/null and b/ui/res/go_bs.png differ
diff --git a/ui/res/go_ws.png b/ui/res/go_ws.png
new file mode 100644
index 0000000..73d4775
Binary files /dev/null and b/ui/res/go_ws.png differ
diff --git a/widgets/gogame.py b/widgets/gogame.py
index fec8954..31e6506 100644
--- a/widgets/gogame.py
+++ b/widgets/gogame.py
@@ -50,6 +50,13 @@ class GoGame(gtk.HBox):
for row in info_rows:
info_box.pack_start(row, expand=False)
+ self.winner_box = gtk.HBox()
+ self.winner_value = gtk.Label('None')
+ self.winner_box.pack_start(gtk.Label('Winner:'), expand=False, padding=5)
+ self.winner_box.pack_end(self.winner_value, expand=False, padding=5)
+
+ info_box.pack_start(self.winner_box, expand=False)
+
self.pass_button = gtk.Button('Pass')
self.resign_button = gtk.Button('Resign')
self.pass_button.connect('clicked', self.on_pass)
@@ -185,6 +192,16 @@ class GoGame(gtk.HBox):
move = 'White'
else:
move = 'None'
+
+ if self.goban.winner != goban.Goban.EMPTY:
+ if self.goban.winner == goban.Goban.BLACK:
+ self.winner_value.set_text('Black')
+ elif self.goban.winner == goban.Goban.WHITE:
+ self.winner_value.set_text('White')
+ elif self.goban.winner == goban.Goban.SCORING:
+ self.winner_value.set_text('Scoring')
+ self.winner_box.show()
+
self.to_move_value.set_text(move)
self.black_cap_value.set_text(str(self.goban.black_captures))
self.white_cap_value.set_text(str(self.goban.white_captures))
@@ -210,10 +227,9 @@ def _build_img_res():
circle_black = _load_png('go_circle_black.png')
circle_white = _load_png('go_circle_white.png')
square = _load_png('go_square.png')
+ bs = _load_png('go_bs.png')
+ ws = _load_png('go_ws.png')
- ret['wH'] = _load_png('go_wH.png')
- ret['bH'] = _load_png('go_bH.png')
-
ret['wT'] = _load_png('go_w.png')
width = ret['wT'].get_width()
height = ret['wT'].get_height()
@@ -236,7 +252,7 @@ def _build_img_res():
ret['d'] = base.copy().rotate_simple(180)
ret['r'] = base.copy().rotate_simple(270)
- for d in ('m', 'h', 'w', 'b'):
+ for d in ('m', 'h', 'w', 'b', 'wH', 'bH', 'ws', 'bs'):
ret[d] = _load_png('go_' + d + '.png')
for d in ('u', 'd', 'l', 'r', 'm', 'dl', 'dr', 'ul', 'ur', 'h', 'w', 'b'):
@@ -260,6 +276,17 @@ def _build_img_res():
height = ret[d + 'S'].get_height()
square.composite(ret[d + 'S'], 0, 0, width, height, 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
+ ret[d + 'ws'] = ret[d].copy()
+ width = ret[d + 'ws'].get_width()
+ height = ret[d + 'ws'].get_height()
+ ws.composite(ret[d + 'ws'], 0, 0, width, height, 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
+
+ ret[d + 'bs'] = ret[d].copy()
+ width = ret[d + 'bs'].get_width()
+ height = ret[d + 'bs'].get_height()
+ bs.composite(ret[d + 'bs'], 0, 0, width, height, 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
+
+
return ret