def sfen(pieces, pieces_in_hand, current_turn_char, move_count): sfen = [] empty = 0 # Position part. for square in shogi.SQUARES: piece_tuple = pieces[square] if piece_tuple is None: empty += 1 else: (piece_type, color) = piece_tuple piece = shogi.Piece(piece_type, color) if empty: sfen.append(str(empty)) empty = 0 sfen.append(piece.symbol()) if shogi.BB_SQUARES[square] & shogi.BB_FILE_1: if empty: sfen.append(str(empty)) empty = 0 if square != shogi.I1: sfen.append('/') sfen.append(' ') # Side to move. current_turn = COLOR_SYMBOLS.index(current_turn_char) if current_turn == shogi.WHITE: sfen.append('w') else: sfen.append('b') sfen.append(' ') # Pieces in hand pih_len = 0 for color in shogi.COLORS: p = pieces_in_hand[color] pih_len += len(p) for piece_type in p.keys(): if p[piece_type] > 1: sfen.append(str(p[piece_type])) elif p[piece_type] >= 1: piece = shogi.Piece(piece_type, color) sfen.append(piece.symbol()) if pih_len == 0: sfen.append('-') sfen.append(' ') # Move count sfen.append(str(move_count)) sfen_str = ''.join(sfen) return sfen_str
def decode_hcpe(hcpe): # HuffmanCodedPos hcp bs = BitStream(hcpe['hcp']) board = shogi.Board() board.clear() # 手番 board.turn = bs.getBit() # 玉の位置 sq0 = bs.getBits(7) sq1 = bs.getBits(7) board.set_piece_at(shogi.SQUARES_L90[sq0], shogi.Piece(shogi.KING, shogi.BLACK)) board.set_piece_at(shogi.SQUARES_L90[sq1], shogi.Piece(shogi.KING, shogi.WHITE)) # 盤上の駒 for sq in shogi.SQUARES_L90: if board.piece_at(sq) is not None and board.piece_at( sq ).piece_type == shogi.KING: # piece(sq) は BKing, WKing, Empty のどれか。 continue numOfBits = 0 code = 0 while numOfBits <= 8: code |= bs.getBit() << numOfBits numOfBits += 1 key = toKey(code, numOfBits) if key in boardCodeToPieceHash: pc = boardCodeToPieceHash[key] board.set_piece_at(sq, pc) break while bs.p < len(bs.data): numOfBits = 0 code = 0 while numOfBits <= 8: code |= bs.getBit() << numOfBits numOfBits += 1 key = toKey(code, numOfBits) if key in handCodeToPieceHash: pc = handCodeToPieceHash[key] board.add_piece_into_hand(pc.piece_type, pc.color) break # u16 bestMove16 bestMove16 = hcpe['bestMove16'] # see: move.hpp:30 # xxxxxxxx xxxxxxxx xxxxxxxx x1111111 移動先 # xxxxxxxx xxxxxxxx xx111111 1xxxxxxx 移動元。駒打ちの際には、PieceType + SquareNum - 1 # xxxxxxxx xxxxxxxx x1xxxxxx xxxxxxxx 1 なら成り to_square = bestMove16 & 0b1111111 from_square = (bestMove16 >> 7) & 0b1111111 drop_piece_type = None if from_square >= 81: drop_piece_type = PieceType[from_square - 81] promotion = bestMove16 & 0b100000000000000 > 0 if drop_piece_type: bestMove = shogi.Move(None, shogi.SQUARES_L90[to_square], drop_piece_type=drop_piece_type) else: bestMove = shogi.Move(shogi.SQUARES_L90[from_square], shogi.SQUARES_L90[to_square], promotion) return board, hcpe['eval'], bestMove, hcpe['gameResult']
# see: position.hpp:161: static void init() boardCodeToPieceHash = {} handCodeToPieceHash = {} def toKey(code, numOfBits): return (numOfBits << 8) + code for key, val in boardCodeTable.items(): pc = shogi.Piece.from_symbol(key) if pc.piece_type != shogi.KING: # 玉は位置で符号化するので、駒の種類では符号化しない。 boardCodeToPieceHash[toKey(val[0], val[1])] = pc for key, val in handCodeTable.items(): for c in shogi.COLORS: pc = shogi.Piece(key, c) handCodeToPieceHash[toKey(val[c][0], val[c][1])] = pc # see: position.hpp:178: struct HuffmanCodedPosAndEval HuffmanCodedPosAndEval = np.dtype([ ('hcp', np.uint8, 32), ('eval', np.int16), ('bestMove16', np.uint16), ('gameResult', np.uint8), ('dummy', np.uint8), ]) class BitStream(object): # 読み込むデータをセットする。 def __init__(self, d):