software_challenge_client 21.0.2 → 22.0.3
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 +4 -1
- data/Dockerfile +1 -1
- data/README.md +1 -1
- data/RELEASES.md +8 -0
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/develop.sh +0 -0
- data/example/main.rb +0 -0
- data/example/start.bat +0 -0
- data/generate-authors.sh +0 -0
- data/lib/software_challenge_client/board.rb +11 -61
- data/lib/software_challenge_client/color.rb +13 -3
- data/lib/software_challenge_client/field.rb +30 -11
- data/lib/software_challenge_client/game_rule_logic.rb +55 -255
- data/lib/software_challenge_client/game_state.rb +18 -73
- data/lib/software_challenge_client/move.rb +41 -0
- data/lib/software_challenge_client/piece.rb +56 -35
- data/lib/software_challenge_client/piece_type.rb +16 -0
- data/lib/software_challenge_client/player.rb +12 -6
- data/lib/software_challenge_client/protocol.rb +49 -114
- data/lib/software_challenge_client/runner.rb +1 -1
- data/lib/software_challenge_client/team.rb +25 -0
- data/lib/software_challenge_client/util/constants.rb +2 -3
- data/lib/software_challenge_client/version.rb +1 -1
- data/lib/software_challenge_client.rb +3 -6
- data/lib/update_client_module.sh +0 -0
- data/push_image_production.sh +12 -0
- data/release.sh +0 -0
- metadata +7 -10
- data/lib/software_challenge_client/coordinate_set.rb +0 -92
- data/lib/software_challenge_client/piece_shape.rb +0 -109
- data/lib/software_challenge_client/player_type.rb +0 -14
- data/lib/software_challenge_client/rotation.rb +0 -22
- data/lib/software_challenge_client/set_move.rb +0 -24
- data/lib/software_challenge_client/skip_move.rb +0 -13
|
@@ -4,6 +4,7 @@ require_relative './util/constants'
|
|
|
4
4
|
require_relative 'player'
|
|
5
5
|
require_relative 'board'
|
|
6
6
|
require_relative 'condition'
|
|
7
|
+
require_relative 'color'
|
|
7
8
|
|
|
8
9
|
# Ein Spielzustand. Wird vom Server an die Computerspieler übermittelt und
|
|
9
10
|
# enthält alles, was der Computerspieler wissen muss, um einen Zug zu machen.
|
|
@@ -14,53 +15,32 @@ class GameState
|
|
|
14
15
|
# @!attribute [rw] turn
|
|
15
16
|
# @return [Integer] Aktuelle Zugnummer (von 0 beginnend)
|
|
16
17
|
attr_accessor :turn
|
|
18
|
+
|
|
17
19
|
# @!attribute [rw] round
|
|
18
20
|
# @return [Integer] Aktuelle Rundennummer (von 1 beginnend)
|
|
19
21
|
attr_accessor :round
|
|
20
22
|
|
|
21
|
-
# @!attribute [rw] startColor
|
|
22
|
-
# @return [Color] Die Farbe, die zuerst legen darf
|
|
23
|
-
attr_accessor :start_color
|
|
24
|
-
# @!attribute [rw] current_color_index
|
|
25
|
-
# @return [Color] Der jetzige Index in der Zug Reihenfolge der Farben.
|
|
26
|
-
attr_accessor :current_color_index
|
|
27
|
-
# @!attribute [rw] ordered_colors
|
|
28
|
-
# @return [Array<Color>] Ein Array aller Farben die ziehen können in
|
|
29
|
-
# der Reihenfolge in der sie drankommen
|
|
30
|
-
attr_accessor :ordered_colors
|
|
31
|
-
|
|
32
|
-
# @!attribute [r] undeployed_blue_pieces
|
|
33
|
-
# @return [Array<PieceShape>] Die blauen, nicht gesetzten Spielsteine
|
|
34
|
-
attr_accessor :undeployed_blue_pieces
|
|
35
|
-
|
|
36
|
-
# @!attribute [r] undeployed_yellow_pieces
|
|
37
|
-
# @return [Array<PieceShape>] Die gelben, nicht gesetzten Spielsteine
|
|
38
|
-
attr_accessor :undeployed_yellow_pieces
|
|
39
|
-
|
|
40
|
-
# @!attribute [r] undeployed_red_pieces
|
|
41
|
-
# @return [Array<PieceShape>] Die roten, nicht gesetzten Spielsteine
|
|
42
|
-
attr_accessor :undeployed_red_pieces
|
|
43
|
-
|
|
44
|
-
# @!attribute [r] undeployed_green_pieces
|
|
45
|
-
# @return [Array<PieceShape>] Die grünen, nicht gesetzten Spielsteine
|
|
46
|
-
attr_accessor :undeployed_green_pieces
|
|
47
|
-
|
|
48
23
|
# @!attribute [r] player_one
|
|
49
24
|
# @return [Player] Der erste Spieler
|
|
50
25
|
attr_reader :player_one
|
|
26
|
+
|
|
51
27
|
# @!attribute [r] player_two
|
|
52
28
|
# @return [Player] Der zweite Spieler
|
|
53
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
|
+
|
|
54
35
|
# @!attribute [rw] board
|
|
55
36
|
# @return [Board] Das aktuelle Spielbrett
|
|
56
37
|
attr_accessor :board
|
|
57
|
-
|
|
58
|
-
# @return [PieceShape] Der Stein, der im ersten Zug von allen Farben gelegt werden muss
|
|
59
|
-
attr_accessor :start_piece
|
|
38
|
+
|
|
60
39
|
# @!attribute [rw] last_move
|
|
61
40
|
# @return [Move] Der zuletzt gemachte Zug (ist nil vor dem ersten Zug, also
|
|
62
41
|
# bei turn == 0)
|
|
63
42
|
attr_accessor :last_move
|
|
43
|
+
|
|
64
44
|
# @!attribute [rw] condition
|
|
65
45
|
# @return [Condition] Gewinner und Gewinngrund, falls das Spiel bereits
|
|
66
46
|
# entschieden ist, sonst nil.
|
|
@@ -73,67 +53,37 @@ class GameState
|
|
|
73
53
|
|
|
74
54
|
# Erstellt einen neuen leeren Spielstand.
|
|
75
55
|
def initialize
|
|
76
|
-
@current_color = Color::RED
|
|
77
|
-
@start_color = Color::RED
|
|
78
56
|
@board = Board.new
|
|
79
57
|
@turn = 0
|
|
80
|
-
@undeployed_blue_pieces = PieceShape.to_a
|
|
81
|
-
@undeployed_yellow_pieces = PieceShape.to_a
|
|
82
|
-
@undeployed_red_pieces = PieceShape.to_a
|
|
83
|
-
@undeployed_green_pieces = PieceShape.to_a
|
|
84
|
-
@start_piece = GameRuleLogic.get_random_pentomino
|
|
85
58
|
end
|
|
86
59
|
|
|
87
60
|
# Fügt einen Spieler zum Spielzustand hinzu.
|
|
88
61
|
#
|
|
89
62
|
# @param player [Player] Der hinzuzufügende Spieler.
|
|
90
63
|
def add_player(player)
|
|
91
|
-
|
|
64
|
+
case player.color
|
|
65
|
+
when Color::RED
|
|
92
66
|
@player_one = player
|
|
93
|
-
|
|
67
|
+
when Color::BLUE
|
|
94
68
|
@player_two = player
|
|
95
69
|
end
|
|
96
70
|
end
|
|
97
71
|
|
|
98
72
|
# @return [Player] Spieler, der gerade an der Reihe ist.
|
|
99
73
|
def current_player
|
|
100
|
-
turn
|
|
74
|
+
turn.even? ? player_one : player_two
|
|
101
75
|
end
|
|
102
76
|
|
|
103
77
|
# @return [Player] Spieler, der gerade nicht an der Reihe ist.
|
|
104
78
|
def other_player
|
|
105
|
-
turn
|
|
79
|
+
turn.even? ? player_two : player_one
|
|
106
80
|
end
|
|
107
81
|
|
|
108
|
-
# @return [
|
|
109
|
-
def
|
|
82
|
+
# @return [Team] Typ des Spielers, der gerade nicht an der Reihe ist.
|
|
83
|
+
def other_team
|
|
110
84
|
other_player.type
|
|
111
85
|
end
|
|
112
86
|
|
|
113
|
-
# @return [Color] Farbe, der gerade an der Reihe ist.
|
|
114
|
-
def current_color
|
|
115
|
-
ordered_colors[current_color_index]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# @return [Array<PieceShape>] Array aller Shapes, der gegebenen Farbe, die noch nicht gelegt wurden
|
|
119
|
-
def undeployed_pieces(color)
|
|
120
|
-
case color
|
|
121
|
-
when Color::RED
|
|
122
|
-
undeployed_red_pieces
|
|
123
|
-
when Color::BLUE
|
|
124
|
-
undeployed_blue_pieces
|
|
125
|
-
when Color::YELLOW
|
|
126
|
-
undeployed_yellow_pieces
|
|
127
|
-
when Color::GREEN
|
|
128
|
-
undeployed_green_pieces
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# @return [Array<PieceShape>] Array aller Shapes, der gegebenen Farbe, die schon gelegt wurden
|
|
133
|
-
def deployed_pieces(color)
|
|
134
|
-
board.deployed_pieces(color)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
87
|
# @return [Bool] Ob diese gamestate in der ersten Runde ist
|
|
138
88
|
def is_first_move?
|
|
139
89
|
round == 1
|
|
@@ -153,11 +103,6 @@ class GameState
|
|
|
153
103
|
!condition.nil?
|
|
154
104
|
end
|
|
155
105
|
|
|
156
|
-
# Entfernt die jetzige Farbe aus der Farbrotation
|
|
157
|
-
def remove_active_color
|
|
158
|
-
ordered_colors.delete current_color
|
|
159
|
-
end
|
|
160
|
-
|
|
161
106
|
# @return [Player] Der Spieler, der das Spiel gewonnen hat, falls dies schon
|
|
162
107
|
# entschieden ist. Sonst false.
|
|
163
108
|
def winner
|
|
@@ -207,6 +152,6 @@ class GameState
|
|
|
207
152
|
|
|
208
153
|
# @return [Array<Field>] Alle Felder mit Blöcken des Spielers, der gerade an der Reihe ist.
|
|
209
154
|
def own_fields
|
|
210
|
-
board.fields_of_color(
|
|
155
|
+
board.fields_of_color(current_player.color)
|
|
211
156
|
end
|
|
212
157
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'has_hints'
|
|
4
|
+
|
|
5
|
+
# Ein Move repräsentiert eine Bewegung eines Steins auf dem Spielbrett
|
|
6
|
+
class Move
|
|
7
|
+
include HasHints
|
|
8
|
+
|
|
9
|
+
# @!attribute [r] Koordinaten von dem der Spielstein in diesem Zug wegbewegt wird
|
|
10
|
+
# @return [Coordinates]
|
|
11
|
+
attr_reader :from
|
|
12
|
+
|
|
13
|
+
# @!attribute [r] Koordinaten zu denen der Spielstein in diesem Zug hinbewegt wird
|
|
14
|
+
# @return [Coordinates]
|
|
15
|
+
attr_reader :to
|
|
16
|
+
|
|
17
|
+
# Erstellt ein neuen Zug.
|
|
18
|
+
def initialize(from, to)
|
|
19
|
+
@from = from
|
|
20
|
+
@to = to
|
|
21
|
+
@hints = []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def piece(gamestate)
|
|
25
|
+
gamestate.board.field_at(from).piece
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def piece_t(gamestate)
|
|
29
|
+
gamestate.board.field_at(to).piece
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def ==(other)
|
|
33
|
+
from == other.from &&
|
|
34
|
+
to == other.to
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @return [String] Gibt die String-Repräsentation zurück
|
|
38
|
+
def to_s
|
|
39
|
+
"Move(#{from}->#{to})"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -2,59 +2,80 @@
|
|
|
2
2
|
|
|
3
3
|
# Ein Spielstein mit Ausrichtung, Koordinaten und Farbe
|
|
4
4
|
class Piece
|
|
5
|
-
|
|
5
|
+
include Constants
|
|
6
|
+
|
|
7
|
+
# @!attribute [rw] Color
|
|
6
8
|
# @return [Color]
|
|
7
|
-
|
|
9
|
+
attr_accessor :color
|
|
8
10
|
|
|
9
|
-
# @!attribute [r]
|
|
10
|
-
# @return [
|
|
11
|
-
attr_reader :
|
|
11
|
+
# @!attribute [r] Typ des Spielsteins
|
|
12
|
+
# @return [PieceType]
|
|
13
|
+
attr_reader :type
|
|
12
14
|
|
|
13
|
-
# @!attribute [
|
|
14
|
-
# @return [Rotation]
|
|
15
|
-
attr_reader :rotation
|
|
16
|
-
|
|
17
|
-
# @!attribute [r] Ob der Stein an der Y-Achse gespiegelt ist
|
|
18
|
-
# @return [Boolean]
|
|
19
|
-
attr_reader :is_flipped
|
|
20
|
-
|
|
21
|
-
# @!attribute [r] Koordinaten
|
|
15
|
+
# @!attribute [rw] Koordinaten
|
|
22
16
|
# @return [Coordinates]
|
|
23
|
-
|
|
17
|
+
attr_accessor :position
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
# @!attribute [rw] tower_height
|
|
20
|
+
# @return [Integer] Die Anzahl Spielsteine übereinander inklusive des obersten
|
|
21
|
+
attr_accessor :height
|
|
26
22
|
|
|
27
|
-
# Erstellt einen neuen
|
|
28
|
-
def initialize(color,
|
|
23
|
+
# Erstellt einen neuen Spielstein.
|
|
24
|
+
def initialize(color, type, position = Coordinates.origin, height = 0)
|
|
29
25
|
@color = color
|
|
30
|
-
@
|
|
31
|
-
@rotation = rotation
|
|
32
|
-
@is_flipped = is_flipped
|
|
26
|
+
@type = type
|
|
33
27
|
@position = position
|
|
28
|
+
@height = height
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Berechnet die Koordinaten zu denen sich dieser Spielstein bewegen könnte.
|
|
32
|
+
#
|
|
33
|
+
# @return [Array<Coordinates>] Die Zielkoordinaten
|
|
34
|
+
def target_coords
|
|
35
|
+
xdir = 0
|
|
36
|
+
if color == Color::RED
|
|
37
|
+
xdir = 1
|
|
38
|
+
else
|
|
39
|
+
xdir = -1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
case type
|
|
43
|
+
when PieceType::Herzmuschel
|
|
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
|
|
34
56
|
|
|
35
|
-
|
|
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
|
|
36
59
|
end
|
|
37
60
|
|
|
38
61
|
def ==(other)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
position == other.position
|
|
62
|
+
!other.nil? &&
|
|
63
|
+
color == other.color &&
|
|
64
|
+
position == other.position &&
|
|
65
|
+
type == other.type
|
|
44
66
|
end
|
|
45
67
|
|
|
68
|
+
# @return [String] Gibt die String-Repräsentation zurück
|
|
46
69
|
def to_s
|
|
47
|
-
"#{color.key} #{
|
|
70
|
+
"#{color.key} #{type.key} at #{position}"
|
|
48
71
|
end
|
|
49
72
|
|
|
50
|
-
|
|
51
|
-
|
|
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]}"
|
|
52
76
|
end
|
|
53
77
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
kind.transform(@rotation, @is_flipped).transform do |it|
|
|
57
|
-
Coordinates.new(it.x + @position.x, it.y + @position.y)
|
|
58
|
-
end.coordinates
|
|
78
|
+
def inspect
|
|
79
|
+
to_s
|
|
59
80
|
end
|
|
60
81
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'typesafe_enum'
|
|
4
|
+
|
|
5
|
+
# Die Spielsteintypen. Herzmuschel, Möwe, Seestern und Robbe
|
|
6
|
+
class PieceType < TypesafeEnum::Base
|
|
7
|
+
new :Herzmuschel, 'C'
|
|
8
|
+
new :Moewe, 'G'
|
|
9
|
+
new :Seestern, 'S'
|
|
10
|
+
new :Robbe, 'R'
|
|
11
|
+
|
|
12
|
+
# @return [String] Gibt den color namen zurück
|
|
13
|
+
def to_s
|
|
14
|
+
self.key.to_s
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -7,16 +7,22 @@ class Player
|
|
|
7
7
|
# @return [String] der Name des Spielers, hat keine Auswirkungen auf das Spiel
|
|
8
8
|
attr_reader :name
|
|
9
9
|
|
|
10
|
-
# @!attribute [r]
|
|
11
|
-
# @return [
|
|
12
|
-
attr_reader :
|
|
10
|
+
# @!attribute [r] color
|
|
11
|
+
# @return [Color] erster (Color::RED) oder zweiter (Color::BLUE) Spieler
|
|
12
|
+
attr_reader :color
|
|
13
|
+
|
|
14
|
+
# @!attribute [rw] amber
|
|
15
|
+
# @return [Integer] Anzahl Bernsteine die dieser Spieler gesammelt hat
|
|
16
|
+
attr_accessor :amber
|
|
13
17
|
|
|
14
18
|
# Konstruktor
|
|
15
|
-
# @param type [
|
|
19
|
+
# @param type [Color] Rot oder blau
|
|
16
20
|
# @param name [String] Name
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
# @param amber [Integer] Menge des Bernsteins die der Spieler hat
|
|
22
|
+
def initialize(color, name, amber = 0)
|
|
23
|
+
@color = color
|
|
19
24
|
@name = name
|
|
25
|
+
@amber = amber
|
|
20
26
|
end
|
|
21
27
|
|
|
22
28
|
def ==(other)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
require 'socket'
|
|
4
4
|
require_relative 'board'
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative '
|
|
5
|
+
require_relative 'move'
|
|
6
|
+
require_relative 'piece_type'
|
|
7
7
|
require_relative 'player'
|
|
8
8
|
require_relative 'network'
|
|
9
9
|
require_relative 'client_interface'
|
|
@@ -61,26 +61,23 @@ class Protocol
|
|
|
61
61
|
case name
|
|
62
62
|
when 'board'
|
|
63
63
|
logger.debug @gamestate.board.to_s
|
|
64
|
-
when '
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
67
71
|
end
|
|
68
|
-
when '
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@gamestate.undeployed_yellow_pieces << shape
|
|
78
|
-
when :red_shapes
|
|
79
|
-
shape = PieceShape.to_a.find {|s| s.key == @context[:last_text].to_sym }
|
|
80
|
-
@gamestate.undeployed_red_pieces << shape
|
|
81
|
-
when :green_shapes
|
|
82
|
-
shape = PieceShape.to_a.find {|s| s.key == @context[:last_text].to_sym }
|
|
83
|
-
@gamestate.undeployed_green_pieces << shape
|
|
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
|
|
84
81
|
end
|
|
85
82
|
end
|
|
86
83
|
end
|
|
@@ -99,7 +96,7 @@ class Protocol
|
|
|
99
96
|
when 'data'
|
|
100
97
|
logger.debug "data(class) : #{attrs['class']}"
|
|
101
98
|
@context[:data_class] = attrs['class']
|
|
102
|
-
if attrs['class'] == '
|
|
99
|
+
if attrs['class'] == 'moveRequest'
|
|
103
100
|
@client.gamestate = gamestate
|
|
104
101
|
move = @client.move_requested
|
|
105
102
|
sendString(move_to_xml(move))
|
|
@@ -116,87 +113,32 @@ class Protocol
|
|
|
116
113
|
when 'state'
|
|
117
114
|
logger.debug 'new gamestate'
|
|
118
115
|
@gamestate = GameState.new
|
|
119
|
-
@gamestate.current_color_index = attrs['currentColorIndex'].to_i
|
|
120
116
|
@gamestate.turn = attrs['turn'].to_i
|
|
121
|
-
@gamestate.round =
|
|
122
|
-
@gamestate.start_piece = PieceShape.to_a.find {|s| s.key == attrs['startPiece'].to_sym }
|
|
117
|
+
@gamestate.round = @gamestate.turn / 2
|
|
123
118
|
logger.debug "Round: #{@gamestate.round}, Turn: #{@gamestate.turn}"
|
|
124
|
-
when 'first'
|
|
125
|
-
logger.debug 'new first player'
|
|
126
|
-
player = Player.new(PlayerType::ONE, attrs['displayName'])
|
|
127
|
-
@gamestate.add_player(player)
|
|
128
|
-
@context[:player] = player
|
|
129
|
-
@context[:color] = :one
|
|
130
|
-
when 'second'
|
|
131
|
-
logger.debug 'new second player'
|
|
132
|
-
player = Player.new(PlayerType::TWO, attrs['displayName'])
|
|
133
|
-
@gamestate.add_player(player)
|
|
134
|
-
@context[:player] = player
|
|
135
|
-
@context[:color] = :two
|
|
136
|
-
when 'orderedColors'
|
|
137
|
-
@context[:color] = :ordered_colors
|
|
138
|
-
@gamestate.ordered_colors = []
|
|
139
119
|
when 'board'
|
|
140
120
|
logger.debug 'new board'
|
|
141
121
|
@gamestate.board = Board.new()
|
|
142
|
-
when '
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@gamestate.board.add_field(field)
|
|
148
|
-
@context[:piece_target] = :field
|
|
149
|
-
@context[:field] = field
|
|
150
|
-
when 'blueShapes'
|
|
151
|
-
@context[:piece_target] = :blue_shapes
|
|
152
|
-
@gamestate.undeployed_blue_pieces = []
|
|
153
|
-
when 'yellowShapes'
|
|
154
|
-
@context[:piece_target] = :yellow_shapes
|
|
155
|
-
@gamestate.undeployed_yellow_pieces = []
|
|
156
|
-
when 'redShapes'
|
|
157
|
-
@context[:piece_target] = :red_shapes
|
|
158
|
-
@gamestate.undeployed_red_pieces = []
|
|
159
|
-
when 'greenShapes'
|
|
160
|
-
@context[:piece_target] = :green_shapes
|
|
161
|
-
@gamestate.undeployed_green_pieces = []
|
|
122
|
+
when 'pieces'
|
|
123
|
+
@context[:entry] = :pieces
|
|
124
|
+
when 'coordinates'
|
|
125
|
+
@context[:x] = attrs['x'].to_i
|
|
126
|
+
@context[:y] = attrs['y'].to_i
|
|
162
127
|
when 'piece'
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
when :last_move
|
|
178
|
-
@context[:last_move_piece] = piece
|
|
179
|
-
else
|
|
180
|
-
raise "unknown piece target #{@context[:piece_target]}"
|
|
181
|
-
end
|
|
182
|
-
when 'lastMove'
|
|
183
|
-
type = attrs['class']
|
|
184
|
-
if type == 'skipmove'
|
|
185
|
-
@gamestate.last_move = SkipMove.new
|
|
186
|
-
else
|
|
187
|
-
@context[:last_move_type] = type
|
|
188
|
-
@context[:piece_target] = :last_move
|
|
189
|
-
end
|
|
190
|
-
when 'position'
|
|
191
|
-
case @context[:piece_target]
|
|
192
|
-
when :last_move
|
|
193
|
-
x = attrs['x'].to_i
|
|
194
|
-
y = attrs['y'].to_i
|
|
195
|
-
piece = @context[:last_move_piece]
|
|
196
|
-
@gamestate.last_move = SetMove.new(Piece.new(piece.color, piece.kind, piece.rotation, piece.is_flipped, Coordinates.new(x, y)))
|
|
197
|
-
end
|
|
198
|
-
when 'startColor'
|
|
199
|
-
@gamestate.start_color = Color::BLUE
|
|
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
|
|
200
142
|
when 'winner'
|
|
201
143
|
# TODO
|
|
202
144
|
# winning_player = parsePlayer(attrs)
|
|
@@ -240,28 +182,21 @@ class Protocol
|
|
|
240
182
|
# @param move [Move] The move to convert to XML.
|
|
241
183
|
def move_to_xml(move)
|
|
242
184
|
builder = Builder::XmlMarkup.new(indent: 2)
|
|
185
|
+
|
|
186
|
+
if move.nil?
|
|
187
|
+
raise 'nil moves are not sendable!'
|
|
188
|
+
end
|
|
189
|
+
|
|
243
190
|
# Converting every the move here instead of requiring the Move
|
|
244
191
|
# class interface to supply a method which returns the XML
|
|
245
192
|
# because XML-generation should be decoupled from internal data
|
|
246
193
|
# structures.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
piece.position(x: move.piece.position.x, y: move.piece.position.y)
|
|
252
|
-
end
|
|
253
|
-
move.hints.each do |hint|
|
|
254
|
-
data.hint(content: hint.content)
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
when SkipMove
|
|
258
|
-
builder.data(class: 'sc.plugin2021.SkipMove') do |data|
|
|
259
|
-
data.color(@gamestate.current_color.key.to_s)
|
|
260
|
-
move.hints.each do |hint|
|
|
261
|
-
data.hint(content: hint.content)
|
|
262
|
-
end
|
|
263
|
-
end
|
|
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)
|
|
264
198
|
end
|
|
199
|
+
|
|
265
200
|
builder.target!
|
|
266
201
|
end
|
|
267
202
|
end
|
|
@@ -9,7 +9,7 @@ class Runner
|
|
|
9
9
|
include Logging
|
|
10
10
|
|
|
11
11
|
def initialize(host, port, client, reservation = nil)
|
|
12
|
-
logger.info 'Software Challenge
|
|
12
|
+
logger.info 'Software Challenge 2022'
|
|
13
13
|
logger.info 'Ruby Client'
|
|
14
14
|
logger.info "Host: #{host}"
|
|
15
15
|
logger.info "Port: #{port}"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'typesafe_enum'
|
|
4
|
+
|
|
5
|
+
require_relative 'color'
|
|
6
|
+
|
|
7
|
+
# Erster oder zweiter Spieler:
|
|
8
|
+
#
|
|
9
|
+
# ONE
|
|
10
|
+
# TWO
|
|
11
|
+
#
|
|
12
|
+
# Zugriff z.B. mit Team::ONE
|
|
13
|
+
class Team < TypesafeEnum::Base
|
|
14
|
+
new :ONE, 'Red'
|
|
15
|
+
new :TWO, 'Blue'
|
|
16
|
+
|
|
17
|
+
# @return [Color] Gibt die zugehörige Farbe zurück
|
|
18
|
+
def to_c
|
|
19
|
+
if self.key == :ONE
|
|
20
|
+
Color::RED
|
|
21
|
+
else
|
|
22
|
+
Color::BLUE
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
# Konstanten zum aktuellen Spiel.
|
|
5
5
|
module Constants
|
|
6
6
|
ROUND_LIMIT = 30 # Rundenbegrenzung. Nach Ende der angegebenen Runde endet auch das Spiel.
|
|
7
|
-
GAME_IDENTIFIER = '
|
|
8
|
-
BOARD_SIZE =
|
|
9
|
-
TOTAL_PIECE_SHAPES = 21
|
|
7
|
+
GAME_IDENTIFIER = 'swc_2022_ostseeschach' # Der Identifikator des Spiels. Für die Kommunikation mit dem Spielserver.
|
|
8
|
+
BOARD_SIZE = 8 # Seitenlänge des Spielbretts in Feldern
|
|
10
9
|
end
|
|
@@ -4,7 +4,6 @@ module SoftwareChallengeClient
|
|
|
4
4
|
require 'software_challenge_client/client_interface.rb'
|
|
5
5
|
require 'software_challenge_client/color.rb'
|
|
6
6
|
require 'software_challenge_client/condition.rb'
|
|
7
|
-
require 'software_challenge_client/coordinate_set.rb'
|
|
8
7
|
require 'software_challenge_client/coordinates.rb'
|
|
9
8
|
require 'software_challenge_client/debug_hint.rb'
|
|
10
9
|
require 'software_challenge_client/field.rb'
|
|
@@ -13,16 +12,14 @@ module SoftwareChallengeClient
|
|
|
13
12
|
require 'software_challenge_client/has_hints.rb'
|
|
14
13
|
require 'software_challenge_client/invalid_move_exception.rb'
|
|
15
14
|
require 'software_challenge_client/logging.rb'
|
|
15
|
+
require 'software_challenge_client/move.rb'
|
|
16
16
|
require 'software_challenge_client/network.rb'
|
|
17
17
|
require 'software_challenge_client/piece.rb'
|
|
18
|
-
require 'software_challenge_client/
|
|
18
|
+
require 'software_challenge_client/piece_type.rb'
|
|
19
19
|
require 'software_challenge_client/player.rb'
|
|
20
|
-
require 'software_challenge_client/player_type.rb'
|
|
21
20
|
require 'software_challenge_client/protocol.rb'
|
|
22
|
-
require 'software_challenge_client/rotation.rb'
|
|
23
21
|
require 'software_challenge_client/runner.rb'
|
|
24
|
-
require 'software_challenge_client/
|
|
25
|
-
require 'software_challenge_client/skip_move.rb'
|
|
22
|
+
require 'software_challenge_client/team.rb'
|
|
26
23
|
require 'software_challenge_client/util/constants.rb'
|
|
27
24
|
require 'software_challenge_client/version.rb'
|
|
28
25
|
end
|
data/lib/update_client_module.sh
CHANGED
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
server=flut
|
|
4
|
+
docker build . -t sc-ruby
|
|
5
|
+
docker tag sc-ruby localhost:5000/sc-ruby
|
|
6
|
+
ssh -M -S ssh-ctrl-socket -fnNT -L 5000:localhost:5000 $server
|
|
7
|
+
ssh -S ssh-ctrl-socket -O check $server || exit 1
|
|
8
|
+
docker login localhost:5000 || exit 1
|
|
9
|
+
docker push localhost:5000/sc-ruby
|
|
10
|
+
ssh -S ssh-ctrl-socket -O exit $server
|
|
11
|
+
ssh $server 'sudo docker pull localhost:5000/sc-ruby'
|
|
12
|
+
ssh $server 'sudo docker tag localhost:5000/sc-ruby sc-ruby'
|