Continued implementation of functions needed for network play
This commit is contained in:
parent
f4680cc631
commit
c7947d9790
3 changed files with 96 additions and 26 deletions
71
lib/goban.py
71
lib/goban.py
|
@ -43,11 +43,38 @@ class Goban:
|
|||
self.hover = rpos
|
||||
|
||||
|
||||
def reset(self):
|
||||
"""Reset the board to a pre-game state"""
|
||||
# Clear the board by setting it to the same size it currently is at
|
||||
self.set_board_size(self.board_size)
|
||||
self.to_move = Goban.BLACK
|
||||
self.black_captures = 0
|
||||
self.white_captures = 0
|
||||
self.last_move = None
|
||||
self.passed_last = False
|
||||
self.ko = None
|
||||
self.hover = None
|
||||
self.elapsed_time = 0
|
||||
self.winner = Goban.EMPTY
|
||||
|
||||
|
||||
def set_board_size(self, new_size):
|
||||
"""Set the board to a new size. This will also
|
||||
reset the board to a blank state, but will *not* reset captures, etc
|
||||
(call reset() first if you want that)"""
|
||||
self.board_size = new_size
|
||||
num_points = board_size * board_size
|
||||
self.board = [Goban.EMPTY] * num_points
|
||||
|
||||
|
||||
def clear_hover(self):
|
||||
self.hover = None
|
||||
|
||||
|
||||
def play_move(self, pos):
|
||||
def play_move(self, pos, color=None):
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
if self.to_move == Goban.EMPTY:
|
||||
return
|
||||
|
||||
|
@ -56,46 +83,55 @@ class Goban:
|
|||
if not self._valid_move(rpos):
|
||||
return
|
||||
|
||||
self.board[rpos] = self.to_move
|
||||
self.board[rpos] = color
|
||||
self._capture(rpos)
|
||||
self.last_move = rpos
|
||||
self.passed_last = False
|
||||
|
||||
self.to_move = self._other_color(self.to_move)
|
||||
self.to_move = self._other_color(color)
|
||||
self.clear_hover()
|
||||
|
||||
|
||||
|
||||
# fixme: need to handle post-game stuff here... scoring code
|
||||
def pass_move(self):
|
||||
def pass_move(self, color=None):
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
if self.passed_last:
|
||||
self.to_move = Goban.EMPTY
|
||||
else:
|
||||
self.to_move = self._other_color(self.to_move)
|
||||
self.to_move = self._other_color(color)
|
||||
self.passed_last = True
|
||||
|
||||
self.last_move = None
|
||||
self.ko = None
|
||||
|
||||
|
||||
def resign(self):
|
||||
def resign(self, color=None):
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
self.passed_last = False
|
||||
self.last_move = None
|
||||
self.ko = None
|
||||
self.winner = self._other_color(self.to_move)
|
||||
self.winner = self._other_color(color)
|
||||
self.to_move = Goban.EMPTY
|
||||
|
||||
|
||||
def _capture(self, pos):
|
||||
def _capture(self, pos, color=None):
|
||||
"""Look for stones captured on the 4 sides of pos, remove them and increment
|
||||
capture counter. This pos must be a *real* position value, not an x,y tuple."""
|
||||
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
# If we get here, we've definitely played a move,
|
||||
# clearing any existing ko point
|
||||
self.ko = None
|
||||
|
||||
# Who are we capturing
|
||||
who = self._other_color(self.to_move)
|
||||
who = self._other_color(color)
|
||||
|
||||
captures = 0
|
||||
|
||||
|
@ -106,13 +142,13 @@ class Goban:
|
|||
if not self._num_liberties(p, who):
|
||||
captures += self._delete_group(p)
|
||||
|
||||
if self.to_move == Goban.BLACK:
|
||||
if color == Goban.BLACK:
|
||||
self.black_captures += captures
|
||||
elif self.to_move == Goban.WHITE:
|
||||
elif color == Goban.WHITE:
|
||||
self.white_captures += captures
|
||||
|
||||
# Check for ko
|
||||
if captures == 1 and self._num_liberties(pos, self.to_move):
|
||||
if captures == 1 and self._num_liberties(pos, color):
|
||||
# find the empty point
|
||||
for p in self._neighbors(pos):
|
||||
if self.board[p] == Goban.EMPTY:
|
||||
|
@ -121,19 +157,22 @@ class Goban:
|
|||
|
||||
|
||||
|
||||
def _valid_move(self, pos):
|
||||
def _valid_move(self, pos, color=None):
|
||||
if not self._on_board(pos):
|
||||
return False
|
||||
|
||||
if color is None:
|
||||
color = self.to_move
|
||||
|
||||
# Can't play atop another stone or on the ko point
|
||||
if self.board[pos] != Goban.EMPTY or pos == self.ko:
|
||||
return False
|
||||
|
||||
# Temporarily place the stone
|
||||
self.board[pos] = self.to_move
|
||||
self.board[pos] = color
|
||||
|
||||
liberties = self._num_liberties(pos, self.to_move)
|
||||
opponent = self._other_color(self.to_move)
|
||||
liberties = self._num_liberties(pos, color)
|
||||
opponent = self._other_color(color)
|
||||
|
||||
kills_group = False
|
||||
for d in self._neighbors(pos):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue