Fixed infinite recursion bug

This commit is contained in:
Anna Rose 2012-04-08 23:11:49 -04:00
parent f5d3608ba2
commit cf1b892d21

40
pygo.py
View File

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