SQL(オセロのデータ整理001:大きなデータの入力)
■SQLiteで大きなデータを扱う。
以前、Powershellで作ったオセロのゲームをテキストファイルとして保存していた。そのうち整理しようと思っていたけど、前回ちょうどSQLiteにふれたので、それを使ってデータベースに入れる。
対象はランダムとランダムで行った10万回のゲームの結果×10ファイル。1ファイルは1.3GBほどあり、メモ帳で開こうとすると「大きすぎてメモ帳では編集できません」とメッセージが出る。データベースに入れれば、表示や操作ができるようになるものか。
1回のゲームの結果のフォーマットは、下のように出力される。
Game:1| Start Othello
________
________
________
___〇●___
___●〇___
________
________
________
=====Trial:1=====
________
________
________
___〇●___
___〇〇___
___〇____
________
________
=====Trial:2=====
(途中省略)
=====Trial:60=====
〇〇〇〇〇〇〇〇
〇〇〇●●●〇〇
〇〇〇〇〇●〇〇
〇〇〇〇〇●●〇
〇〇●〇〇〇●〇
〇●●●〇〇〇●
〇〇〇〇〇〇●●
〇〇〇〇〇〇〇●
●15vs〇49Game:1| End Othello
Start Othello、End Othello、Trialあたりをキーワードとして文字列操作をした後、下のテーブルに入れる。
ゲームテーブル(ID、Trial00、Trial01、(省略)、Trial68、White_result、Black_result、Result、Note)
お互い問題なく石を置くことができれば、空いている60のスペースは60回のターンで埋まり、初期状態も含めて61の列(カラム)があれば足りる。ただ、置くところがなくパスすることも考えて、69(Trial00が初期状態)のカラムを作っておく。
それぞれのカラムの仕様は下のような感じ。
ID:ゲームのID(重複しない、1から順に自動的に入力)
Trialxx:オセロの盤の状態を示す(8×8の64に改行を足した分のテキスト長にする。メモ帳で○を追加・削除しながら保存してファイルサイズを確認すると、○、●、_は3バイト、改行は2バイトだった。なので、64*3バイト+14バイト(206バイト)を確保)
White(Black)_result:最終的な白(黒)の石の数を入力(数値として入力、整数値tinyint)
Result:勝ったプレイヤーなどを白、黒、引き分けで入力(W、B、Eの文字として入力、1バイト)
Note:備考として、後でメモを入れられるようにカラムを設定しておく(32バイト)。
下のコードでゲーム結果をテーブルの形にあうようなリストに変換した。
データベースへの挿入(INSERT)は、別の関数db(game)として定義する。ファイルサイズが大きくても対応できるよう1ゲーム毎にデータベースに入れる。
def txtfile_to_lines(filename):
f = open(filename, 'r', encoding='UTF-8')
game = []
board = ""
row_no = 0
flag = -1
while True:
line = f.readline()
if line:
if line.find("Start Othello") > 0:
line = f.readline()
flag = 0
elif line.find("Trial") > 0:
game.append(board.strip())
board = ""
flag = 0
line = f.readline()
elif line.find("End Othello") > 0:
game.append(board.strip())
flag = 1
if flag == 0:
board = board + line
elif flag == 1:
Black = int(line[line.find("●") + 1:line.find("vs")])
White = int(line[line.find("〇") + 1:line.find("Game")])
if len(game) < 69:
while True:
if len(game) == 69:
break
else:
game.append("")
game.append(White)
game.append(Black)
if Black > White:
game.append("B")
elif Black < White:
game.append("W")
elif Black == White:
game.append("E")
db(game)
# for data in game:
# print(data)
board = ""
game = []
else:
break
f.close()
return game
最終的に、1.2GBのデータベースファイルに変換できた。
このファイルに対して、例えば、次のSQL文を実行すると、下のような結果が得られる。
SELECT White_result, Black_result, Result FROM game where White_result > 59
問題なくデータが入力されているよう。
次回、このデータベースに対してSQLのビューやカーソルなど使って何かできないか試してみる。