snakegame 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +30 -0
- data/Rakefile +6 -0
- data/bin/snake +4 -0
- data/board.rb +61 -0
- data/lib/board.rb +56 -0
- data/lib/game.rb +29 -0
- data/lib/point.rb +36 -0
- data/lib/snake.rb +113 -0
- data/test/board_test.rb +11 -0
- data/test/snake_test.rb +17 -0
- data/test/test_helper.rb +7 -0
- metadata +61 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 1374a26425313391ad96b5778f0bdb4e033e8348
         | 
| 4 | 
            +
              data.tar.gz: a9f34aa408f67733705f5e1d4dcc503f0925c3ef
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 34ab19addd0ec055b412f0a1727def6c77d3d38108c85fd4297b8e178008382a43a0f1e9e8f105b7cdb20d3c6dce19e8202fb024dd5d2821e36ab679ec891df3
         | 
| 7 | 
            +
              data.tar.gz: 0dce5b151508924eff1136f6110dd25e60e75f4a673bab0a9a034ccca184aa90ce1e2bc07b0d8978a0f213c7a6098ac46aec2844bc5332fef2700b624b979c65
         | 
    
        data/.ruby-version
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            2.2.0
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            GEM
         | 
| 2 | 
            +
              remote: https://rubygems.org/
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                coderay (1.1.0)
         | 
| 5 | 
            +
                curses (1.0.1)
         | 
| 6 | 
            +
                method_source (0.8.2)
         | 
| 7 | 
            +
                minitest (5.8.1)
         | 
| 8 | 
            +
                pry (0.10.2)
         | 
| 9 | 
            +
                  coderay (~> 1.1.0)
         | 
| 10 | 
            +
                  method_source (~> 0.8.1)
         | 
| 11 | 
            +
                  slop (~> 3.4)
         | 
| 12 | 
            +
                pry-doc (0.8.0)
         | 
| 13 | 
            +
                  pry (~> 0.9)
         | 
| 14 | 
            +
                  yard (~> 0.8)
         | 
| 15 | 
            +
                rake (10.4.2)
         | 
| 16 | 
            +
                slop (3.6.0)
         | 
| 17 | 
            +
                yard (0.8.7.6)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            PLATFORMS
         | 
| 20 | 
            +
              ruby
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            DEPENDENCIES
         | 
| 23 | 
            +
              curses
         | 
| 24 | 
            +
              minitest
         | 
| 25 | 
            +
              pry
         | 
| 26 | 
            +
              pry-doc
         | 
| 27 | 
            +
              rake
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            BUNDLED WITH
         | 
| 30 | 
            +
               1.10.5
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/bin/snake
    ADDED
    
    
    
        data/board.rb
    ADDED
    
    | @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            class Board
         | 
| 2 | 
            +
              class CursesBoard
         | 
| 3 | 
            +
                attr_accessor :win
         | 
| 4 | 
            +
                def initialize
         | 
| 5 | 
            +
                  Curses.stdscr.keypad(true)
         | 
| 6 | 
            +
                  @win = Curses::Window.new(height, width, 0, 0)
         | 
| 7 | 
            +
                  Curses.stdscr.keypad(true)
         | 
| 8 | 
            +
                  @win.box('|', '-')
         | 
| 9 | 
            +
                  Curses.init_screen
         | 
| 10 | 
            +
                  Curses.curs_set(0)
         | 
| 11 | 
            +
                  Curses.crmode
         | 
| 12 | 
            +
                  Curses.noecho
         | 
| 13 | 
            +
                  Curses.stdscr.nodelay = true
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              attr_accessor :width, :height
         | 
| 17 | 
            +
              def initialize(width: 60, height: 30)
         | 
| 18 | 
            +
                @top_right = Point.new(width, 0)
         | 
| 19 | 
            +
                @bottom_left = Point.new(0, height)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                @width = width
         | 
| 22 | 
            +
                @height = height
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def initialize_snake
         | 
| 26 | 
            +
                x, y = @width / 2, @height / 2
         | 
