Fixed infinite recursion bug
This commit is contained in:
parent
f5d3608ba2
commit
cf1b892d21
40
pygo.py
40
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))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user