Пример #1
0
def hint():
    global last_board
    global last_hint
    if request.method == 'POST':
        data = request.get_json()
        if (last_hint != None) and (last_board != None) and (len(
                last_hint['best_moves']) != 0) and (last_hint['answer'] == ''):
            last_best = last_hint['best_moves'][0]
            current_board = chess.BaseBoard(data['board'].split()[0])
            if ' b ' in data['board']:
                if current_board.piece_at(
                        chess.SQUARE_NAMES.index(last_best['full_move'][2:4])
                ) == last_board.piece_at(
                        chess.SQUARE_NAMES.index(last_best['full_move'][:2])):
                    return jsonify({
                        'answer': 'Молодец, хороший ход.',
                        'best_moves': [],
                        "possible_moves": [],
                        "mate": False
                    })
        if not 'board' in data:
            return {}
        csv = read_csv("data/dataset.tsv", sep='\t')
        hint = HintService(knowledge=csv)
        json = hint.ask(data['board'], data['question'])
        last_board = chess.BaseBoard(data['board'].split()[0])
        last_hint = loads(json)
        return json
    else:
        return {}
Пример #2
0
def diff2squareset(s1, s2):
    board1 = chess.BaseBoard(s1)
    board2 = chess.BaseBoard(s2)
    diffmap = chess.SquareSet()
    for x in range(chess.A1, chess.H8 + 1):
        if board1.piece_at(x) != board2.piece_at(x):
            diffmap.add(x)
    return diffmap
Пример #3
0
def main():
    args = _get_args()
    setup_console_logging()
    target_path = args.target_path
    if args.ignore_cache:
        shutil.rmtree(target_path)
    _create_processed_dir(target_path)
    cache = {}
    cache_path = os.path.join(target_path, '.squares_cache')
    if not args.ignore_cache:
        try:
            cache = {
                k: True
                for k in [line.strip() for line in open(cache_path)]
            }
        except IOError:
            pass
    source_path = args.source_path
    seed_dirs = _subdirectories(source_path)
    for seed_dir in seed_dirs:
        rotation_dirs = _subdirectories(seed_dir)
        for rotation_dir in rotation_dirs:
            with open(os.path.join(rotation_dir, "board.fen")) as f:
                fen = f.read()
                board = chess.BaseBoard(board_fen=fen)
                for img_path in _images(rotation_dir, cache):
                    img = cv2.imread(img_path)
                    _process(board, img, target_path)
    with open(cache_path, 'w') as f:
        f.write("\n".join(cache.keys()))
Пример #4
0
 def IsLocked(self,
              fen,
              pc=10,
              sqs=gamelib.SquareSet([
                  gamelib.C3, gamelib.C4, gamelib.C5, gamelib.C6,
                  gamelib.D3, gamelib.D4, gamelib.D5, gamelib.D6,
                  gamelib.E3, gamelib.E4, gamelib.E5, gamelib.E6,
                  gamelib.F3, gamelib.F4, gamelib.F5, gamelib.F6,
                  gamelib.B3, gamelib.B4, gamelib.B5, gamelib.B6,
                  gamelib.G3, gamelib.G4, gamelib.G5, gamelib.G6
              ])):
     DetectionRange = sqs
     PieceThreshold = pc
     DetectedPieces = 0
     fenbrd = gamelib.Board()
     fenbrd.set_fen(fen)
     bb = gamelib.BaseBoard()
     bb.set_board_fen(fenbrd.board_fen())
     del (fenbrd)
     pcs = list(bb.piece_map().keys())
     for sqr in DetectionRange:
         if sqr in pcs:
             DetectedPieces += 1
     if DetectedPieces > PieceThreshold:
         return True
     else:
         return False
Пример #5
0
def playGame():

    while (Board.is_game_over() == False):
        Board.push(makeMove(Board, 0))
        print(Board)
        Board.push(makeMove(Board, 1))
        print(Board)
        Brd = chess.BaseBoard(Board.board_fen())
    return (chess.svg.board(Brd))
