Class: Advance
Overview
Go forward in the current direction by #distance. When on a sandbank, a value of -1 to go backwards is also legal.
Instance Attribute Summary collapse
-
#distance ⇒ Object
readonly
Returns the value of attribute distance.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#initialize(distance) ⇒ Advance
constructor
A new instance of Advance.
-
#perform!(gamestate, current_player) ⇒ Object
Perform the action.
-
#required_movement(gamestate, current_player) ⇒ Object
returns the required movement points to perform this action.
- #type ⇒ Object
Methods inherited from Action
Constructor Details
#initialize(distance) ⇒ Advance
Returns a new instance of Advance.
128 129 130 |
# File 'lib/software_challenge_client/action.rb', line 128 def initialize(distance) @distance = distance end |
Instance Attribute Details
#distance ⇒ Object (readonly)
Returns the value of attribute distance.
126 127 128 |
# File 'lib/software_challenge_client/action.rb', line 126 def distance @distance end |
Instance Method Details
#==(other) ⇒ Object
219 220 221 |
# File 'lib/software_challenge_client/action.rb', line 219 def ==(other) other.type == type && other.distance == distance end |
#perform!(gamestate, current_player) ⇒ Object
Perform the action.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/software_challenge_client/action.rb', line 133 def perform!(gamestate, current_player) invalid 'Bewegung um 0 ist unzulässig.' if distance.zero? if distance < 0 && gamestate.board.field(current_player.x, current_player.y).type != FieldType::SANDBANK invalid 'Negative Bewegung ist nur auf Sandbank erlaubt.' end begin fields = gamestate.board.get_all_in_direction( current_player.x, current_player.y, current_player.direction, distance ) rescue FieldUnavailableException => e invalid "Feld (#{e.x}, #{e.y}) ist nicht vorhanden" end # test if all fields are passable if fields.any?(&:blocked?) invalid 'Der Weg ist blockiert.' end # Test if movement is enough. req_movement = required_movement(gamestate, current_player) if req_movement > current_player.movement invalid 'Nicht genug Bewegungspunkte.' end # test if opponent is not on fields over which is moved if fields[0...-1].any? { |f| gamestate.occupied_by_other_player? f } invalid 'Man darf nicht über den Gegner fahren.' end # test if moving over sandbank if fields[0...-1].any? { |f| f.type == FieldType::SANDBANK } invalid 'Die Bewegung darf nur auf einer Sandbank enden, '\ 'nicht über sie hinaus gehen.' end target_field = fields.last current_player.x = target_field.x current_player.y = target_field.y if target_field.type == FieldType::SANDBANK current_player.movement = 0 current_player.velocity = 1 else current_player.movement -= req_movement end # test for passenger if current_player.velocity == 1 required_field_for_direction = { Direction::RIGHT.key=> FieldType::PASSENGER3.key, Direction::UP_RIGHT.key=> FieldType::PASSENGER4.key, Direction::UP_LEFT.key=> FieldType::PASSENGER5.key, Direction::LEFT.key=> FieldType::PASSENGER0.key, Direction::DOWN_LEFT.key=> FieldType::PASSENGER2.key, Direction::DOWN_RIGHT.key=> FieldType::PASSENGER1.key } Direction.each do |direction| begin neighbor = gamestate.board.get_in_direction(current_player.x, current_player.y, direction) if neighbor.type.key == required_field_for_direction[direction.key] if current_player.passengers < 2 current_player.passengers += 1 neighbor.type = FieldType::BLOCKED end end rescue FieldUnavailableException # neighbor did not exist, that is okay end end end end |
#required_movement(gamestate, current_player) ⇒ Object
returns the required movement points to perform this action
202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/software_challenge_client/action.rb', line 202 def required_movement(gamestate, current_player) gamestate.board.get_all_in_direction(current_player.x, current_player.y, current_player.direction, distance).map do |field| # pushing costs one more movement on_opponent = field.x == gamestate.other_player.x && field.y == gamestate.other_player.y case field.type when FieldType::WATER, FieldType::GOAL, FieldType::SANDBANK on_opponent ? 2 : 1 when FieldType::LOG on_opponent ? 3 : 2 end end.reduce(:+) end |
#type ⇒ Object
215 216 217 |
# File 'lib/software_challenge_client/action.rb', line 215 def type :advance end |