software_challenge_client 22.1.0.1 → 23.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.rspec +3 -3
  4. data/.rubocop.yml +11 -11
  5. data/.ruby-version +1 -1
  6. data/.stickler.yml +7 -7
  7. data/.vscode/launch.json +40 -40
  8. data/.vscode/settings.json +9 -9
  9. data/AUTHORS +6 -6
  10. data/CODE_OF_CONDUCT.md +13 -13
  11. data/Dockerfile +3 -3
  12. data/Gemfile +5 -5
  13. data/Guardfile +45 -45
  14. data/README.md +172 -147
  15. data/RELEASES.md +144 -140
  16. data/Rakefile +7 -7
  17. data/bin/console +15 -15
  18. data/bin/setup +7 -7
  19. data/develop.sh +3 -3
  20. data/example/client.rb +35 -35
  21. data/example/main.rb +42 -42
  22. data/example/start.bat +2 -2
  23. data/generate-authors.sh +19 -19
  24. data/lib/software_challenge_client/board.rb +149 -127
  25. data/lib/software_challenge_client/client_interface.rb +19 -19
  26. data/lib/software_challenge_client/condition.rb +27 -27
  27. data/lib/software_challenge_client/coordinates.rb +71 -45
  28. data/lib/software_challenge_client/debug_hint.rb +17 -17
  29. data/lib/software_challenge_client/direction.rb +41 -0
  30. data/lib/software_challenge_client/field.rb +70 -69
  31. data/lib/software_challenge_client/game_rule_logic.rb +206 -141
  32. data/lib/software_challenge_client/game_state.rb +57 -24
  33. data/lib/software_challenge_client/invalid_move_exception.rb +15 -15
  34. data/lib/software_challenge_client/logging.rb +26 -26
  35. data/lib/software_challenge_client/move.rb +37 -41
  36. data/lib/software_challenge_client/network.rb +126 -126
  37. data/lib/software_challenge_client/piece.rb +43 -81
  38. data/lib/software_challenge_client/player.rb +31 -31
  39. data/lib/software_challenge_client/protocol.rb +103 -54
  40. data/lib/software_challenge_client/runner.rb +36 -36
  41. data/lib/software_challenge_client/team.rb +23 -25
  42. data/lib/software_challenge_client/util/constants.rb +9 -9
  43. data/lib/software_challenge_client/version.rb +5 -5
  44. data/lib/software_challenge_client.rb +23 -25
  45. data/lib/update_client_module.sh +15 -15
  46. data/push_image_production.sh +12 -12
  47. data/release.sh +9 -9
  48. data/software_challenge_client.gemspec +41 -41
  49. metadata +3 -5
  50. data/lib/software_challenge_client/color.rb +0 -26
  51. data/lib/software_challenge_client/has_hints.rb +0 -11
  52. 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
