Tianshou/GTP/game.py

155 lines
4.1 KiB
Python
Raw Normal View History

2017-11-20 12:44:29 +08:00
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
# $File: game.py
2017-11-28 01:15:46 +08:00
# $Date: Tue Nov 28 01:1540 2017 +0800
2017-11-20 12:44:29 +08:00
# $Author: renyong15 © <mails.tsinghua.edu.cn>
#
import utils
2017-11-28 01:15:46 +08:00
import copy
'''
(1, 1) is considered as the upper left corner of the board,
(size, 1) is the lower left
'''
DELTA = [[1,0], [-1,0], [0, -1], [0, 1]]
class Executor:
def __init__(self, **kwargs):
self.game = kwargs['game']
def _bfs(self, vertex, color, block, status, alive_break):
block.append(vertex)
status[self.game._flatten(vertex)] = True
nei = self._neighbor(vertex)
for n in nei:
if not status[self.game._flatten(n)]:
if self.game.board[self.game._flatten(n)] == color:
self._bfs(n, color, block, status, alive_break)
def _find_block(self, vertex, alive_break = False):
block = []
status = [False] * (self.game.size * self.game.size)
color = self.game.board[self.game._flatten(vertex)]
self._bfs(vertex, color, block, status, alive_break)
for b in block:
for n in self._neighbor(b):
if self.game.board[self.game._flatten(n)] == utils.EMPTY:
return False,block
return True,block
def _check_qi(self, vertex):
pass
def _in_board(self, vertex):
x, y = vertex
if x < 1 or x > self.game.size: return False
if y < 1 or y > self.game.size: return False
return True
def _neighbor(self, vertex):
x,y = vertex
nei = []
for d in DELTA:
_x = x + d[0]
_y = y + d[1]
if self._in_board((_x, _y)):
nei.append((_x, _y))
return nei
def _process_board(self, color, vertex):
nei = self._neighbor(vertex)
for n in nei:
if self.game.board[self.game._flatten(n)] == utils.another_color(color):
can_kill, block = self._find_block(n, alive_break = True)
if can_kill:
for b in block:
self.game.board[self.game._flatten(b)] = utils.EMPTY
def is_valid(self, color, vertex):
if not self._in_board(vertex):
return False
return True
def do_move(self, color, vertex):
if not self.is_valid(color, vertex):
return False
self.game.history.append(copy.copy(self.game.board))
self.game.board[self.game._flatten(vertex)] = color
self._process_board(color,vertex)
return True
2017-11-20 12:44:29 +08:00
class Game:
def __init__(self, size=19, komi=6.5):
self.size = size
self.komi = 6.5
self.board = [utils.EMPTY] * (self.size * self.size)
self.strategy = None
2017-11-28 01:15:46 +08:00
self.executor = Executor(game = self)
self.history = []
2017-11-20 12:44:29 +08:00
def _flatten(self, vertex):
x,y = vertex
2017-11-28 01:15:46 +08:00
return (y - 1) * self.size + (x-1)
2017-11-20 12:44:29 +08:00
def clear(self):
self.board = [utils.EMPTY] * (self.size * self.size)
def set_size(self, n):
self.size = n
self.clear()
def set_komi(self, k):
self.komi = k
2017-11-28 01:15:46 +08:00
def check_valid(self, vertex):
return True
2017-11-20 12:44:29 +08:00
def do_move(self, color, vertex):
if vertex == utils.PASS:
return True
2017-11-28 01:15:46 +08:00
res = self.executor.do_move(color, vertex)
return res
2017-11-20 12:44:29 +08:00
def gen_move(self, color):
2017-11-28 01:15:46 +08:00
#move = self.strategy.gen_move(color)
#return move
return utils.PASS
def status2symbol(self, s):
pool = { utils.WHITE:'#', utils.EMPTY:'.', utils.BLACK:'*', utils.FILL:'F', utils.UNKNOWN:'?'}
return pool[s]
def show_board(self):
row = [i for i in range(1, 20)]
col = ' abcdefghijklmnopqrstuvwxyz'
for i in range(self.size):
print(row[i], end = ' ')
if row[i] < 10:
print(' ', end = '')
for j in range(self.size):
print(self.status2symbol(self.board[self._flatten((j+1,i+1))]), end=' ')
print('\n')
print(' ', end = '')
for j in range(self.size + 1):
print(col[j], end = ' ')
print('\n')
2017-11-20 12:44:29 +08:00