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

Returns a new instance of GameState.



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)

Returns the blue player.

Returns:

  • (Player)

    the blue player



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

def blue
  @blue
end

#boardBoard

Returns the game’s board.

Returns:

  • (Board)

    the game’s board



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

def board
  @board
end

#conditionCondition

Returns the winner and winning reason.

Returns:

  • (Condition)

    the winner and winning reason



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

def condition
  @condition
end

#current_player_colorPlayerColor

Returns the current player’s color.

Returns:



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?

Returns true if the current player has to play a card.

Returns:

  • (Boolean)

    true if the current player has to play a 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

Returns the last move performed.

Returns:

  • (Move)

    the last move performed



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

def last_move
  @last_move
end

#redPlayer (readonly)

Returns the red player.

Returns:



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

def red
  @red
end

#start_player_colorPlayerColor

Returns the start-player’s color.

Returns:



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

def start_player_color
  @start_player_color
end

#turnInteger

Returns turn number.

Returns:

  • (Integer)

    turn number



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

Parameters:

  • player (Player)

    the player, that will be added



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]

Returns gibt liste von Zuegen zurueck, die gemacht werden koennen, vorausgesetzt die gegebene Liste von Aktionen wurde schon gemacht.

Returns:

  • (Array[Move])

    gibt liste von Zuegen zurueck, die gemacht werden koennen, vorausgesetzt die gegebene Liste von Aktionen wurde schon gemacht.



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

Returns:

  • (Player)

    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?

Returns:

  • (Boolean)

    true, if the game has allready 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.

Parameters:

  • type (FieldType)

    of the field to search for

  • index (Integer)

    after which field-index to start searching

Returns:

  • (Field)

    the next field after the given index of given type



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

Returns true if the given field is occupied by the other (not current) player.

Returns:

  • (Boolean)

    true if the given field is occupied by the other (not current) player.



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

Returns:

  • (Player)

    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

Returns:

  • (PlayerColor)

    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

Parameters:

  • move (Move)

    the move, that will be performed

  • player (Player)

    the player, who makes the move



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

Parameters:

  • player (Player)

    the player, whos points to calculate

Returns:

  • (Integer)

    the points of the player



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.

Parameters:

  • type (FieldType)

    of the field to search for

  • index (Integer)

    before which field-index to start searching

Returns:

  • (Field)

    the next field before the given index of given type



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

Returns:

  • (Integer)

    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

Returns:

  • (Player)

    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

Returns:

  • (String)

    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