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.

Parameters:



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>

Returns Die beiden Bewegungsrichtungen, die auf einer Linie mit der Ausrichtung möglich sind.

Parameters:

Returns:

  • (Array<Direction>)

    Die beiden Bewegungsrichtungen, die auf einer Linie mit der Ausrichtung möglich sind.



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>

Returns Die Ausrichtung einer Linie, die auf der Bewegungsrichtung liegt.

Parameters:

  • line_direction (Direction)

    Bewegungsrichtung

Returns:

  • (Array<Direction>)

    Die Ausrichtung einer Linie, die auf der Bewegungsrichtung liegt.



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