Learn AlphaGo & Python (04)

Source: Deep Learning on Medium

Create method apply_move in GameState.

Add property other for class Player in dlgo/gotypes.py

import enum
from collections import namedtuple
class Player(enum.Enum):
black = 1
white = 2
@property
def other(self):
return Player.black if self == Player.white else Player.white
class Point(namedtuple('Point', 'row col')):
pass

Create class Move in dlgo/goboard_slow.py

import copy
from dlgo.gotypes import Player
class Move():
def __init__(self, point=None, is_pass=False, is_resign=False):
assert (point is not None) ^ is_pass & is_resign
self.point = point
self.is_play = (self.point is not None)
self.is_pass = is_pass
self.is_resign = is_resign
@classmethod
def play(cls, point):
return Move(point=point)
@classmethod
def pass_turn(cls):
return Move(is_pass=True)
@classmethod
def resign(cls):
return Move(is_resign=True)
class Board():
def __init__(self, num_rows, num_cols):
self.num_rows = num_rows
self.num_cols = num_cols
self._grid = {}
def place_stone(self, player, point):
self._grid[point] = player
def get(self, point):
return self._grid.get(point)
class GameState():
def __init__(self, board, next_player, previous, move):
self.board = board
self.next_player = next_player
self.previous_state = previous
self.last_move = move
def apply_move(self, move):
if move.is_play:
next_board = copy.deepcopy(self.board)
next_board.place_stone(self.next_player, move.point)
else:
next_board = self.board
return GameState(next_board, self.next_player.other, self, move)
@classmethod
def new_game(cls, board_size):
if isinstance(board_size, int):
board_size = (board_size, board_size)
board = Board(*board_size)
return GameState(board, Player.black, None, None)

Use class Move in dlgo/agent/naive.py

import random
from dlgo.agent.base import Agent
from dlgo import gotypes
from dlgo.goboard_slow import Move
class RandomBot(Agent):
def select_move(self, game_state):
candidates = []
for row in range(1, game_state.board.num_rows + 1):
for col in range(1, game_state.board.num_cols + 1):
candidates.append(gotypes.Point(row, col))
return Move.play(random.choice(candidates))

bot_v_bot.py

from dlgo.agent import naive
from dlgo import goboard_slow
from dlgo import gotypes
import time
COLS = 'ABCDEFGHJKLMNOPQRST'
STONE_TO_CHAR = {
None: '. ',
gotypes.Player.black: 'x ',
gotypes.Player.white: 'o ',
}
def print_board(board):
for row in range(board.num_rows, 0, -1):
bump = " " if row <= 9 else ""
line = []
for col in range(1, board.num_cols + 1):
stone = board.get(gotypes.Point(row=row, col=col))
line.append(STONE_TO_CHAR[stone])
print('%s%d %s' % (bump, row, ''.join(line)))
print(' ' + ' '.join(COLS[:board.num_cols]))
def main():
board_size = 19
bots = {
gotypes.Player.black: naive.RandomBot(),
gotypes.Player.white: naive.RandomBot(),
}
game = goboard_slow.GameState.new_game(board_size)
cnt = 0
while True:
time.sleep(1.0)
print(chr(27) + "[2J")
print_board(game.board)
print()
player = gotypes.Player.black if cnt % 2 == 0 else gotypes.Player.white
cnt += 1
bot_move = bots[player].select_move(game)
game = game.apply_move(bot_move)
if __name__ == '__main__':
main()