software_challenge_client 21.2.0 → 22.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +61 -254
- data/lib/software_challenge_client/game_state.rb +153 -232
- data/lib/software_challenge_client/move.rb +41 -0
- data/lib/software_challenge_client/piece.rb +55 -63
- 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 +201 -266
- 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
@@ -1,92 +0,0 @@
|
|
1
|
-
require_relative 'util/constants'
|
2
|
-
|
3
|
-
# Eine Menge aus Koordinaten
|
4
|
-
class CoordinateSet
|
5
|
-
include Constants
|
6
|
-
|
7
|
-
# @!attribute [r] coordinates
|
8
|
-
# @return [Array<Coordinates>] Die enthaltenen Koordinaten.
|
9
|
-
attr_reader :coordinates
|
10
|
-
|
11
|
-
# Erstellt eine neue leere Koordinaten-Menge.
|
12
|
-
def initialize(coordinates)
|
13
|
-
@coordinates = coordinates
|
14
|
-
end
|
15
|
-
|
16
|
-
# Invertiert die X-Koordinate aller Koordinaten in dieser Menge
|
17
|
-
def flip(should_flip = true)
|
18
|
-
return self unless should_flip
|
19
|
-
|
20
|
-
transform do |it|
|
21
|
-
Coordinates.new(-it.x, it.y)
|
22
|
-
end.align
|
23
|
-
end
|
24
|
-
|
25
|
-
# Enumeriert die enthaltenen Koordinaten
|
26
|
-
def transform
|
27
|
-
CoordinateSet.new(
|
28
|
-
coordinates.map do |it|
|
29
|
-
yield it
|
30
|
-
end
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Gibt die Größe des kleinsten Bereichs zurück, in dem alle enthaltenen Punkte liegen
|
35
|
-
def area
|
36
|
-
minX = coordinates.map(&:x).min
|
37
|
-
minY = coordinates.map(&:y).min
|
38
|
-
maxX = coordinates.map(&:x).max
|
39
|
-
maxY = coordinates.map(&:y).max
|
40
|
-
Coordinates.new(maxX - minX + 1, maxY - minY + 1)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Bewege den Bereich der enthaltenen Koordinaten zum Ursprung
|
44
|
-
def align
|
45
|
-
minX = coordinates.map(&:x).min
|
46
|
-
minY = coordinates.map(&:y).min
|
47
|
-
transform do |it|
|
48
|
-
Coordinates.new(it.x - minX, it.y - minY)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Wende eine Rotation auf den Stein an
|
53
|
-
# @param rotation [Rotation] Die anzuwendene Rotation
|
54
|
-
# @return [CoordinateSet] Die gedrehten Koordinaten
|
55
|
-
def rotate(rotation)
|
56
|
-
case rotation
|
57
|
-
when Rotation::NONE
|
58
|
-
self
|
59
|
-
when Rotation::RIGHT
|
60
|
-
turn_right.align
|
61
|
-
when Rotation::MIRROR
|
62
|
-
mirror.align
|
63
|
-
when Rotation::LEFT
|
64
|
-
turn_left.align
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Drehe alle enthaltenen Koordinaten um 90° nach rechts
|
69
|
-
def turn_right
|
70
|
-
transform do |it|
|
71
|
-
Coordinates.new(-it.y, it.x)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Drehe alle enthaltenen Koordinaten um 90° nach links
|
76
|
-
def turn_left
|
77
|
-
transform do |it|
|
78
|
-
Coordinates.new(it.y, -it.x)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# Spiegle alle enthaltenen Koordinaten um beide Achsen
|
83
|
-
def mirror
|
84
|
-
transform do |it|
|
85
|
-
Coordinates.new(-it.x, -it.y)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def ==(other)
|
90
|
-
coordinates.sort == other.coordinates.sort
|
91
|
-
end
|
92
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'typesafe_enum'
|
4
|
-
|
5
|
-
require_relative 'coordinates'
|
6
|
-
require_relative 'coordinate_set'
|
7
|
-
|
8
|
-
# Die Form eines Spielsteins. Es gibt folgende Formen:
|
9
|
-
#
|
10
|
-
# MONO
|
11
|
-
# DOMINO
|
12
|
-
# TRIO_L
|
13
|
-
# TRIO_I
|
14
|
-
# TETRO_O
|
15
|
-
# TETRO_T
|
16
|
-
# TETRO_I
|
17
|
-
# TETRO_L
|
18
|
-
# TETRO_Z
|
19
|
-
# PENTO_L
|
20
|
-
# PENTO_T
|
21
|
-
# PENTO_V
|
22
|
-
# PENTO_S
|
23
|
-
# PENTO_Z
|
24
|
-
# PENTO_I
|
25
|
-
# PENTO_P
|
26
|
-
# PENTO_W
|
27
|
-
# PENTO_U
|
28
|
-
# PENTO_R
|
29
|
-
# PENTO_X
|
30
|
-
# PENTO_Y
|
31
|
-
#
|
32
|
-
# Zugriff z.B. mit PieceShape::PENTO_S
|
33
|
-
class PieceShape < TypesafeEnum::Base
|
34
|
-
def self.c(x, y)
|
35
|
-
Coordinates.new(x, y)
|
36
|
-
end
|
37
|
-
new :MONO, [c(0, 0)]
|
38
|
-
new :DOMINO, [c(0, 0), c(1, 0)]
|
39
|
-
new :TRIO_L, [c(0, 0), c(0, 1), c(1, 1)]
|
40
|
-
new :TRIO_I, [c(0, 0), c(0, 1), c(0, 2)]
|
41
|
-
new :TETRO_O, [c(0, 0), c(1, 0), c(0, 1), c(1, 1)]
|
42
|
-
new :TETRO_T, [c(0, 0), c(1, 0), c(2, 0), c(1, 1)]
|
43
|
-
new :TETRO_I, [c(0, 0), c(0, 1), c(0, 2), c(0, 3)]
|
44
|
-
new :TETRO_L, [c(0, 0), c(0, 1), c(0, 2), c(1, 2)]
|
45
|
-
new :TETRO_Z, [c(0, 0), c(1, 0), c(1, 1), c(2, 1)]
|
46
|
-
new :PENTO_L, [c(0, 0), c(0, 1), c(0, 2), c(0, 3), c(1, 3)]
|
47
|
-
new :PENTO_T, [c(0, 0), c(1, 0), c(2, 0), c(1, 1), c(1, 2)]
|
48
|
-
new :PENTO_V, [c(0, 0), c(0, 1), c(0, 2), c(1, 2), c(2, 2)]
|
49
|
-
new :PENTO_S, [c(1, 0), c(2, 0), c(3, 0), c(0, 1), c(1, 1)]
|
50
|
-
new :PENTO_Z, [c(0, 0), c(1, 0), c(1, 1), c(1, 2), c(2, 2)]
|
51
|
-
new :PENTO_I, [c(0, 0), c(0, 1), c(0, 2), c(0, 3), c(0, 4)]
|
52
|
-
new :PENTO_P, [c(0, 0), c(1, 0), c(0, 1), c(1, 1), c(0, 2)]
|
53
|
-
new :PENTO_W, [c(0, 0), c(0, 1), c(1, 1), c(1, 2), c(2, 2)]
|
54
|
-
new :PENTO_U, [c(0, 0), c(0, 1), c(1, 1), c(2, 1), c(2, 0)]
|
55
|
-
new :PENTO_R, [c(0, 1), c(1, 1), c(1, 2), c(2, 1), c(2, 0)]
|
56
|
-
new :PENTO_X, [c(1, 0), c(0, 1), c(1, 1), c(2, 1), c(1, 2)]
|
57
|
-
new :PENTO_Y, [c(0, 1), c(1, 0), c(1, 1), c(1, 2), c(1, 3)]
|
58
|
-
|
59
|
-
@transformations
|
60
|
-
Transform = Struct.new(:r, :f, :coords)
|
61
|
-
|
62
|
-
# Anzahl Felder, die der Stein belegt
|
63
|
-
def size
|
64
|
-
value.size
|
65
|
-
end
|
66
|
-
|
67
|
-
# Die Felder, die der Stein belegt
|
68
|
-
def coordinates
|
69
|
-
CoordinateSet.new(value)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Eine Koordinate, die das kleinstmögliche Rechteck beschreibt, welches alle Felder umfasst.
|
73
|
-
def dimension
|
74
|
-
coordinates.area
|
75
|
-
end
|
76
|
-
|
77
|
-
# Erzeugt eine nach Rotation und Flip transformierte Form
|
78
|
-
def transform(rotation, flip)
|
79
|
-
coordinates.rotate(rotation).flip(flip)
|
80
|
-
end
|
81
|
-
|
82
|
-
# Gibt alle Kombinationen aus Rotation und Flipping zurück, welche zu einzigartigen
|
83
|
-
# Koordinatenmengen dieser Form führen.
|
84
|
-
# @return [Array<Transform>] Transform Structs mit Rotation r, Boolean f
|
85
|
-
def unique_transforms()
|
86
|
-
if not defined? @transformations then
|
87
|
-
existing_transforms = []
|
88
|
-
|
89
|
-
Rotation.each do |r|
|
90
|
-
[true, false].each do |f|
|
91
|
-
new_transform = Transform.new(r, f, transform(r, f))
|
92
|
-
|
93
|
-
if existing_transforms.none? { |t| t.coords == new_transform.coords } then
|
94
|
-
existing_transforms << new_transform
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
@transformations = existing_transforms
|
100
|
-
end
|
101
|
-
|
102
|
-
@transformations
|
103
|
-
end
|
104
|
-
|
105
|
-
# Gibt den Form Namen zurück
|
106
|
-
def to_s
|
107
|
-
self.key.to_s
|
108
|
-
end
|
109
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'typesafe_enum'
|
4
|
-
|
5
|
-
# Die Drehung eines Steins
|
6
|
-
class Rotation < TypesafeEnum::Base
|
7
|
-
new :NONE, 0
|
8
|
-
new :RIGHT, 1
|
9
|
-
new :MIRROR, 2
|
10
|
-
new :LEFT, 3
|
11
|
-
|
12
|
-
# Summiere beide Rotationen auf.
|
13
|
-
# (Die resultierende Rotation hat den gleichen Effekt wie die beiden Rotationen einzeln).
|
14
|
-
def rotate(rotation)
|
15
|
-
Rotation.to_a[(value + rotation.value) % Rotation.size]
|
16
|
-
end
|
17
|
-
|
18
|
-
# Gibt den rotation namen zurück
|
19
|
-
def to_s
|
20
|
-
self.key.to_s
|
21
|
-
end
|
22
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'has_hints'
|
4
|
-
|
5
|
-
# Ein SetMove platziert einen Stein auf dem Spielbrett
|
6
|
-
class SetMove
|
7
|
-
include HasHints
|
8
|
-
|
9
|
-
attr_reader :piece
|
10
|
-
|
11
|
-
# Erstellt ein neuen leeren Legezug.
|
12
|
-
def initialize(piece)
|
13
|
-
@piece = piece
|
14
|
-
@hints = []
|
15
|
-
end
|
16
|
-
|
17
|
-
def ==(other)
|
18
|
-
piece == other.piece
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
"SetMove(#{piece}"
|
23
|
-
end
|
24
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'has_hints'
|
4
|
-
|
5
|
-
# Ein SkipMove ziegt an, dass die aktuelle Farbe keinen Stein platzieren will
|
6
|
-
class SkipMove
|
7
|
-
include HasHints
|
8
|
-
|
9
|
-
# Erstellt ein neuen leeren Aussetzzug.
|
10
|
-
def initialize
|
11
|
-
@hints = []
|
12
|
-
end
|
13
|
-
end
|