OSDN Git Service

Fixed a bug #23245.
[shogi-server/shogi-server.git] / shogi_server / usi.rb
1 module ShogiServer # for a namespace
2
3   class Usi
4     class << Usi
5       def escape(str)
6         str.gsub("/", "_").
7             gsub("+", "@").
8             gsub(" ", ".")
9       end
10
11       def unescape(str)
12         str.gsub("_", "/").
13             gsub("@", "+").
14             gsub(".", " ")
15       end
16     end
17
18     def charToPiece(c)
19       player = nil
20       case c
21       when /[A-Z]/
22         player = true
23       when /[a-z]/
24         player = false
25       end
26
27       piece = nil
28       case c.upcase
29       when 'P' 
30         piece = PieceFU
31       when 'L' 
32         piece = PieceKY
33       when 'N' 
34         piece = PieceKE
35       when 'S' 
36         piece = PieceGI
37       when 'G' 
38         piece = PieceKI
39       when 'B' 
40         piece = PieceKA
41       when 'R' 
42         piece = PieceHI
43       when 'K' 
44         piece = PieceOU
45       end
46       return [piece, player]
47     end
48
49     def piece2char(piece)
50       s = ""
51       case piece
52       when PieceFU
53         s = 'P'
54       when PieceKY
55         s = 'L'
56       when PieceKE
57         s = 'N'
58       when PieceGI
59         s = 'S'
60       when PieceKI
61         s = 'G'
62       when PieceKA
63         s = 'B'
64       when PieceHI
65         s = 'R'
66       when PieceOU
67         s = 'K'
68       end
69       s.downcase! if !piece.sente
70       if piece.promoted
71         s = "+%s" % [s]
72       end
73       return s
74     end
75
76     def parseBoard(word, board)
77       x=9; y=1
78       i = 0
79       while (i < word.length)
80         c = word[i,1]
81         case c
82         when /[a-zA-Z]/
83           piece, player = charToPiece(c)
84           piece.new(board, x, y, player)
85           x -= 1
86         when "+"
87           cc = word[i+i]
88           piece, player = charToPiece(cc)
89           piece.new(board, x, y, player, true)
90           x -= 1
91           i += 1
92         when /\d/
93           x -= c.to_i
94         when "/"
95           x = 9
96           y += 1
97         else
98           return 1
99         end
100         i += 1
101       end
102       return 0
103     end
104
105     def hands2usi(hands) 
106       return "" if hands.empty?
107       s = ""
108
109       mapping = [[ShogiServer::PieceHI, "R"],
110                  [ShogiServer::PieceKA, "B"],
111                  [ShogiServer::PieceKI, "G"],
112                  [ShogiServer::PieceGI, "S"],
113                  [ShogiServer::PieceKE, "N"],
114                  [ShogiServer::PieceKY, "L"],
115                  [ShogiServer::PieceFU, "P"]]
116
117       mapping.each do |klass, str|
118         pieces = hands.find_all {|piece| piece.class == klass}
119         unless pieces.empty?
120           if pieces.size > 1 
121             s += "%d" % [pieces.size]
122           end
123           s += str
124         end
125       end
126       return s
127     end
128
129     # "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b -"
130     #
131     def board2usi(board, turn)
132       s = ""
133       for y in 1..9
134         skip = 0
135         9.downto(1) do |x| 
136           piece = board.array[x][y]
137           case piece 
138           when nil
139             skip += 1
140           when ShogiServer::Piece
141             if skip > 0
142               s += skip.to_s
143               skip = 0
144             end
145             s += piece2char(piece)
146           end
147         end
148         if skip > 0
149           s += skip.to_s
150         end
151         s += "/" if y < 9
152       end
153       s += " "
154       if turn
155         s += "b"
156       else
157         s += "w"
158       end
159       s += " "
160       if board.sente_hands.empty? && board.gote_hands.empty?
161         return s += "-"
162       end
163       s += hands2usi(board.sente_hands).upcase
164       s += hands2usi(board.gote_hands).downcase
165       return s
166     end
167   end # class
168
169 end # module