software_challenge_client 22.0.3 → 22.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92678f5a67447b172349fea0f7facbb15a8343281a0cce26eae7de0193088d0a
4
- data.tar.gz: 9d5ece5e7a2660d79300a99825489ebe0ac73135c2a30f7a9549bb17c59ea188
3
+ metadata.gz: 910f87c3bca7d1aa880039a0c4bd5953965f3ddd2ebd48aff96b0f14c2010331
4
+ data.tar.gz: cf0d306bc178528d2e38156dc1654efc5e67f6f877aaf542ff0fb9b80e51705a
5
5
  SHA512:
6
- metadata.gz: e1ed258cfacea34dde52713e4eca66ad1c01dba6c1e6aef340858217a3c1962b71d43e15edbd8783485b8ad68c59a44f7423c7b5d455bc95999fc3cc5487d827
7
- data.tar.gz: a39343c315c2905210d47d82662a49a3f5dc48c1881c8be6b3dc7e8354f69b5423997b44cfa407dcad804f07b43ed2574c996e572692dc8c5c3ca95e1414a857
6
+ metadata.gz: 6341fba9ff7f9dde85015a7493a5187d9fcdfea97fe912159e4dd2cdd82283109338b5788dabd25698474de9b7fad27d6b66480e3c7a34047c159bc5e5900969
7
+ data.tar.gz: 6ff8469aa8d35ddc861dc771d8124ed243697c1db2b3996bd17864f405c0fe91d8a348200b20b9cb359574e71cd1168b925958615d1c23dd025cb0941006dc8d
data/RELEASES.md CHANGED
@@ -1,3 +1,11 @@
1
+ = 22.1.0
2
+
3
+ Fix gamestate.round
4
+
5
+ = 22.0.3
6
+
7
+ First tagged Version for Osteseeschach
8
+
1
9
  = 21.2.0
2
10
 
3
11
  Adjustments for Backend version 21.2.0
