Слияние кода завершено, страница обновится автоматически
import itertools
import re
import time
import sys
import elephantfish
################################################################################
# This module contains functions used by test.py and xboard.py.
# Nothing from here is imported into sunfish.py which is entirely self-sufficient
################################################################################
# Sunfish doesn't have to know about colors, but for more advanced things, such
# as xboard support, we have to.
WHITE, BLACK = range(2)
FEN_INITIAL = 'rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1'
def search(searcher, pos, secs, history=()):
""" This used to be in the Searcher class """
start = time.time()
for depth, move, score in searcher.search(pos, history):
if time.time() - start > secs:
break
return move, score, depth
################################################################################
# Parse and Render moves
################################################################################
def gen_legal_moves(pos):
''' pos.gen_moves(), but without those that leaves us in check.
Also the position after moving is included. '''
for move in pos.gen_moves():
pos1 = pos.move(move)
if not can_kill_king(pos1):
yield move, pos1
def can_kill_king(pos):
# If we just checked for opponent moves capturing the king, we would miss
# captures in case of illegal castling.
return any(pos.value(m) >= elephantfish.MATE_LOWER for m in pos.gen_moves())
def mrender(pos, m):
# Sunfish always assumes promotion to queen
p = 'q' if elephantfish.A9 <= m[1] <= elephantfish.I9 and pos.board[m[0]] == 'P' else ''
m = m if get_color(pos) == WHITE else (254-m[0], 254-m[1])
return elephantfish.render(m[0]) + elephantfish.render(m[1]) + p
def mparse(color, move):
m = (elephantfish.parse(move[0:2]), elephantfish.parse(move[2:4]))
return m if color == WHITE else (254-m[0], 254-m[1])
################################################################################
# Parse and Render positions
################################################################################
def get_color(pos):
''' A slightly hacky way to to get the color from a elephantfish position '''
return BLACK if pos.board.startswith('\n') else WHITE
def parseFEN(fen):
""" Parses a string in Forsyth-Edwards Notation into a Position """
board, color, _, __, ___, ____ = fen.split()
board = re.sub(r'\d', (lambda m: '.'*int(m.group(0))), board)
board = list((16*3 + 3)*' ' + ' '.join(board.split('/')) + (16*3 + 4)*' ')
board[15::16] = ['\n']*16
#if color == 'w': board[::10] = ['\n']*12
#if color == 'b': board[9::10] = ['\n']*12
board = ''.join(board)
score = sum(elephantfish.pst[p][i] for i,p in enumerate(board) if p.isupper())
score -= sum(elephantfish.pst[p.upper()][254-i] for i,p in enumerate(board) if p.islower())
pos = elephantfish.Position(board, score)
return pos if color == 'w' else pos.rotate()
def renderFEN(pos, half_move_clock=0, full_move_clock=1):
color = 'wb'[get_color(pos)]
if get_color(pos) == BLACK:
pos = pos.rotate()
board = '/'.join(pos.board.split())
board = re.sub(r'\.+', (lambda m: str(len(m.group(0)))), board)
castling = '-'
ep = '-'
clock = '{} {}'.format(half_move_clock, full_move_clock)
return ' '.join((board, color, castling, ep, clock))
################################################################################
# Pretty print
################################################################################
def pv(searcher, pos, include_scores=True, include_loop=False):
res = []
seen_pos = set()
color = get_color(pos)
origc = color
if include_scores:
res.append(str(pos.score))
while True:
move = searcher.tp_move.get(pos)
# The tp may have illegal moves, given lower depths don't detect king killing
if move is None or can_kill_king(pos.move(move)):
break
res.append(mrender(pos, move))
pos, color = pos.move(move), 1-color
if pos in seen_pos:
if include_loop:
res.append('loop')
break
seen_pos.add(pos)
if include_scores:
res.append(str(pos.score if color==origc else -pos.score))
return ' '.join(res)
################################################################################
# Bulk move generation
################################################################################
def expand_position(pos):
''' Yields a tree of generators [p, [p, [...], ...], ...] rooted at pos '''
yield pos
for _, pos1 in gen_legal_moves(pos):
yield expand_position(pos1)
def collect_tree_depth(tree, depth):
''' Yields positions exactly at depth '''
root = next(tree)
if depth == 0:
yield root
else:
for subtree in tree:
for pos in collect_tree_depth(subtree, depth-1):
yield pos
def flatten_tree(tree, depth):
''' Yields positions exactly at less than depth '''
if depth == 0:
return
yield next(tree)
for subtree in tree:
for pos in flatten_tree(subtree, depth-1):
yield pos
################################################################################
# Non chess related tools
################################################################################
# Disable buffering
class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
sys.stderr.write(data)
sys.stderr.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )