diff --git a/GTP/.game.py.swp b/GTP/.game.py.swp index ab62fba..4ad0ba6 100644 Binary files a/GTP/.game.py.swp and b/GTP/.game.py.swp differ diff --git a/GTP/.test.py.swp b/GTP/.test.py.swp index 282433b..71ca4b4 100644 Binary files a/GTP/.test.py.swp and b/GTP/.test.py.swp differ diff --git a/GTP/.utils.py.swp b/GTP/.utils.py.swp deleted file mode 100644 index 10f4201..0000000 Binary files a/GTP/.utils.py.swp and /dev/null differ diff --git a/GTP/engine.py b/GTP/engine.py index d153772..cf729b0 100644 --- a/GTP/engine.py +++ b/GTP/engine.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # vim:fenc=utf-8 # $File: engine.py -# $Date: Fri Nov 17 13:5624 2017 +0800 +# $Date: Tue Nov 28 00:0616 2017 +0800 # $Author: renyong15 © # @@ -40,7 +40,7 @@ class GTPEngine(): return "resign" else: x, y = vertex - return "{}{}".format("ABCDEFGHJKLMNOPQRSTYVWYZ"[x - 1], y) + return "{}{}".format("ABCDEFGHIJKLMNOPQRSTYVWYZ"[x - 1], y) @@ -51,7 +51,7 @@ class GTPEngine(): elif s.lower() == "pass": return utils.PASS elif len(s) > 1: - x = "abcdefghjklmnopqrstuvwxyz".find(s[0].lower()) + 1 + x = "abcdefghijklmnopqrstuvwxyz".find(s[0].lower()) + 1 if x == 0: return False if s[1:].isdigit(): @@ -101,13 +101,13 @@ class GTPEngine(): def _parse_cmd(self, message): try: - m = message.strip().split(" ", 1) + m = (message.strip().split(" ", 1) + [None])[:2] if m[0].isdigit(): id_ = int(m[0]) cmd, args = (m[1].split(" ", 1) + [None])[:2] else: id_ = None - cmd, args = (m[0].split(" ", 1) + [None])[:2] + cmd, args = (m[0], m[1]) except: return "invaild command" return id_, cmd, args diff --git a/GTP/game.py b/GTP/game.py index 3034a94..c5d58fa 100644 --- a/GTP/game.py +++ b/GTP/game.py @@ -1,11 +1,90 @@ # -*- coding: utf-8 -*- # vim:fenc=utf-8 # $File: game.py -# $Date: Fri Nov 17 15:0745 2017 +0800 +# $Date: Tue Nov 28 01:1540 2017 +0800 # $Author: renyong15 © # import utils +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 class Game: @@ -14,10 +93,12 @@ class Game: self.komi = 6.5 self.board = [utils.EMPTY] * (self.size * self.size) self.strategy = None + self.executor = Executor(game = self) + self.history = [] def _flatten(self, vertex): x,y = vertex - return (x-1) * self.size + (y-1) + return (y - 1) * self.size + (x-1) def clear(self): @@ -30,21 +111,44 @@ class Game: def set_komi(self, k): self.komi = k + + def check_valid(self, vertex): + return True + def do_move(self, color, vertex): if vertex == utils.PASS: return True - - id_ = self._flatten(vertex) - if self.board[id_] == utils.EMPTY: - self.board[id_] = color - return True - else: - return False + res = self.executor.do_move(color, vertex) + return res + def gen_move(self, color): - move = self.strategy.gen_move(color) - return move - #return utils.PASS + #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') + diff --git a/GTP/test.py b/GTP/test.py index 734e8e6..0574ce0 100644 --- a/GTP/test.py +++ b/GTP/test.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- # vim:fenc=utf-8 # $File: test.py -# $Date: Fri Nov 17 13:5600 2017 +0800 +# $Date: Tue Nov 28 01:0627 2017 +0800 # $Author: renyong15 © # from game import Game from engine import GTPEngine +import utils @@ -34,7 +35,83 @@ print(res) res = e.run_cmd('7 play BLACK C3') print(res) +res = e.run_cmd('play BLACK C4') +res = e.run_cmd('play BLACK C5') +res = e.run_cmd('play BLACK C6') +res = e.run_cmd('play BLACK D3') +print(res) + res = e.run_cmd('8 genmove BLACK') print(res) +g.show_board() +print(g.check_valid((10, 9))) +print(g.executor._neighbor((1,1))) +print(g.do_move(utils.WHITE, (4, 6))) +g.show_board() + + +res = e.run_cmd('play BLACK L10') +res = e.run_cmd('play BLACK L11') +res = e.run_cmd('play BLACK L12') +res = e.run_cmd('play BLACK L13') +res = e.run_cmd('play BLACK L14') +res = e.run_cmd('play BLACK m15') +res = e.run_cmd('play BLACK m9') +res = e.run_cmd('play BLACK C9') +res = e.run_cmd('play BLACK D9') +res = e.run_cmd('play BLACK E9') +res = e.run_cmd('play BLACK F9') +res = e.run_cmd('play BLACK G9') +res = e.run_cmd('play BLACK H9') +res = e.run_cmd('play BLACK I9') + +res = e.run_cmd('play BLACK N9') +res = e.run_cmd('play BLACK N15') +res = e.run_cmd('play BLACK O10') +res = e.run_cmd('play BLACK O11') +res = e.run_cmd('play BLACK O12') +res = e.run_cmd('play BLACK O13') +res = e.run_cmd('play BLACK O14') +res = e.run_cmd('play BLACK M12') + +res = e.run_cmd('play WHITE M10') +res = e.run_cmd('play WHITE M11') +res = e.run_cmd('play WHITE N10') +res = e.run_cmd('play WHITE N11') + +res = e.run_cmd('play WHITE M13') +res = e.run_cmd('play WHITE M14') +res = e.run_cmd('play WHITE N13') +res = e.run_cmd('play WHITE N14') +print(res) + +res = e.run_cmd('play BLACK N12') +print(res) +g.show_board() + +res = e.run_cmd('play BLACK P16') +res = e.run_cmd('play BLACK P17') +res = e.run_cmd('play BLACK P18') +res = e.run_cmd('play BLACK P19') +res = e.run_cmd('play BLACK Q16') +res = e.run_cmd('play BLACK R16') +res = e.run_cmd('play BLACK S16') +res = e.run_cmd('play BLACK S19') + +res = e.run_cmd('play WHITE S18') +res = e.run_cmd('play WHITE S17') +res = e.run_cmd('play WHITE Q19') +res = e.run_cmd('play WHITE Q18') +res = e.run_cmd('play WHITE Q17') +res = e.run_cmd('play WHITE R18') +res = e.run_cmd('play WHITE R17') +print(res) +g.show_board() + +res = e.run_cmd('play WHITE R19') +g.show_board() + +res = e.run_cmd('play BLACK S19') +g.show_board() diff --git a/GTP/utils.py b/GTP/utils.py index dcf0160..b7ce00c 100644 --- a/GTP/utils.py +++ b/GTP/utils.py @@ -1,16 +1,22 @@ # -*- coding: utf-8 -*- # vim:fenc=utf-8 # $File: utils.py -# $Date: Fri Nov 17 10:2407 2017 +0800 +# $Date: Mon Nov 27 18:2755 2017 +0800 # $Author: renyong15 © # WHITE = -1 -BLACK = +1 EMPTY = 0 +BLACK = +1 +FILL = +2 +KO = +3 +UNKNOWN = +4 PASS = (0,0) RESIGN = "resign" +def another_color(color): + return color * -1 +