Use milliseconds to update ICS clocks.
[kaya.git] / lib / ics / style12.rb
blob2bc574912ff6d0b520a66d4dd40efc44176f9298
1 require 'ics/icsapi'
3 module ICS
5 # Style 12 was designed by Daniel Sleator 
6 # (sleator+@cs.cmu.edu) Darooha@ICC
7 class Style12
8   PATTERN = %r{
9     ^<12>\s+                      # header
10     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
11     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
12     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
13     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
14     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
15     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
16     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
17     ([qkbnrpQKBNRP-]{8})\s+       # chessboard
18     ([BW])\s+                     # black/white
19     (-1|[0-7])\s+                 # passing pawn
20     ([01])\s+                     # castle rights
21     ([01])\s+                     # castle rights
22     ([01])\s+                     # castle rights
23     ([01])\s+                     # castle rights
24     (-?\d+)\s+                    # 50 moves made
25     (\d+)\s+                      # game number
26     (\S+)\s+                      # white name
27     (\S+)\s+                      # black name
28     (-[1-4]|[0-2])\s+             # status
29     (\d+)\s+                      # time
30     (\d+)\s+                      # inc
31     (\d+)\s+                      # w material
32     (\d+)\s+                      # b material
33     (-?\d+)\s+                    # w time
34     (-?\d+)\s+                    # b time
35     (\d+)\s+                      # move made
36     (\S+)\s+                      # coordmove
37     (\S+)\s+                      # time used
38     (\S+)\s+                      # algmove
39     ([0-1])                       # flip }x
41   CHESSBOARD = 1
42   TURN = 9
43   EN_PASSANT = 10
44   WHITE_KING_CASTLING = 11
45   WHITE_QUEEN_CASTLING = 12
46   BLACK_KING_CASTLING = 13
47   BLACK_QUEEN_CASTLING = 14
48   REVERSIBLE_MOVES = 15
49   GAME_NUMBER = 16
50   WHITE_PLAYER = 17
51   BLACK_PLAYER = 18
52   RELATION = 19
53   STARTING_TIME = 20
54   STARTING_INCREMENT = 21
55   WHITE_TIME = 24
56   BLACK_TIME = 25
57   MOVE_ORDINAL = 26
58   LAST_MOVE_VERBOSE = 27
59   TIME_USED = 28
60   LAST_MOVE = 29
61   FLIP = 30
62   
63   class Relation
64     MOVE_LIST_START = -4
65     ISOLATED_POSITION = -3
66     OBSERVING_EXAMINED = -2
67     NOT_MY_MOVE = -1
68     OBSERVING_PLAYED = 0
69     MY_MOVE = 1
70     EXAMINING = 2
71   end
73   def self.from_match(match, games)
74     game_number = match[GAME_NUMBER].to_i
75     current_game = games[game_number]
76     icsapi = current_game[:icsapi]
77     state = 
78       icsapi.new_state(:turn => match[TURN] == 'W' ? :white : :black,
79                        :en_passant => match[EN_PASSANT].to_i,
80                        :wk_castling => match[WHITE_KING_CASTLING].to_i == 1,
81                        :wq_castling => match[WHITE_QUEEN_CASTLING].to_i == 1,
82                        :bk_castling => match[BLACK_KING_CASTLING].to_i == 1,
83                        :bq_castling => match[BLACK_QUEEN_CASTLING].to_i == 1)
84     match[CHESSBOARD..CHESSBOARD+8].each_with_index do |row, i|
85       row.split(//).each_with_index do |p, j|
86         piece = icsapi.new_piece(p)
87         state.board[Point.new(j, i)] = piece
88       end
89     end
91     style12 = new(:state => state,
92                   :game_number => match[GAME_NUMBER].to_i,
93                   :move_index => match[MOVE_ORDINAL].to_i,
94                   :white_player => match[WHITE_PLAYER],
95                   :black_player => match[BLACK_PLAYER],
96                   :relation => match[RELATION].to_i,
97                   :last_move => match[LAST_MOVE_VERBOSE],
98                   :last_move_san => match[LAST_MOVE],
99                   :time => {
100                     :white => match[WHITE_TIME].to_i,
101                     :black => match[BLACK_TIME].to_i }
102                   )
103   end
105   def initialize(opts)
106     @opts = opts
107   end
108   
109   def method_missing(field)
110     @opts[field]
111   end
112   
113   def move_index
114     (@opts[:move_index] - 1) * 2 + 
115       (state.turn == :white ? 0 : 1)
116   end