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
|
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))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user