Пример #6
0
def FEN_to_input(FEN, min_move_number=None, max_move_number=None):
    """
    Creates a one hot encoded flat array for a given chess
    board, and an attack matrix.
    :param FEN: The representation of chess board.
    :param min_move_number: Return None if board has not reached
    this move number.
    :param max_move_number: Return None if board has exceeded
     this move number.
    :return: a one hot encoded flat array for a given chess
    board.
    """
    # Default values for min/max move number if not given:
    if min_move_number is None:
        min_move_number = -1

    if max_move_number is None:
        max_move_number = 500

    board = chess.Board(FEN)
    white_turn = board.turn
    base_board = chess.BaseBoard(board.board_fen())
    if board.fullmove_number < min_move_number or board.fullmove_number > max_move_number:
        return None, None, None

    # Mirror board if blacks turn.
    # This avoids the problem of "white-to-play" vs. "black-to-play" when training.
    if not board.turn:
        board = board.mirror()
        base_board = base_board.mirror()

    # Create one hot encoded board and attack matrix
    attack_matrix = []
    pieces = []
    for pos in chess.SQUARES:
        white_attack = base_board.is_attacked_by(chess.WHITE, pos)
        black_attack = base_board.is_attacked_by(chess.BLACK, pos)

        # No attackers = 0, white attack = 1, black attack = 2, both = 3
        if white_attack and black_attack:
            # attack_matrix[chess.square_mirror(pos)] += 1
            attack_matrix.extend(both_attack_tile)
        elif white_attack:
            attack_matrix.extend(white_attacking_tile)
        elif black_attack:
            # attack_matrix[chess.square_mirror(pos)] += 2
            attack_matrix.extend(black_attacking_tile)
        else:
            attack_matrix.extend(neither_attacking_tile)

        pieces.extend(piece_dict[str(board.piece_at(pos))])

    pieces = np.asarray(pieces)
    # pieces = np.reshape(pieces, (-1, 96))
    # attack_matrix = np.reshape(attack_matrix, (-1, 8))
    return pieces, attack_matrix, white_turn
Пример #7
0
 def __init__(self, board=chess.BaseBoard()):
     """
         Returns a Gui object ----
     """
     self.app = QtWidgets.QApplication(sys.argv)
     self.board = board
     self.svg = chess.svg.board(board=self.board)
     self.svgWidget = BoardWidget(self.svg)
     self.svgWidget.adjustSize()
     self.svgWidget.setWindowTitle("chess-bot")
Пример #8
0
def build_board_from_labels(labels, names):
    board = chess.BaseBoard(board_fen=None)
    for pred_label, sq in zip(labels, names):
        if pred_label == "f":
            piece = None
        else:
            piece = chess.Piece.from_symbol(pred_label)

        square = chess.SQUARE_NAMES.index(sq)
        board.set_piece_at(square, piece, promoted=False)
    return board
Пример #9
0
def getMaterialScore(theBoard, pieceScores):
    baseBoard = chess.BaseBoard(board_fen=theBoard.board_fen())
    totalScore = 0
    allPieces = baseBoard.piece_map()
    for key, value in allPieces.items():
        if (value.color == chess.WHITE):
            totalScore = totalScore + pieceScores[value.piece_type]
        else:
            totalScore = totalScore - pieceScores[value.piece_type]

    return totalScore
def getAttacksPerPiece(fen):
    baseBoard = chess.BaseBoard(fen)
    attacks_list = []
    for k in range(64):  # 0 = A1, 1 = A2, etc
        piece = baseBoard.piece_at(k)
        if piece:
            attacks = baseBoard.attacks(k).tolist(
            )  # 64 bools, true if square is attacked from piece in square k
            attacks_sparse = [j for j, x in enumerate(attacks) if x]
            attacks_list.append((str(piece), attacks_sparse))

    return attacks_list
Пример #11
0
    def GetEvalnumber(self, fen):
        evlnum = 0.0
        brd = gamelib.Board()
        brd.set_fen(fen)
        trn = brd.turn
        bb = gamelib.BaseBoard()
        bb.set_board_fen(brd.board_fen())
        piecemap = bb.piece_map()
        engpieces = [
            x.symbol().lower() for x in list(piecemap.values())
            if x.color == trn
        ]
        opppieces = [
            x.symbol().lower() for x in list(piecemap.values())
            if x.color != trn
        ]
        engadv = engpieces.copy()
        oppadv = opppieces.copy()
        for i in engpieces:
            if i in oppadv:
                engadv.remove(i)
                oppadv.remove(i)

        for i in engadv:
            if i == 'q':
                evlnum += 9.0
            elif i == 'r':
                evlnum += 5.0
            elif i == 'b' or i == 'n':
                evlnum += 3.0
            elif i == 'p':
                evlnum += 1.0

        for i in oppadv:
            if i == 'q':
                evlnum -= 9.0
            elif i == 'r':
                evlnum -= 5.0
            elif i == 'b' or i == 'n':
                evlnum -= 3.0
            elif i == 'p':
                evlnum -= 1.0

        for i in range(1, 9):
            pawns = 0
            for j in range(i, 64, 8):
                if j in piecemap and piecemap[j] == gamelib.Piece(1, trn):
                    pawns += 1
            for j in range(pawns):
                evlnum -= ((j + 1) / 10)
        return evlnum
