実現したいこと
2ターン目白の合法手が間違っているのを直したい
発生している問題・分からないこと
2ターン目白の合法手が間違っている
エラーメッセージ
error
1オセロを開始します 2 A B C D E F G H 31 . . . . . . . . 42 . . . . . . . . 53 . . . . . . . . 64 . . . ● ○ . . . 75 . . . ○ ● . . . 86 . . . . . . . . 97 . . . . . . . . 108 . . . . . . . . 11 12合法手: 100000010000000000100000010000000000000000000 13黒の番です 14合法手: d6 c5 f4 e3 15石を置く位置を入力してください (例: d3): e3 16 A B C D E F G H 171 . . . . . . . . 182 . . . . . . . . 193 . . . . ● . . . 204 . . . ● ● . . . 215 . . . ○ ● . . . 226 . . . . . . . . 237 . . . . . . . . 248 . . . . . . . . 25 26合法手: 10000001010000000010000100000000100000000000000000000 27白の番です 28合法手: e6 f5 c4 d3 f3 e2 29石を置く位置を入力してください (例: d3):
該当のソースコード
python
1BOARD_SIZE = 8 2# 盤面(ビットボード)の初期化 3black_disc_bit = 0x0000000810000000 # 黒石(16進数で) 4white_disc_bit = 0x0000001008000000 # 白石(16進数で) 5white_or_black = 0 # 0:黒, 1:白 6blank = ~(black_disc_bit | white_disc_bit) # 空きマス 7 8 9def shift(bitboard, direction): 10 if direction > 0: 11 return bitboard << direction 12 else: 13 return bitboard >> -direction 14 15 16def get_legal_moves(black_disc_bit, white_disc_bit, black_or_white): 17 legal = 0 18 if black_or_white == 0: # 黒のターン 19 player = black_disc_bit 20 opponent = white_disc_bit 21 else: # 白のターン 22 player = white_disc_bit 23 opponent = black_disc_bit 24 25 blank = ~(player | opponent) 26 27 directions = [1, -1, 8, -8, 7, -7, 9, -9] 28 masks = [ 29 0x7F7F7F7F7F7F7F7F, # 左から右 30 0xFEFEFEFEFEFEFEFE, # 右から左 31 0xFFFFFFFFFFFFFFFF, # 上から下 32 0xFFFFFFFFFFFFFFFF, # 下から上 33 0x7F7F7F7F7F7F7F7F, # 左上から右下 34 0xFEFEFEFEFEFEFEFE, # 右上から左下 35 0x7F7F7F7F7F7F7F7F, # 左下から右上 36 0xFEFEFEFEFEFEFEFE, # 右下から左上 37 ] 38 39 for direction, mask in zip(directions, masks): 40 temp = shift(player, direction) & opponent & mask 41 # print(f"temp:{temp},direction:{direction}") 42 while temp: 43 next_temp = shift(temp, direction) & opponent & mask 44 if next_temp: 45 temp |= next_temp 46 else: 47 break 48 # print("temp:{temp},direction:{direction}") 49 # print("legal:", legal) 50 # 合法手を更新 51 legal |= shift(temp, direction) & blank & mask 52 53 return legal # ここで legal を返す 54 55 56def print_board(black, white): 57 print(" A B C D E F G H") 58 for y in range(BOARD_SIZE): 59 row = [] 60 for x in range(BOARD_SIZE): 61 idx = (7 - y) * 8 + x 62 mask = 1 << idx # 検査するマスク 63 if black & mask: 64 row.append("●") 65 elif white & mask: 66 row.append("○") 67 else: 68 row.append(".") 69 print(f"{y+1} {' '.join(row)}") 70 print() 71 72 73def pos_to_bit(pos): 74 # pos: 例 "d3" → (x=3, y=2) 75 x = ord(pos[0]) - ord("a") 76 y = int(pos[1]) - 1 77 idx = (7 - y) * 8 + x 78 return 1 << idx 79 80 81def flip_discs(black, white, pos, black_or_white): 82 bit = pos_to_bit(pos) 83 player = black if black_or_white == 0 else white 84 opponent = white if black_or_white == 0 else black 85 86 directions = [1, -1, 8, -8, 7, -7, 9, -9] 87 masks = [ 88 0x7F7F7F7F7F7F7F7F, # 左から右 89 0xFEFEFEFEFEFEFEFE, # 右から左 90 0xFFFFFFFFFFFFFFFF, # 上から下 91 0xFFFFFFFFFFFFFFFF, # 下から上 92 0x7F7F7F7F7F7F7F7F, # 左上から右下 93 0xFEFEFEFEFEFEFEFE, # 右上から左下 94 0x7F7F7F7F7F7F7F7F, # 左下から右上 95 0xFEFEFEFEFEFEFEFE, # 右下から左上 96 ] 97 98 for direction, mask in zip(directions, masks): 99 flipped = 0 100 temp = shift(bit, direction) & opponent & mask 101 while temp: 102 flipped |= temp 103 temp = shift(temp, direction) & opponent & mask 104 if shift(flipped, direction) & player & mask: 105 player |= flipped 106 opponent &= ~flipped 107 108 if black_or_white == 0: 109 black = player 110 else: 111 white = player 112 113 return black, white 114 115 116# オセロの表示 117def put_disc(black, white, pos, black_or_white): 118 black, white = flip_discs(black, white, pos, black_or_white) 119 bit = pos_to_bit(pos) 120 if black_or_white == 0: 121 black |= bit 122 else: 123 white |= bit 124 return black, white 125 126 127def play_game(): 128 black = black_disc_bit 129 white = white_disc_bit 130 turn = 0 # 0: 黒, 1: 白 131 132 while True: 133 print_board(black, white) 134 legal_moves = get_legal_moves(black, white, turn) 135 print(f"合法手: {legal_moves:b}") # ビット表示で合法手を表示,デバッグ用 136 if legal_moves == 0: 137 turn = 1 - turn # パス 138 legal_moves = get_legal_moves(black, white, turn) 139 if legal_moves == 0: # 両方パスならゲーム終了 140 print("両方パスです。ゲーム終了") 141 break 142 else: 143 print("パス") 144 continue # もう一方のプレイヤーのターンへ 145 146 if turn == 0: 147 print("黒の番です") 148 else: 149 print("白の番です") 150 151 print("合法手: ", end="") 152 legal_moves_list = [] 153 for i in range(64): 154 if (legal_moves >> i) & 1: 155 x = chr(ord("a") + i % 8) 156 y = str(8 - i // 8) 157 move = x + y 158 legal_moves_list.append(move) 159 print(move, end=" ") 160 print() 161 162 while True: 163 pos = input("石を置く位置を入力してください (例: d3): ").lower() 164 if pos == "q": 165 print("中断します。") 166 return 167 if pos in legal_moves_list: 168 black, white = put_disc(black, white, pos, turn) 169 turn = 1 - turn 170 break 171 else: 172 print("無効な手です。もう一度入力してください。") 173 174 print_board(black, white) 175 print("ゲーム終了") 176 black_count = bin(black).count("1") 177 white_count = bin(white).count("1") 178 print(f"黒: {black_count}, 白: {white_count}") 179 if black_count > white_count: 180 print("黒の勝ちです!") 181 elif white_count > black_count: 182 print("白の勝ちです!") 183 else: 184 print("引き分けです!") 185 186 187def main(): 188 print("オセロを開始します") 189 play_game() 190 print("オセロを終了します") 191 print("お疲れ様でした") 192 print("また遊んでください") 193 194 195if __name__ == "__main__": 196 main() 197
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
print文を追加してlegalを出力しましたがよくわかりません。chatgptにも質問しましたが具体的なエラー元の特定方法がわかりません。
補足
macM1
Python 3.10.16
参考
ビットボード解説
https://speakerdeck.com/antenna_three/bitutobodojie-shuo?slide=37
chatgpt
gemini

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。