| 27 | 
            +
                # TODO Make this adjust based on survival likelihood
         | 
| 28 | 
            +
                return { starting_position: Point.new(x, y), vector: Point.new(0, 1) }
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def is_legal?(positions)
         | 
| 32 | 
            +
                positions.all? do |position|
         | 
| 33 | 
            +
                  position.x > @bottom_left.x &&
         | 
| 34 | 
            +
                    position.x < @top_right.x - 1 &&
         | 
| 35 | 
            +
                    position.y > @top_right.y &&
         | 
| 36 | 
            +
                    position.y < @bottom_left.y - 1
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def draw(snake:, fruit:)
         | 
| 41 | 
            +
                @curses_board ||= CursesBoard.new(@height, @width)
         | 
| 42 | 
            +
                @curses_board.win.clear
         | 
| 43 | 
            +
                @curses_board.win.box('|', '-')
         | 
| 44 | 
            +
                Curses.init_screen
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                current_pos = snake.head
         | 
| 47 | 
            +
                @curses_board.win.setpos(*current_pos.graphics_to_a)
         | 
| 48 | 
            +
                @curses_board.win << snake.head_direction
         | 
| 49 | 
            +
                snake.body.each do |body_part|
         | 
| 50 | 
            +
                  @curses_board.win.setpos(*body_part.graphics_to_a)
         | 
| 51 | 
            +
                  @curses_board.win << 'o'
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
                @curses_board.win.setpos(*fruit.graphics_to_a)
         | 
| 54 | 
            +
                @curses_board.win << '🍎'
         | 
| 55 | 
            +
                @curses_board.win.refresh
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def random_position
         | 
| 59 | 
            +
                Point.new(Random.rand(width - 2) + 1, Random.rand(height - 2) + 1)
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
    
        data/lib/board.rb
    ADDED
    
    | @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            class Board
         | 
| 2 | 
            +
              attr_accessor :width, :height
         | 
| 3 | 
            +
              def initialize(width: 60, height: 30)
         | 
| 4 | 
            +
                @top_right = Point.new(width, 0)
         | 
| 5 | 
            +
                @bottom_left = Point.new(0, height)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                @width = width
         | 
| 8 | 
            +
                @height = height
         | 
| 9 | 
            +
                @_game_board = Hash.new {|hash, key| hash[key] = {}}
         | 
| 10 | 
            +
                @win = Curses::Window.new(height, width, 0, 0)
         | 
| 11 | 
            +
                Curses.stdscr.keypad(true)
         | 
| 12 | 
            +
                @win.box('|', '-')
         | 
| 13 | 
            +
                Curses.init_screen
         | 
| 14 | 
            +
                Curses.curs_set(0)
         | 
| 15 | 
            +
                Curses.crmode
         | 
| 16 | 
            +
                Curses.noecho
         | 
| 17 | 
            +
                Curses.stdscr.nodelay = true
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def initialize_snake
         | 
| 21 | 
            +
                x, y = @width / 2, @height / 2
         | 
| 22 | 
            +
                # TODO Make this adjust based on survival likelihood
         | 
| 23 | 
            +
                @_game_board[x][y] = "^"
         | 
| 24 | 
            +
                return { starting_position: Point.new(x, y), vector: Point.new(0, 1) }
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def is_legal?(positions)
         | 
| 28 | 
            +
                positions.all? do |position|
         | 
| 29 | 
            +
                  position.x > @bottom_left.x &&
         | 
| 30 | 
            +
                    position.x < @top_right.x - 1 &&
         | 
| 31 | 
            +
                    position.y > @top_right.y &&
         | 
| 32 | 
            +
                    position.y < @bottom_left.y - 1
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def draw(snake:, fruit:)
         | 
| 37 | 
            +
                @win.clear
         | 
| 38 | 
            +
                @win.box('|', '-')
         | 
| 39 | 
            +
                Curses.init_screen
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                current_pos = snake.head
         | 
