diff --git a/static/gogame.js b/static/gogame.js
index 5c0032e..cf33d99 100644
--- a/static/gogame.js
+++ b/static/gogame.js
@@ -1,14 +1,62 @@
-let stones = document.getElementsByClassName('go-stone-empty');
-let inputRow = document.getElementById('go-input-row');
-let inputCol = document.getElementById('go-input-col');
-let inputPlace = document.getElementById('go-input-place');
-
-for (let i = 0; i < stones.length; ++i) {
- stones[i].onclick = (e) => {
- console.log('place');
- inputCol.value = stones[i].attributes['data-col'].value;
- inputRow.value = stones[i].attributes['data-row'].value;
- inputPlace.click();
- };
+function setupEventHandler() {
+ let stones = document.getElementsByClassName('go-stone-empty');
+ let inputRow = document.getElementById('go-input-row');
+ let inputCol = document.getElementById('go-input-col');
+ let inputPlace = document.getElementById('go-input-place');
+
+ for (let i = 0; i < stones.length; ++i) {
+ stones[i].onclick = (e) => {
+ console.log('place');
+ inputCol.value = stones[i].attributes['data-col'].value;
+ inputRow.value = stones[i].attributes['data-row'].value;
+ inputPlace.click();
+ };
+ }
}
+
+let updateInterval = null;
+if (document.getElementsByClassName('go-territory').length == 0) {
+ setInterval(update, 500);
+}
+
+function update() {
+ var req = new XMLHttpRequest();
+ req.addEventListener('load', (ev) => {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(req.responseText, 'text/html');
+ let currentField = document.querySelector('svg');
+ let newField = doc.querySelector('svg');
+ let currentStones = currentField.getElementsByClassName('go-stone');
+ let newStones = newField.getElementsByClassName('go-stone');
+ let newTerritory = doc.getElementsByClassName('go-territory');
+ let currentInfo = document.getElementById('gameinfo');
+ let newInfo = doc.getElementById('gameinfo');
+ if (newTerritory.length > 0) {
+ window.location.reload();
+ return;
+ }
+ for (let i = 0; i < currentStones.length; ++i) {
+ if (doc.getElementById(currentStones[i].id) === null) {
+ currentStones[i].remove();
+ }
+ }
+ if (currentInfo.classList[0] != newInfo.classList[0]) {
+ console.log(newInfo.classList[0]);
+ currentInfo.innerHTML = newInfo.innerHTML;
+ currentInfo.classList.remove(currentInfo.classList[0]);
+ currentInfo.classList.add(newInfo.classList[0]);
+ }
+ for (let i = 0; i < newStones.length; ++i) {
+ if (document.getElementById(newStones[i].id) === null) {
+ currentField.append(newStones[i]);
+ }
+ }
+
+ setupEventHandler();
+ });
+ req.open('GET', window.location.href);
+ req.send();
+}
+
+setupEventHandler();
diff --git a/templates/cwa/gogame.html.j2 b/templates/cwa/gogame.html.j2
index 4e62c19..4704f42 100644
--- a/templates/cwa/gogame.html.j2
+++ b/templates/cwa/gogame.html.j2
@@ -3,10 +3,10 @@
{%- block body %}
Go: {{ game.human_id }}
-
- Refresh
-
-
- {% for p in players.keys() %}
- -
-
- {% if p == player.uuid %}
- {{ game.players[p].name }}
- {% else %}
- {{ game.players[p].name }}
- {% endif %}
- : {{ captures[colormap[p].value-1] }}
- {% if colormap[p].value == 1 %}
- + {{ komi }}
- {% endif %}
- {% endfor %}
-
-
{%- endblock %}
diff --git a/webgames/go.py b/webgames/go.py
index 7eab858..ccda7b5 100644
--- a/webgames/go.py
+++ b/webgames/go.py
@@ -11,6 +11,7 @@ import re
from threading import Timer, Lock
from webgames.puzzle import Puzzle
+from webgames.player import Player
class BoardSize(enum.Enum):
SMALL = 9
@@ -48,6 +49,7 @@ class GoPuzzle(Puzzle):
self._field = None
self._territory = None
self._abandoned = False
+ self.ai = None
self._timer = None
self._tlock = Lock()
self._captures = [0, 0]
@@ -76,12 +78,16 @@ class GoPuzzle(Puzzle):
with self._tlock:
self._timer = Timer(ABANDON_TIMEOUT, self._shutdown)
self._timer.start()
+ ailevel = int(options.get('go-input-ailevel', 10))
self.size = BoardSize(int(options.get('go-input-boardsize', BoardSize.MEDIUM.value)))
self.gnugo = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.gnugo.connect('/run/gnugo.sock')
self._gtp(f'boardsize {self.size.value}')
self._gtp('clear_board')
self._gtp(f'komi {self.komi}')
+ if len(self._players) == 1:
+ self.ai = Player('GnuGO AI')
+ self._players[self.ai.uuid] = self.ai.uuid
players = list(self._players.keys())
random.shuffle(players)
self.colormap[players[0]] = FieldState.BLACK
@@ -95,16 +101,33 @@ class GoPuzzle(Puzzle):
self._field[i].append(0)
self._territory[i].append(0)
self._urlbase = urlbase
+ # First move if GnuGO AI is black
+ if self.ai is not None:
+ self._gtp(f'level {ailevel}')
+ if self.colormap[self.ai.uuid] == FieldState.BLACK:
+ self._gtp('genmove_black')
+ self.current_player = FieldState(3 - self.current_player.value)
+ self.update_field()
def get_extra_options_html(self) -> str:
- return '''
+ options = '''
-