@@ -1,157 +1,158 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative './util/constants'
4
- require_relative 'player'
5
- require_relative 'board'
6
- require_relative 'condition'
7
- require_relative 'color'
8
-
9
- # Ein Spielzustand. Wird vom Server an die Computerspieler übermittelt und
10
- # enthält alles, was der Computerspieler wissen muss, um einen Zug zu machen.
11
- #
12
- # Um eine Liste der gerade möglichen Züge zu bekommen, gibt es die Methode
13
- # {GameState#possible_moves}.
14
- class GameState
15
- # @!attribute [rw] turn
16
- # @return [Integer] Aktuelle Zugnummer (von 0 beginnend)
17
- attr_accessor :turn
18
-
19
- # @!attribute [rw] round
20
- # @return [Integer] Aktuelle Rundennummer (von 1 beginnend)
21
- attr_accessor :round
22
-
23
- # @!attribute [r] player_one
24
- # @return [Player] Der erste Spieler
25
- attr_reader :player_one
26
-
27
- # @!attribute [r] player_two
28
- # @return [Player] Der zweite Spieler
29
- attr_reader :player_two
30
-
31
- # @!attribute [rw] start_team
32
- # @return [Team] Der Spieler der zuerst zieht
33
- attr_accessor :start_team
34
-
35
- # @!attribute [rw] board
36
- # @return [Board] Das aktuelle Spielbrett
37
- attr_accessor :board
38
-
39
- # @!attribute [rw] last_move
40
- # @return [Move] Der zuletzt gemachte Zug (ist nil vor dem ersten Zug, also
41
- # bei turn == 0)
42
- attr_accessor :last_move
43
-
44
- # @!attribute [rw] condition
45
- # @return [Condition] Gewinner und Gewinngrund, falls das Spiel bereits
46
- # entschieden ist, sonst nil.
47
- attr_accessor :condition
48
-
49
- # Zugriff auf ein Feld des Spielbrettes. Siehe {Board#field}.
50
- def field(x, y)
51
- board.field(x, y)
52
- end
53
-
54
- # Erstellt einen neuen leeren Spielstand.
55
- def initialize
56
- @board = Board.new
57
- @turn = 0
58
- end
59
-
60
- # Fügt einen Spieler zum Spielzustand hinzu.
61
- #
62
- # @param player [Player] Der hinzuzufügende Spieler.
63
- def add_player(player)
64
- case player.color
65
- when Color::RED
66
- @player_one = player
67
- when Color::BLUE
68
- @player_two = player
69
- end
70
- end
71
-
72
- # @return [Player] Spieler, der gerade an der Reihe ist.
73
- def current_player
74
- turn.even? ? player_one : player_two
75
- end
76
-
77
- # @return [Player] Spieler, der gerade nicht an der Reihe ist.
78
- def other_player
79
- turn.even? ? player_two : player_one
80
- end
81
-
82
- # @return [Team] Typ des Spielers, der gerade nicht an der Reihe ist.
83
- def other_team
84
- other_player.type
85
- end
86
-
87
- # @return [Bool] Ob diese gamestate in der ersten Runde ist
88
- def is_first_move?
89
- round == 1
90
- end
91
-
92
- # Führt einen Zug auf dem Spielzustand aus. Das Spielbrett wird entsprechend
93
- # modifiziert.
94
- #
95
- # @param move [Move] Der auszuführende Zug.
96
- def perform!(move)
97
- GameRuleLogic.perform_move(self, move)
98
- end
99
-
100
- # @return [Boolean] true, falls das Spiel bereits geendet hat, false bei noch
101
- # laufenden Spielen.
102
- def game_ended?
103
- !condition.nil?
104
- end
105
-
106
- # @return [Player] Der Spieler, der das Spiel gewonnen hat, falls dies schon
107
- # entschieden ist. Sonst false.
108
- def winner
109
- condition.nil? ? nil : condition.winner
110
- end
111
-
112
- # @return [String] Der Grund, warum das Spiel beendet wurde, nil falls das
113
- # Spiel noch läuft.
114
- def winning_reason
115
- condition.nil? ? nil : condition.reason
116
- end
117
-
118
- # Ermittelt die Punkte eines Spielers. Wenn das Spiel durch Erreichen des
119
- # Rundenlimits beendet wird, hat der Spieler mit den meisten Punkten gewonnen.
120
- #
121
- # @param player [Player] Der Spieler, dessen Punkte berechnet werden sollen.
122
- # @return [Integer] Die Punkte des Spielers
123
- def points_for_player(_player)
124
- # TODO
125
- -1
126
- end
127
-
128
- def ==(other)
129
- turn == other.turn &&
130
- start_color == other.start_color &&
131
- current_color == other.current_color &&
132
- blue == other.blue &&
133
- yellow == other.yellow &&
134
- red == other.red &&
135
- green == other.green &&
136
- board == other.board &&
137
- lastMove == other.lastMove &&
138
- condition == other.condition
139
- end
140
-
141
- # Erzeugt eine Kopie des Spielzustandes. Änderungen an dieser Kopie
142
- # beeinflussen den originalen Spielzustand nicht. Die Kopie kann also zum
143
- # testen von Spielzügen genutzt werden.
144
- def clone
145
- Marshal.load(Marshal.dump(self))
146
- end
147
-
148
- # Wechselt den Spieler, der aktuell an der Reihe ist.
149
- def switch_current_player
150
- @current_player_color = other_player_color
151
- end
152
-
153
- # @return [Array<Field>] Alle Felder mit Blöcken des Spielers, der gerade an der Reihe ist.
154
- def own_fields
155
- board.fields_of_color(current_player.color)
156
- end
157
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './util/constants'
4
+ require_relative 'player'
5
+ require_relative 'board'
6
+ require_relative 'condition'
7
+ require_relative 'color'
8
+
9
+ # Ein Spielzustand. Wird vom Server an die Computerspieler übermittelt und
10
+ # enthält alles, was der Computerspieler wissen muss, um einen Zug zu machen.
11
+ #
12
+ # Um eine Liste der gerade möglichen Züge zu bekommen, gibt es die Methode
13
+ # {GameState#possible_moves}.
14
+ class GameState
15
+ # @!attribute [rw] turn
16
+ # @return [Integer] Aktuelle Zugnummer (von 0 beginnend)
17
+ attr_accessor :turn
18
+
19
+ # @!attribute [r] player_one
20
+ # @return [Player] Der erste Spieler
21
+ attr_reader :player_one
22
+
23
+ # @!attribute [r] player_two
24
+ # @return [Player] Der zweite Spieler
25
+ attr_reader :player_two
26
+
27
+ # @!attribute [rw] start_team
28
+ # @return [Team] Der Spieler der zuerst zieht
29
+ attr_accessor :start_team
30
+
31
+ # @!attribute [rw] board
32
+ # @return [Board] Das aktuelle Spielbrett
33
+ attr_accessor :board
34
+
35
+ # @!attribute [rw] last_move
36
+ # @return [Move] Der zuletzt gemachte Zug (ist nil vor dem ersten Zug, also
37
+ # bei turn == 0)
38
+ attr_accessor :last_move
39
+
40
+ # @!attribute [rw] condition
41
+ # @return [Condition] Gewinner und Gewinngrund, falls das Spiel bereits
42
+ # entschieden ist, sonst nil.
43
+ attr_accessor :condition
44
+
45
+ # Zugriff auf ein Feld des Spielbrettes. Siehe {Board#field}.
46
+ def field(x, y)
47
+ board.field(x, y)
48
+ end
49
+
50
+ # Erstellt einen neuen leeren Spielstand.
51
+ def initialize
52
+ @board = Board.new
53
+ @turn = 0
54
+ end
55
+
56
+ # Fügt einen Spieler zum Spielzustand hinzu.
57
+ #
58
+ # @param player [Player] Der hinzuzufügende Spieler.
59
+ def add_player(player)
60
+ case player.color
61
+ when Color::RED
62
+ @player_one = player
63
+ when Color::BLUE
64
+ @player_two = player
65
+ end
66
+ end
67
+
68
+ # @return [Player] Spieler, der gerade an der Reihe ist.
69
+ def current_player
70
+ turn.even? ? player_one : player_two
71
+ end
72
+
73
+ # @return [Player] Spieler, der gerade nicht an der Reihe ist.
74
+ def other_player
75
+ turn.even? ? player_two : player_one
76
+ end
77
+
78
+ # @return [Team] Typ des Spielers, der gerade nicht an der Reihe ist.
79
+ def other_team
80
+ other_player.type
81
+ end
82
+
83
+ # @return [Integer] Aktuelle Rundennummer (von 1 beginnend)
84
+ def round
85
+ turn / 2 + 1
86
+ end
87
+
88
+ # @return [Bool] Ob diese gamestate in der ersten Runde ist
89
+ def is_first_move?
90
+ round == 1
91
+ end
92
+
93
+ # Führt einen Zug auf dem Spielzustand aus. Das Spielbrett wird entsprechend
94
+ # modifiziert.
95
+ #
96
+ # @param move [Move] Der auszuführende Zug.
97
+ def perform!(move)
98
+ GameRuleLogic.perform_move(self, move)
99
+ end
100
+
101
+ # @return [Boolean] true, falls das Spiel bereits geendet hat, false bei noch
102
+ # laufenden Spielen.
103
+ def game_ended?
104
+ !condition.nil?
105
+ end
106
+
107
+ # @return [Player] Der Spieler, der das Spiel gewonnen hat, falls dies schon
108
+ # entschieden ist. Sonst false.
109
+ def winner
110
+ condition.nil? ? nil : condition.winner
111
+ end
112
+
113
+ # @return [String] Der Grund, warum das Spiel beendet wurde, nil falls das
114
+ # Spiel noch läuft.
115
+ def winning_reason
116
+ condition.nil? ? nil : condition.reason
117
+ end
118
+
119
+ # Ermittelt die Punkte eines Spielers. Wenn das Spiel durch Erreichen des
120
+ # Rundenlimits beendet wird, hat der Spieler mit den meisten Punkten gewonnen.
121
+ #
122
+ # @param player [Player] Der Spieler, dessen Punkte berechnet werden sollen.
123
+ # @return [Integer] Die Punkte des Spielers
124
+ def points_for_player(_player)
125
+ # TODO
126
+ -1
127
+ end
128
+
129
+ def ==(other)
130
+ turn == other.turn &&
131
+ start_color == other.start_color &&
132
+ current_color == other.current_color &&
133
+ blue == other.blue &&
134
+ yellow == other.yellow &&
135
+ red == other.red &&
136
+ green == other.green &&
137
+ board == other.board &&
138
+ lastMove == other.lastMove &&
139
+ condition == other.condition
140
+ end
141
+
142
+ # Erzeugt eine Kopie des Spielzustandes. Änderungen an dieser Kopie
143
+ # beeinflussen den originalen Spielzustand nicht. Die Kopie kann also zum
144
+ # testen von Spielzügen genutzt werden.
145
+ def clone
146
+ Marshal.load(Marshal.dump(self))
147
+ end
148
+
149
+ # Wechselt den Spieler, der aktuell an der Reihe ist.
150
+ def switch_current_player
151
+ @current_player_color = other_player_color
152
+ end
153
+
154
+ # @return [Array<Field>] Alle Felder mit Blöcken des Spielers, der gerade an der Reihe ist.
155
+ def own_fields
156
+ board.fields_of_color(current_player.color)
157
+ end
158
+ end
@@ -1,202 +1,201 @@
1
- # encoding: UTF-8
2
- # frozen_string_literal: true
3
- require 'socket'
4
- require_relative 'board'
5
- require_relative 'move'
6
- require_relative 'piece_type'
7
- require_relative 'player'
8
- require_relative 'network'
9
- require_relative 'client_interface'
10
- require 'rexml/document'
11
- require 'rexml/streamlistener'
12
- require 'builder'
13
-
14
- # This class handles communication to the server over the XML communication
15
- # protocol. Messages from the server are parsed and moves are serialized and
16
- # send back.
17
- class Protocol
18
- include Logging
19
- include REXML::StreamListener
20
-
21
- # @!attribute [r] gamestate
22
- # @return [Gamestate] current gamestate
23
- attr_reader :gamestate
24
- # @!attribute [rw] roomId
25
- # @return [String] current room id
26
- attr_accessor :roomId
27
- # @!attribute [r] client
28
- # @return [ClientInterface] current client
29
- attr_reader :client
30
-
31
- def initialize(network, client)
32
- @gamestate = GameState.new
33
- @network = network
34
- @client = client
35
- @context = {} # for saving context when stream-parsing the XML
36
- @client.gamestate = @gamestate
37
- end
38
-
39
- # starts xml-string parsing
40
- #
41
- # @param text [String] the xml-string that will be parsed
42
- def process_string(text)
43
- #logger.debug "Parse XML:\n#{text}\n----END XML"
44
- begin
45
- REXML::Document.parse_stream(text, self)
46
- rescue REXML::ParseException => e
47
- # to parse incomplete xml, ignore missing end tag exceptions
48
- raise e unless e.message =~ /Missing end tag/
49
- end
50
- end
51
-
52
- # called when text is encountered
53
- def text(text)
54
- @context[:last_text] = text
55
- end
56
-
57
- # called if an end-tag is read
58
- #
59
- # @param name [String] the end-tag name, that was read
60
- def tag_end(name)
61
- case name
62
- when 'board'
63
- logger.debug @gamestate.board.to_s
64
- when 'startTeam'
65
- @gamestate.add_player(Player.new(Color::RED, "ONE", 0))
66
- @gamestate.add_player(Player.new(Color::BLUE, "TWO", 0))
67
- if @context[:last_text] == "ONE"
68
- @gamestate.start_team = @gamestate.player_one
69
- else
70
- @gamestate.start_team = @gamestate.player_two
71
- end
72
- when 'team'
73
- @context[:team] = @context[:last_text]
74
- when 'int'
75
- if @context[:team] == "ONE"
76
- logger.info 'Got player one amber'
77
- @gamestate.player_one.amber = @context[:last_text].to_i
78
- else
79
- logger.info 'Got player two amber'
80
- @gamestate.player_two.amber = @context[:last_text].to_i
81
- end
82
- end
83
- end
84
-
85
- # called if a start tag is read
86
- # Depending on the tag the gamestate is updated
87
- # or the client will be asked for a move
88
- #
89
- # @param name [String] the start-tag, that was read
90
- # @param attrs [Dictionary<String, String>] Attributes attached to the tag
91
- def tag_start(name, attrs)
92
- case name
93
- when 'room'
94
- @roomId = attrs['roomId']
95
- logger.info 'roomId : ' + @roomId
96
- when 'data'
97
- logger.debug "data(class) : #{attrs['class']}"
98
- @context[:data_class] = attrs['class']
99
- if attrs['class'] == 'moveRequest'
100
- @client.gamestate = gamestate
101
- move = @client.move_requested
102
- sendString(move_to_xml(move))
103
- end
104
- if attrs['class'] == 'error'
105
- logger.info "Game ended - ERROR: #{attrs['message']}"
106
- @network.disconnect
107
- end
108
- if attrs['class'] == 'result'
109
- logger.info 'Got game result'
110
- @network.disconnect
111
- @gamestate.condition = Condition.new(nil, '')
112
- end
113
- when 'state'
114
- logger.debug 'new gamestate'
115
- @gamestate = GameState.new
116
- @gamestate.turn = attrs['turn'].to_i
117
- @gamestate.round = @gamestate.turn / 2
118
- logger.debug "Round: #{@gamestate.round}, Turn: #{@gamestate.turn}"
119
- when 'board'
120
- logger.debug 'new board'
121
- @gamestate.board = Board.new()
122
- when 'pieces'
123
- @context[:entry] = :pieces
124
- when 'coordinates'
125
- @context[:x] = attrs['x'].to_i
126
- @context[:y] = attrs['y'].to_i
127
- when 'piece'
128
- x = @context[:x]
129
- y = @context[:y]
130
- team = Team.find_by_key(attrs['team'].to_sym)
131
- type = PieceType.find_by_key(attrs['type'].to_sym)
132
- count = attrs['count'].to_i
133
- field = Field.new(x, y, Piece.new(team.to_c, type, Coordinates.new(x, y), count))
134
- @gamestate.board.add_field(field)
135
- when 'from'
136
- @context[:from] = Coordinates.new(attrs['x'].to_i, attrs['y'].to_i)
137
- when 'to'
138
- from = @context[:from]
139
- @gamestate.last_move = Move.new(Coordinates.new(from.x, from.y), Coordinates.new(attrs['x'].to_i, attrs['y'].to_i))
140
- when 'ambers'
141
- @context[:entry] = :ambers
142
- when 'winner'
143
- # TODO
144
- # winning_player = parsePlayer(attrs)
145
- # @gamestate.condition = Condition.new(winning_player, @gamestate.condition.reason)
146
- when 'score'
147
- # TODO
148
- # there are two score tags in the result, but reason attribute should be equal on both
149
- # @gamestate.condition = Condition.new(@gamestate.condition.winner, attrs['reason'])
150
- when 'left'
151
- logger.debug 'got left event, terminating'
152
- @network.disconnect
153
- when 'sc.protocol.responses.CloseConnection'
154
- logger.debug 'got left close connection event, terminating'
155
- @network.disconnect
156
- end
157
- end
158
-
159
- # send a xml document
160
- #
161
- # @param document [REXML::Document] the document, that will be send to the connected server
162
- def sendXml(document)
163
- @network.sendXML(document)
164
- end
165
-
166
- # send a string
167
- #
168
- # @param string [String] The string that will be send to the connected server.
169
- def sendString(string)
170
- @network.sendString("<room roomId=\"#{@roomId}\">#{string}</room>")
171
- end
172
-
173
- # converts "this_snake_case" to "thisSnakeCase"
174
- def snake_case_to_lower_camel_case(string)
175
- string.split('_').inject([]) do |result, e|
176
- result + [result.empty? ? e : e.capitalize]
177
- end.join
178
- end
179
-
180
- # Converts a move to XML for sending to the server.
181
- #
182
- # @param move [Move] The move to convert to XML.
183
- def move_to_xml(move)
184
- builder = Builder::XmlMarkup.new(indent: 2)
185
-
186
- if move.nil?
187
- raise 'nil moves are not sendable!'
188
- end
189
-
190
- # Converting every the move here instead of requiring the Move
191
- # class interface to supply a method which returns the XML
192
- # because XML-generation should be decoupled from internal data
193
- # structures.
194
-
195
- builder.data(class: 'move') do |d|
196
- d.from(x: move.from.x, y: move.from.y)
197
- d.to(x: move.to.x, y: move.to.y)
198
- end
199
-
200
- builder.target!
201
- end
202
- end
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+ require 'socket'
4
+ require_relative 'board'
5
+ require_relative 'move'
6
+ require_relative 'piece_type'
7
+ require_relative 'player'
8
+ require_relative 'network'
9
+ require_relative 'client_interface'
10
+ require 'rexml/document'
11
+ require 'rexml/streamlistener'
12
+ require 'builder'
13
+
14
+ # This class handles communication to the server over the XML communication
15
+ # protocol. Messages from the server are parsed and moves are serialized and
16
+ # send back.
17
+ class Protocol
18
+ include Logging
19
+ include REXML::StreamListener
20
+
21
+ # @!attribute [r] gamestate
22
+ # @return [Gamestate] current gamestate
23
+ attr_reader :gamestate
24
+ # @!attribute [rw] roomId
25
+ # @return [String] current room id
26
+ attr_accessor :roomId
27
+ # @!attribute [r] client
28
+ # @return [ClientInterface] current client
29
+ attr_reader :client
30
+
31
+ def initialize(network, client)
32
+ @gamestate = GameState.new
33
+ @network = network
34
+ @client = client
35
+ @context = {} # for saving context when stream-parsing the XML
36
+ @client.gamestate = @gamestate
37
+ end
38
+
39
+ # starts xml-string parsing
40
+ #
41
+ # @param text [String] the xml-string that will be parsed
42
+ def process_string(text)
43
+ #logger.debug "Parse XML:\n#{text}\n----END XML"
44
+ begin
45
+ REXML::Document.parse_stream(text, self)
46
+ rescue REXML::ParseException => e
47
+ # to parse incomplete xml, ignore missing end tag exceptions
48
+ raise e unless e.message =~ /Missing end tag/
49
+ end
50
+ end
51
+
52
+ # called when text is encountered
53
+ def text(text)
54
+ @context[:last_text] = text
55
+ end
56
+
57
+ # called if an end-tag is read
58
+ #
59
+ # @param name [String] the end-tag name, that was read
60
+ def tag_end(name)
61
+ case name
62
+ when 'board'
63
+ logger.debug @gamestate.board.to_s
64
+ when 'startTeam'
65
+ @gamestate.add_player(Player.new(Color::RED, "ONE", 0))
66
+ @gamestate.add_player(Player.new(Color::BLUE, "TWO", 0))
67
+ if @context[:last_text] == "ONE"
68
+ @gamestate.start_team = @gamestate.player_one
69
+ else
70
+ @gamestate.start_team = @gamestate.player_two
71
+ end
72
+ when 'team'
73
+ @context[:team] = @context[:last_text]
74
+ when 'int'
75
+ if @context[:team] == "ONE"
76
+ logger.info 'Got player one amber'
77
+ @gamestate.player_one.amber = @context[:last_text].to_i
78
+ else
79
+ logger.info 'Got player two amber'
80
+ @gamestate.player_two.amber = @context[:last_text].to_i
81
+ end
82
+ end
83
+ end
84
+
85
+ # called if a start tag is read
86
+ # Depending on the tag the gamestate is updated
87
+ # or the client will be asked for a move
88
+ #
89
+ # @param name [String] the start-tag, that was read
90
+ # @param attrs [Dictionary<String, String>] Attributes attached to the tag
91
+ def tag_start(name, attrs)
92
+ case name
93
+ when 'room'
94
+ @roomId = attrs['roomId']
95
+ logger.info 'roomId : ' + @roomId
96
+ when 'data'
97
+ logger.debug "data(class) : #{attrs['class']}"
98
+ @context[:data_class] = attrs['class']
99
+ if attrs['class'] == 'moveRequest'
100
+ @client.gamestate = gamestate
101
+ move = @client.move_requested
102
+ sendString(move_to_xml(move))
103
+ end
104
+ if attrs['class'] == 'error'
105
+ logger.info "Game ended - ERROR: #{attrs['message']}"
106
+ @network.disconnect
107
+ end
108
+ if attrs['class'] == 'result'
109
+ logger.info 'Got game result'
110
+ @network.disconnect
111
+ @gamestate.condition = Condition.new(nil, '')
112
+ end
113
+ when 'state'
114
+ logger.debug 'new gamestate'
115
+ @gamestate = GameState.new
116
+ @gamestate.turn = attrs['turn'].to_i
117
+ logger.debug "Round: #{@gamestate.round}, Turn: #{@gamestate.turn}"
118
+ when 'board'
119
+ logger.debug 'new board'
120
+ @gamestate.board = Board.new()
121
+ when 'pieces'
122
+ @context[:entry] = :pieces
123
+ when 'coordinates'
124
+ @context[:x] = attrs['x'].to_i
125
+ @context[:y] = attrs['y'].to_i
126
+ when 'piece'
127
+ x = @context[:x]
128
+ y = @context[:y]
129
+ team = Team.find_by_key(attrs['team'].to_sym)
130
+ type = PieceType.find_by_key(attrs['type'].to_sym)
131
+ count = attrs['count'].to_i
132
+ field = Field.new(x, y, Piece.new(team.to_c, type, Coordinates.new(x, y), count))
133
+ @gamestate.board.add_field(field)
134
+ when 'from'
135
+ @context[:from] = Coordinates.new(attrs['x'].to_i, attrs['y'].to_i)
136
+ when 'to'
137
+ from = @context[:from]
138
+ @gamestate.last_move = Move.new(Coordinates.new(from.x, from.y), Coordinates.new(attrs['x'].to_i, attrs['y'].to_i))
139
+ when 'ambers'
140
+ @context[:entry] = :ambers
141
+ when 'winner'
142
+ # TODO
143
+ # winning_player = parsePlayer(attrs)
144
+ # @gamestate.condition = Condition.new(winning_player, @gamestate.condition.reason)
145
+ when 'score'
146
+ # TODO
147
+ # there are two score tags in the result, but reason attribute should be equal on both
148
+ # @gamestate.condition = Condition.new(@gamestate.condition.winner, attrs['reason'])
149
+ when 'left'
150
+ logger.debug 'got left event, terminating'
151
+ @network.disconnect
152
+ when 'sc.protocol.responses.CloseConnection'
153
+ logger.debug 'got left close connection event, terminating'
154
+ @network.disconnect
155
+ end
156
+ end
157
+
158
+ # send a xml document
159
+ #
160
+ # @param document [REXML::Document] the document, that will be send to the connected server
161
+ def sendXml(document)
162
+ @network.sendXML(document)
163
+ end
164
+
165
+ # send a string
166
+ #
167
+ # @param string [String] The string that will be send to the connected server.
168
+ def sendString(string)
169
+ @network.sendString("<room roomId=\"#{@roomId}\">#{string}</room>")
170
+ end
171
+
172
+ # converts "this_snake_case" to "thisSnakeCase"
173
+ def snake_case_to_lower_camel_case(string)
174
+ string.split('_').inject([]) do |result, e|
175
+ result + [result.empty? ? e : e.capitalize]
176
+ end.join
177
+ end
178
+
179
+ # Converts a move to XML for sending to the server.
180
+ #
181
+ # @param move [Move] The move to convert to XML.
182
+ def move_to_xml(move)
183
+ builder = Builder::XmlMarkup.new(indent: 2)
184
+
185
+ if move.nil?
186
+ raise 'nil moves are not sendable!'
187
+ end
188
+
189
+ # Converting every the move here instead of requiring the Move
190
+ # class interface to supply a method which returns the XML
191
+ # because XML-generation should be decoupled from internal data
192
+ # structures.
193
+
194
+ builder.data(class: 'move') do |d|
195
+ d.from(x: move.from.x, y: move.from.y)
196
+ d.to(x: move.to.x, y: move.to.y)
197
+ end
198
+
199
+ builder.target!
200
+ end
201
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
  module SoftwareChallengeClient
4
- VERSION = '22.0.3'
4
+ VERSION = '22.1.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: software_challenge_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 22.0.3
4
+ version: 22.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 'kwollw '
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-10-02 00:00:00.000000000 Z
13
+ date: 2021-12-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: builder
@@ -326,7 +326,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
326
326
  - !ruby/object:Gem::Version
327
327
  version: '0'
328
328
  requirements: []
329
- rubygems_version: 3.1.4
329
+ rubygems_version: 3.1.6
330
330
  signing_key:
331
331
  specification_version: 4
332
332
  summary: Provides functions to build a client for the coding competition Software-Challenge