| 42 | 
            +
                @win.setpos(*current_pos.graphics_to_a)
         | 
| 43 | 
            +
                @win << snake.head_direction
         | 
| 44 | 
            +
                snake.body.each do |body_part|
         | 
| 45 | 
            +
                  @win.setpos(*body_part.graphics_to_a)
         | 
| 46 | 
            +
                  @win << 'o'
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
                @win.setpos(*fruit.graphics_to_a)
         | 
| 49 | 
            +
                @win << '🍎'
         | 
| 50 | 
            +
                @win.refresh
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def random_position
         | 
| 54 | 
            +
                Point.new(Random.rand(width - 2) + 1, Random.rand(height - 2) + 1)
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
    
        data/lib/game.rb
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            require_relative 'snake'
         | 
| 2 | 
            +
            require_relative 'board'
         | 
| 3 | 
            +
            require_relative 'point'
         | 
| 4 | 
            +
            require 'curses'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class IllegalStateError < StandardError; end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            class Game
         | 
| 9 | 
            +
              def initialize
         | 
| 10 | 
            +
                @board = Board.new
         | 
| 11 | 
            +
                @snake = Snake.new(@board.initialize_snake)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              def play
         | 
| 14 | 
            +
                food = @board.random_position
         | 
| 15 | 
            +
                while true
         | 
| 16 | 
            +
                  change = Curses.getch
         | 
| 17 | 
            +
                  @snake.process_direction(change)
         | 
| 18 | 
            +
                  begin
         | 
| 19 | 
            +
                    food = @snake.tick(food)
         | 
| 20 | 
            +
                    raise unless @board.is_legal?(@snake.positions)
         | 
| 21 | 
            +
                  rescue IllegalStateError
         | 
| 22 | 
            +
                    raise "You died!"
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  food ||= @board.random_position
         | 
| 25 | 
            +
                  @board.draw(snake: @snake, fruit: food)
         | 
| 26 | 
            +
                  sleep 0.1
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
    
        data/lib/point.rb
    ADDED
    
    | @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            class Point
         | 
| 2 | 
            +
              attr_reader :x, :y
         | 
| 3 | 
            +
              def initialize(x, y)
         | 
| 4 | 
            +
                @x = x
         | 
| 5 | 
            +
                @y = y
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def +(other)
         | 
| 9 | 
            +
                Point.new(x + other.x, y + other.y)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def to_a
         | 
| 13 | 
            +
                [x, y]
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              # Yay y,x standard!
         | 
| 17 | 
            +
              def graphics_to_a
         | 
| 18 | 
            +
                [y, x]
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def hash
         | 
| 22 | 
            +
                [x.hash, y.hash].hash
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def eql?(other)
         | 
| 26 | 
            +
                x == other.x && y == other.y
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def ==(other)
         | 
| 30 | 
            +
                eql?(other)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def -(other)
         | 
| 34 | 
            +
                Point.new(x - other.x, y - other.y)
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
    
        data/lib/snake.rb
    ADDED
    
    | @@ -0,0 +1,113 @@ | |
| 1 | 
            +
            require 'curses'
         | 
| 2 | 
            +
            require 'forwardable'
         | 
| 3 | 
            +
            require_relative 'point'
         | 
| 4 | 
            +
            class Snake
         | 
| 5 | 
            +
              class PreviousVectorRecord
         | 
| 6 | 
            +
                attr_reader :vector, :remaining
         | 
| 7 | 
            +
                def initialize(vector, remaining)
         | 
| 8 | 
            +
                  @vector = vector
         | 
| 9 | 
            +
                  @remaining = remaining
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def decrement
         | 
| 13 | 
            +
                  @remaining -= 1
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def increment
         | 
| 17 | 
            +
                  @remaining += 1
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def valid?
         | 
| 21 | 
            +
                  @remaining > 0
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              class BodyPart
         | 
| 26 | 
            +
                extend Forwardable
         | 
| 27 | 
            +
                def_delegators(:@position, :x, :y, :graphics_to_a)
         | 
