Class: Line

Inherits:
Object
  • Object
show all
Includes:
Constants, Enumerable
Defined in:
lib/software_challenge_client/line.rb

Overview

Ein Iterator, der alle Koordinatenpaare auf einer Linie des Spielbrettes enthält.

Constant Summary

Constants included from Constants

Constants::GAME_IDENTIFIER, Constants::ROUND_LIMIT, Constants::SIZE

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start, direction) ⇒ Line

Erzeugt einen neuen Iterator.


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/software_challenge_client/line.rb', line 18

def initialize(start, direction)
  @direction = direction
  @start = start
  # we will iterate from left to right, so find the leftmost field on the line
  # inside the field note that (0,0) is the lowest, leftmost point, x-axis
  # goes to the right, y-axis goes up
  case @direction
  when LineDirection::HORIZONTAL
    leftmost_x = 0
    leftmost_y = @start.y
  when LineDirection::VERTICAL
    leftmost_x = @start.x
    leftmost_y = SIZE - 1
  when LineDirection::RISING_DIAGONAL
    # for rising diagonals, we have to decrease x and y
    shift = [@start.x, @start.y].min
    leftmost_x = @start.x - shift
    leftmost_y = @start.y - shift
  when LineDirection::FALLING_DIAGONAL
    # for falling diagonals, we have to decrease x and increase y
    shift = [@start.x, (SIZE - 1) - @start.y].min
    leftmost_x = @start.x - shift
    leftmost_y = @start.y + shift
  end
  @xi = leftmost_x
  @yi = leftmost_y

  @members = []
  while @xi >= 0 && @yi >= 0 && @xi < SIZE && @yi < SIZE
    @members << Coordinates.new(@xi, @yi)
    # horizontal lines and diagonals move right
    if [LineDirection::HORIZONTAL,
        LineDirection::RISING_DIAGONAL,
        LineDirection::FALLING_DIAGONAL].include? @direction
      @xi += 1
    end
    # vertical lines and falling diagonals move down
    if [LineDirection::VERTICAL,
        LineDirection::FALLING_DIAGONAL].include? @direction
      @yi -= 1
    elsif @direction == LineDirection::RISING_DIAGONAL
      # rising diagonals move up
      @yi += 1
    end
  end
end

Class Method Details

.between(start, bound, direction) ⇒ Object

Begrenzt den Iterator auf Koordinatenpaare von Feldern innerhalb der gegebenen beiden Koordinatenpaare (exklusive). Kann als Filter verwendet werden.

Examples:

Line.new(
  Coordinates.new(2, 3), LineDirection::HORIZONTAL
).select do |c|
  Line.between(Coordinates.new(2, 3), Coordinates.new(5, 3), LineDirection::HORIZONTAL).call(c)
end

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/software_challenge_client/line.rb', line 78

def self.between(start, bound, direction)
  lower_x = [start.x, bound.x].min
  lower_y = [start.y, bound.y].min
  higher_x = [start.x, bound.x].max
  higher_y = [start.y, bound.y].max
  proc do |f|
    case direction
    when LineDirection::HORIZONTAL
      f.x > lower_x && f.x < higher_x
    when LineDirection::VERTICAL
      f.y > lower_y && f.y < higher_y
    when LineDirection::RISING_DIAGONAL, LineDirection::FALLING_DIAGONAL
      f.x > lower_x && f.x < higher_x && f.y > lower_y && f.y < higher_y
    else
      throw `unknown direction ${direction}`
    end
  end
end

.directions_for_line_direction(line_direction) ⇒ Array<Direction>


99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/software_challenge_client/line.rb', line 99

def self.directions_for_line_direction(line_direction)
  case line_direction
  when LineDirection::HORIZONTAL
    [Direction::LEFT, Direction::RIGHT]
  when LineDirection::VERTICAL
    [Direction::UP, Direction::DOWN]
  when LineDirection::RISING_DIAGONAL
    [Direction::UP_RIGHT, Direction::DOWN_LEFT]
  when LineDirection::FALLING_DIAGONAL
    [Direction::UP_LEFT, Direction::DOWN_RIGHT]
  end
end

.line_direction_for_direction(direction) ⇒ Array<Direction>


114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/software_challenge_client/line.rb', line 114

def self.line_direction_for_direction(direction)
  case direction
  when Direction::LEFT, Direction::RIGHT
    LineDirection::HORIZONTAL
  when Direction::UP, Direction::DOWN
    LineDirection::VERTICAL
  when Direction::UP_RIGHT, Direction::DOWN_LEFT
    LineDirection::RISING_DIAGONAL
  when Direction::UP_LEFT, Direction::DOWN_RIGHT
    LineDirection::FALLING_DIAGONAL
  end
end

Instance Method Details

#each(&block) ⇒ Object


65
66
67
# File 'lib/software_challenge_client/line.rb', line 65

def each(&block)
  @members.each(&block)
end