学習したマッチ箱と勝負する(AIプログラミング 第3回)
考えるマッチ箱
前回、「マッチ箱」に三目並べを学習させました。2097個のマッチ箱と勝負して果たして勝てるかという実験です。
先手を入力できるように変更したソースコードがこちらです。
import random
import csv
# csvファイルを読み込む
with open("matchbox.csv", "r", encoding="Shift_jis") as f:
reader = list(csv.reader(f))
print("マッチ箱の数:", len(reader))
# 繰り返し処理(試行回数)
for step in range(10):
# 盤面
board_1 = [0,0,0,0,0,0,0,0,0]
# 1手目(入力)==========
print("1┃2┃3")
print("━✚━✚━")
print("4┃5┃6")
print("━✚━✚━")
print("7┃8┃9")
sente = int(input("1手目を入力してください。"))
board_1[sente-1] = 1
# 2手目(コンピュータ)==========
box1 = -1
for i in range(len(reader)):
# 文字リストを数値に変換
reader[i] = [int(j) for j in reader[i]]
# 同じマッチ箱があるか探す
if board_1[0:9] == reader[i][0:9]:
box1 = i
print("マッチ箱が見つかりました(2手目)",box1)
break
# マッチ箱が見つからなかった場合
if box1 == -1:
print("マッチ箱の数2:", len(reader))
box1 = len(reader)
# リストを結合
board_1.extend([0,0,0,0,0,0,0,0,0])
# ビーズを用意
for i in range(9):
if board_1[i] == 0:
board_1[i+9] = 1
# マッチ箱を追加
reader.append(board_1[:])
board_2 = reader[box1][:]
n = sum(board_2[9:])
n = random.randrange(n)
for i in range(9):
if n - board_2[i+9] < 0:
# 次の一手
next_com1 = i
board_2[i] = -1
board_2[i+9] = 0
break
n = n - board_2[i+9]
# 3手目(入力)==========
board_3 = board_2[:]
print(board_3[:3])
print(board_3[3:6])
print(board_3[6:9])
next_move = -1
while next_move == -1:
sente = int(input("3手目を入力してください。"))
if sente <= 9 and board_3[sente-1] == 0:
next_move = sente - 1
board_3[next_move] = 1
board_3[next_move+9] = 0
# 4手目(コンピュータ)==========
box2 = -1
for i in range(len(reader)):
# 文字リストを数値に変換
reader[i] = [int(j) for j in reader[i]]
# 同じマッチ箱があるか探す
if board_3[0:9] == reader[i][0:9]:
box2 = i
print("===マッチ箱が見つかりました===",box2)
break
# マッチ箱が見つからなかった場合
if box2 == -1:
print("マッチ箱の数4:", len(reader))
box2 = len(reader)
# ビーズを初期化(これが大事)
for i in range(9):
if board_3[i] == 0:
board_3[i+9] = 1
# マッチ箱を追加
reader.append(board_3[:])
board_4 = reader[box2][:]
n = sum(board_4[9:])
if n == 0:
print("打つ手がありません!(4手目)")
# 2手目がダメだったで、2手目は打たないようにする
print("2手目の「×」の手は?")
print(board_2)
print("前の一手", next_com1)
# 1手前に戻してこの手は打たないようにする
reader[box1][next_com1+9] = 0
print(reader[box1])
print(board_4[:3])
print(board_4[3:6])
print(board_4[6:9])
continue
n = random.randrange(n)
for i in range(9):
if n - board_4[i+9] < 0:
# 次の一手
next_com2 = i
board_4[i] = -1
board_4[i+9] = 0
break
n = n - board_4[i+9]
# 5手目(ランダム)==========
board_5 = board_4[:]
print(board_5[:3])
print(board_5[3:6])
print(board_5[6:9])
next_move = -1
while next_move == -1:
sente = int(input("5手目を入力してください。"))
if board_5[sente-1] == 0:
next_move = sente - 1
board_5[next_move] = 1
board_5[next_move+9] = 0
#「〇」の勝ちを確認
if (board_5[0] == 1 and board_5[1] == 1 and board_5[2] == 1) \
or (board_5[3] == 1 and board_5[4] == 1 and board_5[5] == 1) \
or (board_5[6] == 1 and board_5[7] == 1 and board_5[8] == 1) \
or (board_5[0] == 1 and board_5[3] == 1 and board_5[6] == 1) \
or (board_5[1] == 1 and board_5[4] == 1 and board_5[7] == 1) \
or (board_5[2] == 1 and board_5[5] == 1 and board_5[8] == 1) \
or (board_5[0] == 1 and board_5[4] == 1 and board_5[8] == 1) \
or (board_5[2] == 1 and board_5[4] == 1 and board_5[6] == 1):
print(board_5[:3])
print(board_5[3:6])
print(board_5[6:9])
print("「〇」の勝ちです")
# ここに負けた時の処理
print("1手前の「×」の手は?")
print(board_4)
print("前の一手", next_com2)
# 1手前に戻してこの手は打たないようにする
reader[box2][next_com2] = 0
reader[box2][next_com2+9] = 0
print(reader[box2])
#break
continue
# 6手目(コンピュータ)==========
box3 = -1
for i in range(len(reader)):
# 文字リストを数値に変換
reader[i] = [int(j) for j in reader[i]]
# 同じマッチ箱があるか探す
if board_5[0:9] == reader[i][0:9]:
box3 = i
print("===マッチ箱が見つかりました===",box3)
break
# マッチ箱が見つからなかった場合
if box3 == -1:
print("マッチ箱の数6:", len(reader))
box3 = len(reader)
# ビーズを初期化(これが大事)
for i in range(9):
if board_5[i] == 0:
board_5[i+9] = 1
# マッチ箱を追加
reader.append(board_5[:])
board_6 = reader[box3][:]
n = sum(board_6[9:])
if n == 0:
print("打つ手がありません!(6手目)")
# 4手目がダメだったで、4手目は打たないようにする
print("4手目の「×」の手は?")
print(board_4)
print("前の一手", next_com2)
# 1手前に戻してこの手は打たないようにする
reader[box2][next_com2] = 0
reader[box2][next_com2+9] = 0
print(reader[box2])
print(board_6[:3])
print(board_6[3:6])
print(board_6[6:9])
continue
n = random.randrange(n)
for i in range(9):
if n - board_6[i+9] < 0:
# 次の一手
next_com3 = i
board_6[i] = -1
board_6[i+9] = 0
break
n = n - board_6[i+9]
#「×」の勝ちを確認
if (board_6[0] == -1 and board_6[1] == -1 and board_6[2] == -1) \
or (board_6[3] == -1 and board_6[4] == -1 and board_6[5] == -1) \
or (board_6[6] == -1 and board_6[7] == -1 and board_6[8] == -1) \
or (board_6[0] == -1 and board_6[3] == -1 and board_6[6] == -1) \
or (board_6[1] == -1 and board_6[4] == -1 and board_6[7] == -1) \
or (board_6[2] == -1 and board_6[5] == -1 and board_6[8] == -1) \
or (board_6[0] == -1 and board_6[4] == -1 and board_6[8] == -1) \
or (board_6[2] == -1 and board_6[4] == -1 and board_6[6] == -1):
print(board_6[:3])
print(board_6[3:6])
print(board_6[6:9])
print("「×」の勝ちです")
# ここに勝った時の処理
continue
# 7手目(ランダム)==========
board_7 = board_6[:]
print(board_7[:3])
print(board_7[3:6])
print(board_7[6:9])
next_move = -1
while next_move == -1:
sente = int(input("7手目を入力してください。"))
if board_7[sente-1] == 0:
next_move = sente - 1
board_7[next_move] = 1
board_7[next_move+9] = 0
#「〇」の勝ちを確認
if (board_7[0] == 1 and board_7[1] == 1 and board_7[2] == 1) \
or (board_7[3] == 1 and board_7[4] == 1 and board_7[5] == 1) \
or (board_7[6] == 1 and board_7[7] == 1 and board_7[8] == 1) \
or (board_7[0] == 1 and board_7[3] == 1 and board_7[6] == 1) \
or (board_7[1] == 1 and board_7[4] == 1 and board_7[7] == 1) \
or (board_7[2] == 1 and board_7[5] == 1 and board_7[8] == 1) \
or (board_7[0] == 1 and board_7[4] == 1 and board_7[8] == 1) \
or (board_7[2] == 1 and board_7[4] == 1 and board_7[6] == 1):
print(board_7[:3])
print(board_7[3:6])
print(board_7[6:9])
print("「〇」の勝ちです")
# ここに負けた時の処理
print("1手前の「×」の手は?")
print(board_6)
print("前の一手", next_com3)
# 1手前に戻してこの手は打たないようにする
reader[box3][next_com3+9] = 0
print(reader[box3])
#break
continue
# 8手目(コンピュータ)
box4 = -1
for i in range(len(reader)):
# 文字リストを数値に変換
reader[i] = [int(j) for j in reader[i]]
# 同じマッチ箱があるか探す
if board_7[0:9] == reader[i][0:9]:
box4 = i
print("===マッチ箱が見つかりました===",box4)
break
# マッチ箱が見つからなかった場合
if box4 == -1:
print("マッチ箱の数8:", len(reader))
box4 = len(reader)
# ビーズを初期化(これが大事)
for i in range(9):
if board_7[i] == 0:
board_7[i+9] = 1
# マッチ箱を追加
reader.append(board_7[:])
board_8 = reader[box4][:]
n = sum(board_8[9:])
if n == 0:
print("打つ手がありません!(8手目)")
# 6手目がダメだったで、6手目は打たないようにする
print("6手目の「×」の手は?")
print(board_6)
print("前の一手", next_com3)
# 1手前に戻してこの手は打たないようにする
reader[box3][next_com3] = 0
reader[box3][next_com3+9] = 0
print(reader[box3])
print(board_8[:3])
print(board_8[3:6])
print(board_8[6:9])
continue
n = random.randrange(n)
for i in range(9):
if n - board_8[i+9] < 0:
# 次の一手
next_com4 = i
board_8[i] = -1
board_8[i+9] = 0
break
n = n - board_8[i+9]
#「×」の勝ちを確認
if (board_8[0] == -1 and board_8[1] == -1 and board_8[2] == -1) \
or (board_8[3] == -1 and board_8[4] == -1 and board_8[5] == -1) \
or (board_8[6] == -1 and board_8[7] == -1 and board_8[8] == -1) \
or (board_8[0] == -1 and board_8[3] == -1 and board_8[6] == -1) \
or (board_8[1] == -1 and board_8[4] == -1 and board_8[7] == -1) \
or (board_8[2] == -1 and board_8[5] == -1 and board_8[8] == -1) \
or (board_8[0] == -1 and board_8[4] == -1 and board_8[8] == -1) \
or (board_8[2] == -1 and board_8[4] == -1 and board_8[6] == -1):
print(board_8[:3])
print(board_8[3:6])
print(board_8[6:9])
print("「×」の勝ちです")
# ここに勝った時の処理
continue
# 9手目(ランダム)
board_9 = board_8[:]
sente = random.randrange(1)
for i in range(9):
if board_9[i] == 0:
if sente == 0:
# 次の一手
next_move = i
board_9[i] = 1
board_9[i+9] = 0
break
sente -= 1
#「〇」の勝ちを確認
if (board_9[0] == 1 and board_9[1] == 1 and board_9[2] == 1) \
or (board_9[3] == 1 and board_9[4] == 1 and board_9[5] == 1) \
or (board_9[6] == 1 and board_9[7] == 1 and board_9[8] == 1) \
or (board_9[0] == 1 and board_9[3] == 1 and board_9[6] == 1) \
or (board_9[1] == 1 and board_9[4] == 1 and board_9[7] == 1) \
or (board_9[2] == 1 and board_9[5] == 1 and board_9[8] == 1) \
or (board_9[0] == 1 and board_9[4] == 1 and board_9[8] == 1) \
or (board_9[2] == 1 and board_9[4] == 1 and board_9[6] == 1):
print(board_9[:3])
print(board_9[3:6])
print(board_9[6:9])
print("「〇」の勝ちです")
# ここに負けた時の処理
print("1手前の「×」の手は?")
print(board_8)
print("前の一手", next_com4)
# 1手前に戻してこの手は打たないようにする
reader[box4][next_com4] = 0
reader[box4][next_com4+9] = 0
print(reader[box4])
#break
continue
print(board_9[:3])
print(board_9[3:6])
print(board_9[6:9])
print("引き分けです")
# ここに引き分けの時の処理
# csvファイルに書き込み
with open("matchbox.csv", "w", encoding="Shift_jis") as f: # 文字コードをShift_JISに指定
writer = csv.writer(f, lineterminator="\n") # writerオブジェクトの作成 改行記号で行を区切る
writer.writerows(reader) # csvファイルに書き込み
1~9以外の数字を入力すると、おかしくなったりエラーになりますが気にしません。
勝負しました。はい、勝てませんでした。成功です。
勝った時に報酬を与えていないので、ここに打ったら勝てるという盤面でも勝つ手を打ってくれないです。(負けない手を打ちます)
次回は、「オセロ」もやってみたいのですが、先に「ミニマックス法」が気になるので引き続き「三目並べ」を使って勉強していきたいと思います。