software_challenge_client 22.0.3 → 22.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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