Continued implementation of functions needed for network play

This commit is contained in:
Anna Rose Wiggins 2012-04-15 20:57:23 -04:00
parent f4680cc631
commit c7947d9790
3 changed files with 96 additions and 26 deletions

View file

@ -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):