Continued implementation of functions needed for network play
This commit is contained in:
parent
f4680cc631
commit
c7947d9790
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):
|
||||
|
|
|
@ -26,11 +26,14 @@ class NetworkThread(threading.Thread):
|
|||
self.socket = GTPSocket(socket)
|
||||
self.send_lock = threading.Lock()
|
||||
|
||||
GTPSocket.known_cmds = GTPSocket.known_cmds & set(dispatcher.keys())
|
||||
GTPSocket.known_cmds = GTPSocket.known_cmds & set(NetworkThread.dispatcher.keys())
|
||||
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
while True:
|
||||
gtp = self.socket.get()
|
||||
if gtp is not None:
|
||||
NetworkThread.dispatcher[gtp.command](gtp)
|
||||
|
||||
|
||||
def do_quit(self, gtp):
|
||||
|
@ -38,19 +41,31 @@ class NetworkThread(threading.Thread):
|
|||
|
||||
|
||||
def do_boardsize(self, gtp):
|
||||
pass
|
||||
with self.goban_lock:
|
||||
self.goban.set_board_size(int(gtp.arguments[0]))
|
||||
|
||||
|
||||
def do_clear_board(self, gtp):
|
||||
pass
|
||||
with self.goban_lock:
|
||||
self.goban.reset()
|
||||
|
||||
|
||||
def do_komi(self, gtp):
|
||||
pass
|
||||
with self.goban_lock:
|
||||
self.goban.komi = float(gtp.arguments[0])
|
||||
|
||||
|
||||
def do_play(self, gtp):
|
||||
pass
|
||||
if gtp.arguments[0] == 'black':
|
||||
color = goban.Goban.BLACK
|
||||
elif gtp.arguments[0] == 'white':
|
||||
color = goban.Goban.WHITE
|
||||
|
||||
row = int(gtp.arguments[1][1:])
|
||||
col = ord(gtp.arguments[1][0]) - 96
|
||||
|
||||
with self.goban_lock:
|
||||
self.goban.play_move((row,col), color)
|
||||
|
||||
|
||||
def do_genmove(self, gtp):
|
||||
|
|
|
@ -6,7 +6,7 @@ import pygame
|
|||
from pygame.locals import *
|
||||
import sgc
|
||||
from sgc.locals import *
|
||||
|
||||
import socket
|
||||
|
||||
|
||||
class GUI:
|
||||
|
@ -63,9 +63,12 @@ class GUI:
|
|||
self.quit_btn.activate = sys.exit
|
||||
self.quit_btn.add()
|
||||
|
||||
# self.waiting
|
||||
self.wait_dialog = sgc.widgets.Dialog(title="Please wait...", widget=sgc.widgets.Label(text='Waiting for a connection'))
|
||||
self.wait_dialog.rect.center = self.screen.rect.center
|
||||
|
||||
# pygame.time.set_timer(USEREVENT, 1000)
|
||||
# Generate a spurious event once a second, just to
|
||||
# force an update
|
||||
pygame.time.set_timer(USEREVENT, 1000)
|
||||
|
||||
|
||||
def do_event(self):
|
||||
|
@ -141,7 +144,20 @@ class GUI:
|
|||
|
||||
# fixme: this uses localhost as a stub
|
||||
def wait_for_game(self):
|
||||
pass
|
||||
self.wait_dialog.add()
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.bind(("127.0.0.1", 6859))
|
||||
sock.listen(1)
|
||||
conn, addr = sock.accept()
|
||||
sock.close()
|
||||
|
||||
self.socket = gtpsocket.GTPSocket(conn)
|
||||
self.net_thread = networkthread.NetworkThread(self.goban, conn)
|
||||
self.net_thread.start()
|
||||
self.network_mode = True
|
||||
|
||||
self.wait_dialog.remove()
|
||||
|
||||
|
||||
def do_hover(self, event):
|
||||
|
|
Loading…
Reference in New Issue
Block a user