Windows標準付属ゲームのスコア履歴を記録する

スコアがどこに入っているかを調べると、%APPDATA%\Microsoft Games の下のゲーム毎のフォルダーに格納されている。
ソリテアだと、%APPDATA%\Microsoft Games\Solitaire\SolitaireSettings.xml
ゲーム名のフォルダーは、Explorerから見ると「ソリテア」と片仮名になっているが、実際にはSolitaireと英字だ。Usersと「ユーザー」のようなもの。


拡張子がxmlになっているが、xmlの前後に何か付いていて、そのままではxmlパーサーで読めない。
そこで、以前と、以降を最初に削除してやってから、パーサーに掛ける。
勝ち数、試合数、勝率をホームディレクトリの下のゲーム名のフォルダーに日付を付けて記録する。
これをタスクマネージャから毎日実行すれば良い。

require "rexml/document"

ROOT= "<Root>".encode("UTF-16LE").force_encoding("ASCII-8BIT")
TOOR="</Root>".encode("UTF-16LE").force_encoding("ASCII-8BIT")

def game(name, tag)
  name1 = name.gsub(/\s/,"")
  file=File.join(ENV["LOCALAPPDATA"],"Microsoft Games",name,"#{name1}Settings.xml")
  outf =File.expand_path("~/#{name1}.txt")

  data = open(file,"rb",encoding:"ASCII-8BIT").read
  text = data[/#{ROOT}.*#{TOOR}/m].force_encoding("UTF-16LE").encode("UTF-8")
  doc  = REXML::Document.new(text)
  played = doc.root.get_elements("//#{tag}/GamesPlayed")[0].text.to_i
  won    = doc.root.get_elements("//#{tag}/GamesWon")[0].text.to_i

  out = [Time.now.strftime("%F"),played, won, won.to_f/played.to_f].join("\t")
  open(outf,"a"){|f| f.puts out}
end

game("Solitaire", "NoTimeScoringStats")

game("Hearts", "Stats")

game("Spider Solitaire", "StatsIntermediate")