Пример #12
0
def reprgener(fen):
    brd = chess.Board()
    brd.set_fen(fen)
    bb = chess.BaseBoard()
    bb.set_board_fen(brd.board_fen())
    pcmap = bb.piece_map()
    repres = []
    for i in range(64):
        if i in pcmap:
            repres.append(pcmap[i].symbol())
        else:
            repres.append('.')
    strrepres = ''.join([elem for elem in repres])
    return strrepres
Пример #13
0
    def make_svg(self, request):
        try:
            parts = request.query["fen"].replace("_", " ").split(" ", 1)
            board = chess.BaseBoard("/".join(parts[0].split("/")[0:8]))
        except KeyError:
            raise aiohttp.web.HTTPBadRequest(reason="fen required")
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="invalid fen")

        try:
            size = min(max(int(request.query.get("size", 360)), 16), 1024)
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="size is not a number")

        try:
            uci = request.query.get("lastMove") or request.query["lastmove"]
            lastmove = chess.Move.from_uci(uci)
        except KeyError:
            lastmove = None
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(
                reason="lastMove is not a valid uci move")

        try:
            check = chess.SQUARE_NAMES.index(request.query["check"])
        except KeyError:
            check = None
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(
                reason="check is not a valid square name")

        try:
            arrows = [
                arrow(s.strip())
                for s in request.query.get("arrows", "").split(",")
                if s.strip()
            ]
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="invalid arrow")

        flipped = request.query.get("orientation", "white") == "black"

        return chess.svg.board(board,
                               coordinates=False,
                               flipped=flipped,
                               lastmove=lastmove,
                               check=check,
                               arrows=arrows,
                               size=size,
                               style=self.css)
Пример #14
0
    def CalculateInitHashKey(self):
        """
        计算初始hashKey64,hashIndex32
        """

        board = chess.BaseBoard()

        for square in chess.SQUARES:
            piece = board.piece_at(square)
            if (piece != None):
                self.hashKey64 = self.hashKey64 ^ self.hashKeyMap[piece.color][
                    piece.piece_type][square]
                self.hashIndex32 = self.hashIndex32 ^ self.hashIndexMap[
                    piece.color][piece.piece_type][square]

        return
Пример #15
0
def is_guarded(p_sq, board_state_FEN):
	# converts FEN to only the board part of the FEN
	fen = board_state_FEN.split()[0]

	#creates a baseboard object in python chess
	board = chess.BaseBoard(fen)

	#converts the piece_square tuple to a chess.SQUARE
	sq = chess.square(p_sq[0],p_sq[1])

	#creates a list for the pieces to return
	guarding_pieces = []

	#iterates through list of white pieces guarding and stores them in the list
	for guarder_square in board.attackers(chess.WHITE, sq):
		guarding_pieces.append([chess.square_file(guarder_square), chess.square_rank(guarder_square)])	

	return guarding_pieces
Пример #16
0
    def make_svg(self, request):
        parts = request["fen"].replace("_", " ").split(" ", 1)
        board = chess.BaseBoard("/".join(parts[0].split("/")[0:8]))
        size = min(max(int(request.get("size", 360)), 16), 1024)

        try:
            uci = request.get("lastMove") or request["lastmove"]
            lastmove = chess.Move.from_uci(uci)
        except KeyError:
            lastmove = None

        try:
            check = chess.SQUARE_NAMES.index(request["check"])
        except KeyError:
            check = None

        flipped = request.get("orientation", "white") == "black"

        return chess.svg.board(board, coordinates=True, flipped=flipped, lastmove=lastmove, check=check, size=size, style=self.css)
