It would be useful to choose Ruby for my new concert, so this morning I wrote the following. It takes a PGN file from the chess games I played and indexes them with the first move. I would appreciate any suggestions on how to make it more "idiomatic."
Since it does not accept command line arguments (for example, for a file name) and does not apply to object-oriented sentences on these lines, it is certainly welcome.
Keep in mind that I am creating an index of all the moves (not just the first steps) from all the games, because I would like to end up indexing more than just the first move.
Data follows the code.
games = []
file = File.new("jemptymethod.pgn", "r")
is_header = false
is_score = false
Game = Struct::new(:header, :score)
while (line = file.gets)
if !line.chomp.empty?
if !is_score && !is_header
game = Game::new('','')
end
if /^\[/.match(line)
is_header = true
game.header << line
else
is_score = true
game.score << line
end
else
if is_score
is_score = false
is_header = false
games << game
end
end
end
file.close
puts "# Games: " + games.length.to_s
moves_index = {}
first_moves = {}
games.each { |gm|
score_tokens = gm.score.split(/\s+/);
game_moves = []
score_tokens.each_index{|i|
if i%3 != 0
move_token = score_tokens[i]
if !moves_index.has_key?(move_token)
moves_index[move_token] = moves_index.keys.length
end
game_moves << moves_index[move_token]
end
}
first_move = moves_index.index(game_moves[0])
if !first_moves.has_key?(first_move)
first_moves[first_move] = 1
else
first_moves[first_move] = 1 + first_moves[first_move]
end
}
first_moves.sort{|a,b| -1*(a[1]<=>b[1])}.each{|k,v|
puts "1. #{k} occurred #{v} times"
}
Data (total 3 games, I worked with 25):
[Event "Enough With the Draws Already ;)"]
[Site "http://www.queenalice.com/game.php?id=533406"]
[Date "2009.2.1"]
[Round "-"]
[White "Troy"]
[Black "jemptymethod"]
[Result "1/2-1/2"]
[WhiteElo "1300"]
[BlackElo "2076"]
[ECO "C36"]
1. e4 e5 2. f4 exf4 3. Nf3 Be7 4. Bc4 Nf6 5. Qe2 d5 6. exd5 Nxd5 7. O-O Be6 8.
d4 Nc6 9. Nc3 O-O 10. Nxd5 Bxd5 11. Bxd5 Qxd5 12. Bxf4 Bd6 13. Qd2 Rae8 14. Bxd6
Qxd6 15. Rae1 h6 16. c3 Qd5 17. b3 Qa5 18. h3 a6 19. Rf2 Re7 20. Rxe7 Nxe7 21.
Ne5 Nd5 22. c4 Qxd2 1/2-1/2
[Event "AUTO-MASTER-620"]
[Site "http://www.queenalice.com/game.php?id=545265"]
[Date "2009.2.23"]
[Round "2"]
[White "testouverture"]
[Black "jemptymethod"]
[Result "1/2-1/2"]
[WhiteElo "2240"]
[BlackElo "2179"]
[ECO "A52"]
1. d4 Nf6 2. c4 e5 3. dxe5 Ng4 4. Nf3 Bc5 5. e3 Nc6 6. Be2 O-O 7. O-O Re8 8. b3
Ngxe5 9. Bb2 Nxf3+ 10. Bxf3 Ne5 11. Nc3 a5 12. Ne4 Bf8 13. Bh5 Ra6 14. f4 Ng6
15. Ng5 d5 16. Nxf7 Kxf7 17. f5 Kg8 18. fxg6 hxg6 19. Qd4 Qe7 20. Bf3 dxc4 21.
Qxc4+ Be6 22. Qc3 c6 23. Be2 Raa8 24. Bd3 Bf5 25. Bxf5 gxf5 26. Rf3 Qc5 27. Re1
Qxc3 28. Bxc3 g6 29. g4 Bg7 30. Bxg7 fxg4 31. Rg3 Kxg7 32. Rxg4 Rad8 33. Kf2
1/2-1/2
[Event "AUTO-MASTER-620"]
[Site "http://www.queenalice.com/game.php?id=545266"]
[Date "2009.2.23"]
[Round "2"]
[White "jemptymethod"]
[Black "testouverture"]
[Result "0-1"]
[WhiteElo "2079"]
[BlackElo "2306"]
[ECO "B22"]
1. e4 c5 2. c3 d5 3. exd5 Qxd5 4. d4 Nc6 5. dxc5 Qxd1+ 6. Kxd1 e5 7. Be3 Nf6 8.
b4 a5 9. b5 Ne7 10. Nf3 Ng4 11. Bc4 Nf5 12. Ke2 Nfxe3 13. fxe3 Bxc5 14. h3 Nxe3
15. Nxe5 f6 0-1