- moves = []
27
- fields = gamestate.board.fields_of_color(gamestate.current_player.color)
28
-
29
- fields.each do |f|
30
- moves.push(*moves_for_piece(gamestate, f.piece))
31
- end
32
-
33
- moves.select { |m| valid_move?(gamestate, m) }.to_a
34
- end
35
-
36
- # Gibt einen zufälligen möglichen Zug zurück
37
- # @param gamestate [GameState] Der zu untersuchende Spielstand.
38
- #
39
- # @return [Move] Ein möglicher Move
40
- def self.possible_move(gamestate)
41
- possible_moves(gamestate).sample
42
- end
43
-
44
- # Hilfsmethode um Legezüge für einen [Piece] zu berechnen.
45
- # @param gamestate [GameState] Der zu untersuchende Spielstand.
46
- # @param piece [Piece] Der Typ des Spielsteines
47
- #
48
- # @return [Array<Move>] Die möglichen Moves
49
- def self.moves_for_piece(gamestate, piece)
50
- moves = Set[]
51
- piece.target_coords.each do |c|
52
- moves << Move.new(piece.position, c)
53
- end
54
- moves.select { |m| valid_move?(gamestate, m) }.to_a
55
- end
56
-
57
- # --- Move Validation ------------------------------------------------------------
58
-
59
- # Prüft, ob der gegebene [Move] zulässig ist.
60
- # @param gamestate [GameState] Der zu untersuchende Spielstand.
61
- # @param move [Move] Der zu überprüfende Zug
62
- #
63
- # @return ob der Zug zulässig ist
64
- def self.valid_move?(gamestate, move)
65
- return false unless gamestate.current_player.color == move.piece(gamestate).color
66
-
67
- return false unless gamestate.board.in_bounds?(move.to)
68
-
69
- return false if gamestate.board.field_at(move.to).color == move.piece(gamestate).color
70
-
71
- return false unless move.piece(gamestate).target_coords.include? move.to
72
-
73
- # TODO 2022: Forgot checks?
74
-
75
- true
76
- end
77
-
78
- # Überprüft, ob die gegebene [position] mit einem Spielstein belegt ist.
79
- # @param board [Board] Das aktuelle Spielbrett
80
- # @param position [Coordinates] Die zu überprüfenden Koordinaten
81
- #
82
- # @return [Boolean] Ob die position belegt wurde
83
- def self.obstructed?(board, position)
84
- !board.field_at(position).empty?
85
- end
86
-
87
- # --- Perform Move ------------------------------------------------------------
88
-
89
- # Führe den gegebenen [Move] im gebenenen [GameState] aus.
90
- # @param gamestate [GameState] der aktuelle Spielstand
91
- # @param move der auszuführende Zug
92
- #
93
- # @return [GameState] Der theoretische GameState
94
- def self.perform_move(gamestate, move)
95
- raise 'Invalid move!' unless valid_move?(gamestate, move)
96
-
97
- from_field = gamestate.board.field_at(move.from)
98
- to_field = gamestate.board.field_at(move.to)
99
-
100
- # Update board pieces if one is stepped on
101
- if not to_field.empty?
102
- from_field.piece.height = from_field.piece.height + 1
103
-
104
- # Check for high tower
105
- if from_field.piece.height >= 3
106
- gamestate.current_player.amber = gamestate.current_player.amber + 1
107
- to_field.piece = nil
108
- end
109
- end
110
-
111
- # Update board fields
112
- to_field.piece = from_field.piece
113
- from_field.piece = nil
114
-
115
- # Update position value of the moved piece
116
- if !to_field.empty? && !to_field.piece.nil?
117
- to_field.piece.position = Coordinates.new(to_field.coordinates.x, to_field.coordinates.y)
118
- end
119
-
120
- gamestate.turn += 1
121
- gamestate.last_move = move
122
- end
123
-
124
- # --- Other ------------------------------------------------------------
125
-
126
- # Prueft, ob ein Spieler im gegebenen GameState gewonnen hat.
127
- # @param gamestate [GameState] Der zu untersuchende GameState.
128
- #
129
- # @return [Condition] nil, if the game is not won or a Condition indicating the winning player
130
- def self.winning_condition(gamestate)
131
- if gamestate.player_one.amber >= 2
132
- Condition.new(gamestate.player_one, "Spieler 1 hat 2 Bernsteine erreicht")
133
- end
134
-
135
- if gamestate.player_two.amber >= 2
136
- Condition.new(gamestate.player_two, "Spieler 2 hat 2 Bernsteine erreicht")
137
- end
138
-
139
- nil
140
- end
141
- end
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] start_team
28
- # @return [Team] Der Spieler der zuerst zieht
29
- attr_accessor :start_team
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] 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
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.color
61
- when Color::RED
62
+ case player.team
63
+ when Team::ONE
62
64
  @player_one = player
63
- when Color::BLUE
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
- turn.even? ? player_two : player_one
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 is_first_move?
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(_player)
125
- # TODO
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
- start_color == other.start_color &&
132
- current_color == other.current_color &&
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.fields_of_color(current_player.color)
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
- 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
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