def test_check(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) pseudo_effect = BlackPseudoOuEffect( data_format=self.data_format, use_cudnn=self.use_cudnn )(ph) long_check = WhiteLongCheckLayer()(ph, pseudo_effect) # 利きの長い駒のみに限定する # UM,RYの長い利きのみで、短い利きは対象に含めない white_pieces = [Piece.WHITE_KY, Piece.WHITE_KA, Piece.WHITE_HI, Piece.WHITE_UM, Piece.WHITE_RY] for direction in get_eight_directions(): with self.test_session() as sess: for i, j, k, piece in product(range(9), range(9), range(1, 9), white_pieces): x, y = self._get_position( direction=direction, i=i, j=j, k=k ) if x not in range(9) or y not in range(9): continue # OUから見てdirectionの方向に相手の駒を配置 board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_OU board[0, 0, x, y] = piece else: board[0, i, j, 0] = Piece.BLACK_OU board[0, x, y, 0] = piece with self.subTest(direction=direction, i=i, j=j, k=k, piece=piece): check = sess.run(long_check, feed_dict={ph: board}) for key, value in check.items(): # ブロードキャストが正しく行われるために4次元が必要 self.assertTupleEqual((1, 1, 1, 1), value.shape) if key == direction: d = get_opposite_direction(direction=direction) if piece == Piece.WHITE_KY: self.assertEqual(value, d == Direction.DOWN) elif piece in (Piece.WHITE_KA, Piece.WHITE_UM): self.assertEqual( value, d in get_diagonal_directions() ) elif piece in (Piece.WHITE_HI, Piece.WHITE_RY): self.assertEqual( value, d in get_cross_directions() ) else: # ここには到達しないはず raise ValueError() else: self.assertFalse(value)
def test_long_check(self): """ 長い利きで王手されている場合に王以外の駒が動ける場所の判定のテスト :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) pseudo_effect = BlackPseudoOuEffect(data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) all_check, long_check = WhiteAllCheckLayer()(ph, pseudo_effect) available_square = CheckAvailableSquareLayer()(pseudo_effect, all_check) available_square = tf.squeeze(available_square) long_piece_list = [ Piece.WHITE_KY, Piece.WHITE_KA, Piece.WHITE_HI, Piece.WHITE_UM, Piece.WHITE_RY ] with self.test_session() as sess: for tmp in product(get_eight_directions(), range(9), range(9), range(1, 9), long_piece_list): direction, i, j, k, piece = tmp # 短い利きは含めない if (piece == Piece.WHITE_UM and direction in get_cross_directions()): continue elif (piece == Piece.WHITE_RY and direction == get_diagonal_directions()): continue x, y = self._get_position(direction=direction, i=i, j=j, k=k) if x not in range(9) or y not in range(9): continue board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_OU board[0, 0, x, y] = piece else: board[0, i, j, 0] = Piece.BLACK_OU board[0, x, y, 0] = piece with self.subTest(direction=direction, i=i, j=j, piece=piece): square, check = sess.run( [available_square, long_check[direction]], feed_dict={ph: board}) self.assertTupleEqual(square.shape, (9, 9)) if check: for u, v in zip(*self._get_range(i=i, j=j, x=x, y=y)): self.assertTrue(square[u, v]) square[u, v] = False self.assertFalse(np.any(square)) else: self.assertTrue(np.all(square))
def test_effect1_short(self): """ UMの短い利きをテスト :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) for direction in chain(get_eight_directions(), [Direction.RIGHT_DOWN_DOWN, Direction.LEFT_DOWN_DOWN]): white_effect = WhiteNaiveShortEffectLayer( direction=direction, data_format=self.data_format, use_cudnn=self.use_cudnn )(ph) # チャネルの処理が面倒なので、次元を下げる white_effect = tf.squeeze(white_effect) with self.test_session() as sess: for i, j in product(range(9), repeat=2): with self.subTest(direction=direction, i=i, j=j): board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.WHITE_UM else: board[0, i, j, 0] = Piece.WHITE_UM effect = sess.run(white_effect, feed_dict={ph: board}) self.assertTupleEqual(effect.shape, (9, 9)) if direction not in get_cross_directions(): # 利きがあるマスはない self.assertFalse(np.any(effect)) continue if direction == Direction.RIGHT: u, v = i - 1, j elif direction == Direction.UP: u, v = i, j - 1 elif direction == Direction.DOWN: u, v = i, j + 1 elif direction == Direction.LEFT: u, v = i + 1, j else: # ここには到達しないはず raise ValueError() if u not in range(9) or v not in range(9): # 盤の端に駒があるので、盤の中に利きはない self.assertFalse(np.any(effect)) continue self.assertTrue(effect[u, v]) # 利きがあるのは1か所だけのはず effect[u, v] = False self.assertFalse(np.any(effect))
def test_ry_pin(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) # ここではすべて有効に設定 available_board = np.ones(shape, dtype=np.bool) ph = tf.placeholder(tf.int32, shape=shape) ry_effect = BlackRyEffectLayer(data_format=self.data_format, use_cudnn=self.use_cudnn)( ph, available_board) # 余計な方向がないことを確認する self.assertEqual(8, len(ry_effect)) # 利用しやすいように次元を下げる ry_effect = { direction: tf.squeeze(effect) for direction, effect in ry_effect.items() } # 8種類の距離を一つにまとめる cross_directions = get_cross_directions() ry_effect = { direction: tf.reduce_any(effect, axis=0) if direction in cross_directions else effect for direction, effect in ry_effect.items() } with self.test_session() as sess: for i, j in product(range(9), repeat=2): # (i, j)に駒を置く board[:] = Piece.EMPTY for pin_direction in PinDirection: if pin_direction == PinDirection.SIZE: continue offset = Piece.SIZE + pin_direction * 14 if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_RY + offset else: board[0, i, j, 0] = Piece.BLACK_RY + offset effect = sess.run(ry_effect, feed_dict={ph: board}) for direction, e in effect.items(): with self.subTest(i=i, j=j, direction=direction): s, t = self._get_range(i=i, j=j, direction=direction) for x, y in zip(s, t): if x not in range(9) or y not in range(9): break if (pin_direction == PinDirection[ direction.name]): self.assertTrue(e[x, y]) # 利きをリセット e[x, y] = False # 最後にまとめて一つも利きがないことを確認する self.assertFalse(np.all(e))
def test_ry_effect(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) # 適当なマスクを設定 available_board = np.zeros(81, dtype=np.bool) available_board[::2] = True available_board = np.reshape(available_board, shape) ph = tf.placeholder(tf.int32, shape=shape) ry_effect = BlackRyEffectLayer(data_format=self.data_format, use_cudnn=self.use_cudnn)( ph, available_board) # 余計な方向がないことを確認する self.assertEqual(8, len(ry_effect)) # 利用しやすいように次元を下げる ry_effect = { direction: tf.squeeze(effect) for direction, effect in ry_effect.items() } # 8種類の距離を一つにまとめる cross_directions = get_cross_directions() ry_effect = { direction: tf.reduce_any(effect, axis=0) if direction in cross_directions else effect for direction, effect in ry_effect.items() } # Layerに渡したので、変更しても大丈夫 # アクセスしやすいように次元を下げる available_board = np.squeeze(available_board) with self.test_session() as sess: for i, j in product(range(9), repeat=2): # (i, j)に駒を置く board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_RY else: board[0, i, j, 0] = Piece.BLACK_RY effect = sess.run(ry_effect, feed_dict={ph: board}) for direction, e in effect.items(): with self.subTest(i=i, j=j, direction=direction): s, t = self._get_range(i=i, j=j, direction=direction) for x, y in zip(s, t): if x not in range(9) or y not in range(9): break if available_board[x, y]: self.assertTrue(e[x, y]) # 利きをリセット e[x, y] = False # 最後にまとめて一つも利きがないことを確認する self.assertFalse(np.all(e))
def test_ki_move(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) effect = { direction: np.empty(shape, dtype=np.bool) for direction in chain(get_cross_directions(), [Direction.RIGHT_UP, Direction.LEFT_UP]) } board = np.empty(shape, dtype=np.int32) ph_board = tf.placeholder(tf.int32, shape=shape) ki_effect = { direction: tf.placeholder(tf.bool, shape=shape) for direction in effect.keys() } non_promoting = BlackKiMoveLayer()(ph_board, ki_effect) # アクセスしやすいように次元を下げる non_promoting = { key: tf.squeeze(value) for key, value in non_promoting.items() } feed_dict = { placeholder: effect[direction] for direction, placeholder in ki_effect.items() } feed_dict[ph_board] = board with self.test_session() as sess: for i, j, piece in product(range(9), range(9), range(Piece.SIZE)): for e in effect.values(): e[:] = False if self.data_format == 'NCHW': e[0, 0, i, j] = True else: e[0, i, j, 0] = True piece = Piece(piece) board[:] = piece n = sess.run(non_promoting, feed_dict=feed_dict) b = np.squeeze(board) for direction, move in n.items(): with self.subTest(i=i, j=j, direction=direction): self.assertTupleEqual((9, 9), move.shape) if b[i, j] < Piece.WHITE_FU: # 自身の駒があって動けない self.assertFalse(np.all(move)) else: self.assertTrue(move[i, j]) move[i, j] = False self.assertFalse(np.all(move))
def test_hi_pin(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) # ここでは相手の利きがない設定 black_effect_mask = np.zeros(shape, dtype=np.bool) ph = tf.placeholder(tf.int32, shape=shape) short_effect = WhiteShortEffectLayer(data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) long_effect = WhiteLongEffectLayer(data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) ou_effect = WhiteOuEffectLayer(data_format=self.data_format, use_cudnn=self.use_cudnn)( ph, black_effect_mask) effect_count = WhiteEffectCountLayer()(short_effect, long_effect, ou_effect) effect_count = tf.squeeze(effect_count) with self.test_session() as sess: for i, j in product(range(9), repeat=2): # (i, j)に駒を置く board[:] = Piece.EMPTY for pin_direction in PinDirection: if pin_direction == PinDirection.SIZE: continue offset = Piece.SIZE - Piece.WHITE_FU + pin_direction * 14 if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.WHITE_HI + offset else: board[0, i, j, 0] = Piece.WHITE_HI + offset count = sess.run(effect_count, feed_dict={ph: board}) with self.subTest(i=i, j=j, pin_direction=pin_direction): c = 0 for direction in get_cross_directions(): if pin_direction != PinDirection[direction.name]: continue s, t = self._get_range(i=i, j=j, direction=direction) for x, y in zip(s, t): self.assertEqual(count[x, y], 1) c += 1 self.assertEqual(np.sum(count), c)
def test_short_check(self): """ 短い利きで王手されている場合に王以外の駒が動ける場所の判定をテスト :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) pseudo_effect = BlackPseudoOuEffect(data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) all_check, _ = WhiteAllCheckLayer()(ph, pseudo_effect) available_square = CheckAvailableSquareLayer()(pseudo_effect, all_check) available_square = tf.squeeze(available_square) short_check = WhiteShortCheckLayer()(ph, pseudo_effect) with self.test_session() as sess: for direction in chain( get_eight_directions(), [Direction.RIGHT_UP_UP, Direction.LEFT_UP_UP]): for i, j, piece in product(range(9), range(9), range(Piece.WHITE_FU, Piece.EMPTY)): piece = Piece(piece) if piece == Piece.WHITE_OU: # OUで王手はない continue # 長い利きはここではテストしない if piece == Piece.WHITE_KY and direction == Direction.UP: continue elif (piece in (Piece.WHITE_KA, Piece.WHITE_UM) and direction in get_diagonal_directions()): continue elif (direction in get_cross_directions() and piece in (Piece.WHITE_HI, Piece.WHITE_RY)): continue x, y = self._get_position(direction=direction, i=i, j=j) if x not in range(9) or y not in range(9): continue board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_OU board[0, 0, x, y] = piece else: board[0, i, j, 0] = Piece.BLACK_OU board[0, x, y, 0] = piece with self.subTest(direction=direction, i=i, j=j, piece=piece): square, check = sess.run( [available_square, short_check[direction]], feed_dict={ph: board}) self.assertTupleEqual(square.shape, (9, 9)) if check: self.assertTrue(square[x, y]) square[x, y] = False self.assertFalse(np.any(square)) else: self.assertTrue(np.all(square))
def test_effect1_long(self): """ KAの利きがあるかを確認するテスト 他の駒が利きを遮る場合は考えない :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) for direction in chain( get_eight_directions(), [Direction.RIGHT_DOWN_DOWN, Direction.LEFT_DOWN_DOWN]): if direction in (Direction.RIGHT_DOWN_DOWN, Direction.LEFT_DOWN_DOWN): # 桂馬の方向の長い利きはあり得ないのでエラー with self.assertRaises(ValueError): WhiteNaiveLongEffectLayer(direction=direction, data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) continue white_effect = WhiteNaiveLongEffectLayer( direction=direction, data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) # チャネルの処理が面倒なので、次元を下げる white_effect = tf.squeeze(white_effect) with self.test_session() as sess: for i, j in product(range(9), repeat=2): with self.subTest(direction=direction, i=i, j=j): board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.WHITE_RY else: board[0, i, j, 0] = Piece.WHITE_RY effect = sess.run(white_effect, feed_dict={ph: board}) self.assertTupleEqual(effect.shape, (9, 9)) if direction not in get_cross_directions(): # 利きがあるマスはない self.assertFalse(np.any(effect)) continue if direction == Direction.RIGHT: edge = i == 0 elif direction == Direction.LEFT: edge = i == 8 elif direction == Direction.UP: edge = j == 0 elif direction == Direction.DOWN: edge = j == 8 else: raise ValueError(direction) if edge: # 盤の端に駒があるので、盤の中に利きはない self.assertFalse(np.any(effect)) continue if direction == Direction.RIGHT: self.assertTrue(np.all(effect[:i, j])) effect[:i, j] = False elif direction == Direction.LEFT: self.assertTrue(np.all(effect[i + 1:, j])) effect[i + 1:, j] = False elif direction == Direction.UP: self.assertTrue(np.all(effect[i, :j])) effect[i, :j] = False elif direction == Direction.DOWN: self.assertTrue(np.all(effect[i, j + 1:])) effect[i, j + 1:] = False else: raise ValueError(direction) self.assertFalse(np.any(effect))
def test_effect2(self): """ HIの利きのある4方向にそれぞれ駒をおいて利きを遮った場合のテスト :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) # 利きを遮る駒の候補を作成 # 各方向についてテストするので、利きの長い駒以外が候補 block_piece_list = [ p for p in Piece if p not in (Piece.WHITE_KY, Piece.WHITE_KA, Piece.WHITE_HI, Piece.WHITE_UM, Piece.WHITE_RY, Piece.EMPTY, Piece.SIZE) ] ph = tf.placeholder(tf.int32, shape=shape) for direction in get_cross_directions(): white_effect = WhiteNaiveLongEffectLayer( direction=direction, data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) # チャネルの処理が面倒なので、次元を下げる white_effect = tf.squeeze(white_effect) with self.test_session() as sess: for i, j, k, l in product(range(9), range(9), range(9), [0, 1]): # KAを(i, j)に、 # 遮る駒を(i * l + k * (1 - l), j * (1 - l) + k * l)に置く x = i * l + k * (1 - l) y = j * (1 - l) + k * l if i == x and j == y: continue with self.subTest(direction=direction, i=i, j=j, k=k, l=l): board[:] = Piece.EMPTY block_piece = np.random.choice(block_piece_list) if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.WHITE_RY board[0, 0, x, y] = block_piece else: board[0, i, j, 0] = Piece.WHITE_RY board[0, x, y, 0] = block_piece effect = sess.run(white_effect, feed_dict={ph: board}) self.assertTupleEqual(effect.shape, (9, 9)) # 必ず4方向のどこかにあるので、xかyを比較すれば十分 if direction == Direction.RIGHT: block = x < i u, v = slice(x, i), j s, t = slice(None, i), j elif direction == Direction.LEFT: block = x > i u, v = slice(i + 1, x + 1), j s, t = slice(i + 1, None), j elif direction == Direction.UP: block = y < j u, v = i, slice(y, j) s, t = i, slice(None, j) elif direction == Direction.DOWN: block = y > j u, v = i, slice(j + 1, y + 1) s, t = i, slice(j + 1, None) else: raise ValueError(direction) if block: self.assertTrue(np.all(effect[u, v])) effect[u, v] = False else: self.assertTrue(np.all(effect[s, t])) effect[s, t] = False self.assertFalse(np.any(effect))
def test_um_move(self): """ UMについて成り、成らずの判定のテスト 利きが通るかどうかは別のところで判定しているので、ここでは考えない :return: """ shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) # 移動距離ごとに用意 effect = { direction: [np.empty(shape, dtype=np.bool) for _ in range(8)] for direction in get_diagonal_directions() } effect.update({ direction: np.empty(shape, dtype=np.bool) for direction in get_cross_directions() }) board = np.empty(shape, dtype=np.int32) ph_board = tf.placeholder(tf.int32, shape=shape) um_effect = { direction: [tf.placeholder(tf.bool, shape=shape) for _ in range(8)] for direction in get_diagonal_directions() } um_effect.update({ direction: tf.placeholder(tf.bool, shape=shape) for direction in get_cross_directions() }) non_promoting = BlackUmMoveLayer()(ph_board, um_effect) # アクセスしやすいように次元を下げる non_promoting = { key: tf.squeeze(value) for key, value in non_promoting.items() } feed_dict = {} for direction, ph_list in um_effect.items(): if direction in get_diagonal_directions(): for ph, e in zip(ph_list, effect[direction]): feed_dict[ph] = e else: feed_dict[ph_list] = effect[direction] feed_dict[ph_board] = board with self.test_session() as sess: for i, j, piece in product(range(9), range(9), range(Piece.SIZE)): for direction, effect_list in effect.items(): if direction in get_diagonal_directions(): for e in effect_list: e[:] = False if self.data_format == 'NCHW': e[0, 0, i, j] = True else: e[0, i, j, 0] = True else: effect_list[:] = False if self.data_format == 'NCHW': effect_list[0, 0, i, j] = True else: effect_list[0, i, j, 0] = True piece = Piece(piece) board[:] = piece n = sess.run(non_promoting, feed_dict=feed_dict) b = np.squeeze(board) for direction, distance in product(effect.keys(), range(8)): if direction in get_cross_directions(): if distance > 0: continue if direction == Direction.UP and j == 8: continue elif direction == Direction.DOWN and j == 0: continue elif direction == Direction.RIGHT and i == 8: continue elif direction == Direction.LEFT and i == 0: continue if direction in (Direction.RIGHT_UP, Direction.LEFT_UP): if j + distance >= 8: continue elif direction in (Direction.RIGHT_DOWN, Direction.LEFT_DOWN): if j - distance <= 0: continue if direction in (Direction.RIGHT_UP, Direction.RIGHT_DOWN): if i + distance >= 8: continue elif direction in (Direction.LEFT_UP, Direction.LEFT_DOWN): if i - distance <= 0: continue n_move = n[direction] if direction in get_diagonal_directions(): with self.subTest(i=i, j=j, piece=piece, direction=direction, distance=distance): self.assertTupleEqual((8, 9, 9), n_move.shape) if b[i, j] < Piece.WHITE_FU: # 自身の駒があって動けない self.assertFalse(np.all(n_move[distance])) else: self.assertTrue(n_move[distance, i, j]) n_move[distance, i, j] = False self.assertFalse(np.all(n_move[distance])) else: with self.subTest(i=i, j=j, piece=piece, direction=direction): self.assertTupleEqual((9, 9), n_move.shape) if b[i, j] < Piece.WHITE_FU: # 自身の駒があって動けない self.assertFalse(np.all(n_move)) else: self.assertTrue(n_move[i, j]) n_move[i, j] = False self.assertFalse(np.all(n_move))
def test_pin1(self): shape = (1, 1, 9, 9) if self.data_format == 'NCHW' else (1, 9, 9, 1) board = np.empty(shape, dtype=np.int32) ph = tf.placeholder(tf.int32, shape=shape) pseudo_effect = BlackPseudoOuEffect(data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) long_effect = { direction: WhiteNaiveLongEffectLayer(direction=direction, data_format=self.data_format, use_cudnn=self.use_cudnn)(ph) for direction in get_eight_directions() } pinned_board = BlackPinLayer(data_format=self.data_format)( ph, pseudo_effect, long_effect) offset = tf.squeeze(pinned_board - ph) long_piece_list = (Piece.WHITE_KY, Piece.WHITE_KA, Piece.WHITE_HI, Piece.WHITE_UM, Piece.WHITE_RY) pinned_piece_list = [ Piece(p) for p in range(Piece.BLACK_FU, Piece.WHITE_FU) if p != Piece.BLACK_OU ] with self.test_session() as sess: for tmp in product(get_eight_directions(), range(9), range(9), range(1, 8)): direction, i, j, k = tmp offset_value = Piece.SIZE + PinDirection[direction.name] * 14 # ピンされる駒の移動 x, y = self._get_position(direction=direction, i=i, j=j, k=k) if x not in range(9) or y not in range(9): continue for l in range(k + 1, 9): # 利きの長い駒の位置 u, v = self._get_position(direction=direction, i=i, j=j, k=l) if u not in range(9) or v not in range(9): continue board[:] = Piece.EMPTY if self.data_format == 'NCHW': board[0, 0, i, j] = Piece.BLACK_OU else: board[0, i, j, 0] = Piece.BLACK_OU for long_piece in long_piece_list: pinned_piece = np.random.choice(pinned_piece_list) if self.data_format == 'NCHW': board[0, 0, x, y] = pinned_piece board[0, 0, u, v] = long_piece else: board[0, x, y, 0] = pinned_piece board[0, u, v, 0] = long_piece if long_piece == Piece.WHITE_KY: pin = direction == Direction.UP elif long_piece in (Piece.WHITE_KA, Piece.WHITE_UM): pin = direction in get_diagonal_directions() elif long_piece in (Piece.WHITE_HI, Piece.WHITE_RY): pin = direction in get_cross_directions() else: # ここには到達しないはず raise ValueError(direction) with self.subTest(direction=direction, i=i, j=j, k=k, l=l, pinned_piece=pinned_piece, long_piece=long_piece): o = sess.run(offset, feed_dict={ph: board}) if pin: self.assertEqual(o[x, y], offset_value) # 他がすべて0であることを確認 o[x, y] = 0 self.assertTrue(np.all(o == 0)) else: self.assertTrue(np.all(o == 0))