Пример #17
0
def FEN_to_one_hot_no_attack_mat(FEN,
                                 min_move_number=None,
                                 max_move_number=None):
    """
    Creates a one hot encoded flat array for a given chess
    board.
    :param FEN: The representation of chess board.
    :param min_move_number: Return None if board has not reached
    this move number.
    :param max_move_number: Return None if board has exceeded
     this move number.
    :return: a one hot encoded flat array for a given chess
    board.
    """
    # Default values for min/max move number if not given:
    if min_move_number is None:
        min_move_number = -1

    if max_move_number is None:
        max_move_number = 500

    board = chess.Board(FEN)
    white_turn = board.turn
    base_board = chess.BaseBoard(board.board_fen())
    if board.fullmove_number < min_move_number or board.fullmove_number > max_move_number:
        return None, None, None

    # Mirror board if blacks turn.
    # This avoids the problem of "white-to-play" vs. "black-to-play" when training.
    if not board.turn:
        board = board.mirror()
        base_board = base_board.mirror()

    # Create one hot encoded board:
    pieces = []
    for pos in chess.SQUARES:
        pieces.extend(piece_dict[str(board.piece_at(pos))])

    pieces = np.asarray(pieces)
    # pieces = np.reshape(pieces, (-1, 96))
    # attack_matrix = np.reshape(attack_matrix, (-1, 8))
    return pieces, None, white_turn
Пример #18
0
def heuristic(state, n_moves):

    baseBoard = chess.BaseBoard(state.fen().split()[0])

    my_score = 0
    opponent_score = 0

    my_color = state.turn
    opponent_color = not my_color

    for pieceType, value in piece_values:
        my_score += len(baseBoard.pieces(pieceType, my_color)) * value
        opponent_score += len(baseBoard.pieces(pieceType,
                                               opponent_color)) * value

    if my_score > opponent_score:
        points = 1 - opponent_score / my_score
    else:
        points = my_score / opponent_score - 1

    return points
    # return points * max_points(state.fullmove_number, n_moves)
