From c8361dee621ec1b3c236b5ba1f5f7b93fc9fd5b9 Mon Sep 17 00:00:00 2001 From: Andrés Ambrois Date: Mon, 21 Jul 2008 21:27:55 +0000 Subject: Fixes and additions: Scorekeeping, basic Ko, Illegal moves, messages --- diff --git a/boardwidget.py b/boardwidget.py index 95e19fd..4ea9cdd 100755 --- a/boardwidget.py +++ b/boardwidget.py @@ -99,8 +99,13 @@ class BoardWidget(gtk.EventBox): assert y < self.myBoard.size self.myBoard.setPointi( x, y, color ) + self.update_score(self.myBoard.score) return None - + + def update_score(self, score): + if score == 0: + return 0 + self.activity.info_panel.show_score(_("Score is: Whites %(W)d - Blacks %(B)d" % score)) # def remove(self, column, value): # """Return: @@ -215,14 +220,20 @@ class BoardWidget(gtk.EventBox): boolean check if the stone play is legal """ if self.myBoard.status.has_key( (x,y) ) : + self.activity.info_panel.show(_("There already is a stone there!")) return False c = 'W' if self.lastColor is 1 : c = 'B' -# if not self.myBoard.legal( (x,y), c ) : -# return False + if not self.myBoard.legal( (x,y), c ) : + self.activity.info_panel.show(_("Illegal move")) + return False + + if self.myBoard.checkKo( (x, y), c): + self.activity.info_panel.show(_("Ko violation!")) + return False logger.debug( " returning legal ") return True diff --git a/game.py b/game.py index 89a68ca..804fe03 100755 --- a/game.py +++ b/game.py @@ -52,8 +52,12 @@ class abstractBoard: self.status = {} self.undostack = [] self.boardSize = boardSize + self.score = {'B' : 0, 'W' : 0} _logger.setLevel( logging.DEBUG ) - _logger.debug( "init baord size %d", boardSize ) + _logger.debug( "init board size %d", boardSize ) + + def increase_score(self, color): + self.score[color] = self.score[color] + 1 def neighbors(self,x): """ Returns the coordinates of the 4 (resp. 3 resp. 2 at the side 1 in the corner) intersections @@ -81,39 +85,69 @@ class abstractBoard: """ This plays a color=black/white stone at pos, if that is a legal move (disregarding ko), and deletes stones captured by that move. It returns 1 if the move has been played, 0 if not. """ - if self.status.has_key(pos): # check if empty return 0 - l = self.legal(pos,color) - if l: # legal move? - captures = l[1] - for x in captures: del self.status[x] # remove captured stones, if any + if self.legal(pos,color): # legal move? + self.status[pos] = color + captures = self.get_captures(pos, color) + if captures: + for x in captures: + del self.status[x] # remove captured stones, if any + self.increase_score(self.invert(color)) self.undostack.append((pos,color,captures)) # remember move + captured stones for easy undo - return 1 - else: return 0 - - def legal(self, pos, color): - """ Check if a play by color at pos would be a legal move. """ + return self.score + else: + return 0 + + def get_captures(self, pos, color): + """Returns a list of captured stones resulting from placing a color stone at pos """ c = [] # captured stones + for x in self.neighbors(pos): if self.status.has_key(x) and self.status[x]==self.invert(color): - c = c + self.hasNoLibExcP(x, pos) - - self.status[pos]=color - + c = c + self.hasNoLibExcP(x, self.invert(color), pos) + if c: captures = [] for x in c: if not x in captures: captures.append(x) - return (1, captures) - - if self.hasNoLibExcP(pos): - del self.status[pos] + return captures + + return 0 + + def checkKo(self, pos, color): + ''' + Check if a move by color at pos would be a basic Ko infraction + ''' + # Basically what we need to check, is if the current play would undo + # all that was done by the last entry in undostack (capture what was placed + # and place what was captured). + if self.undostack: + lastpos, lastcolor, lastcaptures = self.undostack[-1] + currentcaptures = self.get_captures(pos, color) + if lastcaptures != 0 and currentcaptures != 0: + if lastcolor != color and lastcaptures[0] == pos and lastpos == currentcaptures[0]: + return 1 + return 0 + + def legal(self, pos, color): + """ Check if a play by color at pos would be a legal move. """ + if self.status.has_key(pos): + return 0 + + # If the play at pos would leave that stone without liberties, we have two possibilities: + # 1- It's a capturing move + # 2- It's an illegal move + if self.hasNoLibExcP(pos, color): + # Check if it would capture any stones + if self.get_captures(pos, color): + return 1 + # It didnt, so I guess it's illegal return 0 - else: return (1, []) + else: return 1 - def hasNoLibExcP(self, pos, exc = None): + def hasNoLibExcP(self, pos, color, exc = None): """ This function checks if the string (=solidly connected) of stones containing the stone at pos has a liberty (resp. has a liberty besides that at exc). If no liberties are found, a list of all stones in the string is returned. @@ -136,10 +170,10 @@ class abstractBoard: n = [] # this will contain the stones found in this iteration of the loop for x in newlyFound: for y in self.neighbors(x): - if not self.status.has_key(y) and y != exc: # found a liberty + if not self.status.has_key(y) and y != exc and y != pos: # found a liberty return [] - elif self.status.has_key(y) and self.status[y]==self.status[x] \ - and not y in st and not y in newlyFound: # found another stone of same color + elif self.status.has_key(y) and self.status[y]==color \ + and not y in newlyFound and not y in st: # found another stone of same color n.append(y) foundNew = 1 @@ -190,6 +224,7 @@ class GoGame(ExportedGObject): self.is_initiator = is_initiator self.entered = False self.player_id = None + self.active_player = 1 self.buddies_panel = buddies_panel self.info_panel = info_panel self.owner = owner @@ -315,7 +350,7 @@ class GoGame(ExportedGObject): self.change_turn() def insert_cb(self, column, sender=None): - # Someone placed a stone + # Someone placed a stone handle = self.tube.bus_name_to_handle[sender] _logger.debug('Insert(%d) from %s', column, sender) diff --git a/infopanel.py b/infopanel.py index 8bb3718..9e7e16d 100755 --- a/infopanel.py +++ b/infopanel.py @@ -9,6 +9,9 @@ class InfoPanel(hippo.CanvasBox): self.status_box = hippo.CanvasBox(spacing=4, padding=5, orientation=hippo.ORIENTATION_VERTICAL) self.append(self.status_box) + self.score_box = hippo.CanvasBox(spacing=4, padding=5, + orientation=hippo.ORIENTATION_VERTICAL) + self.append(self.score_box) def show(self, text): textwidget = hippo.CanvasText(text=text, @@ -17,4 +20,12 @@ class InfoPanel(hippo.CanvasBox): xalign=hippo.ALIGNMENT_CENTER) self.status_box.remove_all() self.status_box.append(textwidget) + + def show_score(self, text): + textwidget = hippo.CanvasText(text=text, + font_desc=pango.FontDescription('Sans 10'), + color=style.COLOR_WHITE.get_int(), + xalign=hippo.ALIGNMENT_CENTER) + self.score_box.remove_all() + self.score_box.append(textwidget) -- cgit v0.9.1