Class: Pitchcar::Track

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pieces, size_restrictions = {}) ⇒ Track

Returns a new instance of Track.



12
13
14
15
16
# File 'lib/track.rb', line 12

def initialize(pieces, size_restrictions = {})
  self.pieces = pieces
  self.max_size = size_restrictions.fetch(:max, x: Float::INFINITY, y: Float::INFINITY)
  self.min_size = size_restrictions.fetch(:min, x: 1, y: 1)
end

Instance Attribute Details

#max_sizeObject

Returns the value of attribute max_size.



10
11
12
# File 'lib/track.rb', line 10

def max_size
  @max_size
end

#min_sizeObject

Returns the value of attribute min_size.



10
11
12
# File 'lib/track.rb', line 10

def min_size
  @min_size
end

#piecesObject

Returns the value of attribute pieces.



10
11
12
# File 'lib/track.rb', line 10

def pieces
  @pieces
end

Class Method Details

.build_from(track_pieces, size_restrictions = {}) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/track.rb', line 18

def self.build_from(track_pieces, size_restrictions = {})
  track = Track.new([Pieces::Piece.first_from_string(track_pieces.chars.first)], size_restrictions)
  track_pieces.chars[1..-1].each do |piece_str|
    track.pieces << Pieces::Piece.type_from_string(piece_str).new(track.pieces.last.next_coordinate.merge(direction: track.pieces.last.next_direction))
  end
  track
end

Instance Method Details

#assign_start_pieceObject



92
93
94
95
96
97
98
99
# File 'lib/track.rb', line 92

def assign_start_piece
  return self if pieces.any? { |piece| piece.instance_of? Pieces::Start }
  start_index = pieces.each_index.select { |i| pieces[i].is_a? Pieces::StraightRightWall }.sample
  # If there are no straight right pieces, pick any straight piece to be the start
  start_index = pieces.each_index.select { |i| pieces[i].is_a? Pieces::Straight }.sample if start_index.nil?
  pieces[start_index] = Pieces::Start.new(pieces[start_index].to_h) unless start_index.nil?
  self
end

#graph_sortedObject

Returns pieces list sorted from in a top-bottom left-right manner



70
71
72
73
74
75
76
77
78
# File 'lib/track.rb', line 70

def graph_sorted
  pieces.sort do |piece, other_piece|
    if piece.y == other_piece.y
      piece.x <=> other_piece.x
    else
      other_piece.y <=> piece.y
    end
  end
end

#overlaps?Boolean

Returns:

  • (Boolean)


50
51
52
53
# File 'lib/track.rb', line 50

def overlaps?
  string = to_s
  @overlaps ||= string.include?('LLL') || string.include?('RRR') ||  pieces.group_by { |piece| [piece.x, piece.y] }.values.any? { |set| set.size > 1 }
end

#sizeObject



43
44
45
46
47
48
# File 'lib/track.rb', line 43

def size
  x_coords = pieces.map(&:x)
  y_coords = pieces.map(&:y)
  # We have to add one, because a piece takes up a discrete distance
  { x: x_coords.max - x_coords.min + 1, y: y_coords.max - y_coords.min + 1 }
end

#titleObject



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/track.rb', line 80

def title
  results = { nouns: [], adjs: [] }
  [{ name: :nouns, types: %w(items superitems) }, {name: :adjs, types: %w(adj superadj) }].each do |part|
    part[:types].each do |type|
      Random.srand(hash.hex)
      results[part[:name]] << Bazaar.get_item(type).capitalize
    end
  end
  Random.srand(hash.hex)
  "#{results[:adjs].sample} #{results[:nouns].sample}"
end

#to_jsonObject



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

def to_json
  assign_start_piece.pieces.map(&:to_h).to_json
end

#to_pngObject



38
39
40
41
# File 'lib/track.rb', line 38

def to_png
  TrackImage.new(assign_start_piece).render
  puts "Track image saved to #{Dir.pwd}/track.png"
end

#to_sObject



30
31
32
# File 'lib/track.rb', line 30

def to_s
  assign_start_piece.pieces.map(&:to_s).join(' ')
end

#valid?(tracks = []) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/track.rb', line 26

def valid?(tracks=[])
  ends_correctly? && !overlaps? && !rotation_exists?(tracks) && within_size_restrictions?
end

#with_wall_combinations(pieces = self.pieces, tracks = []) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/track.rb', line 55

def with_wall_combinations(pieces = self.pieces, tracks = [])
  straight_index = pieces.find_index { |piece| piece.instance_of? Pieces::Straight }
  if straight_index
    pieces_copy = pieces.dup

    [Pieces::StraightLeftWall, Pieces::StraightRightWall].map do |piece_type|
      pieces_copy[straight_index] = piece_type.new(pieces[straight_index].to_h)
      with_wall_combinations(pieces_copy, tracks)
    end.last
  else
    tracks << Track.new(pieces.dup)
  end
end