class TheRoastedChessNuts(Player):
    moves = 0
    color = None
    board = None
    currGame = None
    baseBoard = chess.BaseBoard()

    recently_captured = None
    rejected_move = None

    def __init__(self):
        pass

    def handle_game_start(self, color, board):
        """
        This function is called at the start of the game.

        :param color: chess.BLACK or chess.WHITE -- your color assignment for the game
        :param board: chess.Board -- initial board state
        :return:
        """
        # TODO: implement this method
        moves = 0
        self.board = board.copy()
        self.color = color
        self.currGame = Game()
        self.recently_captured = None
        self.rejected_move = None
        self.baseBoard = board.copy()

    def handle_opponent_move_result(self, captured_piece, captured_square):
        """
        This function is called at the start of your turn and gives you the chance to update your board.

        :param captured_piece: bool - true if your opponents captured your piece with their last move
        :param captured_square: chess.Square - position where your piece was captured
        """
        # self.board.push()
        if captured_piece:
            self.board.remove_piece_at(captured_square)
            # if(self.color == chess.WHITE):
            #     self.board.set_piece_at(captured_square, Piece(3, chess.BLACK))
            # else:
            #     self.board.set_piece_at(captured_square, Piece(3, chess.WHITE))
            self.recently_captured = captured_square
        else:
            self.recently_captured = None

    def choose_sense(self, possible_sense, possible_moves, seconds_left):
        """
        This function is called to choose a square to perform a sense on.

        :param possible_sense: List(chess.SQUARES) -- list of squares to sense around
        :param possible_moves: List(chess.Moves) -- list of acceptable moves based on current board
        :param seconds_left: float -- seconds left in the game

        :return: chess.SQUARE -- the center of 3x3 section of the board you want to sense
        :example: choice = chess.A1
        """
        # TODO: update this method

        # edges = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
        #          8 , 16, 24, 32, 40, 48, 56
        #          15, 23, 31, 39, 47, 55, 63
        #          57, 58, 59, 60, 61, 62 ]
        # result = random.choice(possible_sense)

        # while result in edges:
        #     result = random.choice(possible_sense)

        result = random.choice(possible_sense)

        # if a piece has been recently captured, figured out what happened there
        if self.recently_captured is not None:
            result = self.recently_captured

        # if a move got rejected, chances are something is in the middle.
        # figure out what that is
        if self.rejected_move is not None:
            start = self.rejected_move.from_square
            end = self.rejected_move.to_square

            avg_file = int(
                (chess.square_file(start) + chess.square_file(end)) / 2)
            avg_rank = int(
                (chess.square_rank(start) + chess.square_rank(end)) / 2)

            result = (8 * avg_rank) + avg_file

        # shift the chosen square to produce a 3x3 within borders
        if chess.square_file(result) == 0:
            result += 1
        elif chess.square_file(result) == 7:
            result -= 1

        if chess.square_rank(result) == 0:
            result += 8
        elif chess.square_rank(result) == 7:
            result -= 8

        return result

    def handle_sense_result(self, sense_result):
        """
        This is a function called after your picked your 3x3 square to sense and gives you the chance to update your
        board.

        :param sense_result: A list of tuples, where each tuple contains a :class:`Square` in the sense, and if there
                             was a piece on the square, then the corresponding :class:`chess.Piece`, otherwise `None`.
        :example:
        [
            (A8, Piece(ROOK, BLACK)), (B8, Piece(KNIGHT, BLACK)), (C8, Piece(BISHOP, BLACK)),
            (A7, Piece(PAWN, BLACK)), (B7, Piece(PAWN, BLACK)), (C7, Piece(PAWN, BLACK)),
            (A6, None), (B6, None), (C8, None)
        ]
        """
        # TODO: implement this method
        # Hint: until this method is implemented, any senses you make will be lost.
        for sr in sense_result:
            self.board.remove_piece_at(sr[0])
            if sr[1]:
                self.board.set_piece_at(sr[0], sr[1])

    def choose_move(self, possible_moves, seconds_left):
        """
        Choose a to enact from a list of possible moves.

        :param possible_moves: List(chess.Moves) -- list of acceptable moves based only on pieces
        :param seconds_left: float -- seconds left to make a move
        
        :return: chess.Move -- object that includes the square you're moving from to the square you're moving to
        :example: choice = chess.Move(chess.F2, chess.F4)
        
        :condition: If you intend to move a pawn for promotion other than Queen, please specify the promotion parameter
        :example: choice = chess.Move(chess.G7, chess.G8, promotion=chess.KNIGHT) *default is Queen
        """
        # TODO: update this method
        # choice = random.choice(possible_moves)
        choice = None
        best = None
        if self.color == chess.WHITE:
            if self.moves == 0:
                choice = chess.Move(chess.E2, chess.E4)
            elif self.moves == 1:
                choice = chess.Move(chess.G1, chess.F3)
            elif self.moves == 2:
                choice = chess.Move(chess.F1, chess.C4)
            elif self.moves == 3:
                choice = chess.Move(chess.E1, chess.G1)
            else:
                best = calculate_best_move(50, len(possible_moves), self.board,
                                           self.color, possible_moves)[1]
            self.moves = self.moves + 1
        if self.color == chess.BLACK:
            if self.moves == 0:
                choice = chess.Move(chess.E7, chess.E5)
            elif self.moves == 1:
                choice = chess.Move(chess.G8, chess.F6)
            elif self.moves == 2:
                choice = chess.Move(chess.F8, chess.C5)
            elif self.moves == 3:
                choice = chess.Move(chess.E8, chess.G8)
            else:
                best = calculate_best_move(50, len(possible_moves), self.board,
                                           self.color, possible_moves)[1]
            self.moves = self.moves + 1
        if best:
            return chess.Move(best.from_square, best.to_square)
        return choice

    def handle_move_result(self, requested_move, taken_move, reason,
                           captured_piece, captured_square):
        """
        This is a function called at the end of your turn/after your move was made and gives you the chance to update
        your board.

        :param requested_move: chess.Move -- the move you intended to make
        :param taken_move: chess.Move -- the move that was actually made
        :param reason: String -- description of the result from trying to make requested_move
        :param captured_piece: bool - true if you captured your opponents piece
        :param captured_square: chess.Square - position where you captured the piece
        """
        # TODO: implement this method
        if not taken_move.__eq__(requested_move):
            self.rejected_move = requested_move
        else:
            self.rejected_move = None

        if taken_move is not None:
            self.board.push(taken_move)

    def handle_game_end(self, winner_color,
                        win_reason):  # possible GameHistory object...
        """
        This function is called at the end of the game to declare a winner.

        :param winner_color: Chess.BLACK/chess.WHITE -- the winning color
        :param win_reason: String -- the reason for the game ending
        """
        # TODO: implement this method
        # print(winner_color, "by", win_reason)

        if (winner_color == self.color):
            print("Tom and Aaki won! :D", win_reason)
        else:
            print("Tom and Aaki lost :(", win_reason)
