software_challenge_client 22.1.0.1 → 23.0.2
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 +4 -4
- data/.gitignore +15 -15
- data/.rspec +3 -3
- data/.rubocop.yml +11 -11
- data/.ruby-version +1 -1
- data/.stickler.yml +7 -7
- data/.vscode/launch.json +40 -40
- data/.vscode/settings.json +9 -9
- data/AUTHORS +6 -6
- data/CODE_OF_CONDUCT.md +13 -13
- data/Dockerfile +3 -3
- data/Gemfile +5 -5
- data/Guardfile +45 -45
- data/README.md +172 -147
- data/RELEASES.md +144 -140
- data/Rakefile +7 -7
- data/bin/console +15 -15
- data/bin/setup +7 -7
- data/develop.sh +3 -3
- data/example/client.rb +35 -35
- data/example/main.rb +42 -42
- data/example/start.bat +2 -2
- data/generate-authors.sh +19 -19
- data/lib/software_challenge_client/board.rb +149 -127
- data/lib/software_challenge_client/client_interface.rb +19 -19
- data/lib/software_challenge_client/condition.rb +27 -27
- data/lib/software_challenge_client/coordinates.rb +71 -45
- data/lib/software_challenge_client/debug_hint.rb +17 -17
- data/lib/software_challenge_client/direction.rb +41 -0
- data/lib/software_challenge_client/field.rb +70 -69
- data/lib/software_challenge_client/game_rule_logic.rb +206 -141
- data/lib/software_challenge_client/game_state.rb +57 -24
- data/lib/software_challenge_client/invalid_move_exception.rb +15 -15
- data/lib/software_challenge_client/logging.rb +26 -26
- data/lib/software_challenge_client/move.rb +37 -41
- data/lib/software_challenge_client/network.rb +126 -126
- data/lib/software_challenge_client/piece.rb +43 -81
- data/lib/software_challenge_client/player.rb +31 -31
- data/lib/software_challenge_client/protocol.rb +103 -54
- data/lib/software_challenge_client/runner.rb +36 -36
- data/lib/software_challenge_client/team.rb +23 -25
- data/lib/software_challenge_client/util/constants.rb +9 -9
- data/lib/software_challenge_client/version.rb +5 -5
- data/lib/software_challenge_client.rb +23 -25
- data/lib/update_client_module.sh +15 -15
- data/push_image_production.sh +12 -12
- data/release.sh +9 -9
- data/software_challenge_client.gemspec +41 -41
- metadata +3 -5
- data/lib/software_challenge_client/color.rb +0 -26
- data/lib/software_challenge_client/has_hints.rb +0 -11
- data/lib/software_challenge_client/piece_type.rb +0 -16
@@ -1,126 +1,126 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# frozen_string_literal: false
|
3
|
-
|
4
|
-
require 'socket'
|
5
|
-
require 'rexml/document'
|
6
|
-
require 'rexml/element'
|
7
|
-
|
8
|
-
require_relative 'protocol'
|
9
|
-
require_relative 'board'
|
10
|
-
require_relative 'client_interface'
|
11
|
-
require_relative 'util/constants'
|
12
|
-
|
13
|
-
# This class handles the socket connection to the server
|
14
|
-
class Network
|
15
|
-
include Logging
|
16
|
-
include Constants
|
17
|
-
|
18
|
-
# @!attribute [r] connected
|
19
|
-
# @return [Boolean] true, if the client is connected to a server
|
20
|
-
attr_reader :connected
|
21
|
-
|
22
|
-
def initialize(host, port, board, client, reservation = nil)
|
23
|
-
@host = host
|
24
|
-
@port = port
|
25
|
-
@board = board
|
26
|
-
@client = client
|
27
|
-
|
28
|
-
@connected = false
|
29
|
-
@protocol = Protocol.new(self, @client)
|
30
|
-
@reservation_id = reservation || ''
|
31
|
-
@receive_buffer = ''
|
32
|
-
end
|
33
|
-
|
34
|
-
# connects the client with a given server
|
35
|
-
#
|
36
|
-
# @return [Boolean] true, if successfully connected to the server
|
37
|
-
def connect
|
38
|
-
@socket = TCPSocket.open(@host, @port)
|
39
|
-
logger.info 'Connection to server established.'
|
40
|
-
@connected = true
|
41
|
-
|
42
|
-
sendString('<protocol>')
|
43
|
-
document = REXML::Document.new
|
44
|
-
if @reservation_id != ''
|
45
|
-
element = REXML::Element.new('joinPrepared')
|
46
|
-
element.add_attribute('reservationCode', @reservation_id)
|
47
|
-
else
|
48
|
-
element = REXML::Element.new('join')
|
49
|
-
element.add_attribute('gameType', GAME_IDENTIFIER)
|
50
|
-
end
|
51
|
-
document.add(element)
|
52
|
-
sendXML(document)
|
53
|
-
@connected
|
54
|
-
end
|
55
|
-
|
56
|
-
# disconnects the client from a server
|
57
|
-
def disconnect
|
58
|
-
if @connected
|
59
|
-
sendString('</protocol>')
|
60
|
-
@connected = false
|
61
|
-
@socket.close
|
62
|
-
end
|
63
|
-
logger.info 'Connection to server closed.'
|
64
|
-
end
|
65
|
-
|
66
|
-
# reads from the socket until "</room>" is read
|
67
|
-
def readString
|
68
|
-
return false unless @connected
|
69
|
-
sock_msg = ''
|
70
|
-
|
71
|
-
line = ''
|
72
|
-
@socket.each_char do |char|
|
73
|
-
line += char
|
74
|
-
sock_msg += char
|
75
|
-
line = '' if ['\n', ' '].include? char
|
76
|
-
break if ['</room>', '</protocol>'].include? line
|
77
|
-
end
|
78
|
-
if sock_msg != ''
|
79
|
-
@receive_buffer.concat(sock_msg)
|
80
|
-
|
81
|
-
# Remove <protocol> tag
|
82
|
-
@receive_buffer = @receive_buffer.gsub('<protocol>', '')
|
83
|
-
@receive_buffer = @receive_buffer.gsub('</protocol>', '')
|
84
|
-
|
85
|
-
logger.debug "Received XML from server: #{@receive_buffer}"
|
86
|
-
|
87
|
-
# Process text
|
88
|
-
@protocol.process_string(@receive_buffer)
|
89
|
-
emptyReceiveBuffer
|
90
|
-
end
|
91
|
-
true
|
92
|
-
end
|
93
|
-
|
94
|
-
# sends a xml Document to the buffer
|
95
|
-
#
|
96
|
-
# @param xml [REXML::Document] the Document, that will be sent
|
97
|
-
def sendXML(xml)
|
98
|
-
text = ''
|
99
|
-
xml.write(text)
|
100
|
-
sendString(text)
|
101
|
-
end
|
102
|
-
|
103
|
-
# processes an incomming message
|
104
|
-
#
|
105
|
-
# @return [Boolean] true, if the processing of a incomming message was successfull
|
106
|
-
def processMessages
|
107
|
-
return false unless @connected
|
108
|
-
readString
|
109
|
-
end
|
110
|
-
|
111
|
-
# sends a string to the socket
|
112
|
-
#
|
113
|
-
# @param s [String] the message, to be sent
|
114
|
-
def sendString(s)
|
115
|
-
return unless @connected
|
116
|
-
logger.debug "Sending: #{s}"
|
117
|
-
@socket.print(s)
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
# empties the receive buffer
|
123
|
-
def emptyReceiveBuffer
|
124
|
-
@receive_buffer = ''
|
125
|
-
end
|
126
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
4
|
+
require 'socket'
|
5
|
+
require 'rexml/document'
|
6
|
+
require 'rexml/element'
|
7
|
+
|
8
|
+
require_relative 'protocol'
|
9
|
+
require_relative 'board'
|
10
|
+
require_relative 'client_interface'
|
11
|
+
require_relative 'util/constants'
|
12
|
+
|
13
|
+
# This class handles the socket connection to the server
|
14
|
+
class Network
|
15
|
+
include Logging
|
16
|
+
include Constants
|
17
|
+
|
18
|
+
# @!attribute [r] connected
|
19
|
+
# @return [Boolean] true, if the client is connected to a server
|
20
|
+
attr_reader :connected
|
21
|
+
|
22
|
+
def initialize(host, port, board, client, reservation = nil)
|
23
|
+
@host = host
|
24
|
+
@port = port
|
25
|
+
@board = board
|
26
|
+
@client = client
|
27
|
+
|
28
|
+
@connected = false
|
29
|
+
@protocol = Protocol.new(self, @client)
|
30
|
+
@reservation_id = reservation || ''
|
31
|
+
@receive_buffer = ''
|
32
|
+
end
|
33
|
+
|
34
|
+
# connects the client with a given server
|
35
|
+
#
|
36
|
+
# @return [Boolean] true, if successfully connected to the server
|
37
|
+
def connect
|
38
|
+
@socket = TCPSocket.open(@host, @port)
|
39
|
+
logger.info 'Connection to server established.'
|
40
|
+
@connected = true
|
41
|
+
|
42
|
+
sendString('<protocol>')
|
43
|
+
document = REXML::Document.new
|
44
|
+
if @reservation_id != ''
|
45
|
+
element = REXML::Element.new('joinPrepared')
|
46
|
+
element.add_attribute('reservationCode', @reservation_id)
|
47
|
+
else
|
48
|
+
element = REXML::Element.new('join')
|
49
|
+
element.add_attribute('gameType', GAME_IDENTIFIER)
|
50
|
+
end
|
51
|
+
document.add(element)
|
52
|
+
sendXML(document)
|
53
|
+
@connected
|
54
|
+
end
|
55
|
+
|
56
|
+
# disconnects the client from a server
|
57
|
+
def disconnect
|
58
|
+
if @connected
|
59
|
+
sendString('</protocol>')
|
60
|
+
@connected = false
|
61
|
+
@socket.close
|
62
|
+
end
|
63
|
+
logger.info 'Connection to server closed.'
|
64
|
+
end
|
65
|
+
|
66
|
+
# reads from the socket until "</room>" is read
|
67
|
+
def readString
|
68
|
+
return false unless @connected
|
69
|
+
sock_msg = ''
|
70
|
+
|
71
|
+
line = ''
|
72
|
+
@socket.each_char do |char|
|
73
|
+
line += char
|
74
|
+
sock_msg += char
|
75
|
+
line = '' if ['\n', ' '].include? char
|
76
|
+
break if ['</room>', '</protocol>'].include? line
|
77
|
+
end
|
78
|
+
if sock_msg != ''
|
79
|
+
@receive_buffer.concat(sock_msg)
|
80
|
+
|
81
|
+
# Remove <protocol> tag
|
82
|
+
@receive_buffer = @receive_buffer.gsub('<protocol>', '')
|
83
|
+
@receive_buffer = @receive_buffer.gsub('</protocol>', '')
|
84
|
+
|
85
|
+
logger.debug "Received XML from server: #{@receive_buffer}"
|
86
|
+
|
87
|
+
# Process text
|
88
|
+
@protocol.process_string(@receive_buffer)
|
89
|
+
emptyReceiveBuffer
|
90
|
+
end
|
91
|
+
true
|
92
|
+
end
|
93
|
+
|
94
|
+
# sends a xml Document to the buffer
|
95
|
+
#
|
96
|
+
# @param xml [REXML::Document] the Document, that will be sent
|
97
|
+
def sendXML(xml)
|
98
|
+
text = ''
|
99
|
+
xml.write(text)
|
100
|
+
sendString(text)
|
101
|
+
end
|
102
|
+
|
103
|
+
# processes an incomming message
|
104
|
+
#
|
105
|
+
# @return [Boolean] true, if the processing of a incomming message was successfull
|
106
|
+
def processMessages
|
107
|
+
return false unless @connected
|
108
|
+
readString
|
109
|
+
end
|
110
|
+
|
111
|
+
# sends a string to the socket
|
112
|
+
#
|
113
|
+
# @param s [String] the message, to be sent
|
114
|
+
def sendString(s)
|
115
|
+
return unless @connected
|
116
|
+
logger.debug "Sending: #{s}"
|
117
|
+
@socket.print(s)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# empties the receive buffer
|
123
|
+
def emptyReceiveBuffer
|
124
|
+
@receive_buffer = ''
|
125
|
+
end
|
126
|
+
end
|
@@ -1,81 +1,43 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
coords = [Coordinates.new(xdir,-1), Coordinates.new(xdir,1)]
|
45
|
-
when PieceType::Moewe
|
46
|
-
coords = [Coordinates.new(1,0), Coordinates.new(-1,0), Coordinates.new(0,1),
|
47
|
-
Coordinates.new(0,-1)]
|
48
|
-
when PieceType::Seestern
|
49
|
-
coords = [Coordinates.new(xdir,0), Coordinates.new(1,1), Coordinates.new(-1,1),
|
50
|
-
Coordinates.new(1,-1), Coordinates.new(-1,-1)]
|
51
|
-
when PieceType::Robbe
|
52
|
-
coords = [Coordinates.new(-1,2), Coordinates.new(1,2), Coordinates.new(-2,1),
|
53
|
-
Coordinates.new(2,1), Coordinates.new(-1,-2), Coordinates.new(1,-2),
|
54
|
-
Coordinates.new(-2,-1), Coordinates.new(2,-1)]
|
55
|
-
end
|
56
|
-
|
57
|
-
coords.map{ |x| x + position }.to_a
|
58
|
-
coords.map{ |x| x + position }.select{ |c| c.x >= 0 && c.y >=0 && c.x < BOARD_SIZE && c.y < BOARD_SIZE}.to_a
|
59
|
-
end
|
60
|
-
|
61
|
-
def ==(other)
|
62
|
-
!other.nil? &&
|
63
|
-
color == other.color &&
|
64
|
-
position == other.position &&
|
65
|
-
type == other.type
|
66
|
-
end
|
67
|
-
|
68
|
-
# @return [String] Gibt die String-Repräsentation zurück
|
69
|
-
def to_s
|
70
|
-
"#{color.key} #{type.key} at #{position}"
|
71
|
-
end
|
72
|
-
|
73
|
-
# @return [String] Gibt eine Kurzfassung der String-Repräsentation zurück
|
74
|
-
def to_ss
|
75
|
-
"#{color.key.to_s[0]}#{type.key.to_s[0]}"
|
76
|
-
end
|
77
|
-
|
78
|
-
def inspect
|
79
|
-
to_s
|
80
|
-
end
|
81
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'direction'
|
4
|
+
|
5
|
+
# Ein Spielstein mit Ausrichtung, Koordinaten und Farbe
|
6
|
+
class Piece
|
7
|
+
include Constants
|
8
|
+
|
9
|
+
# @!attribute [rw] Team
|
10
|
+
# @return [Team]
|
11
|
+
attr_accessor :team
|
12
|
+
|
13
|
+
# @!attribute [rw] Koordinaten
|
14
|
+
# @return [Coordinates]
|
15
|
+
attr_accessor :coords
|
16
|
+
|
17
|
+
# Erstellt einen neuen Spielstein.
|
18
|
+
def initialize(team, coords = Coordinates.origin)
|
19
|
+
@team = team
|
20
|
+
@coords = coords
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
!other.nil? &&
|
25
|
+
team == other.team &&
|
26
|
+
coords == other.coords
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] Gibt die String-Repräsentation zurück
|
30
|
+
def to_s
|
31
|
+
"#{team.key} at #{coords}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# To short string
|
35
|
+
# @return [String] Gibt eine Kurzfassung der String-Repräsentation zurück
|
36
|
+
def to_ss
|
37
|
+
"#{team.key.to_s[0]}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def inspect
|
41
|
+
to_s
|
42
|
+
end
|
43
|
+
end
|
@@ -1,31 +1,31 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# Ein Spieler
|
5
|
-
class Player
|
6
|
-
# @!attribute [r] name
|
7
|
-
# @return [String] der Name des Spielers, hat keine Auswirkungen auf das Spiel
|
8
|
-
attr_reader :name
|
9
|
-
|
10
|
-
# @!attribute [r]
|
11
|
-
# @return [
|
12
|
-
attr_reader :
|
13
|
-
|
14
|
-
# @!attribute [rw]
|
15
|
-
# @return [Integer] Anzahl
|
16
|
-
attr_accessor :
|
17
|
-
|
18
|
-
# Konstruktor
|
19
|
-
# @param type [
|
20
|
-
# @param name [String] Name
|
21
|
-
# @param amber [Integer] Menge
|
22
|
-
def initialize(
|
23
|
-
@
|
24
|
-
@name = name
|
25
|
-
@
|
26
|
-
end
|
27
|
-
|
28
|
-
def ==(other)
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Ein Spieler
|
5
|
+
class Player
|
6
|
+
# @!attribute [r] name
|
7
|
+
# @return [String] der Name des Spielers, hat keine Auswirkungen auf das Spiel
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
# @!attribute [r] team
|
11
|
+
# @return [Team] erster (Team::ONE) oder zweiter (Team::TWO) Spieler
|
12
|
+
attr_reader :team
|
13
|
+
|
14
|
+
# @!attribute [rw] fishes
|
15
|
+
# @return [Integer] Anzahl Fische die dieser Spieler gesammelt hat
|
16
|
+
attr_accessor :fishes
|
17
|
+
|
18
|
+
# Konstruktor
|
19
|
+
# @param type [Team] One oder Two
|
20
|
+
# @param name [String] Name
|
21
|
+
# @param amber [Integer] Menge der Fische die der Spieler hat
|
22
|
+
def initialize(team, name, fishes = 0)
|
23
|
+
@team = team
|
24
|
+
@name = name
|
25
|
+
@fishes = fishes
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
team == other.team
|
30
|
+
end
|
31
|
+
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'socket'
|
4
4
|
require_relative 'board'
|
5
5
|
require_relative 'move'
|
6
|
-
require_relative 'piece_type'
|
7
6
|
require_relative 'player'
|
8
7
|
require_relative 'network'
|
9
8
|
require_relative 'client_interface'
|
@@ -28,12 +27,25 @@ class Protocol
|
|
28
27
|
# @return [ClientInterface] current client
|
29
28
|
attr_reader :client
|
30
29
|
|
30
|
+
# @!attribute [rw] x
|
31
|
+
# @return [Integer] x
|
32
|
+
attr_reader :x
|
33
|
+
# @!attribute [rw] y
|
34
|
+
# @return [Integer] y
|
35
|
+
attr_reader :y
|
36
|
+
# @!attribute [rw] i
|
37
|
+
# @return [Integer] i
|
38
|
+
attr_reader :i
|
39
|
+
|
31
40
|
def initialize(network, client)
|
32
41
|
@gamestate = GameState.new
|
33
42
|
@network = network
|
34
43
|
@client = client
|
35
44
|
@context = {} # for saving context when stream-parsing the XML
|
36
45
|
@client.gamestate = @gamestate
|
46
|
+
@x = 0
|
47
|
+
@y = 0
|
48
|
+
@i = 0
|
37
49
|
end
|
38
50
|
|
39
51
|
# starts xml-string parsing
|
@@ -42,7 +54,7 @@ class Protocol
|
|
42
54
|
def process_string(text)
|
43
55
|
#logger.debug "Parse XML:\n#{text}\n----END XML"
|
44
56
|
begin
|
45
|
-
REXML::Document.parse_stream(text, self)
|
57
|
+
REXML::Document.parse_stream(text.encode('UTF-8', :invalid => :replace, :undef => :replace), self)
|
46
58
|
rescue REXML::ParseException => e
|
47
59
|
# to parse incomplete xml, ignore missing end tag exceptions
|
48
60
|
raise e unless e.message =~ /Missing end tag/
|
@@ -54,34 +66,6 @@ class Protocol
|
|
54
66
|
@context[:last_text] = text
|
55
67
|
end
|
56
68
|
|
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
69
|
# called if a start tag is read
|
86
70
|
# Depending on the tag the gamestate is updated
|
87
71
|
# or the client will be asked for a move
|
@@ -98,6 +82,14 @@ class Protocol
|
|
98
82
|
@context[:data_class] = attrs['class']
|
99
83
|
if attrs['class'] == 'moveRequest'
|
100
84
|
@client.gamestate = gamestate
|
85
|
+
if gamestate.turn == 0
|
86
|
+
gamestate.myself_player = gamestate.start_player
|
87
|
+
logger.debug "I am #{gamestate.myself_player}"
|
88
|
+
elsif gamestate.turn == 1
|
89
|
+
gamestate.myself_player = gamestate.not_player(gamestate.start_player)
|
90
|
+
logger.debug "I am #{gamestate.myself_player}"
|
91
|
+
end
|
92
|
+
gamestate.current_player = gamestate.myself_player
|
101
93
|
move = @client.move_requested
|
102
94
|
sendString(move_to_xml(move))
|
103
95
|
end
|
@@ -112,32 +104,35 @@ class Protocol
|
|
112
104
|
end
|
113
105
|
when 'state'
|
114
106
|
logger.debug 'new gamestate'
|
115
|
-
|
107
|
+
#@gamestate = GameState.new
|
116
108
|
@gamestate.turn = attrs['turn'].to_i
|
117
109
|
logger.debug "Round: #{@gamestate.round}, Turn: #{@gamestate.turn}"
|
118
110
|
when 'board'
|
111
|
+
@x = 0
|
112
|
+
@y = 0
|
113
|
+
@i = 0
|
119
114
|
logger.debug 'new board'
|
120
115
|
@gamestate.board = Board.new()
|
121
|
-
when 'pieces'
|
122
|
-
|
123
|
-
when 'coordinates'
|
124
|
-
|
125
|
-
|
126
|
-
when 'piece'
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
when 'from'
|
135
|
-
|
136
|
-
when 'to'
|
137
|
-
|
138
|
-
|
139
|
-
when 'ambers'
|
140
|
-
|
116
|
+
# when 'pieces'
|
117
|
+
# @context[:entry] = :pieces
|
118
|
+
# when 'coordinates'
|
119
|
+
# @context[:x] = attrs['x'].to_i
|
120
|
+
# @context[:y] = attrs['y'].to_i
|
121
|
+
# when 'piece'
|
122
|
+
# x = @context[:x]
|
123
|
+
# y = @context[:y]
|
124
|
+
# team = Team.find_by_key(attrs['team'].to_sym)
|
125
|
+
# type = PieceType.find_by_key(attrs['type'].to_sym)
|
126
|
+
# count = attrs['count'].to_i
|
127
|
+
# field = Field.new(x, y, Piece.new(team.to_c, type, Coordinates.new(x, y), count))
|
128
|
+
# @gamestate.board.add_field(field)
|
129
|
+
# when 'from'
|
130
|
+
# @context[:from] = Coordinates.new(attrs['x'].to_i, attrs['y'].to_i)
|
131
|
+
# when 'to'
|
132
|
+
# from = @context[:from]
|
133
|
+
# @gamestate.last_move = Move.new(Coordinates.new(from.x, from.y), Coordinates.new(attrs['x'].to_i, attrs['y'].to_i))
|
134
|
+
# when 'ambers'
|
135
|
+
# @context[:entry] = :ambers
|
141
136
|
when 'winner'
|
142
137
|
# TODO
|
143
138
|
# winning_player = parsePlayer(attrs)
|
@@ -155,6 +150,50 @@ class Protocol
|
|
155
150
|
end
|
156
151
|
end
|
157
152
|
|
153
|
+
# called if an end-tag is read
|
154
|
+
#
|
155
|
+
# @param name [String] the end-tag name, that was read
|
156
|
+
def tag_end(name)
|
157
|
+
case name
|
158
|
+
when 'board'
|
159
|
+
logger.debug @gamestate.board.to_s
|
160
|
+
when 'startTeam'
|
161
|
+
@gamestate.add_player(Player.new(Team::ONE, "ONE", 0))
|
162
|
+
@gamestate.add_player(Player.new(Team::TWO, "TWO", 0))
|
163
|
+
if @context[:last_text] == "ONE"
|
164
|
+
@gamestate.start_player = @gamestate.player_one
|
165
|
+
else
|
166
|
+
@gamestate.start_player = @gamestate.player_two
|
167
|
+
end
|
168
|
+
when 'int'
|
169
|
+
@i += 1
|
170
|
+
if i == 1
|
171
|
+
logger.info 'Got player one fishes'
|
172
|
+
@gamestate.player_one.fishes = @context[:last_text].to_i
|
173
|
+
elsif i == 2
|
174
|
+
logger.info 'Got player two fishes'
|
175
|
+
@gamestate.player_two.fishes = @context[:last_text].to_i
|
176
|
+
else
|
177
|
+
logger.info 'We got a problemo'
|
178
|
+
end
|
179
|
+
when 'list'
|
180
|
+
@y += 1
|
181
|
+
@x = 0
|
182
|
+
when 'field'
|
183
|
+
if @context[:last_text] == "ONE"
|
184
|
+
field = Field.new(@x, @y, Piece.new(Team::ONE, Coordinates.new(@x, @y)))
|
185
|
+
elsif @context[:last_text] == "TWO"
|
186
|
+
field = Field.new(@x, @y, Piece.new(Team::TWO, Coordinates.new(@x, @y)))
|
187
|
+
else
|
188
|
+
field = Field.new(@x, @y, nil, @context[:last_text].to_i)
|
189
|
+
end
|
190
|
+
@gamestate.board.add_field(field)
|
191
|
+
@x += 1
|
192
|
+
else
|
193
|
+
why = 'tho'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
158
197
|
# send a xml document
|
159
198
|
#
|
160
199
|
# @param document [REXML::Document] the document, that will be send to the connected server
|
@@ -191,9 +230,19 @@ class Protocol
|
|
191
230
|
# because XML-generation should be decoupled from internal data
|
192
231
|
# structures.
|
193
232
|
|
194
|
-
|
195
|
-
|
196
|
-
|
233
|
+
to_d = Coordinates.oddr_to_doubled(move.to)
|
234
|
+
|
235
|
+
if move.from.nil?
|
236
|
+
builder.data(class: 'move') do |d|
|
237
|
+
d.to(x: to_d.x, y: to_d.y)
|
238
|
+
end
|
239
|
+
else
|
240
|
+
from_d = Coordinates.oddr_to_doubled(move.from)
|
241
|
+
|
242
|
+
builder.data(class: 'move') do |d|
|
243
|
+
d.from(x: from_d.x, y: from_d.y)
|
244
|
+
d.to(x: to_d.x, y: to_d.y)
|
245
|
+
end
|
197
246
|
end
|
198
247
|
|
199
248
|
builder.target!
|