Factored the board code into a 'goban' library, and re-implemented it to use simple arrays and to be much, much simpler. Unfortunately, though, it doesn't quite work yet
This commit is contained in:
parent
55dbed09f5
commit
1474af0e5f
273
lib/goban.py
Normal file
273
lib/goban.py
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
import pygame
|
||||||
|
from pygame.locals import *
|
||||||
|
|
||||||
|
|
||||||
|
class Goban:
|
||||||
|
"""Represents the go board. Handles stone placement, captures, etc"""
|
||||||
|
|
||||||
|
# enum values for the board array
|
||||||
|
EMPTY=0
|
||||||
|
WHITE=1
|
||||||
|
BLACK=2
|
||||||
|
# GRAY_WHITE=3
|
||||||
|
# GRAY_BLACK=4
|
||||||
|
|
||||||
|
def __init__(self, board_size=19):
|
||||||
|
# Build the board intersections
|
||||||
|
self.board_size = board_size
|
||||||
|
num_points = board_size * board_size
|
||||||
|
self.board = [Goban.EMPTY] * num_points
|
||||||
|
|
||||||
|
self.def_draw_codes = self._make_default_draw_codes()
|
||||||
|
|
||||||
|
self.to_move = Goban.BLACK
|
||||||
|
self.black_captures = 0
|
||||||
|
self.white_captures = 0
|
||||||
|
self.ko = None
|
||||||
|
self.hover = None
|
||||||
|
self.elapsed_time = 0
|
||||||
|
|
||||||
|
|
||||||
|
def set_hover(self, pos):
|
||||||
|
rpos = self._real_pos(pos)
|
||||||
|
|
||||||
|
if not self._valid_move(rpos):
|
||||||
|
self.clear_hover()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.hover = rpos
|
||||||
|
|
||||||
|
|
||||||
|
def clear_hover(self):
|
||||||
|
self.hover = None
|
||||||
|
|
||||||
|
|
||||||
|
# fixme - somewhere in this or its component functions we need to
|
||||||
|
# identify ko points :)
|
||||||
|
def place_stone(self, pos):
|
||||||
|
rpos = self._real_pos(pos)
|
||||||
|
|
||||||
|
if not self._valid_move(rpos):
|
||||||
|
return
|
||||||
|
|
||||||
|
# fixme - update the GRAY status of affected squares
|
||||||
|
|
||||||
|
self.board[rpos] = self.to_move
|
||||||
|
self._capture(rpos)
|
||||||
|
|
||||||
|
self.to_move = self._other_color(self.to_move)
|
||||||
|
|
||||||
|
|
||||||
|
def _capture(self, pos):
|
||||||
|
"""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."""
|
||||||
|
|
||||||
|
# Who are we capturing
|
||||||
|
who = self._other_color(self.to_move)
|
||||||
|
|
||||||
|
for p in [pos + 1, pos - 1, pos + self.board_size, pos - self.board_size]:
|
||||||
|
if not self._on_board(p):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not self._has_liberties(p, who):
|
||||||
|
if self.to_move == Goban.BLACK:
|
||||||
|
self.black_captures += self._delete_group(p)
|
||||||
|
elif self.to_move == Goban.WHITE:
|
||||||
|
self.white_captures += self._delete_group(p)
|
||||||
|
|
||||||
|
|
||||||
|
def _valid_move(self, pos):
|
||||||
|
if not self._on_board(pos):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Can't play atop another stone
|
||||||
|
if self.board[pos] == Goban.EMPTY:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Temporarily place the stone
|
||||||
|
self.board[pos] = self.to_move
|
||||||
|
|
||||||
|
liberties = self._has_liberties(pos, self.to_move)
|
||||||
|
opponent = self._other_color(self.to_move)
|
||||||
|
|
||||||
|
kills_group = False
|
||||||
|
for d in [pos + 1, pos - 1, pos + self.board_size, pos - self.board_size]:
|
||||||
|
if not self._on_board(d):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self._has_liberties(d, opponent) == 0:
|
||||||
|
kills_group = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# Remove temporary stone
|
||||||
|
self.board[pos] = Goban.EMPTY
|
||||||
|
|
||||||
|
return liberties > 0 or kills_group
|
||||||
|
|
||||||
|
|
||||||
|
# Recursively find whether there are liberties for the group
|
||||||
|
# at pos. Positive numbers are not necessarily accurate -
|
||||||
|
# treat this as a boolean
|
||||||
|
def _has_liberties(self, pos, who, checked=None):
|
||||||
|
if not self._on_board(pos):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if checked is None:
|
||||||
|
bs = board_size * board_size
|
||||||
|
checked = [False] * bs
|
||||||
|
|
||||||
|
if checked[pos]:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
checked[pos] = True
|
||||||
|
|
||||||
|
square = self.board[pos]
|
||||||
|
|
||||||
|
if square == Goban.EMPTY:
|
||||||
|
return 1
|
||||||
|
elif square != who:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
liberties = 0
|
||||||
|
for d in [pos + 1, pos - 1, pos + self.board_size, pos - self.board_size]:
|
||||||
|
liberties += self._has_liberties(d, who, checked)
|
||||||
|
|
||||||
|
return liberties
|
||||||
|
|
||||||
|
|
||||||
|
# We don't need to worry about crossing ourselves with the
|
||||||
|
# recursion here, because we've already deleted the stone.
|
||||||
|
# It would be more efficient to avoid going backwards,
|
||||||
|
# but a lot more complicated (see _has_liberties)
|
||||||
|
def _delete_group(self, pos):
|
||||||
|
if not self._on_board(pos):
|
||||||
|
return
|
||||||
|
|
||||||
|
who = self.board[pos]
|
||||||
|
|
||||||
|
if who == Goban.EMPTY:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return self._delete_group_r(pos, who)
|
||||||
|
|
||||||
|
if who == Goban.EMPTY:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
self.board[x][y].state = Goban.EMPTY
|
||||||
|
|
||||||
|
|
||||||
|
# fixme - needs to be evaluated with new data model
|
||||||
|
def _delete_group_r(self, pos, who):
|
||||||
|
if not self._on_board(pos):
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.board[pos] != who:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
self.board[pos] = Goban.EMPTY
|
||||||
|
|
||||||
|
num_deleted = 1
|
||||||
|
|
||||||
|
num_deleted += self._delete_group_r(pos + 1, who)
|
||||||
|
num_deleted += self._delete_group_r(pos - 1, who)
|
||||||
|
num_deleted += self._delete_group_r(pos + self.board_size, who)
|
||||||
|
num_deleted += self._delete_group_r(pos - self.board_size, who)
|
||||||
|
|
||||||
|
return num_deleted
|
||||||
|
|
||||||
|
|
||||||
|
def draw_board(self, size, img_res):
|
||||||
|
ret = pygame.Surface((size,size))
|
||||||
|
|
||||||
|
inc = size / self.board_size;
|
||||||
|
|
||||||
|
for pos in range(len(self.board)):
|
||||||
|
point = self.board[pos]
|
||||||
|
|
||||||
|
if point == Goban.EMPTY:
|
||||||
|
s = img_res[self.def_draw_codes[pos]]
|
||||||
|
elif point == Goban.BLACK:
|
||||||
|
s = img_res('b')
|
||||||
|
elif point == Goban.WHITE:
|
||||||
|
s = img_res('w')
|
||||||
|
|
||||||
|
s = pygame.transform.scale(s, (inc, inc))
|
||||||
|
ret.blit(s, ((pos % self.board_size) *inc, (pos / self.board_size) *inc))
|
||||||
|
|
||||||
|
if self.hover == point:
|
||||||
|
c = img_res['bH']
|
||||||
|
if self.to_move == Goban.WHITE:
|
||||||
|
c = img_res['wH']
|
||||||
|
c = pygame.transform.scale(c, (inc, inc))
|
||||||
|
ret.blit(c, ((pos % self.board_size) *inc, (pos / self.board_size) *inc))
|
||||||
|
|
||||||
|
return ret.convert_alpha()
|
||||||
|
|
||||||
|
|
||||||
|
def draw_info(self):
|
||||||
|
textbox = pygame.Surface((150, 300))
|
||||||
|
textbox = textbox.convert()
|
||||||
|
textbox.fill((250, 250, 250))
|
||||||
|
|
||||||
|
font = pygame.font.Font(None, 24)
|
||||||
|
time = font.render('Time: {:02d}:{:02d}'.format(self.elapsed_time / 60, self.elapsed_time % 60), 1, (10, 10, 10))
|
||||||
|
heading = font.render('Captures', 1, (10, 10, 10))
|
||||||
|
black_cap = font.render('Black: {}'.format(self.black_captures), 1, (10, 10, 10))
|
||||||
|
white_cap = font.render('White: {}'.format(self.white_captures), 1, (10, 10, 10))
|
||||||
|
if self.to_move == Goban.BLACK:
|
||||||
|
turn = font.render('To move: Black', 1, (10, 10, 10))
|
||||||
|
elif self.to_move == Goban.WHITE:
|
||||||
|
turn = font.render('To move: White', 1, (10, 10, 10))
|
||||||
|
|
||||||
|
textbox.blit(heading, (0, 0))
|
||||||
|
textbox.blit(black_cap, (0, 28))
|
||||||
|
textbox.blit(white_cap, (0, 56))
|
||||||
|
textbox.blit(turn, (0, 100))
|
||||||
|
textbox.blit(time, (0, 150))
|
||||||
|
|
||||||
|
return textbox
|
||||||
|
|
||||||
|
|
||||||
|
def _make_default_draw_codes(self):
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
for pos in range(len(self.board)):
|
||||||
|
if pos == 0:
|
||||||
|
ret.append('ul')
|
||||||
|
elif pos == self.board_size - 1:
|
||||||
|
ret.append('ur')
|
||||||
|
elif pos == self.board_size * self.board_size - 19:
|
||||||
|
ret.append('dl')
|
||||||
|
elif pos == self.board_size * self.board_size - 1:
|
||||||
|
ret.append('dr')
|
||||||
|
elif pos in [60, 66, 72, 174, 180, 186, 288, 294, 300]:
|
||||||
|
ret.append('h')
|
||||||
|
elif pos < self.board_size - 1:
|
||||||
|
ret.append('u')
|
||||||
|
elif pos % self.board_size == 0:
|
||||||
|
ret.append('l')
|
||||||
|
elif pos > (self.board_size * self.board_size - 20):
|
||||||
|
ret.append('d')
|
||||||
|
elif pos % self.board_size == 18:
|
||||||
|
ret.append('r')
|
||||||
|
else:
|
||||||
|
ret.append('m')
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _real_pos(self, pos):
|
||||||
|
x,y = pos
|
||||||
|
return x * self.board_size + y
|
||||||
|
|
||||||
|
|
||||||
|
def _on_board(self, pos):
|
||||||
|
return pos < 0 or pos > self.board_size * self.board_size - 1
|
||||||
|
|
||||||
|
|
||||||
|
def _other_color(self, color):
|
||||||
|
if color == Goban.BLACK:
|
||||||
|
return Goban.WHITE
|
||||||
|
elif color == Goban.WHITE:
|
||||||
|
return Goban.BLACK
|
307
pygo.py
307
pygo.py
|
@ -3,9 +3,13 @@
|
||||||
#
|
#
|
||||||
# A GTK Python GO client
|
# A GTK Python GO client
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append('lib/')
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pygame
|
import pygame
|
||||||
from pygame.locals import *
|
from pygame.locals import *
|
||||||
|
import goban
|
||||||
|
|
||||||
|
|
||||||
def load_png(name, alpha=None):
|
def load_png(name, alpha=None):
|
||||||
|
@ -54,288 +58,6 @@ def build_img_res():
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class GobanSquare:
|
|
||||||
"""A single square on the go board"""
|
|
||||||
|
|
||||||
def __init__(self, pos):
|
|
||||||
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'
|
|
||||||
elif (self.x, self.y) == (1,19):
|
|
||||||
self.default_draw_code = 'ur'
|
|
||||||
elif (self.x, self.y) == (19,1):
|
|
||||||
self.default_draw_code = 'dl'
|
|
||||||
elif (self.x, self.y) == (19,19):
|
|
||||||
self.default_draw_code = 'dr'
|
|
||||||
elif (self.x, self.y) in [(4,4), (4,10), (4,16), (10,4), (10,10), (10,16), (16,4), (16,10), (16,16)]:
|
|
||||||
self.default_draw_code = 'h'
|
|
||||||
elif self.x == 1:
|
|
||||||
self.default_draw_code = 'u'
|
|
||||||
elif self.y == 1:
|
|
||||||
self.default_draw_code = 'l'
|
|
||||||
elif self.x == 19:
|
|
||||||
self.default_draw_code = 'd'
|
|
||||||
elif self.y == 19:
|
|
||||||
self.default_draw_code = 'r'
|
|
||||||
else:
|
|
||||||
self.default_draw_code = 'm'
|
|
||||||
|
|
||||||
|
|
||||||
def toggle_marked(self):
|
|
||||||
if self.marked:
|
|
||||||
self.marked = False
|
|
||||||
else:
|
|
||||||
self.marked = True
|
|
||||||
|
|
||||||
|
|
||||||
def get_draw_code(self):
|
|
||||||
ret = None
|
|
||||||
|
|
||||||
if self.state == -1:
|
|
||||||
ret = self.default_draw_code
|
|
||||||
elif self.state == 0:
|
|
||||||
ret = 'b'
|
|
||||||
elif self.state == 1:
|
|
||||||
ret = 'w'
|
|
||||||
|
|
||||||
if self.marked:
|
|
||||||
if self.state >=0:
|
|
||||||
ret = self.default_draw_code + 'T'
|
|
||||||
else:
|
|
||||||
ret = self.default_draw_code + 'C'
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Goban:
|
|
||||||
"""Represents the go board. Handles stone placement, captures, etc"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
# Build the 361 board intersections
|
|
||||||
self.board = []
|
|
||||||
for i in range(19):
|
|
||||||
self.board.append([])
|
|
||||||
for j in range(19):
|
|
||||||
self.board[i].append(GobanSquare((i+1, j+1)))
|
|
||||||
|
|
||||||
self.turn = 0
|
|
||||||
self.captures = []
|
|
||||||
self.captures.append(0)
|
|
||||||
self.captures.append(0)
|
|
||||||
self.hover = None
|
|
||||||
self.elapsed_time = 0
|
|
||||||
|
|
||||||
|
|
||||||
def set_hover(self, pos):
|
|
||||||
if not self._valid_move(pos):
|
|
||||||
self.clear_hover()
|
|
||||||
return
|
|
||||||
|
|
||||||
x,y = pos
|
|
||||||
self.hover = self.board[x][y]
|
|
||||||
|
|
||||||
|
|
||||||
def clear_hover(self):
|
|
||||||
self.hover = None
|
|
||||||
|
|
||||||
|
|
||||||
def place_stone(self, pos):
|
|
||||||
if not self._valid_move(pos):
|
|
||||||
return
|
|
||||||
|
|
||||||
x, y = pos
|
|
||||||
self.board[x][y].state = self.turn
|
|
||||||
self._capture(pos)
|
|
||||||
self.turn = (self.turn + 1) % 2
|
|
||||||
|
|
||||||
|
|
||||||
def toggle_marked(self, pos):
|
|
||||||
x,y = pos
|
|
||||||
if x < 0 or x > 18 or y < 0 or y > 18:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.board[x][y].toggle_marked()
|
|
||||||
|
|
||||||
|
|
||||||
def _capture(self, pos):
|
|
||||||
x, y = pos
|
|
||||||
who = (self.turn + 1) % 2
|
|
||||||
|
|
||||||
for p in [(x, y+1), (x, y-1), (x+1, y), (x-1, y)]:
|
|
||||||
newx, newy = p
|
|
||||||
if newx < 0 or newx > 18 or newy < 0 or newy > 18 or self.board[newx][newy].state == self.turn:
|
|
||||||
continue
|
|
||||||
|
|
||||||
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
|
|
||||||
if x < 0 or x > 18 or y < 0 or y > 18:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Can't play atop another stone
|
|
||||||
if self.board[x][y].state != -1:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Temporarily place the stone
|
|
||||||
self.board[x][y].state = self.turn
|
|
||||||
|
|
||||||
liberties = self._has_liberties(pos, self.turn)
|
|
||||||
self._clear_checks()
|
|
||||||
|
|
||||||
opponent = (self.turn + 1) % 2
|
|
||||||
|
|
||||||
kills_group = False
|
|
||||||
for d in [(x, y+1), (x, y-1), (x+1, y), (x-1, y)]:
|
|
||||||
new_x, new_y = d
|
|
||||||
if new_x < 0 or new_x > 18 or new_y < 0 or new_y > 18:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if self._has_liberties(d, opponent) == 0:
|
|
||||||
kills_group = True
|
|
||||||
break
|
|
||||||
self._clear_checks()
|
|
||||||
|
|
||||||
# Remove temporary stone
|
|
||||||
self.board[x][y].state = -1
|
|
||||||
|
|
||||||
return liberties > 0 or kills_group
|
|
||||||
|
|
||||||
|
|
||||||
# Recursively find whether there are liberties for the group
|
|
||||||
# at pos. Positive numbers are not necessarily accurate -
|
|
||||||
# treat this as a boolean
|
|
||||||
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
|
|
||||||
else:
|
|
||||||
liberties = 0
|
|
||||||
for d in [(x, y+1), (x-1, y), (x+1, y), (x, y-1)]:
|
|
||||||
liberties += self._has_liberties(d, who)
|
|
||||||
|
|
||||||
return liberties
|
|
||||||
|
|
||||||
|
|
||||||
# We don't need to worry about crossing ourselves with the
|
|
||||||
# recursion here, because we've already deleted the stone.
|
|
||||||
# It would be more efficient to avoid going backwards,
|
|
||||||
# but a lot more complicated (see _has_liberties)
|
|
||||||
def _delete_group(self, pos):
|
|
||||||
x,y = pos
|
|
||||||
if x < 0 or x > 18 or y < 0 or y > 18:
|
|
||||||
return
|
|
||||||
|
|
||||||
who = self.board[x][y].state
|
|
||||||
|
|
||||||
if who == -1:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.board[x][y].state = -1
|
|
||||||
|
|
||||||
num_deleted = 1
|
|
||||||
|
|
||||||
num_deleted += self._delete_group_r((x, y+1), who)
|
|
||||||
num_deleted += self._delete_group_r((x, y-1), who)
|
|
||||||
num_deleted += self._delete_group_r((x+1, y), who)
|
|
||||||
num_deleted += self._delete_group_r((x-1, y), who)
|
|
||||||
|
|
||||||
return num_deleted
|
|
||||||
|
|
||||||
|
|
||||||
def _delete_group_r(self, pos, who):
|
|
||||||
x,y = pos
|
|
||||||
if x < 0 or x > 18 or y < 0 or y > 18:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if self.board[x][y].state != who:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
self.board[x][y].state = -1
|
|
||||||
|
|
||||||
num_deleted = 1
|
|
||||||
|
|
||||||
num_deleted += self._delete_group_r((x, y+1), who)
|
|
||||||
num_deleted += self._delete_group_r((x, y-1), who)
|
|
||||||
num_deleted += self._delete_group_r((x+1, y), who)
|
|
||||||
num_deleted += self._delete_group_r((x-1, y), who)
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
inc = size / 19;
|
|
||||||
i = 0
|
|
||||||
for row in self.board:
|
|
||||||
j = 0
|
|
||||||
for square in row:
|
|
||||||
s = img_res[square.get_draw_code()]
|
|
||||||
s = pygame.transform.scale(s, (inc, inc))
|
|
||||||
ret.blit(s, (j*inc,i*inc))
|
|
||||||
|
|
||||||
if self.hover == square:
|
|
||||||
c = img_res['bH']
|
|
||||||
if self.turn == 1:
|
|
||||||
c = img_res['wH']
|
|
||||||
c = pygame.transform.scale(c, (inc, inc))
|
|
||||||
ret.blit(c, (j*inc,i*inc))
|
|
||||||
|
|
||||||
j += 1
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
return ret.convert_alpha()
|
|
||||||
|
|
||||||
|
|
||||||
def draw_info(self):
|
|
||||||
textbox = pygame.Surface((150, 300))
|
|
||||||
textbox = textbox.convert()
|
|
||||||
textbox.fill((250, 250, 250))
|
|
||||||
|
|
||||||
font = pygame.font.Font(None, 24)
|
|
||||||
time = font.render('Time: {:02d}:{:02d}'.format(self.elapsed_time / 60, self.elapsed_time % 60), 1, (10, 10, 10))
|
|
||||||
heading = font.render('Captures', 1, (10, 10, 10))
|
|
||||||
black_cap = font.render('Black: {}'.format(self.captures[0]), 1, (10, 10, 10))
|
|
||||||
white_cap = font.render('White: {}'.format(self.captures[1]), 1, (10, 10, 10))
|
|
||||||
turn = font.render('Turn: {}'.format(['Black', 'White'][self.turn]), 1, (10, 10, 10))
|
|
||||||
|
|
||||||
textbox.blit(heading, (0, 0))
|
|
||||||
textbox.blit(black_cap, (0, 28))
|
|
||||||
textbox.blit(white_cap, (0, 56))
|
|
||||||
textbox.blit(turn, (0, 100))
|
|
||||||
textbox.blit(time, (0, 150))
|
|
||||||
|
|
||||||
return textbox
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Basic screen init
|
# Basic screen init
|
||||||
|
@ -354,12 +76,12 @@ def main():
|
||||||
board_size = 800
|
board_size = 800
|
||||||
board_inc = board_size / 19
|
board_inc = board_size / 19
|
||||||
|
|
||||||
goban = Goban()
|
gb = goban.Goban()
|
||||||
|
|
||||||
board = goban.draw_board(board_size, img_res)
|
board = gb.draw_board(board_size, img_res)
|
||||||
background.blit(board, (0,0))
|
background.blit(board, (0,0))
|
||||||
|
|
||||||
text = goban.draw_info()
|
text = gb.draw_info()
|
||||||
background.blit(text, (815, 25))
|
background.blit(text, (815, 25))
|
||||||
|
|
||||||
screen.blit(background, (0, 0))
|
screen.blit(background, (0, 0))
|
||||||
|
@ -381,9 +103,9 @@ def main():
|
||||||
col = x / board_inc
|
col = x / board_inc
|
||||||
|
|
||||||
if x <= board_size:
|
if x <= board_size:
|
||||||
goban.set_hover((row,col))
|
gb.set_hover((row,col))
|
||||||
else:
|
else:
|
||||||
goban.clear_hover()
|
gb.clear_hover()
|
||||||
|
|
||||||
# Place a stone on left-click
|
# Place a stone on left-click
|
||||||
if event.type == MOUSEBUTTONDOWN:
|
if event.type == MOUSEBUTTONDOWN:
|
||||||
|
@ -393,18 +115,15 @@ def main():
|
||||||
|
|
||||||
if x <= board_size:
|
if x <= board_size:
|
||||||
if event.button == 1:
|
if event.button == 1:
|
||||||
goban.place_stone((row, col))
|
gb.place_stone((row, col))
|
||||||
|
|
||||||
if event.button == 3:
|
|
||||||
goban.toggle_marked((row, col))
|
|
||||||
|
|
||||||
if event.type == USEREVENT:
|
if event.type == USEREVENT:
|
||||||
goban.elapsed_time += 1
|
gb.elapsed_time += 1
|
||||||
|
|
||||||
board = goban.draw_board(board_size, img_res)
|
board = gb.draw_board(board_size, img_res)
|
||||||
background.blit(board, (0,0))
|
background.blit(board, (0,0))
|
||||||
|
|
||||||
text = goban.draw_info()
|
text = gb.draw_info()
|
||||||
background.blit(text, (815, 25))
|
background.blit(text, (815, 25))
|
||||||
|
|
||||||
screen.blit(background, (0, 0))
|
screen.blit(background, (0, 0))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user