| 28 | 
            +
                attr_accessor :position, :vector
         | 
| 29 | 
            +
                def initialize(position, vector)
         | 
| 30 | 
            +
                  @position = position
         | 
| 31 | 
            +
                  @vector = vector
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              DIRECTION_HASH = {
         | 
| 35 | 
            +
                # We are in graphics land, so 0, 0 is the origin,
         | 
| 36 | 
            +
                # and the y axis goes down _positively_
         | 
| 37 | 
            +
                Curses::KEY_UP => Point.new(0, -1),
         | 
| 38 | 
            +
                Curses::KEY_DOWN => Point.new(0, 1),
         | 
| 39 | 
            +
                Curses::KEY_RIGHT => Point.new(1, 0),
         | 
| 40 | 
            +
                Curses::KEY_LEFT => Point.new(-1, 0)
         | 
| 41 | 
            +
              }
         | 
| 42 | 
            +
              attr_accessor :head, :body
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def initialize(starting_position:, vector:)
         | 
| 45 | 
            +
                @head = starting_position
         | 
| 46 | 
            +
                @vector = vector
         | 
| 47 | 
            +
                @current_direction = DIRECTION_HASH.invert[vector]
         | 
| 48 | 
            +
                @body = []
         | 
| 49 | 
            +
                @previous_vector_changes = {}
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def positions
         | 
| 53 | 
            +
                [@head] + @body
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              def add_body_part
         | 
| 57 | 
            +
                if @body.empty?
         | 
| 58 | 
            +
                  @body << BodyPart.new(@head - @vector, @vector)
         | 
| 59 | 
            +
                else
         | 
| 60 | 
            +
                  @body << BodyPart.new(@body.last.position - @body.last.vector, @body.last.vector)
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
                @previous_vector_changes.values.each(&:increment)
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              def handle_food(food, next_head_position)
         | 
| 66 | 
            +
                if next_head_position.eql? food
         | 
| 67 | 
            +
                  5.times { add_body_part }
         | 
| 68 | 
            +
                  return nil
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
                food
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def update_body
         | 
| 74 | 
            +
                @body.map do |part|
         | 
| 75 | 
            +
                  if new_vector_record = @previous_vector_changes[part.position]
         | 
| 76 | 
            +
                    part.vector = new_vector_record.vector
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                  part.position = part.position + part.vector
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
              def tick(food)
         | 
| 83 | 
            +
                next_head_position = head + @vector
         | 
| 84 | 
            +
                raise IllegalStateError if body.any? {|part| part.position == next_head_position }
         | 
| 85 | 
            +
                food = handle_food(food, next_head_position)
         | 
| 86 | 
            +
                update_body
         | 
| 87 | 
            +
                @head = next_head_position
         | 
| 88 | 
            +
                @previous_vector_changes.values.each(&:decrement)
         | 
| 89 | 
            +
                @previous_vector_changes.select! { |key, val| val.valid? }
         | 
| 90 | 
            +
                food
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              def process_direction(direction)
         | 
| 94 | 
            +
                return if direction.nil?
         | 
| 95 | 
            +
                @current_direction = direction if DIRECTION_HASH.keys.include?(direction)
         | 
| 96 | 
            +
                @vector = DIRECTION_HASH[direction] || @vector
         | 
| 97 | 
            +
                5.times { add_body_part } if direction == 'a'
         | 
| 98 | 
            +
                @previous_vector_changes[head] = PreviousVectorRecord.new(@vector, @body.length + 1)
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              def head_direction
         | 
| 102 | 
            +
                case @current_direction
         | 
| 103 | 
            +
                when Curses::KEY_UP
         | 
| 104 | 
            +
                  '^'
         | 
| 105 | 
            +
                when Curses::KEY_DOWN
         | 
| 106 | 
            +
                  'v'
         | 
| 107 | 
            +
                when Curses::KEY_RIGHT
         | 
| 108 | 
            +
                  '>'
         | 
