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,141 +1,206 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './util/constants'
|
4
|
-
require_relative 'invalid_move_exception'
|
5
|
-
require_relative 'move'
|
6
|
-
|
7
|
-
require 'set'
|
8
|
-
|
9
|
-
# Methoden, welche die Spielregeln von Ostseeschach abbilden.
|
10
|
-
#
|
11
|
-
# Es gibt hier viele Helfermethoden, die von den beiden Hauptmethoden {GameRuleLogic#valid_move?}
|
12
|
-
# und {GameRuleLogic.possible_moves} benutzt werden.
|
13
|
-
class GameRuleLogic
|
14
|
-
include Constants
|
15
|
-
|
16
|
-
SUM_MAX_SQUARES = 89
|
17
|
-
|
18
|
-
# --- Possible Moves ------------------------------------------------------------
|
19
|
-
|
20
|
-
# Gibt alle möglichen Züge für den Spieler zurück, der in der gamestate dran ist.
|
21
|
-
# Diese ist die wichtigste Methode dieser Klasse für Schüler.
|
22
|
-
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
23
|
-
#
|
24
|
-
# @return [Array<Move>] Die möglichen Moves
|
25
|
-
def self.possible_moves(gamestate)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
#
|
63
|
-
# @
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
gamestate.turn
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './util/constants'
|
4
|
+
require_relative 'invalid_move_exception'
|
5
|
+
require_relative 'move'
|
6
|
+
|
7
|
+
require 'set'
|
8
|
+
|
9
|
+
# Methoden, welche die Spielregeln von Ostseeschach abbilden.
|
10
|
+
#
|
11
|
+
# Es gibt hier viele Helfermethoden, die von den beiden Hauptmethoden {GameRuleLogic#valid_move?}
|
12
|
+
# und {GameRuleLogic.possible_moves} benutzt werden.
|
13
|
+
class GameRuleLogic
|
14
|
+
include Constants
|
15
|
+
|
16
|
+
SUM_MAX_SQUARES = 89
|
17
|
+
|
18
|
+
# --- Possible Moves ------------------------------------------------------------
|
19
|
+
|
20
|
+
# Gibt alle möglichen Züge für den Spieler zurück, der in der gamestate dran ist.
|
21
|
+
# Diese ist die wichtigste Methode dieser Klasse für Schüler.
|
22
|
+
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
23
|
+
#
|
24
|
+
# @return [Array<Move>] Die möglichen Moves
|
25
|
+
def self.possible_moves(gamestate)
|
26
|
+
if gamestate.turn < 8
|
27
|
+
self.possible_setmoves(gamestate)
|
28
|
+
else
|
29
|
+
self.possible_normalmoves(gamestate)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gibt alle möglichen Lege-Züge für den Spieler zurück, der in der gamestate dran ist.
|
34
|
+
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
35
|
+
#
|
36
|
+
# @return [Array<Move>] Die möglichen Moves
|
37
|
+
def self.possible_setmoves(gamestate)
|
38
|
+
moves = []
|
39
|
+
|
40
|
+
(0...BOARD_SIZE).to_a.map do |x|
|
41
|
+
(0...BOARD_SIZE).to_a.map do |y|
|
42
|
+
if gamestate.board.field(x, y).fishes == 1
|
43
|
+
moves.push(Move.new(nil, Coordinates.new(x, y)))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
moves
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.possible_normalmoves(gamestate)
|
52
|
+
moves = []
|
53
|
+
fields = gamestate.board.fields_of_team(gamestate.current_player.team)
|
54
|
+
|
55
|
+
fields.each do |f|
|
56
|
+
moves.push(*moves_for_piece(gamestate, f.piece))
|
57
|
+
end
|
58
|
+
|
59
|
+
moves.select { |m| valid_move?(gamestate, m) }.to_a
|
60
|
+
end
|
61
|
+
|
62
|
+
# Gibt einen zufälligen möglichen Zug zurück
|
63
|
+
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
64
|
+
#
|
65
|
+
# @return [Move] Ein möglicher Move
|
66
|
+
def self.possible_move(gamestate)
|
67
|
+
self.possible_moves(gamestate).sample
|
68
|
+
end
|
69
|
+
|
70
|
+
# Hilfsmethode um Legezüge für einen [Piece] zu berechnen.
|
71
|
+
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
72
|
+
# @param piece [Piece] Der Typ des Spielsteines
|
73
|
+
#
|
74
|
+
# @return [Array<Move>] Die möglichen Moves
|
75
|
+
def self.moves_for_piece(gamestate, piece)
|
76
|
+
moves = Set[]
|
77
|
+
self.target_coords(gamestate, piece).each do |c|
|
78
|
+
moves << Move.new(piece.coords, c)
|
79
|
+
end
|
80
|
+
moves.select { |m| valid_move?(gamestate, m) }.to_a
|
81
|
+
end
|
82
|
+
|
83
|
+
# Berechnet die Koordinaten zu denen sich dieser Spielstein bewegen könnte.
|
84
|
+
#
|
85
|
+
# @return [Array<Coordinates>] Die Zielkoordinaten
|
86
|
+
def self.target_coords(gamestate, piece)
|
87
|
+
coords = []
|
88
|
+
c = Coordinates.oddr_to_doubled(piece.coords)
|
89
|
+
|
90
|
+
Direction.each { |d|
|
91
|
+
x = c.x
|
92
|
+
y = c.y
|
93
|
+
disp = d.to_vec()
|
94
|
+
|
95
|
+
# doubled taversal
|
96
|
+
for i in 0..8 do
|
97
|
+
x += disp.x
|
98
|
+
y += disp.y
|
99
|
+
|
100
|
+
oddr_coords = Coordinates.doubled_to_oddr_int(x, y)
|
101
|
+
if !gamestate.board.in_bounds?(oddr_coords) || !gamestate.board.field_at(oddr_coords).free?
|
102
|
+
break
|
103
|
+
end
|
104
|
+
|
105
|
+
coords.push(oddr_coords)
|
106
|
+
end
|
107
|
+
}
|
108
|
+
|
109
|
+
coords
|
110
|
+
end
|
111
|
+
|
112
|
+
# --- Move Validation ------------------------------------------------------------
|
113
|
+
|
114
|
+
# Prüft, ob der gegebene [Move] zulässig ist.
|
115
|
+
# @param gamestate [GameState] Der zu untersuchende Spielstand.
|
116
|
+
# @param move [Move] Der zu überprüfende Zug
|
117
|
+
#
|
118
|
+
# @return ob der Zug zulässig ist
|
119
|
+
def self.valid_move?(gamestate, move)
|
120
|
+
if gamestate.turn < 8
|
121
|
+
# Setmove
|
122
|
+
|
123
|
+
# Must be setmove
|
124
|
+
return false unless move.from == nil
|
125
|
+
|
126
|
+
# Must have 1 fish to set on
|
127
|
+
return false unless gamestate.board.field_at(move.to).fishes == 1
|
128
|
+
|
129
|
+
# Must have no piece on it
|
130
|
+
return false unless gamestate.board.field_at(move.to).piece == nil
|
131
|
+
else
|
132
|
+
# Normal move
|
133
|
+
|
134
|
+
# Must be normal move
|
135
|
+
return false unless !move.from.nil?
|
136
|
+
|
137
|
+
# Team must be correct
|
138
|
+
return false unless gamestate.current_player.team == gamestate.board.field_at(move.from).piece.team
|
139
|
+
|
140
|
+
# Move must stay in bounds
|
141
|
+
return false unless gamestate.board.in_bounds?(move.to)
|
142
|
+
|
143
|
+
# Move must go onto free field
|
144
|
+
return false unless gamestate.board.field_at(move.to).free?
|
145
|
+
|
146
|
+
# Move must go onto valid coords
|
147
|
+
return false unless self.target_coords(gamestate, gamestate.board.field_at(move.from).piece).include?(move.to)
|
148
|
+
end
|
149
|
+
|
150
|
+
# TODO 2023: Forgot checks?
|
151
|
+
|
152
|
+
true
|
153
|
+
end
|
154
|
+
|
155
|
+
# --- Perform Move ------------------------------------------------------------
|
156
|
+
|
157
|
+
# Führe den gegebenen [Move] im gebenenen [GameState] aus.
|
158
|
+
# @param gamestate [GameState] der aktuelle Spielstand
|
159
|
+
# @param move der auszuführende Zug
|
160
|
+
#
|
161
|
+
# @return [GameState] Der theoretische GameState
|
162
|
+
def self.perform_move(gamestate, move)
|
163
|
+
raise 'Invalid move!' unless valid_move?(gamestate, move)
|
164
|
+
|
165
|
+
target_field = gamestate.board.field_at(move.to)
|
166
|
+
|
167
|
+
gamestate.current_player.fishes += target_field.fishes
|
168
|
+
|
169
|
+
if gamestate.turn < 8
|
170
|
+
target_field.piece = Piece.new(gamestate.current_player.team, move.to)
|
171
|
+
else
|
172
|
+
start_field = gamestate.board.field_at(move.from)
|
173
|
+
|
174
|
+
start_field.fishes = 0
|
175
|
+
|
176
|
+
target_field.piece = start_field.piece
|
177
|
+
start_field.piece = nil?
|
178
|
+
end
|
179
|
+
|
180
|
+
other_player = gamestate.not_player(gamestate.current_player)
|
181
|
+
if gamestate.can_move?(other_player)
|
182
|
+
gamestate.current_player = other_player
|
183
|
+
end
|
184
|
+
|
185
|
+
gamestate.turn += 1
|
186
|
+
end
|
187
|
+
|
188
|
+
# --- Other ------------------------------------------------------------
|
189
|
+
|
190
|
+
# Prueft, ob ein Spieler im gegebenen GameState gewonnen hat.
|
191
|
+
# @param gamestate [GameState] Der zu untersuchende GameState.
|
192
|
+
#
|
193
|
+
# @return [Condition] nil, if the game is not won or a Condition indicating the winning player
|
194
|
+
def self.winning_condition(gamestate)
|
195
|
+
|
196
|
+
if GameRuleLogic.possible_moves(gamestate).count == 0
|
197
|
+
if gamestate.player_one.fishes > gamestate.player_two.fishes
|
198
|
+
Condition.new(gamestate.player_one, "Spieler 1 hat mehr Fische erreicht und gewonnen!")
|
199
|
+
else
|
200
|
+
Condition.new(gamestate.player_one, "Spieler 2 hat mehr Fische erreicht und gewonnen!")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
nil
|
205
|
+
end
|
206
|
+
end
|
@@ -4,7 +4,6 @@ require_relative './util/constants'
|
|
4
4
|
require_relative 'player'
|
5
5
|
require_relative 'board'
|
6
6
|
require_relative 'condition'
|
7
|
-
require_relative 'color'
|
8
7
|
|
9
8
|
# Ein Spielzustand. Wird vom Server an die Computerspieler übermittelt und
|
10
9
|
# enthält alles, was der Computerspieler wissen muss, um einen Zug zu machen.
|
@@ -24,18 +23,21 @@ class GameState
|
|
24
23
|
# @return [Player] Der zweite Spieler
|
25
24
|
attr_reader :player_two
|
26
25
|
|
27
|
-
# @!attribute [rw]
|
28
|
-
# @return [
|
29
|
-
attr_accessor :
|
26
|
+
# @!attribute [rw] start_player
|
27
|
+
# @return [Player] Der Spieler der zuerst zieht
|
28
|
+
attr_accessor :start_player
|
30
29
|
|
31
30
|
# @!attribute [rw] board
|
32
31
|
# @return [Board] Das aktuelle Spielbrett
|
33
32
|
attr_accessor :board
|
34
33
|
|
35
|
-
# @!attribute [rw]
|
36
|
-
# @return [
|
37
|
-
|
38
|
-
|
34
|
+
# @!attribute [rw] current_player
|
35
|
+
# @return [Player] Der Spieler, der akutell dran ist
|
36
|
+
attr_accessor :current_player
|
37
|
+
|
38
|
+
# @!attribute [rw] myself_player
|
39
|
+
# @return [Player] Der Spieler, der von diesem Skript gesteuert wird
|
40
|
+
attr_accessor :myself_player
|
39
41
|
|
40
42
|
# @!attribute [rw] condition
|
41
43
|
# @return [Condition] Gewinner und Gewinngrund, falls das Spiel bereits
|
@@ -57,22 +59,26 @@ class GameState
|
|
57
59
|
#
|
58
60
|
# @param player [Player] Der hinzuzufügende Spieler.
|
59
61
|
def add_player(player)
|
60
|
-
case player.
|
61
|
-
when
|
62
|
+
case player.team
|
63
|
+
when Team::ONE
|
62
64
|
@player_one = player
|
63
|
-
when
|
65
|
+
when Team::TWO
|
64
66
|
@player_two = player
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
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
70
|
# @return [Player] Spieler, der gerade nicht an der Reihe ist.
|
74
71
|
def other_player
|
75
|
-
|
72
|
+
current_player == player_one ? player_two : player_one
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Player] Der Spieler, der nicht p ist.
|
76
|
+
def not_player(p)
|
77
|
+
if p == player_one
|
78
|
+
player_two
|
79
|
+
else
|
80
|
+
player_one
|
81
|
+
end
|
76
82
|
end
|
77
83
|
|
78
84
|
# @return [Team] Typ des Spielers, der gerade nicht an der Reihe ist.
|
@@ -80,13 +86,25 @@ class GameState
|
|
80
86
|
other_player.type
|
81
87
|
end
|
82
88
|
|
89
|
+
# Findet den Spieler für ein Team.
|
90
|
+
#
|
91
|
+
# @param team [Team] Das Team
|
92
|
+
# @return [Player] Der zugehörige Spieler
|
93
|
+
def player_from_team(team)
|
94
|
+
if team == Team::ONE
|
95
|
+
@player_one
|
96
|
+
else
|
97
|
+
@player_two
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
83
101
|
# @return [Integer] Aktuelle Rundennummer (von 1 beginnend)
|
84
102
|
def round
|
85
103
|
turn / 2 + 1
|
86
104
|
end
|
87
105
|
|
88
106
|
# @return [Bool] Ob diese gamestate in der ersten Runde ist
|
89
|
-
def
|
107
|
+
def is_first_round?
|
90
108
|
round == 1
|
91
109
|
end
|
92
110
|
|
@@ -98,6 +116,21 @@ class GameState
|
|
98
116
|
GameRuleLogic.perform_move(self, move)
|
99
117
|
end
|
100
118
|
|
119
|
+
# Überprüft ob der gegebene Spieler ziehen könnte oder blockiert ist
|
120
|
+
#
|
121
|
+
# @param player [Player] Der Spieler.
|
122
|
+
# @return [Boolean] true, falls der Spieler ziehen könnte
|
123
|
+
def can_move?(player)
|
124
|
+
can = false
|
125
|
+
|
126
|
+
for f in board.fields_of_team(player.team) do
|
127
|
+
n = board.neighbors_of(f)
|
128
|
+
can &= n.any? { |x| x.free? }
|
129
|
+
end
|
130
|
+
|
131
|
+
can
|
132
|
+
end
|
133
|
+
|
101
134
|
# @return [Boolean] true, falls das Spiel bereits geendet hat, false bei noch
|
102
135
|
# laufenden Spielen.
|
103
136
|
def game_ended?
|
@@ -121,15 +154,15 @@ class GameState
|
|
121
154
|
#
|
122
155
|
# @param player [Player] Der Spieler, dessen Punkte berechnet werden sollen.
|
123
156
|
# @return [Integer] Die Punkte des Spielers
|
124
|
-
def points_for_player(
|
125
|
-
|
126
|
-
-1
|
157
|
+
def points_for_player(player)
|
158
|
+
player.nil? ? 0 : player.fishes
|
127
159
|
end
|
128
160
|
|
161
|
+
# TODO: Fix
|
129
162
|
def ==(other)
|
130
163
|
turn == other.turn &&
|
131
|
-
|
132
|
-
|
164
|
+
myself_player == other.myself_player &&
|
165
|
+
current_player == other.current_player &&
|
133
166
|
blue == other.blue &&
|
134
167
|
yellow == other.yellow &&
|
135
168
|
red == other.red &&
|
@@ -148,6 +181,6 @@ class GameState
|
|
148
181
|
|
149
182
|
# @return [Array<Field>] Alle Felder mit Blöcken des Spielers, der gerade an der Reihe ist.
|
150
183
|
def own_fields
|
151
|
-
board.
|
184
|
+
board.fields_of_team(current_player.team)
|
152
185
|
end
|
153
186
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# Exception, die geworfen wird, wenn ein ungültiger Zug ausgeführt wird.
|
5
|
-
# @see GameRuleLogic#perform_move
|
6
|
-
class InvalidMoveException < StandardError
|
7
|
-
def initialize(msg, move)
|
8
|
-
@move = move
|
9
|
-
super(msg)
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
"#{super}: #{@move}"
|
14
|
-
end
|
15
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Exception, die geworfen wird, wenn ein ungültiger Zug ausgeführt wird.
|
5
|
+
# @see GameRuleLogic#perform_move
|
6
|
+
class InvalidMoveException < StandardError
|
7
|
+
def initialize(msg, move)
|
8
|
+
@move = move
|
9
|
+
super(msg)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"#{super}: #{@move}"
|
14
|
+
end
|
15
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
# Dieses Modul kann inkludiert werden, um eine Logausgabe auf der Konsole verwenden zu können.
|
6
|
-
# See http://stackoverflow.com/a/6768164/390808
|
7
|
-
#
|
8
|
-
# Verwendung:
|
9
|
-
#
|
10
|
-
# class MyClass
|
11
|
-
# include Logging
|
12
|
-
#
|
13
|
-
# def a_method(x)
|
14
|
-
# logger.debug "you provided #{x}"
|
15
|
-
# end
|
16
|
-
# end
|
17
|
-
module Logging
|
18
|
-
def logger
|
19
|
-
Logging.logger
|
20
|
-
end
|
21
|
-
|
22
|
-
# Global, memoized, lazy initialized instance of a logger
|
23
|
-
def self.logger
|
24
|
-
@logger ||= Logger.new(STDOUT)
|
25
|
-
end
|
26
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# Dieses Modul kann inkludiert werden, um eine Logausgabe auf der Konsole verwenden zu können.
|
6
|
+
# See http://stackoverflow.com/a/6768164/390808
|
7
|
+
#
|
8
|
+
# Verwendung:
|
9
|
+
#
|
10
|
+
# class MyClass
|
11
|
+
# include Logging
|
12
|
+
#
|
13
|
+
# def a_method(x)
|
14
|
+
# logger.debug "you provided #{x}"
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
module Logging
|
18
|
+
def logger
|
19
|
+
Logging.logger
|
20
|
+
end
|
21
|
+
|
22
|
+
# Global, memoized, lazy initialized instance of a logger
|
23
|
+
def self.logger
|
24
|
+
@logger ||= Logger.new(STDOUT)
|
25
|
+
end
|
26
|
+
end
|
@@ -1,41 +1,37 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# @!attribute [r] Koordinaten
|
10
|
-
# @return [Coordinates]
|
11
|
-
attr_reader :
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def
|
25
|
-
gamestate.board.field_at(
|
26
|
-
end
|
27
|
-
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def to_s
|
39
|
-
"Move(#{from}->#{to})"
|
40
|
-
end
|
41
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Ein Move repräsentiert eine Bewegung eines Steins auf dem Spielbrett
|
4
|
+
class Move
|
5
|
+
# @!attribute [r] Koordinaten von dem der Spielstein in diesem Zug wegbewegt wird
|
6
|
+
# @return [Coordinates]
|
7
|
+
attr_reader :from
|
8
|
+
|
9
|
+
# @!attribute [r] Koordinaten zu denen der Spielstein in diesem Zug hinbewegt wird
|
10
|
+
# @return [Coordinates]
|
11
|
+
attr_reader :to
|
12
|
+
|
13
|
+
# Erstellt ein neuen Zug.
|
14
|
+
def initialize(from, to)
|
15
|
+
@from = from
|
16
|
+
@to = to
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO: Remove these?
|
20
|
+
def piece(gamestate)
|
21
|
+
gamestate.board.field_at(from).piece
|
22
|
+
end
|
23
|
+
|
24
|
+
def piece_t(gamestate)
|
25
|
+
gamestate.board.field_at(to).piece
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
from == other.from &&
|
30
|
+
to == other.to
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String] Gibt die String-Repräsentation zurück
|
34
|
+
def to_s
|
35
|
+
"Move(#{from}->#{to})"
|
36
|
+
end
|
37
|
+
end
|