Class: Linotype::Move

Inherits:
Object
  • Object
show all
Defined in:
lib/linotype/move.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(game, player, tiles) ⇒ Move

Returns a new instance of Move.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/linotype/move.rb', line 7

def initialize(game, player, tiles)
  @game = game
  self.player = player
  @tiles = tiles
  set_previous_tile_values
  calculate_valid
  if valid?
    calculate_scores(:before)
    @game.moves << self
    cover_tiles!
    calculate_scores(:after)
    calculate_net_scores
    @game.toggle_current_player
  else
    @game.moves << self
  end
end

Instance Attribute Details

#gameObject (readonly)

Returns the value of attribute game.



4
5
6
# File 'lib/linotype/move.rb', line 4

def game
  @game
end

#invalid_reasonObject (readonly)

Returns the value of attribute invalid_reason.



4
5
6
# File 'lib/linotype/move.rb', line 4

def invalid_reason
  @invalid_reason
end

#playerObject

Returns the value of attribute player.



5
6
7
# File 'lib/linotype/move.rb', line 5

def player
  @player
end

#previous_tile_valuesObject

Returns the value of attribute previous_tile_values.



5
6
7
# File 'lib/linotype/move.rb', line 5

def previous_tile_values
  @previous_tile_values
end

#scoreObject (readonly)

Returns the value of attribute score.



4
5
6
# File 'lib/linotype/move.rb', line 4

def score
  @score
end

#tilesObject (readonly)

Returns the value of attribute tiles.



4
5
6
# File 'lib/linotype/move.rb', line 4

def tiles
  @tiles
end

Instance Method Details

#calculate_net_scoresObject



51
52
53
54
55
56
57
# File 'lib/linotype/move.rb', line 51

def calculate_net_scores
  self.score[:defended] = score[:defended_after] - score[:defended_before]
  self.score[:covered] = score[:covered_after] - score[:covered_before]
  self.score[:edges] = score[:edges_after] - score[:edges_before]
  self.score[:corners] = score[:corners_after] - score[:corners_before]
  self.score[:corners_defended] = score[:corners_defended_after] - score[:corners_defended_before]
end

#calculate_scores(time) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/linotype/move.rb', line 42

def calculate_scores(time)
  self.score["defended_#{time}".to_sym] = @game.defended_tiles(player).count
  self.score["covered_#{time}".to_sym] = @game.covered_tiles(player).count
  self.score["edges_#{time}".to_sym] = @game.edge_tiles(player).count
  self.score["corners_#{time}".to_sym] = @game.corner_tiles(player).count
  self.score["corners_defended_#{time}".to_sym] = (@game.defended_tiles(player) & @game.corner_tiles(player)).count
  self.score["remaining_uncovered_#{time}".to_sym] = @game.uncovered_tiles.count
end

#calculate_validObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/linotype/move.rb', line 97

def calculate_valid
  if pass?
    @valid = true
  elsif !uses_game_tiles?
    @invalid_reason = "does not use game tile letters"
  elsif !in_dictionary?
    @invalid_reason = "is not in dictionary"
  elsif !new_word_in_game?
    @invalid_reason = "has been played before"
  elsif !enough_characters?
    @invalid_reason = "is too short"
  elsif prefix_of_previous_word?
    @invalid_reason = "is a prefix of a previously played word"
  else
    @valid = true
  end
end

#cover_tiles!Object



75
76
77
78
# File 'lib/linotype/move.rb', line 75

def cover_tiles!
  @previously_defended_tiles = @tiles.select { |tile| tile.defended? }
  (@tiles - @previously_defended_tiles).each { |tile| tile.covered_by = @player }
end

#enough_characters?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/linotype/move.rb', line 128

def enough_characters?
  word.length >= 2
end

#first_covered_corner?Boolean

Returns:

  • (Boolean)


140
141
142
# File 'lib/linotype/move.rb', line 140

def first_covered_corner?
  score[:corners_defended_before] == 0 && score[:corners_defended_after] > 0
end

#in_dictionary?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/linotype/move.rb', line 115

def in_dictionary?
  game.dictionary.valid?(word)
end

#invalid?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/linotype/move.rb', line 63

def invalid?
  !valid?
end

#new_word_in_game?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/linotype/move.rb', line 124

def new_word_in_game?
  !game.valid_moves.collect(&:word).include?(word)
end

#pass?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/linotype/move.rb', line 71

def pass?
  @tiles.empty?
end

#prefix_of_previous_word?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/linotype/move.rb', line 132

def prefix_of_previous_word?
  game.valid_moves.find { |move| move.word =~ /\A#{word}/ }
end

#set_previous_tile_valuesObject



35
36
37
38
39
40
# File 'lib/linotype/move.rb', line 35

def set_previous_tile_values
  self.previous_tile_values = {}
  tiles.each do |tile|
    self.previous_tile_values[tile] = { covered_by: tile.covered_by }
  end
end

#to_hashObject



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/linotype/move.rb', line 84

def to_hash
  {
    player: game.player_number(@player),
    word: word,
    valid: valid?,
    coordinates: @tiles.collect(&:to_a),
    invalid_reason: @invalid_reason,
    player_sequence: game.valid_moves.select { |move| move.player == @player }.index(self).to_i + 1,
    total_sequence: game.valid_moves.index(self).to_i + 1,
    score: score
  }
end

#uncover_tiles!Object



80
81
82
# File 'lib/linotype/move.rb', line 80

def uncover_tiles!
  (@tiles - @previously_defended_tiles).each { |tile| tile.covered_by = nil }
end

#undo!Object



29
30
31
32
33
# File 'lib/linotype/move.rb', line 29

def undo!
  tiles.each { |tile| tile.covered_by = previous_tile_values[tile][:covered_by] }
  game.moves.delete(self)
  game.toggle_current_player if valid?
end

#uses_game_tiles?Boolean

Returns:

  • (Boolean)


119
120
121
122
# File 'lib/linotype/move.rb', line 119

def uses_game_tiles?
  letters = game.letters
  word.each_char { |letter| return false unless letters.delete(letter) }
end

#valid?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/linotype/move.rb', line 59

def valid?
  !!@valid
end

#winning_move?Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/linotype/move.rb', line 136

def winning_move?
  score[:remaining_uncovered_after] == 0 && score[:covered_after] >= game.all_tiles.count
end

#wordObject



67
68
69
# File 'lib/linotype/move.rb', line 67

def word
  @tiles.collect(&:letter).join
end