"""A Gomocup brain that weighs every empty point near the stones by the lines it would make for itself and the lines it would break for the other side (open and closed twos, threes and fours), and plays the heaviest.""" import sys N, board, me = 15, {}, 1 D = [(1, 0), (0, 1), (1, 1), (1, -1)] WEIGHT = {(5, 0): 1e7, (5, 1): 1e7, (5, 2): 1e7, (4, 2): 1e5, (4, 1): 1e4, (3, 2): 5e3, (3, 1): 400, (2, 2): 300, (2, 1): 40, (1, 2): 10, (1, 1): 2} def line(x, y, c, dx, dy): n, ends = 1, 0 for s in (1, -1): i = 1 while board.get((x + s * i * dx, y + s * i * dy)) == c: n += 1 i += 1 a, b = x + s * i * dx, y + s * i * dy if 0 <= a < N and 0 <= b < N and (a, b) not in board: ends += 1 return min(n, 5), ends def value(x, y): attack = sum(WEIGHT.get(line(x, y, me, dx, dy), 0) for dx, dy in D) defend = sum(WEIGHT.get(line(x, y, 3 - me, dx, dy), 0) for dx, dy in D) return attack * 1.1 + defend def move(): near = {(x + a, y + b) for (x, y) in board for a in (-2, -1, 0, 1, 2) for b in (-2, -1, 0, 1, 2)} cands = [p for p in near if 0 <= p[0] < N and 0 <= p[1] < N and p not in board] or [(N // 2, N // 2)] return max(cands, key=lambda p: (value(*p), -abs(p[0] - N // 2) - abs(p[1] - N // 2))) def play(): x, y = move() board[(x, y)] = me print(f'{x},{y}', flush=True) for raw in sys.stdin: cmd, _, arg = raw.strip().partition(' ') cmd = cmd.upper() if cmd == 'START': N = int(arg) board.clear() print('OK', flush=True) elif cmd == 'BEGIN': play() elif cmd == 'TURN': x, y = map(int, arg.split(',')) board[(x, y)] = 2 play() elif cmd == 'BOARD': for l in sys.stdin: if l.strip().upper() == 'DONE': break x, y, f = map(int, l.split(',')) board[(x, y)] = 1 if f == 1 else 2 play() elif cmd == 'ABOUT': print('name="threats", version="1", author="shoal-games"', flush=True) elif cmd == 'END': break elif cmd not in ('INFO', 'RESTART'): print('UNKNOWN', flush=True)