diff --git a/pygo.py b/pygo.py index 60047ab..ec9b46a 100755 --- a/pygo.py +++ b/pygo.py @@ -7,6 +7,7 @@ import os import pygame from pygame.locals import * + def load_png(name): """ Load image and return image object""" fullname = os.path.join('res', name) @@ -55,6 +56,7 @@ class GobanSquare: self.x, self.y = pos self.state = -1 self.marked = False + self.checked = False # Used for recursive checks if (self.x, self.y) == (1,1): self.default_draw_code = 'ul' @@ -152,6 +154,8 @@ class Goban: if not self._has_liberties(p, who): self.captures[self.turn] += self._delete_group(p) + self._clear_checks() + def _valid_move(self, pos): x, y = pos @@ -166,6 +170,7 @@ class Goban: self.board[x][y].state = self.turn liberties = self._has_liberties(pos, self.turn) + self._clear_checks() opponent = (self.turn + 1) % 2 @@ -174,7 +179,9 @@ class Goban: if not self._has_liberties(d, opponent): kills_group = True break + self._clear_checks() + # Remove temporary stone self.board[x][y].state = -1 return liberties > 0 or kills_group @@ -183,35 +190,26 @@ class Goban: # Recursively find whether there are liberties for the group # at pos. Positive numbers are not necessarily accurate - # treat this as a boolean - # fixme: Apparently there is some case that causes infinite recursion, - # yay! def _has_liberties(self, pos, who, direction = None): x,y = pos if x < 0 or x > 18 or y < 0 or y > 18: return 0 square = self.board[x][y] + + if square.checked: + return 0 + else: + square.checked = True + if square.state == -1: return 1 elif square.state != who: return 0 - elif square.state == who: - to_check = [] - - if direction == None: - to_check = [((x, y+1), 'r'), ((x-1, y), 'u'), ((x+1, y), 'd'), ((x, y-1), 'l')] - if direction == 'r': - to_check = [((x, y+1), 'r'), ((x-1, y), 'u'), ((x+1, y), 'd')] - if direction == 'l': - to_check = [((x, y-1), 'l'), ((x-1, y), 'u'), ((x+1, y), 'd')] - if direction == 'u': - to_check = [((x, y+1), 'r'), ((x-1, y), 'u'), ((x, y-1), 'l')] - if direction == 'd': - to_check = [((x, y+1), 'r'), ((x, y-1), 'l'), ((x+1, y), 'd')] - + else: liberties = 0 - for d, c in to_check: - liberties += self._has_liberties(d, who, c) + for d in [(x, y+1), (x-1, y), (x+1, y), (x, y-1)]: + liberties += self._has_liberties(d, who) return liberties @@ -262,6 +260,12 @@ class Goban: return num_deleted + def _clear_checks(self): + for row in self.board: + for col in row: + col.checked = False + + def draw_board(self, size, img_res): ret = pygame.Surface((size,size))