In [144]:
import sys
import os
import json
import chess
from time import sleep, time
from datetime import datetime, timedelta
from random import random, choice
from IPython.display import clear_output
# Bots
import random_bot
#import final_bot
import basic_bot_1_1
dev = True
### Functions
def print_time(to_print,
t=0,
clear=True):
if clear: clear_output()
print to_print, '\n'
sys.stdout.flush()
sleep(t)
pass
def get_config(board, me):
cmap = {
( 'WIN', 'WHITE'): 'W_win',
('DRAW', 'WHITE'): 'W_draw',
('LOSE', 'WHITE'): 'W_lose',
( 'WIN', 'BLACK'): 'B_win',
('DRAW', 'BLACK'): 'B_draw',
('LOSE', 'BLACK'): 'B_lose'}
result = None
if board.is_checkmate():
if not board.turn == me:
result = 'WIN'
else:
result = 'LOSE'
else:
result = 'DRAW'
return cmap[(result,turn_color[me])]
def get_status(board):
result = ""
if board.is_game_over():
if board.is_checkmate(): result = 'Checkmate! ' + turn_color[not board.turn] + ' wins'
if board.is_stalemate(): result = 'Stalemate! DRAW'
if board.is_insufficient_material(): result = 'Insufficient material. DRAW',
if board.is_seventyfive_moves(): result = 'Seventyfive moves without capture or pawn move. DRAW'
if board.is_fivefold_repetition(): result = 'Fivefold repetition. DRAW'
else:
result = turn_color[board.turn], 'to move'
return result
### Parameters
turn_color = {
True:'WHITE',
False:'BLACK',
None: None
}
def new_state():
state = {
'played_since': '',
'game_desc': '',
'fen': '',
'turn_desc': '',
'W_win': 0,
'W_draw': 0,
'W_lose': 0,
'B_win': 0,
'B_draw': 0,
'B_lose' : 0
}
return state
def init_state():
state = None
if os.path.exists('../html/state'):
with open('../html/state', 'r') as f:
state = json.loads(f.read())
if not state:
state = new_state()
return state
def write_state(state):
with open('../html/state', 'w') as f:
f.write(json.dumps(state, indent=4))
pass
state = init_state()
# The Arena
me_bot = basic_bot_1_1
he_bot = random_bot
players = [chess.WHITE, chess.BLACK]
min_turn_time = 0.1
# In[ ]:
if not state['played_since']:
state['played_since'] = (datetime.fromtimestamp(time())+timedelta(hours=1)).strftime('%Y-%m-%d %H:%M:%S')
In [233]:
while True:
board = chess.Board() # Set up the board
me = choice(players) # My color
turn = 0
cpu_time = {chess.WHITE: 0, chess.BLACK: 0}
state['game_desc'] = 'Bot plays ' + turn_color[me] + ', ' + turn_color[not me] + ' is random\n'
while not board.is_game_over():
t0 = time()
turn+=1
state['fen'] = board.fen()
tt = time()
if board.turn == me:
state['turn_desc'] = str(1+turn/2) + ' - My move, ' + turn_color[board.turn]
move = me_bot.move(board) # My move!
else:
state['turn_desc'] = str(1+turn/2) + ' - His move, ' + turn_color[board.turn]
move = he_bot.move(board) # My opponent's move
ct = time() - tt
cpu_time[board.turn] += ct
board.push(move) # Make the move
if dev:
print_time(board)
print state
sys.stdout.flush()
t1 = time()
if t1-t0 < min_turn_time:
sleep(min_turn_time - (t1-t0))
write_state(state)
state['fen'] = board.fen()
state['game_desc'] = get_status(board)
result = None
if board.is_checkmate():
result = turn_color[not board.turn]
state[get_config(board, me)] += 1
write_state(state)
log_entry = {
'move_stack': ','.join([str(move) for move in board.move_stack]),
'winner': turn_color[not board.turn] if board.is_checkmate() else None,
'WHITE': {
'bot': me_bot.name() if me == chess.WHITE else he_bot.name(),
'cpu_time': cpu_time[chess.WHITE]
},
'BLACK': {
'bot': me_bot.name() if me == chess.BLACK else he_bot.name(),
'cpu_time': cpu_time[chess.BLACK]
},
}
#with open('log_entry') as f:
# f.write(json.dumps(log_entry, separators=(',', ': ')))
# write_command = 's3cmd put log_entry %i s3://larsbk/%s/%s/%s/%i' % (i,
# log_entry[winner],
# log_entry[not loser],
# color,i)
#
#
#write_command = 's3cmd put'
#
sleep(8)
In [175]:
value_piece = {
chess.PAWN: 1.0,
chess.KNIGHT: 2.9,
chess.BISHOP: 3.1,
chess.ROOK: 5.0,
chess.QUEEN: 9.0,
chess.KING: 0.0
}
f = 1/6.
w = [[1,1,1,1,1,1,1,1],
[1,2,2,2,2,2,2,1],
[1,2,3,3,3,3,2,1],
[1,2,3,5,5,3,2,1],
[1,2,3,5,5,3,2,1],
[1,2,3,3,3,3,2,1],
[1,2,2,2,2,2,2,1],
[1,1,1,1,1,1,1,1]]
square_importance = {}
for i,r in enumerate(w):
for j,c in enumerate(r):
square_importance[chess.square(i,j)] = f*((c-1)/(5.-1))
In [165]:
def eval_board(board):
if board.is_game_over():
if board.is_checkmate():
result = -1 * (int(board.turn) - int(not board.turn)) * float('inf')
else:
result = 0
else:
result = eval_player(board, chess.WHITE) - eval_player(board, chess.BLACK)
return result
def eval_player(board, player):
score_material = 0
score_presence = 0
score_position = 0
for piece_type in xrange(1,7):
for square in board.pieces(piece_type, player):
score_material += value_piece[piece_type]
score_presence += square_importance[square]
for square in board.pieces(piece_type, not player):
attackers = sorted([value_piece[board.piece_type_at(s)] for s in board.attackers(board.turn, square)])
defenders = sorted([value_piece[board.piece_type_at(s)] for s in board.attackers(not board.turn, square)])
defendant = value_piece[piece_type]
gain = 0
while attackers:
gain += defendant
if defenders:
gain -= attackers.pop(0)
defendand = defenders.pop(0)
else:
break
score_position += max(0, (player==board.turn) * gain)
return score_material + score_presence + score_position
In [232]:
def move(board, show=False):
tree = build_tree(board)
result = parse_tree(tree)
return result[0].pop(0)
def board_push(board, move):
new_board = board.copy()
new_board.push(move)
return new_board
def build_tree(root_board, halfmove_depth=1, limit_halfmove_depth=2):
if halfmove_depth == limit_halfmove_depth:
return {root_board.fen(): [(move, board_push(root_board, move).fen()) for move in root_board.legal_moves]}
else:
return {root_board.fen(): [(move, build_tree(board_push(root_board, move),
halfmove_depth=halfmove_depth+1,
limit_halfmove_depth=limit_halfmove_depth)) for move in root_board.legal_moves]}
pass
def parse_tree(tree):
ans = _parse_tree(tree)
return (ans[1:][::-1],ans[0])
def _parse_tree(tree):
root_board = chess.Board(tree.keys().pop())
sign = int(root_board.turn) - int(not root_board.turn)
if tree.values().pop():
movelist = tree.values().pop()
if type(movelist.pop()[1])==str:
return list(max([(sign*eval_board(chess.Board(fen)),move) for (move,fen) in movelist]))
else:
ans = max([(-1*t[0],t[1:]) for t in [_parse_tree(subtree)+[move] for (move, subtree) in movelist]])
return [ans[0]]+ans[1]
else:
return list((-sign * float('inf'), move))
pass
In [228]:
board = chess.Board()
root_board = board
moves = [move for move in board.legal_moves]
In [229]:
tree = build_tree(board)
In [230]:
#tree.values()
In [231]:
parse_tree(tree)
Out[231]:
In [178]:
board
Out[178]:
In [176]:
value_piece
Out[176]:
In [121]:
a = {1: []}
if a.values().pop(): print "ja"
In [126]:
print chess.Board(tree.keys().pop())
In [ ]: