Class: GameState

Inherits:
Object
  • Object
show all
Defined in:
lib/software_challenge_client/game_state.rb

Overview

The state of a game, as received from the server.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGameState



44
45
46
47
48
49
50
# File 'lib/software_challenge_client/game_state.rb', line 44

def initialize
  @current_player_color = PlayerColor::RED
  @start_player_color = PlayerColor::RED
  @board = Board.new
  @has_to_play_card = false
  @turn = 0
end

Instance Attribute Details

#bluePlayer (readonly)



25
26
27
# File 'lib/software_challenge_client/game_state.rb', line 25

def blue
  @blue
end

#boardBoard



28
29
30
# File 'lib/software_challenge_client/game_state.rb', line 28

def board
  @board
end

#conditionCondition



34
35
36
# File 'lib/software_challenge_client/game_state.rb', line 34

def condition
  @condition
end

#current_player_colorPlayerColor



19
20
21
# File 'lib/software_challenge_client/game_state.rb', line 19

def current_player_color
  @current_player_color
end

#has_to_play_cardBoolean Also known as: has_to_play_card?



37
38
39
# File 'lib/software_challenge_client/game_state.rb', line 37

def has_to_play_card
  @has_to_play_card
end

#last_moveMove



31
32
33
# File 'lib/software_challenge_client/game_state.rb', line 31

def last_move
  @last_move
end

#redPlayer (readonly)



22
23
24
# File 'lib/software_challenge_client/game_state.rb', line 22

def red
  @red
end

#start_player_colorPlayerColor



16
17
18
# File 'lib/software_challenge_client/game_state.rb', line 16

def start_player_color
  @start_player_color
end

#turnInteger



13
14
15
# File 'lib/software_challenge_client/game_state.rb', line 13

def turn
  @turn
end

Instance Method Details

#==(other) ⇒ Object

Compared with other state.



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/software_challenge_client/game_state.rb', line 165

def ==(other)
  turn == other.turn &&
      start_player_color == other.start_player_color &&
      current_player_color == other.current_player_color &&
      red == other.red &&
      blue == other.blue &&
      board == other.board &&
      lastMove == other.lastMove &&
      has_to_play_card == other.has_to_play_card &&
      condition == other.condition
end

#add_player(player) ⇒ Object

adds a player to the gamestate



55
56
57
58
59
60
61
# File 'lib/software_challenge_client/game_state.rb', line 55

def add_player(player)
  if player.color == PlayerColor::RED
    @red = player
  elsif player.color == PlayerColor::BLUE
    @blue = player
  end
end

#check_for_playable_cards(actions) ⇒ Array[Move]



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/software_challenge_client/game_state.rb', line 251

def check_for_playable_cards(actions)
  found_card_playing_moves = []
  if current_player.must_play_card
    if GameRules.is_valid_to_play_eat_salad(self)[0]
      found_card_playing_moves << Move.new(actions + [Card.new(CardType::EAT_SALAD)])
    end
    [20, -20, 0].each do |carrots|
      if GameRules.is_valid_to_play_take_or_drop_carrots(self,carrots)[0]
        found_card_playing_moves << Move.new(actions + [Card.new(CardType::TAKE_OR_DROP_CARROTS, carrots)])
      end
    end
    if GameRules.is_valid_to_play_hurry_ahead(self)[0]
      actions_with_card_played = actions + [Card.new(CardType::HURRY_AHEAD)]
      # pruefe, ob auf Hasenfeld gelandet
      clone = self.deep_clone
      Card.new(CardType::HURRY_AHEAD).perform!(clone)
      moves = []
      if GameRules.must_play_card(clone)
        moves = clone.check_for_playable_cards(actions_with_card_played)
      end
      if moves.empty?
        found_card_playing_moves << Move.new(actions_with_card_played)
      else
        found_card_playing_moves += moves
      end
    end
    if GameRules.is_valid_to_play_fall_back(self)[0]
      actions_with_card_played = actions + [Card.new(CardType::FALL_BACK)]
      # pruefe, ob auf Hasenfeld gelandet
      clone = self.deep_clone
      Card.new(CardType::FALL_BACK).perform!(clone)
      moves = []
      if GameRules.must_play_card(clone)
        moves = clone.check_for_playable_cards(actions_with_card_played)
      end
      if moves.empty?
        found_card_playing_moves << Move.new(actions_with_card_played)
      else
        found_card_playing_moves += moves
      end
    end
  end
  found_card_playing_moves
end

#current_fieldObject



188
189
190
# File 'lib/software_challenge_client/game_state.rb', line 188

def current_field
  field(current_player.index)
end

#current_playerPlayer

gets the current player



66
67
68
69
# File 'lib/software_challenge_client/game_state.rb', line 66

def current_player
  return red if current_player_color == PlayerColor::RED
  return blue if current_player_color == PlayerColor::BLUE
end

#deep_cloneObject

Create a deep copy of the gamestate. Can be used to perform moves on without changing the original gamestate.



179
180
181
# File 'lib/software_challenge_client/game_state.rb', line 179

def deep_clone
  Marshal.load(Marshal.dump(self))
end

#field(index) ⇒ Object



40
41
42
# File 'lib/software_challenge_client/game_state.rb', line 40

def field(index)
  board.field(index)
end

#game_ended?Boolean

has the game ended?



106
107
108
# File 'lib/software_challenge_client/game_state.rb', line 106

def game_ended?
  !condition.nil?
end

#is_first(player) ⇒ Object



192
193
194
195
196
197
198
# File 'lib/software_challenge_client/game_state.rb', line 192

def is_first(player)
  if PlayerColor.opponent_color(player.color) == PlayerColor::RED
    player.index > red.index
  else
    player.index > blue.index
  end
end

#is_second(player) ⇒ Object



200
201
202
# File 'lib/software_challenge_client/game_state.rb', line 200

def is_second(player)
  !is_first(player)
end

#next_field_of_type(type, index) ⇒ Field

Searches forward starting at the field with the given index. The field at the given index is not considered. If no field of the given type exists, nil is returned.



158
159
160
161
162
# File 'lib/software_challenge_client/game_state.rb', line 158

def next_field_of_type(type, index)
  return nil if index >= board.fields.size
  return nil if index < 0
  board.fields.slice((index + 1)..(board.fields.size - 1)).find {|f| f.type == type}
end

#occupied_by_other_player?(field) ⇒ Boolean



134
135
136
# File 'lib/software_challenge_client/game_state.rb', line 134

def occupied_by_other_player?(field)
  field.index == other_player.index
end

#other_playerPlayer

gets the other (not the current) player



74
75
76
77
# File 'lib/software_challenge_client/game_state.rb', line 74

def other_player
  return blue if current_player_color == PlayerColor::RED
  return red if current_player_color == PlayerColor::BLUE
end

#other_player_colorPlayerColor

gets the other (not the current) player’s color



82
83
84
# File 'lib/software_challenge_client/game_state.rb', line 82

def other_player_color
  PlayerColor.opponent_color(current_player_color)
end

#perform!(move, player) ⇒ Object

performs a move on the gamestate



97
98
99
100
101
# File 'lib/software_challenge_client/game_state.rb', line 97

def perform!(move, player)
  move.actions.each do |action|
    action.perform!(self, player)
  end
end

#points_for_player(player) ⇒ Integer

calculates a player’s points based on the current gamestate



128
129
130
# File 'lib/software_challenge_client/game_state.rb', line 128

def points_for_player(player)
  player.index
end

#possible_movesObject



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/software_challenge_client/game_state.rb', line 208

def possible_moves
  found_moves = []
  if GameRules.is_valid_to_eat(self)[0]
    # Wenn ein Salat gegessen werden kann, muss auch ein Salat gegessen werden
    found_moves << Move.new([EatSalad.new])
    return found_moves
  end
  if GameRules.is_valid_to_exchange_carrots(self, 10)[0]
    found_moves << Move.new([ExchangeCarrots.new(10)])
  end
  if GameRules.is_valid_to_exchange_carrots(self, -10)[0]
    found_moves << Move.new([ExchangeCarrots.new(-10)])
  end
  if GameRules.is_valid_to_fall_back(self)[0]
    found_moves << Move.new([FallBack.new])
  end
  # Generiere mögliche Vorwärtszüge
  (1..(GameRules.calculate_movable_fields(self.current_player.carrots))).each do |distance|
    actions = []
    clone = self.deep_clone
    # Überprüfe ob Vorwärtszug möglich ist
    if GameRules.is_valid_to_advance(clone, distance)[0]
      try_advance = Advance.new(distance)
      try_advance.perform!(clone)
      actions << try_advance
      # überprüfe, ob eine Karte gespielt werden muss/kann
      if GameRules.must_play_card(clone)
        clone.check_for_playable_cards(actions).each do |card|
          found_moves << card # TODO: this is unexpected, rename or refactor
        end
      else
      # Füge möglichen Vorwärtszug hinzu
        found_moves << Move.new(actions)
      end
    end
  end
  if found_moves.empty?
    found_moves << Move.new([Skip.new])
  end
  found_moves
end

#previous_field_of_type(type, index) ⇒ Field

Searches backwards starting at the field with the given index. The field at the given index is not considered. If no field of the given type exists, nil is returned.



145
146
147
148
149
# File 'lib/software_challenge_client/game_state.rb', line 145

def previous_field_of_type(type, index)
  return nil if index < 1
  return nil if index >= board.fields.size
  board.fields.slice(0..(index - 1)).reverse.find {|f| f.type == type}
end

#roundInteger

gets the current round



89
90
91
# File 'lib/software_challenge_client/game_state.rb', line 89

def round
  turn / 2
end

#set_last_action(action) ⇒ Object



183
184
185
186
# File 'lib/software_challenge_client/game_state.rb', line 183

def set_last_action(action)
  return if action.instance_of? Skip
  current_player.last_non_skip_action = action
end

#switch_current_playerObject



204
205
206
# File 'lib/software_challenge_client/game_state.rb', line 204

def switch_current_player
  current_player_color = other_player_color
end

#winnerPlayer

gets the game’s winner



113
114
115
# File 'lib/software_challenge_client/game_state.rb', line 113

def winner
  condition.nil? ? nil : condition.winner
end

#winning_reasonString

gets the winning reason



120
121
122
# File 'lib/software_challenge_client/game_state.rb', line 120

def winning_reason
  condition.nil? ? nil : condition.reason
end