TIM Labs

2015年6月アーカイブ

早速だが、コードを見てほしい。ネットワークデータを一旦ローカルの一時ファイルに受け取り、後でゆっくり読み書きしよう、という意図のコードだ。呼び出し元はファイルハンドルを受けとり、シークを含めた読み書きができる、というか、したい。

def create_tempfile(*)
  network_source = ... # 省略
  Tempfile.new("example").binmode.tap do |file|
    IO.copy_stream(network_source, file)
    file.rewind
  end
end

ところが、このコードには問題がある。普段何も問題なく動くのに、時折このメソッドから受け取るファイルに対して操作をしようとしたら IOError が発生することがある。しかもこのエラーは環境や時間、扱うデータによって発生したりしなかったりするし、スタックトレースはなにやら所謂ライブラリ類の奥深く。そもそも問題の原因がここであることを突き止めるにも一苦労があったわけだが、えーっと、現場の苦労話はさておきだ、とにかく「問題の原因はこのコード」、「発生している例外が持つメッセージは "closed stream"」である。

どう直せば解決するか、分かっただろうか?

問題

以前、オセロの対戦AIの作成しましたが、そこでは実装を簡略化する為に盤面の価値を

  • 盤面の価値 = 自分の石の数 - 相手の石の数

という単純な方法で決めていました。 でも、これには問題があります。

  • 同じ石でも配置場所によって価値は異なるはずです(例: 角は最強)。それが考慮されていません。
  • ゲーム終盤になってくると石の数が重要になってきます。でも序盤から石の数を重視するのは方向性としておかしいです。

という訳で、

  • 序盤から中盤では石の配置場所を重視する
  • 終盤では石の数を重視する

形で盤面の価値を算出すれば、結構良さそうなAIになりそうです。

しかし、今度は

  • 「序盤」「中盤」「終盤」をどのように区別するのか?
  • 石の配置場所の強弱はどう決めるのか?
  • 同じ配置場所でも周囲の状況次第で強弱が異なるのでは?

という問題が出てきます。これは作るのが面倒臭そうです。

どうにかしてお手軽かつそこそこ強そうなAIを作れないものでしょうか?

このアーカイブについて

このページには、2015年6月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2015年5月です。

次のアーカイブは2015年7月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。