tablescript 0.0.4 → 1.0.0
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 +4 -4
- data/.gitignore +3 -1
- data/.rubocop.yml +9 -0
- data/Gemfile +20 -0
- data/README.md +55 -44
- data/Rakefile +27 -3
- data/examples/namespaces.rb +33 -0
- data/examples/wandering_monsters.rb +15 -0
- data/lib/tablescript.rb +22 -66
- data/lib/tablescript/api.rb +50 -0
- data/lib/tablescript/exception.rb +24 -0
- data/lib/tablescript/library.rb +44 -0
- data/lib/tablescript/library_dumper.rb +42 -0
- data/lib/tablescript/lookup_strategy.rb +41 -0
- data/lib/tablescript/namespace.rb +85 -0
- data/lib/tablescript/namespace_generator.rb +20 -0
- data/lib/tablescript/roll_and_ignore_duplicates_strategy.rb +69 -0
- data/lib/tablescript/roll_and_ignore_strategy.rb +49 -0
- data/lib/tablescript/roll_context.rb +51 -0
- data/lib/tablescript/roll_strategy.rb +48 -0
- data/lib/tablescript/table.rb +54 -32
- data/lib/tablescript/table_entries.rb +66 -0
- data/lib/tablescript/table_entry.rb +18 -14
- data/lib/tablescript/version.rb +8 -8
- data/spec/spec_helper.rb +4 -0
- data/spec/tablescript/api_spec.rb +66 -0
- data/spec/tablescript/library_spec.rb +13 -0
- data/spec/tablescript/lookup_strategy_spec.rb +35 -0
- data/spec/tablescript/namespace_spec.rb +25 -0
- data/spec/tablescript/roll_and_ignore_strategy_spec.rb +57 -0
- data/spec/tablescript/roll_strategy_spec.rb +56 -0
- data/spec/tablescript/table_entry_spec.rb +42 -0
- data/spec/tablescript/table_spec.rb +88 -0
- data/spec/tablescript_spec.rb +7 -0
- data/tablescript.gemspec +26 -20
- metadata +112 -5
- data/lib/tablescript/dice_roller.rb +0 -94
- data/lib/tablescript/roll_descriptor.rb +0 -55
- data/lib/tablescript/table_entry_environment.rb +0 -124
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# Exception
|
21
|
+
#
|
22
|
+
class Exception < StandardError
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# Library
|
21
|
+
#
|
22
|
+
class Library
|
23
|
+
attr_reader :root
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@root = Namespace.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def table(path)
|
30
|
+
parts = path.split('/')
|
31
|
+
return @root.resolve(path) if parts.size == 1
|
32
|
+
return @root.resolve(parts[1..-1].join('/')) if parts[0].empty?
|
33
|
+
@root.resolve(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.instance
|
37
|
+
@instance ||= Library.new
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
attr_writer :instance
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Tablescript
|
2
|
+
##
|
3
|
+
# LibraryDumper
|
4
|
+
#
|
5
|
+
class LibraryDumper
|
6
|
+
def initialize(stream = STDOUT)
|
7
|
+
@stream = stream
|
8
|
+
end
|
9
|
+
|
10
|
+
def dump(library = nil)
|
11
|
+
dump_namespace(library.nil? ? Library.instance.root : library)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def dump_namespace(namespace, level = 0)
|
17
|
+
@stream.puts indent(level) + "Namespace #{namespace.name}"
|
18
|
+
dump_tables(namespace.tables, level + 1)
|
19
|
+
dump_namespaces(namespace.namespaces, level + 1)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dump_tables(tables, level)
|
23
|
+
return if tables.empty?
|
24
|
+
@stream.puts indent(level) + 'Tables:'
|
25
|
+
tables.each_value do |table|
|
26
|
+
@stream.puts indent(level + 1) + table.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump_namespaces(namespaces, level)
|
31
|
+
return if namespaces.empty?
|
32
|
+
@stream.puts indent(level) + 'Namespaces:'
|
33
|
+
namespaces.each_value do |namespace|
|
34
|
+
dump_namespace(namespace, level + 1)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def indent(level)
|
39
|
+
" " * level
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# LookupStrategy
|
21
|
+
#
|
22
|
+
class LookupStrategy
|
23
|
+
def initialize(table, roll)
|
24
|
+
@table = table
|
25
|
+
@roll = roll
|
26
|
+
@value = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def value
|
30
|
+
evaluate
|
31
|
+
@value
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def evaluate
|
37
|
+
return unless @value.nil?
|
38
|
+
@value = @table.lookup(@roll)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# Namespace
|
21
|
+
#
|
22
|
+
class Namespace
|
23
|
+
attr_reader :parent, :namespaces, :tables
|
24
|
+
|
25
|
+
def initialize(name = '', parent = nil)
|
26
|
+
@name = name
|
27
|
+
@parent = parent
|
28
|
+
@namespaces = {}
|
29
|
+
@tables = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
def add(table)
|
33
|
+
raise Exception, "Table #{table.name} already defined" if @tables.key?(table.name)
|
34
|
+
@tables[table.name] = table
|
35
|
+
end
|
36
|
+
|
37
|
+
def resolve?(path)
|
38
|
+
begin
|
39
|
+
resolve(path)
|
40
|
+
rescue Tablescript::Exception
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def resolve(path)
|
47
|
+
parts = path.split('/')
|
48
|
+
return table(path) if parts.size == 1
|
49
|
+
if parts[0] == @name
|
50
|
+
return table(parts[1]) if parts.size == 2
|
51
|
+
raise Exception, "Namespace #{parts[1]} not found in #{name} namespace (#{path})" unless @namespaces.key?(parts[1])
|
52
|
+
return @namespaces[parts[1]].resolve(parts[1..-1].join('/'))
|
53
|
+
else
|
54
|
+
raise Exception, "Namespace #{parts[0]} not found in #{name} namespace (#{path})" unless @namespaces.key?(parts[0])
|
55
|
+
return @namespaces[parts[0]].resolve(parts[1..-1].join('/'))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def table(table_name)
|
60
|
+
raise Exception, "No such table #{table_name} in #{name}" unless @tables.key?(table_name)
|
61
|
+
@tables[table_name]
|
62
|
+
end
|
63
|
+
|
64
|
+
def table?(table_name)
|
65
|
+
@tables.key?(table_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def namespace(name)
|
69
|
+
@namespaces[name] ||= Namespace.new(name, self)
|
70
|
+
end
|
71
|
+
|
72
|
+
def name
|
73
|
+
return 'global' if @parent.nil?
|
74
|
+
@name
|
75
|
+
end
|
76
|
+
|
77
|
+
def each_namespace(&blk)
|
78
|
+
@namespaces.each_value(&blk)
|
79
|
+
end
|
80
|
+
|
81
|
+
def each_table(&blk)
|
82
|
+
@tables.each_value(&blk)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Tablescript
|
2
|
+
##
|
3
|
+
# NamespaceGenerator
|
4
|
+
#
|
5
|
+
class NamespaceGenerator
|
6
|
+
def initialize(scope)
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def namespace(name, &blk)
|
11
|
+
generator = NamespaceGenerator.new(@scope.namespace(name.to_s))
|
12
|
+
generator.instance_eval(&blk)
|
13
|
+
end
|
14
|
+
|
15
|
+
def table(name, &blk)
|
16
|
+
table = Table.new(name.to_s, @scope, &blk)
|
17
|
+
@scope.add(table)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# RollAndIgnoreDuplicatesStrategy
|
21
|
+
#
|
22
|
+
class RollAndIgnoreDuplicatesStrategy
|
23
|
+
def initialize(table, roll_count, ignore = nil)
|
24
|
+
@table = table
|
25
|
+
@roll_count = roll_count
|
26
|
+
@roll_history = ignore || RpgLib::RollSet.new
|
27
|
+
@entry_ids = Set.new
|
28
|
+
@rolls = []
|
29
|
+
@values = []
|
30
|
+
end
|
31
|
+
|
32
|
+
def rolls
|
33
|
+
evaluate
|
34
|
+
@rolls
|
35
|
+
end
|
36
|
+
|
37
|
+
def values
|
38
|
+
evaluate
|
39
|
+
@values
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def evaluate
|
45
|
+
loop do
|
46
|
+
roll_next_value
|
47
|
+
break if @values.size == @roll_count
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def roll_next_value
|
52
|
+
roll = next_roll(@table.dice_to_roll)
|
53
|
+
entry = @table.entries.lookup(roll)
|
54
|
+
return if @entry_ids.include?(entry.id)
|
55
|
+
record(roll, entry)
|
56
|
+
end
|
57
|
+
|
58
|
+
def record(roll, entry)
|
59
|
+
@entry_ids.add(entry.id)
|
60
|
+
@roll_history.add(entry.roll)
|
61
|
+
@rolls << roll
|
62
|
+
@values << entry.evaluate(roll, @table)
|
63
|
+
end
|
64
|
+
|
65
|
+
def next_roll(dice)
|
66
|
+
RpgLib::DiceRoller.instance.roll_and_ignore(dice, @roll_history)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# RollAndIgnoreStrategy
|
21
|
+
#
|
22
|
+
class RollAndIgnoreStrategy
|
23
|
+
def initialize(table, rollset, roller = nil)
|
24
|
+
@table = table
|
25
|
+
@rollset = rollset
|
26
|
+
@roller = roller || RpgLib::DiceRoller.instance
|
27
|
+
@roll = nil
|
28
|
+
@value = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def roll
|
32
|
+
evaluate
|
33
|
+
@roll
|
34
|
+
end
|
35
|
+
|
36
|
+
def value
|
37
|
+
evaluate
|
38
|
+
@value
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def evaluate
|
44
|
+
return unless @roll.nil?
|
45
|
+
@roll = @roller.roll_and_ignore(@table.dice_to_roll, @rollset)
|
46
|
+
@value = @table.lookup(@roll)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
#
|
21
|
+
#
|
22
|
+
class RollContext
|
23
|
+
attr_reader :roll
|
24
|
+
|
25
|
+
def initialize(roll, table, entry)
|
26
|
+
@roll = roll
|
27
|
+
@table = table
|
28
|
+
@entry = entry
|
29
|
+
end
|
30
|
+
|
31
|
+
def table_name
|
32
|
+
@table.name
|
33
|
+
end
|
34
|
+
|
35
|
+
def dice_rolled
|
36
|
+
@table.dice_to_roll
|
37
|
+
end
|
38
|
+
|
39
|
+
def reroll
|
40
|
+
RollStrategy.new(@table).value
|
41
|
+
end
|
42
|
+
|
43
|
+
def reroll_and_ignore(*args)
|
44
|
+
RollAndIgnoreStrategy.new(@table, RpgLib::RollSet.new(*args)).value
|
45
|
+
end
|
46
|
+
|
47
|
+
def reroll_and_ignore_duplicates(times)
|
48
|
+
RollAndIgnoreDuplicatesStrategy.new(@table, times, RpgLib::RollSet.new(@entry.roll)).values
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright 2017 Jamie Hale
|
2
|
+
#
|
3
|
+
# This file is part of the Tablescript gem.
|
4
|
+
#
|
5
|
+
# Tablescript is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# Tablescript is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with Tablescript. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
module Tablescript
|
19
|
+
##
|
20
|
+
# RollStrategy
|
21
|
+
#
|
22
|
+
class RollStrategy
|
23
|
+
def initialize(table, roller = nil)
|
24
|
+
@table = table
|
25
|
+
@roller = roller || RpgLib::DiceRoller.instance
|
26
|
+
@roll = nil
|
27
|
+
@value = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def roll
|
31
|
+
evaluate
|
32
|
+
@roll
|
33
|
+
end
|
34
|
+
|
35
|
+
def value
|
36
|
+
evaluate
|
37
|
+
@value
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def evaluate
|
43
|
+
return unless @roll.nil?
|
44
|
+
@roll = @roller.roll_die(@table.entries.size)
|
45
|
+
@value = @table.lookup(@roll)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|