Пример #20
0
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""An HTTP service that renders chess board images"""

import argparse
import asyncio
import aiohttp.web
import chess
import svg
import cairosvg
import re
import hashlib

index = 1

with open('fen18.txt', 'r') as f:
    for fen in f:
        parts = fen.replace("_", " ").split(" ", 1)
        board = chess.BaseBoard("/".join(parts[0].split("/")[0:8]))
        size = 360

        svgtext = svg.board(board,
                            coordinates=True,
                            size=size,
                            style=open("default.css", "r").read())
        hash_object = hashlib.md5(fen.encode())
        svgfile = open("fen18/file_{0}.svg".format(index), "w")
        svgfile.write(svgtext)
        svgfile.close()
        index = index + 1
Пример #21
0
def main():
    new_usb_data = False
    usb_data_exist = False

    def send_leds(message=b'\x00' * 8):
        serial_out.put(message)

    send_leds(b'\xff' * 8)
    chessboard = chess.Board()
    board_state = chessboard.fen()
    move = []
    starting_position = chess.STARTING_FEN
    rotate180 = False
    mystate = "init"

    codes.load_calibration(port)
    calibration = False
    new_setup = True
    calibration_samples_counter = 0
    calibration_samples = []

    usb_data_history_depth = 3
    usb_data_history = list(range(usb_data_history_depth))
    usb_data_history_filled = False
    usb_data_history_i = 0
    move_detect_tries = 0
    move_detect_max_tries = 3

    out = Unbuffered(sys.stdout)

    # out = sys.stdout
    def output(line):
        print(line, file=out)
        # print('\n', file=out)
        sys.stdout.flush()
        # logging.debug(line)

    send_leds()

    while True:
        smove = ""

        time.sleep(0.001)
        # logging.debug(f'testing for items in serial_in queue')
        if not serial_in.empty():
            try:
                logging.debug(
                    f'serial data is pending on serial_in queue, running get()'
                )
                data = serial_in.get()
                serial_in.task_done()
                logging.debug(
                    f'serial data received from serial_in queue: {data}')
                usb_data = list(map(int, data.split(" ")))
                new_usb_data = True
                usb_data_exist = True
                # logging.debug(f'data from usb {usb_data}')

            except Exception as e:
                logging.info(
                    f'No new data from usb, perhaps chess board not connected: {str(e)}'
                )

        if calibration == True and new_usb_data == True:
            send_leds(b'\xff' * 8)
            calibration_samples.append(usb_data)
            new_usb_data = False
            logging.info("    adding new calibration sample")
            calibration_samples_counter += 1
            if calibration_samples_counter >= 15:
                logging.info(
                    "------- we have collected enough samples for averaging ----"
                )
                usb_data = codes.statistic_processing_for_calibration(
                    calibration_samples, False)
                codes.calibration(usb_data, new_setup, port)
                calibration = False
                output(
                    'readyok'
                )  # as calibration takes some time, we safely(?) assume that "isready" has already been sent, so we reply readyness
                send_leds()

        if not stack.empty():
            logging.debug(f'getting uci command from stack')
            smove = stack.get()
            stack.task_done()
            logging.debug(f'>>> {smove} ')

            if smove == 'quit':
                break

            elif smove == 'uci':
                output('id name CERTABO physical board')
                output(
                    'id author Harald Klein (based on work from Thomas Ahle & Contributors)'
                )
                output('option name Calibrate type check default false')
                output('option name Rotate type check default false')
                output('uciok')

            elif smove == 'isready':
                if not calibration:
                    output('readyok')

            elif smove == 'ucinewgame':
                logging.debug("new game")
                # stack.append('position fen ...')

            elif smove.startswith('setoption name Calibrate value true'):
                logging.info("Calibrating board")
                calibration = True

            elif smove.startswith('setoption name Rotate value true'):
                logging.info("Rotating board")
                rotate180 = True

            elif smove.startswith('position fen'):
                _, _, fen = smove.split(' ', 2)
                logging.debug(f'fen: {fen}')

            elif smove.startswith('position startpos'):
                parameters = smove.split(' ')
                logging.debug(f'startpos received {parameters}')

                #logging.info(f'{len(parameters)}')
                if len(parameters) > 2:
                    if parameters[2] == 'moves':
                        tmp_chessboard = chess.Board()
                        for move in parameters[3:]:
                            logging.debug(f'move: {move}')
                            tmp_chessboard.push_uci(move)
                        board_state = tmp_chessboard.fen()
                        logging.debug(f'startpos board state: {board_state}')
                        new_move = codes.get_moves(chessboard, board_state)
                        logging.info(f'bot opponent played: {new_move}')
                        chessboard = tmp_chessboard
                        mystate = "user_shall_place_oppt_move"
                else:
                    # we did receive a startpos without any moves, so we're probably white and it's our turn
                    chessboard = chess.Board()
                    # if chessboard.turn == chess.WHITE:
                    logging.debug(f'startpos board state: {board_state}')
                    mystate = "user_shall_place_his_move"
                    logging.info(f'we are white, it is our turn')

            elif smove.startswith('go'):
                logging.debug("go...")
                # output('resign')
                possible_moves = list(chessboard.legal_moves)
                logging.debug(f'legal moves: {possible_moves}')
                #logging.debug(f'legal move: {possible_moves[0]}')
                #output('currmove e7e5')
                #shuffle(possible_moves)
                #output(f'bestmove {possible_moves[0]}')

            else:
                logging.debug(f'unhandled: {smove}')
                pass

        if new_usb_data:
            new_usb_data = False

            if usb_data_history_i >= usb_data_history_depth:
                usb_data_history_filled = True
                usb_data_history_i = 0

            usb_data_history[usb_data_history_i] = list(usb_data)[:]
            usb_data_history_i += 1
            if usb_data_history_filled:
                usb_data_processed = codes.statistic_processing(
                    usb_data_history, False)
                if usb_data_processed != []:
                    test_state = codes.usb_data_to_FEN(usb_data_processed,
                                                       rotate180)
                    if test_state != "":
                        board_state_usb = test_state
                        game_process_just_started = False

                        # compare virtual board state and state from usb
                        s1 = chessboard.board_fen()
                        s2 = board_state_usb.split(" ")[0]
                        if s1 != s2:
                            if mystate == "user_shall_place_oppt_move":

                                try:
                                    move_detect_tries += 1
                                    move = codes.get_moves(
                                        chessboard, board_state_usb)
                                except codes.InvalidMove:
                                    board1 = chess.BaseBoard(s1)
                                    board2 = chess.BaseBoard(s2)
                                    for x in range(chess.A1, chess.H8 + 1):
                                        if board1.piece_at(
                                                x) != board2.piece_at(x):
                                            logging.debug(
                                                f'Difference on Square {chess.SQUARE_NAMES[x]} - {board1.piece_at(x)} <-> {board2.piece_at(x)}'
                                            )
                                    if move_detect_tries > move_detect_max_tries:
                                        logging.info("Invalid move")
                                    else:
                                        move_detect_tries = 0
                                if move:
                                    send_leds(
                                        codes.move2ledbytes(move, rotate180))
                                    logging.info(f'moves difference: {move}')
                                    logging.info("move for opponent")
                                    output(f'info string move for opponent')
                            elif mystate == "user_shall_place_his_move":
                                try:
                                    move_detect_tries += 1
                                    move = codes.get_moves(
                                        chessboard, board_state_usb)
                                    logging.debug(f'moves difference: {move}')
                                    logging.debug(f'move count: {len(move)}')
                                    if len(move) == 1:
                                        # single move
                                        bestmove = move[0]
                                        legal_moves = list(
                                            chessboard.legal_moves)
                                        logging.debug(
                                            f'valid moves {legal_moves}')
                                        if chess.Move.from_uci(
                                                bestmove) in list(
                                                    chessboard.legal_moves):
                                            logging.debug('valid move')
                                        else:
                                            logging.debug('invalid move')
                                        logging.info("user moves")
                                        chessboard.push_uci(bestmove)
                                        output(f'bestmove {bestmove}')
                                        mystate = "init"
                                except codes.InvalidMove:
                                    board1 = chess.BaseBoard(s1)
                                    board2 = chess.BaseBoard(s2)
                                    wrongmove = ""
                                    for x in range(chess.A1, chess.H8 + 1):
                                        if board1.piece_at(
                                                x) != board2.piece_at(x):
                                            logging.debug(
                                                f'Difference on Square {chess.SQUARE_NAMES[x]} - {board1.piece_at(x)} <-> {board2.piece_at(x)}'
                                            )
                                            wrongmove += chess.SQUARE_NAMES[x]
                                            if len(wrongmove) == 4:
                                                send_leds(
                                                    codes.move2ledbytes(
                                                        wrongmove, rotate180))

                                    if move_detect_tries > move_detect_max_tries:
                                        logging.info("Invalid move")
                                    else:
                                        move_detect_tries = 0

                            else:
                                if DEBUG:
                                    logging.info(
                                        "Place pieces on their places")
                                    output(
                                        f'info string place pieces on their places'
                                    )
                                    logging.info("Virtual board: %s",
                                                 chessboard.fen())
                        else:  # board is the same
                            if mystate == "user_shall_place_oppt_move":
                                logging.info(
                                    "user has moved opponent, now it's his own turn"
                                )
                                mystate = "user_shall_place_his_move"
                            send_leds()

    # we quit, stop input thread
    interrupted.release()
    interrupted_serial.release()
Пример #22
0
 def render_base():
     return chess.svg.board(chess.BaseBoard())
Пример #23
0
def preprocess(dataFile,
               outFilePrefix,
               gamesPerFile=5000,
               ngames=0,
               startAt=0,
               onlyWins=False):

    # Seek forward in file until given starting game
    pgn = open(dataFile)
    for i in xrange(startAt):
        chess.pgn.read_game(pgn)

    # Inputs and labeled output for each network
    psInputs, psLabels = [], []  # piece selector
    pmInputs, pmLabels = [], []  # pawn move
    knmInputs, knmLabels = [], []  # knight move
    bmInputs, bmLabels = [], []  # bishope move
    rmInputs, rmLabels = [], []  # rook move
    qmInputs, qmLabels = [], []  # queen move
    kmInputs, kmLabels = [], []  # king move

    # Writes a set of data into a numbered output file
    def writeOut(n):
        psData = psInputs, psLabels
        pmData = pmInputs, pmLabels
        knmData = knmInputs, knmLabels
        bmData = bmInputs, bmLabels
        rmData = rmInputs, rmLabels
        qmData = qmInputs, qmLabels
        kmData = kmInputs, kmLabels
        data = [psData, pmData, knmData, bmData, rmData, qmData, kmData]
        f = gzip.open(outFilePrefix + '_' + str(n / gamesPerFile), 'wb')
        cPickle.dump(data, f, protocol=2)
        f.close()

    n = 0  # Counts number of games processed
    reset = False  # True when a new file/data-set is started
    #  (except on first run, when it is redundant)
    while (ngames == 0) or (n < ngames):

        if n != 0 and n % 100 == 0:
            print "Preprocessed first %s games" % n

        gameNode = chess.pgn.read_game(pgn)
        if gameNode == None:
            break

        if reset:
            psInputs, psLabels = [], []
            pmInputs, pmLabels = [], []
            knmInputs, knmLabels = [], []
            bmInputs, bmLabels = [], []
            rmInputs, rmLabels = [], []
            qmInputs, qmLabels = [], []
            kmInputs, kmLabels = [], []
            reset = False

        if gameNode.headers['Result'] == '1-0':
            winner = chess.WHITE
        else:
            winner = chess.BLACK

        while not gameNode.is_end():
            board = gameNode.board()
            move = gameNode.variations[0].move

            # If onlyWins is set, only process turns from player
            # who won the current game
            if (not onlyWins) or (board.turn == winner):
                boardTensor = boardToTensor(board, board.turn)
                psInputs.append(boardTensor)
                piece = board.piece_at(move.from_square)
                pieceSelectorBoard = chess.BaseBoard('8/8/8/8/8/8/8/8')
                pieceSelectorBoard.set_piece_at(move.from_square, piece)
                psLabels.append(
                    boardToProbability(pieceSelectorBoard, board.turn,
                                       piece.piece_type))

                moveSelectorBoard = chess.BaseBoard('8/8/8/8/8/8/8/8')
                moveSelectorBoard.set_piece_at(move.to_square, piece)
                if piece.piece_type == chess.PAWN:
                    pmInputs.append(boardTensor)
                    pmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
                elif piece.piece_type == chess.KNIGHT:
                    knmInputs.append(boardTensor)
                    knmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
                elif piece.piece_type == chess.BISHOP:
                    bmInputs.append(boardTensor)
                    bmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
                elif piece.piece_type == chess.ROOK:
                    rmInputs.append(boardTensor)
                    rmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
                elif piece.piece_type == chess.QUEEN:
                    qmInputs.append(boardTensor)
                    qmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
                elif piece.piece_type == chess.KING:
                    kmInputs.append(boardTensor)
                    kmLabels.append(
                        boardToProbability(moveSelectorBoard, board.turn,
                                           piece.piece_type))
            gameNode = gameNode.variations[0]
        n += 1
        if n % gamesPerFile == 0:
            writeOut(n)
            reset = True
    if not reset: writeOut(n)