| 109 | 
            +
                when Curses::KEY_LEFT
         | 
| 110 | 
            +
                  '<'
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
            end
         | 
    
        data/test/board_test.rb
    ADDED
    
    
    
        data/test/snake_test.rb
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Snake do
         | 
| 4 | 
            +
              let(:point_one) { Point.new(5, 5) }
         | 
| 5 | 
            +
              let(:point_two) { Point.new(3, 5) }
         | 
| 6 | 
            +
              let(:snake) { Snake.new(starting_position: Point.new(5, 5), vector: Point.new(1, 1)) }
         | 
| 7 | 
            +
              it 'tests handle_food with food' do
         | 
| 8 | 
            +
                food = snake.handle_food(point_one, point_one)
         | 
| 9 | 
            +
                assert food.nil?
         | 
| 10 | 
            +
                assert snake.body.length > 1
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              it 'tests handle_food without food' do
         | 
| 13 | 
            +
                food = snake.handle_food(point_one, point_two)
         | 
| 14 | 
            +
                assert food == point_one
         | 
| 15 | 
            +
                snake.body.length.must_equal 0
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
    
        data/test/test_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: snakegame
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Michael Steger
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2015-10-12 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies: []
         | 
| 13 | 
            +
            description: Play snake!
         | 
| 14 | 
            +
            email:
         | 
| 15 | 
            +
            - mjsteger1@gmail.com
         | 
| 16 | 
            +
            executables:
         | 
| 17 | 
            +
            - snake
         | 
| 18 | 
            +
            extensions: []
         | 
| 19 | 
            +
            extra_rdoc_files: []
         | 
| 20 | 
            +
            files:
         | 
| 21 | 
            +
            - ".ruby-version"
         | 
| 22 | 
            +
            - Gemfile
         | 
| 23 | 
            +
            - Gemfile.lock
         | 
| 24 | 
            +
            - Rakefile
         | 
| 25 | 
            +
            - bin/snake
         | 
| 26 | 
            +
            - board.rb
         | 
| 27 | 
            +
            - lib/board.rb
         | 
| 28 | 
            +
            - lib/game.rb
         | 
| 29 | 
            +
            - lib/point.rb
         | 
| 30 | 
            +
            - lib/snake.rb
         | 
| 31 | 
            +
            - test/board_test.rb
         | 
| 32 | 
            +
            - test/snake_test.rb
         | 
| 33 | 
            +
            - test/test_helper.rb
         | 
| 34 | 
            +
            homepage: http://stegerwerks.org
         | 
| 35 | 
            +
            licenses: []
         | 
| 36 | 
            +
            metadata: {}
         | 
| 37 | 
            +
            post_install_message: 
         | 
| 38 | 
            +
            rdoc_options: []
         | 
| 39 | 
            +
            require_paths:
         | 
| 40 | 
            +
            - lib
         | 
| 41 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 42 | 
            +
              requirements:
         | 
| 43 | 
            +
              - - ">="
         | 
| 44 | 
            +
                - !ruby/object:Gem::Version
         | 
| 45 | 
            +
                  version: '0'
         | 
| 46 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 47 | 
            +
              requirements:
         | 
| 48 | 
            +
              - - ">="
         | 
| 49 | 
            +
                - !ruby/object:Gem::Version
         | 
| 50 | 
            +
                  version: '0'
         | 
| 51 | 
            +
            requirements: []
         | 
| 52 | 
            +
            rubyforge_project: 
         | 
| 53 | 
            +
            rubygems_version: 2.4.5
         | 
| 54 | 
            +
            signing_key: 
         | 
| 55 | 
            +
            specification_version: 4
         | 
| 56 | 
            +
            summary: snake game with curses
         | 
| 57 | 
            +
            test_files:
         | 
| 58 | 
            +
            - test/board_test.rb
         | 
| 59 | 
            +
            - test/snake_test.rb
         | 
| 60 | 
            +
            - test/test_helper.rb
         | 
| 61 | 
            +
            has_rdoc: 
         |