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.
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