ruby-stones 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/stones +23 -0
- data/lib/extensions/array.rb +5 -0
- data/lib/stones.rb +10 -0
- data/lib/stones/board.rb +78 -0
- data/lib/stones/board/with_head.rb +27 -0
- data/lib/stones/board/with_stones.rb +24 -0
- data/lib/stones/color.rb +25 -0
- data/lib/stones/direction.rb +25 -0
- data/lib/stones/execution_context.rb +11 -0
- data/lib/stones/gbb.rb +14 -0
- data/lib/stones/gbb/gbb_reader.rb +52 -0
- data/lib/stones/gbb/gbb_writer.rb +37 -0
- data/lib/stones/program.rb +48 -0
- data/lib/stones/version.rb +3 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5e91e5b19b7e1af7d13c7d8188306f6d61ccfa11
|
4
|
+
data.tar.gz: af406f7c45f5acd829b2693d8e9413d8b08cf3aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 846d8f203ad7d55bf298883aabe507462f9c7002dd00d0b7f6ff90e884724ee655f79cfe4f65242bb2e00e7e78149b3360421bbdcf80f7c34f58d0b02efe01e9
|
7
|
+
data.tar.gz: 22edef2eac5e62bc4d6fd7ec3fd8224488b32e5322ed4561e8e6599ef982271e137de161127a925ebb195c88595e9aaadf664441fea72a12a5d66bb4b28edfaf
|
data/bin/stones
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if ARGV.size != 3
|
4
|
+
puts 'Not enough arguments. Must pass program file, input board file and output board file'
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
|
8
|
+
program = File.read ARGV[0]
|
9
|
+
input_gbb = File.read ARGV[1]
|
10
|
+
output_gbb_file = ARGV[2]
|
11
|
+
|
12
|
+
require 'stones'
|
13
|
+
|
14
|
+
Main = Class.new
|
15
|
+
Main.class_eval do
|
16
|
+
include Stones::Program
|
17
|
+
eval program
|
18
|
+
end
|
19
|
+
|
20
|
+
context = Stones::ExecutionContext.new
|
21
|
+
context.board = Stones::Gbb.read input_gbb
|
22
|
+
context.run Main
|
23
|
+
File.write output_gbb_file, Stones::Gbb.write(context.board)
|
data/lib/stones.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Stones
|
2
|
+
end
|
3
|
+
|
4
|
+
require_relative 'stones/direction'
|
5
|
+
require_relative 'stones/color'
|
6
|
+
require_relative 'stones/board'
|
7
|
+
require_relative 'stones/execution_context'
|
8
|
+
require_relative 'stones/program'
|
9
|
+
require_relative 'stones/gbb'
|
10
|
+
require_relative 'stones/version'
|
data/lib/stones/board.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative './board/with_head'
|
2
|
+
require_relative './board/with_stones'
|
3
|
+
|
4
|
+
module Stones
|
5
|
+
class OutOfBoardError < RuntimeError
|
6
|
+
end
|
7
|
+
|
8
|
+
class Board
|
9
|
+
include WithHead
|
10
|
+
include WithStones
|
11
|
+
|
12
|
+
attr_reader :cells, :head_position
|
13
|
+
|
14
|
+
def initialize(cells, position)
|
15
|
+
@cells = cells
|
16
|
+
@head_position = position
|
17
|
+
end
|
18
|
+
|
19
|
+
def size
|
20
|
+
[cells[0].size, cells.size]
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
self.class == other.class &&
|
25
|
+
self.cells == other.cells &&
|
26
|
+
self.head_position == other.head_position
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash
|
30
|
+
self.cells.hash ^ self.head_position.hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.empty(x, y, position=[0, 0])
|
34
|
+
self.new(empty_cells(x, y), position)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.from(cells, position=[0, 0])
|
38
|
+
self.new(cells.map { |row| row.map { |cell| empty_cell.merge(cell) } }, position)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def each_cell
|
44
|
+
(0..(size[0]-1)).each do |x|
|
45
|
+
(0..(size[1]-1)).each do |y|
|
46
|
+
yield cell_at([x, y]), x, y
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def cell_at(position)
|
52
|
+
raise OutOfBoardError unless within_bounds? position
|
53
|
+
cells[-(position[1]+1)][position[0]]
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_cell(position, cell)
|
57
|
+
cell_at(position).merge! cell
|
58
|
+
end
|
59
|
+
|
60
|
+
def within_bounds?(position)
|
61
|
+
(x, y) = size
|
62
|
+
position[0] >= 0 && position[1] >= 0 &&
|
63
|
+
position[0] < x && position[1] < y
|
64
|
+
end
|
65
|
+
|
66
|
+
def head_cell
|
67
|
+
cell_at(head_position)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.empty_cell
|
71
|
+
{red: 0, black: 0, green: 0, blue: 0}
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.empty_cells(x, y)
|
75
|
+
(1..y).map { (1..x).map { empty_cell } }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Stones
|
2
|
+
module WithHead
|
3
|
+
def can_move?(direction)
|
4
|
+
within_bounds? next_position(direction)
|
5
|
+
end
|
6
|
+
|
7
|
+
def move!(direction)
|
8
|
+
move_to! next_position(direction)
|
9
|
+
end
|
10
|
+
|
11
|
+
def move_to_edge!(direction)
|
12
|
+
move!(direction) while can_move?(direction)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def move_to!(position)
|
18
|
+
raise OutOfBoardError unless within_bounds? position
|
19
|
+
@head_position = position
|
20
|
+
end
|
21
|
+
|
22
|
+
def next_position(direction)
|
23
|
+
direction.call(*@head_position)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Stones
|
2
|
+
module WithStones
|
3
|
+
def push!(color, amount=1)
|
4
|
+
head_cell[color] += amount
|
5
|
+
end
|
6
|
+
|
7
|
+
def pop!(color)
|
8
|
+
raise "#{color} Underflow" if head_cell[color] == 0
|
9
|
+
head_cell[color] -= 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def clear!
|
13
|
+
@cells = self.class.empty_cells(*size)
|
14
|
+
end
|
15
|
+
|
16
|
+
def count(color)
|
17
|
+
head_cell[color]
|
18
|
+
end
|
19
|
+
|
20
|
+
def exist?(color)
|
21
|
+
count(color) > 0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/stones/color.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Stones
|
2
|
+
module Color
|
3
|
+
def red
|
4
|
+
:red
|
5
|
+
end
|
6
|
+
|
7
|
+
def blue
|
8
|
+
:blue
|
9
|
+
end
|
10
|
+
|
11
|
+
def green
|
12
|
+
:green
|
13
|
+
end
|
14
|
+
|
15
|
+
def black
|
16
|
+
:black
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.all
|
20
|
+
[red, green, black, blue]
|
21
|
+
end
|
22
|
+
|
23
|
+
module_function :red, :blue, :green, :black
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Stones
|
2
|
+
module Direction
|
3
|
+
def east
|
4
|
+
@east ||= -> (x, y) { [x+1, y] }
|
5
|
+
end
|
6
|
+
|
7
|
+
def west
|
8
|
+
@west ||= -> (x, y) { [x-1, y] }
|
9
|
+
end
|
10
|
+
|
11
|
+
def north
|
12
|
+
@north ||= -> (x, y) { [x, y+1] }
|
13
|
+
end
|
14
|
+
|
15
|
+
def south
|
16
|
+
@south ||= -> (x, y) { [x, y-1] }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.all
|
20
|
+
[east, west, south, north]
|
21
|
+
end
|
22
|
+
|
23
|
+
module_function :north, :south, :east, :west
|
24
|
+
end
|
25
|
+
end
|
data/lib/stones/gbb.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../../extensions/array.rb'
|
2
|
+
|
3
|
+
|
4
|
+
class MatchData
|
5
|
+
def to_position
|
6
|
+
[self[1].to_i, self[2].to_i]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Stones
|
11
|
+
class GbbReader
|
12
|
+
COLORS = {'Azul' => :blue, 'Negro' => :black, 'Rojo' => :red, 'Verde' => :green}
|
13
|
+
|
14
|
+
def from_string(gbb_string)
|
15
|
+
board = nil
|
16
|
+
|
17
|
+
lines = gbb_string.lines.reject { |it| it.start_with? 'GBB', '%%' }
|
18
|
+
|
19
|
+
/size (\d+) (\d+)/.match(lines[0]) { |match| board = Board.empty(match[1].to_i, match[2].to_i) }
|
20
|
+
/head (\d+) (\d+)/.match(lines.last) { |match| board.send :move_to!, match.to_position }
|
21
|
+
|
22
|
+
lines.drop(1).init.each do |cell_line|
|
23
|
+
position = get_position_from cell_line
|
24
|
+
cell = create_cell_from cell_line
|
25
|
+
|
26
|
+
board.send :set_cell, position, cell
|
27
|
+
end
|
28
|
+
|
29
|
+
board
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def get_position_from(cell_line)
|
35
|
+
/cell (\d+) (\d+)/.match(cell_line).to_position
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_cell_from(cell_line)
|
39
|
+
cell = {}
|
40
|
+
|
41
|
+
cell_line.scan(/(Azul|Negro|Rojo|Verde) (\d+)/) do |match|
|
42
|
+
cell[to_color(match[0])] = match[1].to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
cell
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_color(gbb_color_string)
|
49
|
+
COLORS[gbb_color_string]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Stones
|
2
|
+
module GbbWriter
|
3
|
+
def self.write(board)
|
4
|
+
"GBB/1.0\n" +
|
5
|
+
"size #{board.size[0]} #{board.size[1]}\n" +
|
6
|
+
"#{write_cells board}" +
|
7
|
+
"head #{board.head_position[0]} #{board.head_position[1]}"
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def self.write_cells(board)
|
13
|
+
cells_gbb = ''
|
14
|
+
|
15
|
+
board.send :each_cell do |cell, x, y|
|
16
|
+
cell = cell.select { |color, count| count > 0 }
|
17
|
+
next if cell.empty?
|
18
|
+
cells_gbb << "cell #{x} #{y} #{write_colors cell}\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
cells_gbb
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.write_colors(cell)
|
25
|
+
cell.map { |color, count| "#{to_gbb_color color} #{count}" }.join(' ')
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.to_gbb_color(color)
|
29
|
+
case color
|
30
|
+
when :red then 'Rojo'
|
31
|
+
when :green then 'Verde'
|
32
|
+
when :black then 'Negro'
|
33
|
+
when :blue then 'Azul'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Stones
|
2
|
+
module Program
|
3
|
+
attr_accessor :board
|
4
|
+
|
5
|
+
include Stones::Color
|
6
|
+
include Stones::Direction
|
7
|
+
|
8
|
+
def move!(direction)
|
9
|
+
board.move!(direction)
|
10
|
+
end
|
11
|
+
|
12
|
+
def move_to_edge!(direction)
|
13
|
+
board.move_to_edge!
|
14
|
+
end
|
15
|
+
|
16
|
+
def can_move?(direction)
|
17
|
+
board.can_move?(direction)
|
18
|
+
end
|
19
|
+
|
20
|
+
def push!(color)
|
21
|
+
board.push!(color)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pop!(color)
|
25
|
+
board.pop!(color)
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear!
|
29
|
+
board.clear!
|
30
|
+
end
|
31
|
+
|
32
|
+
def count(color)
|
33
|
+
board.count(color)
|
34
|
+
end
|
35
|
+
|
36
|
+
def exist?(color)
|
37
|
+
board.exists?(color)
|
38
|
+
end
|
39
|
+
|
40
|
+
def colors
|
41
|
+
Color.all
|
42
|
+
end
|
43
|
+
|
44
|
+
def directions
|
45
|
+
Direction.all
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-stones
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Federico Aloi
|
8
|
+
- Franco Bulgarelli
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.7'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: codeclimate-test-reporter
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: Write Gobstones program within Ruby
|
71
|
+
email:
|
72
|
+
- federico.aloi@gmail.com
|
73
|
+
- flbulgarelli@yahoo.com.ar
|
74
|
+
executables:
|
75
|
+
- stones
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- bin/stones
|
80
|
+
- lib/extensions/array.rb
|
81
|
+
- lib/stones.rb
|
82
|
+
- lib/stones/board.rb
|
83
|
+
- lib/stones/board/with_head.rb
|
84
|
+
- lib/stones/board/with_stones.rb
|
85
|
+
- lib/stones/color.rb
|
86
|
+
- lib/stones/direction.rb
|
87
|
+
- lib/stones/execution_context.rb
|
88
|
+
- lib/stones/gbb.rb
|
89
|
+
- lib/stones/gbb/gbb_reader.rb
|
90
|
+
- lib/stones/gbb/gbb_writer.rb
|
91
|
+
- lib/stones/program.rb
|
92
|
+
- lib/stones/version.rb
|
93
|
+
homepage: https://github.com/uqbar-project/ruby-stones
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.2.0
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Pure ruby library that implements a Gobstones-like board and dsl
|
117
|
+
test_files: []
|