Make update code on playing a stone much more efficient
This commit is contained in:
parent
e9032003f7
commit
becf13e4ab
47
lib/goban.py
47
lib/goban.py
|
@ -67,19 +67,33 @@ class Goban:
|
|||
self.hover = None
|
||||
|
||||
|
||||
# For performance reasons (to help with drawing code)
|
||||
# any modified positions are returned in a list.
|
||||
# This is self._changed, which is modified by this
|
||||
# function and by _delete_group_r().
|
||||
# This list will *also* contain the last move and any
|
||||
# previous or new ko positions.
|
||||
def play_move(self, pos, color=None):
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
if self.to_move == Goban.EMPTY:
|
||||
return
|
||||
return None
|
||||
|
||||
rpos = self._real_pos(pos)
|
||||
|
||||
if not self._valid_move(rpos, color):
|
||||
return
|
||||
return None
|
||||
|
||||
self.board[rpos] = color
|
||||
self._changed = []
|
||||
self._changed.append(rpos)
|
||||
|
||||
if self.ko is not None:
|
||||
self._changed.append(self.ko)
|
||||
if self.last_move is not None:
|
||||
self._changed.append(self.last_move)
|
||||
|
||||
self._capture(rpos)
|
||||
self.last_move = rpos
|
||||
self.passed_last = False
|
||||
|
@ -87,6 +101,12 @@ class Goban:
|
|||
self.to_move = self._other_color(color)
|
||||
self.clear_hover()
|
||||
|
||||
# If there is a new ko, send that back too
|
||||
if self.ko is not None:
|
||||
self._changed.append(self.ko)
|
||||
|
||||
return self._changed
|
||||
|
||||
|
||||
|
||||
# fixme: need to handle post-game stuff here... scoring code
|
||||
|
@ -94,6 +114,12 @@ class Goban:
|
|||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
self._changed = []
|
||||
if self.ko is not None:
|
||||
self._changed.append(self.ko)
|
||||
if self.last_move is not None:
|
||||
self._changed.append(self.last_move)
|
||||
|
||||
if self.passed_last:
|
||||
self.to_move = Goban.EMPTY
|
||||
else:
|
||||
|
@ -103,17 +129,27 @@ class Goban:
|
|||
self.last_move = None
|
||||
self.ko = None
|
||||
|
||||
return self._changed
|
||||
|
||||
|
||||
def resign(self, color=None):
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
self._changed = []
|
||||
if self.ko is not None:
|
||||
self._changed.append(self.ko)
|
||||
if self.last_move is not None:
|
||||
self._changed.append(self.last_move)
|
||||
|
||||
self.passed_last = False
|
||||
self.last_move = None
|
||||
self.ko = None
|
||||
self.winner = self._other_color(color)
|
||||
self.to_move = Goban.EMPTY
|
||||
|
||||
return self._changed
|
||||
|
||||
|
||||
def _capture(self, pos, color=None):
|
||||
"""Look for stones captured on the 4 sides of pos, remove them and increment
|
||||
|
@ -232,12 +268,6 @@ class Goban:
|
|||
|
||||
return self._delete_group_r(pos, who)
|
||||
|
||||
if who == Goban.EMPTY:
|
||||
return 0
|
||||
|
||||
self.board[x][y].state = Goban.EMPTY
|
||||
|
||||
|
||||
|
||||
def _delete_group_r(self, pos, who):
|
||||
if not self._on_board(pos):
|
||||
|
@ -247,6 +277,7 @@ class Goban:
|
|||
return 0
|
||||
|
||||
self.board[pos] = Goban.EMPTY
|
||||
self._changed.append(pos)
|
||||
|
||||
num_deleted = 1
|
||||
|
||||
|
|
2
pygo.py
2
pygo.py
|
@ -51,7 +51,7 @@ class Pygo():
|
|||
self.gogame = gogame.GoGame(goban.Goban())
|
||||
self.contents.pack_start(self.gogame)
|
||||
self.gogame.show_all()
|
||||
self.gogame.update()
|
||||
self.gogame.update() # Initial board draw
|
||||
|
||||
|
||||
def on_net_direct(self, widget):
|
||||
|
|
|
@ -108,11 +108,14 @@ class GoGame(gtk.HBox):
|
|||
row = int(y / inc)
|
||||
col = int(x / inc)
|
||||
|
||||
self.goban.play_move((row,col))
|
||||
self.update()
|
||||
changed = self.goban.play_move((row,col))
|
||||
print changed
|
||||
self.update(changed)
|
||||
|
||||
|
||||
def do_board_configure(self, widget, event):
|
||||
print 'configure'
|
||||
|
||||
gc = widget.get_style().fg_gc[gtk.STATE_NORMAL]
|
||||
x,y,width,height = widget.get_allocation()
|
||||
self.board_backbuf = gtk.gdk.Pixmap(widget.window, width, height, depth=-1)
|
||||
|
@ -121,6 +124,8 @@ class GoGame(gtk.HBox):
|
|||
|
||||
|
||||
def do_board_expose(self, widget, event):
|
||||
print 'expose'
|
||||
|
||||
x , y, width, height = event.area
|
||||
widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
|
||||
self.board_backbuf, x, y, x, y, width, height)
|
||||
|
@ -130,7 +135,11 @@ class GoGame(gtk.HBox):
|
|||
# fixme: rendering/updating the whole board is pretty slow. Eliminate the need to
|
||||
# render the whole board when a stone is played (we need a list of modified
|
||||
# locations from somewhere)
|
||||
# fixme: the board doesn't get drawn initially, even though the backbuffer *should*
|
||||
# have the board in it before our first expose event
|
||||
def update_board(self, to_update=None):
|
||||
print 'update'
|
||||
|
||||
if to_update == None:
|
||||
to_update = range(len(self.goban.board))
|
||||
|
||||
|
@ -169,13 +178,13 @@ class GoGame(gtk.HBox):
|
|||
|
||||
|
||||
def on_pass(self, widget):
|
||||
self.goban.pass_move()
|
||||
self.update()
|
||||
changed = self.goban.pass_move()
|
||||
self.update(changed)
|
||||
|
||||
|
||||
def on_resign(self, widget):
|
||||
self.goban.resign()
|
||||
self.update()
|
||||
changed = self.goban.resign()
|
||||
self.update(changed)
|
||||
|
||||
|
||||
# fixme: Add a widget to show the outcome
|
||||
|
@ -191,9 +200,9 @@ class GoGame(gtk.HBox):
|
|||
self.white_cap_value.set_text(str(self.goban.white_captures))
|
||||
|
||||
|
||||
def update(self):
|
||||
def update(self, changed):
|
||||
self.update_info()
|
||||
self.update_board()
|
||||
self.update_board(changed)
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user