word-search-puzzle 0.1.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 +7 -0
- data/.ruby-version +1 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +98 -0
- data/README.md +53 -0
- data/Rakefile +18 -0
- data/docs/development.md +19 -0
- data/docs/images/color-option.png +0 -0
- data/docs/images/puzzle-01.png +0 -0
- data/docs/images/puzzle-03.png +0 -0
- data/docs/options.md +157 -0
- data/examples/01-default.rb +13 -0
- data/examples/02-read_words_file.rb +18 -0
- data/examples/03-render_options.rb +16 -0
- data/examples/04-custom_shape.rb +43 -0
- data/examples/05-read_gaps_file.rb +18 -0
- data/examples/ball-gaps.csv +48 -0
- data/examples/ball-shape.txt +10 -0
- data/examples/starwars.txt +10 -0
- data/lib/word-search-puzzle/cell.rb +44 -0
- data/lib/word-search-puzzle/cli/user_actions.rb +22 -0
- data/lib/word-search-puzzle/cli.rb +55 -0
- data/lib/word-search-puzzle/grid.rb +91 -0
- data/lib/word-search-puzzle/input.rb +96 -0
- data/lib/word-search-puzzle/strategy.rb +63 -0
- data/lib/word-search-puzzle/version.rb +6 -0
- data/lib/word-search-puzzle.rb +26 -0
- data/sig/word-search-puzzle/cell.rbs +4 -0
- data/sig/word-search-puzzle/version.rbs +8 -0
- data/word-search-puzzle +7 -0
- data/word-search-puzzle.gemspec +35 -0
- metadata +101 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9294041e86cf760a8de12fda97d4217675d7ba8bc424ea039d61411a1a62167e
|
|
4
|
+
data.tar.gz: 9eba51b91b9a55347eca122e07c81782877bdf16d4e2e2f966e8840d3ccbaa1a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 16f10a31d33c73f88d26ade1245ab20bf10eee17e58ba30e1858f0aba2fa5972e0a90809103180424b01a11756bd915f2d223845ce897dfa4ec2ec303fb9660f
|
|
7
|
+
data.tar.gz: 20281180b73200edf1b907e2a0a4201615abfa9d66a6f8e32763f7789b0579ec130e4947238f2b32e951493a8a5982f9734711ed272a48363603ff9825b26cc0
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.4.2
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
# Specify your gem's dependencies in word-search-puzzle.gemspec
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
gem "rake", "~> 13.0"
|
|
9
|
+
gem "test-unit", "~> 3.0"
|
|
10
|
+
gem "standard", "~> 1.3"
|
|
11
|
+
|
|
12
|
+
# warning:
|
|
13
|
+
# <These gems> were loaded from the standard library,
|
|
14
|
+
# but will no longer be part of the default gems starting from Ruby 3.5.0.
|
|
15
|
+
# You can add irb to your Gemfile or gemspec to silence this warning.
|
|
16
|
+
gem "rdoc", "~> 6.15"
|
|
17
|
+
gem "irb", "~> 1.15"
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
word-search-puzzle (0.1.0)
|
|
5
|
+
colorize (~> 1.1.0)
|
|
6
|
+
thor (~> 1.4.0)
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
ast (2.4.3)
|
|
12
|
+
colorize (1.1.0)
|
|
13
|
+
date (3.4.1)
|
|
14
|
+
erb (5.1.1)
|
|
15
|
+
io-console (0.8.1)
|
|
16
|
+
irb (1.15.2)
|
|
17
|
+
pp (>= 0.6.0)
|
|
18
|
+
rdoc (>= 4.0.0)
|
|
19
|
+
reline (>= 0.4.2)
|
|
20
|
+
json (2.15.0)
|
|
21
|
+
language_server-protocol (3.17.0.5)
|
|
22
|
+
lint_roller (1.1.0)
|
|
23
|
+
parallel (1.27.0)
|
|
24
|
+
parser (3.3.9.0)
|
|
25
|
+
ast (~> 2.4.1)
|
|
26
|
+
racc
|
|
27
|
+
power_assert (2.0.5)
|
|
28
|
+
pp (0.6.3)
|
|
29
|
+
prettyprint
|
|
30
|
+
prettyprint (0.2.0)
|
|
31
|
+
prism (1.5.2)
|
|
32
|
+
psych (5.2.6)
|
|
33
|
+
date
|
|
34
|
+
stringio
|
|
35
|
+
racc (1.8.1)
|
|
36
|
+
rainbow (3.1.1)
|
|
37
|
+
rake (13.3.0)
|
|
38
|
+
rdoc (6.15.0)
|
|
39
|
+
erb
|
|
40
|
+
psych (>= 4.0.0)
|
|
41
|
+
tsort
|
|
42
|
+
regexp_parser (2.11.3)
|
|
43
|
+
reline (0.6.2)
|
|
44
|
+
io-console (~> 0.5)
|
|
45
|
+
rubocop (1.80.2)
|
|
46
|
+
json (~> 2.3)
|
|
47
|
+
language_server-protocol (~> 3.17.0.2)
|
|
48
|
+
lint_roller (~> 1.1.0)
|
|
49
|
+
parallel (~> 1.10)
|
|
50
|
+
parser (>= 3.3.0.2)
|
|
51
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
52
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
53
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
|
54
|
+
ruby-progressbar (~> 1.7)
|
|
55
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
56
|
+
rubocop-ast (1.47.1)
|
|
57
|
+
parser (>= 3.3.7.2)
|
|
58
|
+
prism (~> 1.4)
|
|
59
|
+
rubocop-performance (1.25.0)
|
|
60
|
+
lint_roller (~> 1.1)
|
|
61
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
62
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
63
|
+
ruby-progressbar (1.13.0)
|
|
64
|
+
standard (1.51.1)
|
|
65
|
+
language_server-protocol (~> 3.17.0.2)
|
|
66
|
+
lint_roller (~> 1.0)
|
|
67
|
+
rubocop (~> 1.80.2)
|
|
68
|
+
standard-custom (~> 1.0.0)
|
|
69
|
+
standard-performance (~> 1.8)
|
|
70
|
+
standard-custom (1.0.2)
|
|
71
|
+
lint_roller (~> 1.0)
|
|
72
|
+
rubocop (~> 1.50)
|
|
73
|
+
standard-performance (1.8.0)
|
|
74
|
+
lint_roller (~> 1.1)
|
|
75
|
+
rubocop-performance (~> 1.25.0)
|
|
76
|
+
stringio (3.1.7)
|
|
77
|
+
test-unit (3.7.0)
|
|
78
|
+
power_assert
|
|
79
|
+
thor (1.4.0)
|
|
80
|
+
tsort (0.2.0)
|
|
81
|
+
unicode-display_width (3.2.0)
|
|
82
|
+
unicode-emoji (~> 4.1)
|
|
83
|
+
unicode-emoji (4.1.0)
|
|
84
|
+
|
|
85
|
+
PLATFORMS
|
|
86
|
+
ruby
|
|
87
|
+
x86_64-linux
|
|
88
|
+
|
|
89
|
+
DEPENDENCIES
|
|
90
|
+
irb (~> 1.15)
|
|
91
|
+
rake (~> 13.0)
|
|
92
|
+
rdoc (~> 6.15)
|
|
93
|
+
standard (~> 1.3)
|
|
94
|
+
test-unit (~> 3.0)
|
|
95
|
+
word-search-puzzle!
|
|
96
|
+
|
|
97
|
+
BUNDLED WITH
|
|
98
|
+
2.7.2
|
data/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Word Search Puzzle
|
|
2
|
+
|
|
3
|
+
Ruby gem to create word search puzzles.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the gem by executing:
|
|
8
|
+
|
|
9
|
+
$ gem install word-search-puzzle
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Execute `word-search-puzzle` from the command line.
|
|
14
|
+
|
|
15
|
+
**Example**: create puzzle with default options.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
$ word-search-puzzle create --words=JEDI,SITH,STARWARS
|
|
19
|
+
```
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
> Each execution builds a different puzzle.
|
|
23
|
+
|
|
24
|
+
**Example**: Create a puzzle showing the final solution.
|
|
25
|
+
```
|
|
26
|
+
$ word-search-puzzle create --words=VADER,OBIWAN,LUKE --padding='.' --size=6x6
|
|
27
|
+
. R . . . .
|
|
28
|
+
. . E . . .
|
|
29
|
+
. . . D . .
|
|
30
|
+
O B I W A N
|
|
31
|
+
. . . . . V
|
|
32
|
+
E K U L . .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Example**: Create puzzle reading words from text file.
|
|
36
|
+
```
|
|
37
|
+
$ word-search-puzzle create --words=examples/starwars.txt
|
|
38
|
+
```
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
> **WARNING:**
|
|
42
|
+
> Depending on the number and size of the words, the size of the grid, and the numbers of gaps, sometimes it will not be possible to find a solution.
|
|
43
|
+
|
|
44
|
+
## Documentation
|
|
45
|
+
|
|
46
|
+
* [Command line options and examples](docs/options.md)
|
|
47
|
+
* [Examples using the Ruby library](examples/)
|
|
48
|
+
* [Development](docs/development.md)
|
|
49
|
+
|
|
50
|
+
## Contributing
|
|
51
|
+
|
|
52
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/dvarrui/word-search-puzzle.
|
|
53
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rake/testtask"
|
|
5
|
+
|
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
|
7
|
+
t.libs << "test"
|
|
8
|
+
t.libs << "lib"
|
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require "standard/rake"
|
|
13
|
+
|
|
14
|
+
task default: %i[test standard]
|
|
15
|
+
|
|
16
|
+
task :help do
|
|
17
|
+
puts "Usage: rake --tasks or rake --help"
|
|
18
|
+
end
|
data/docs/development.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[<< back](../README.md)
|
|
2
|
+
|
|
3
|
+
# Development
|
|
4
|
+
|
|
5
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
6
|
+
|
|
7
|
+
* To install this gem onto your local machine, run `bundle exec rake install`.
|
|
8
|
+
* To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Install the gem by executing:
|
|
13
|
+
|
|
14
|
+
$ gem install word-search-puzzle
|
|
15
|
+
|
|
16
|
+
If bundler is being used to manage dependencies, install the gem and add to the application's Gemfile by executing:
|
|
17
|
+
|
|
18
|
+
$ bundle add word-search-puzzle
|
|
19
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/docs/options.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
[<< back](../README.md)
|
|
2
|
+
|
|
3
|
+
# Command line options
|
|
4
|
+
|
|
5
|
+
## Help
|
|
6
|
+
|
|
7
|
+
* Show help: `word-search-puzzle help`
|
|
8
|
+
* Show **create** action help: `word-search-puzzle help create`
|
|
9
|
+
|
|
10
|
+
# Building options
|
|
11
|
+
|
|
12
|
+
> Used to create different puzzles.
|
|
13
|
+
|
|
14
|
+
* `--words`, Comma separated list of word or file name with de words.
|
|
15
|
+
* `--size`, Grid size. Default value 10x10.
|
|
16
|
+
|
|
17
|
+
## Words options
|
|
18
|
+
|
|
19
|
+
**Example**: Create puzzle using these words: JEDO, SITH, STARWARS.
|
|
20
|
+
```
|
|
21
|
+
$ word-search-puzzle create --words=JEDI,SITH,STARWARS
|
|
22
|
+
D S O I D P O V W K
|
|
23
|
+
N J E D I D H P Q T
|
|
24
|
+
Q S T L M J Z N R M
|
|
25
|
+
L T O Y U B S B L P
|
|
26
|
+
N A K H W Q I K C K
|
|
27
|
+
G R Y D E I T R I N
|
|
28
|
+
N W E F H U H U F H
|
|
29
|
+
R A B S J U G M K U
|
|
30
|
+
U R V M A F H W D H
|
|
31
|
+
Q S O S L I V R O C
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Example**: Create puzzle reading words from TXT file.
|
|
35
|
+
```
|
|
36
|
+
$ word-search-puzzle create --words=examples/starwars.txt
|
|
37
|
+
A W L U K E D W Y G
|
|
38
|
+
O P 3 C R C D G W Z
|
|
39
|
+
S R A W R A T S E S
|
|
40
|
+
T Y O D A D N U Q L
|
|
41
|
+
V R O D A R E P M E
|
|
42
|
+
A R Y O B I W A N C
|
|
43
|
+
D H 2 W D F L I G K
|
|
44
|
+
E Y S D X S N E D N
|
|
45
|
+
R V H U 2 E B V I W
|
|
46
|
+
R J F S I T H G S A
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Size option
|
|
50
|
+
|
|
51
|
+
**Example**: Create default size puzzle (10 rows and 10 cols).
|
|
52
|
+
```
|
|
53
|
+
$ word-search-puzzle create --words=examples/starwars.txt
|
|
54
|
+
X U B R E D A V O B
|
|
55
|
+
R N S A D O Y B E T
|
|
56
|
+
2 A R R F M I Z M Z
|
|
57
|
+
D X A I L W Q J P D
|
|
58
|
+
2 H W F A U D E E N
|
|
59
|
+
C T R N L M K S R X
|
|
60
|
+
H J A B H A S E A U
|
|
61
|
+
G V T W H I I O D N
|
|
62
|
+
E R S T S E T S O X
|
|
63
|
+
Q C 3 P O L H W R M
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Example**: Create 8x20 puzzle (8 rows and 20 cols).
|
|
67
|
+
```
|
|
68
|
+
$ word-search-puzzle create --words=examples/starwars.txt --size=8x20
|
|
69
|
+
C E K U L K W S S I Y I G O B I W A N X
|
|
70
|
+
L E F A T F S L W O C Y R 2 D 2 I Z P P
|
|
71
|
+
E Y V S J R N U D O Y L R H X Q O Q N O
|
|
72
|
+
Y H W T I C H A T V V J F G K R E O M Z
|
|
73
|
+
P N V Y P S P G J J R I J O P 3 C I S O
|
|
74
|
+
K Z K X T R O D A R E P M E T L E I A N
|
|
75
|
+
S R A W R A T S X Z E L O B A W T P Y O
|
|
76
|
+
D S L L G M N C A V A D E R O H C L L G
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
*+Example**: Create 9x9 puzzle (rows and 9 cols).
|
|
80
|
+
```
|
|
81
|
+
$ word-search-puzzle create --words=examples/starwars.txt --size=9
|
|
82
|
+
X R I Y O Y S V B
|
|
83
|
+
T O O Q B L R H Z
|
|
84
|
+
J D C V I U A T T
|
|
85
|
+
A A K A W K W I O
|
|
86
|
+
O R L D A E R S P
|
|
87
|
+
N E E E N 2 A I 3
|
|
88
|
+
M P I R D J T K C
|
|
89
|
+
L M A 2 K Z S V T
|
|
90
|
+
R E R G I P N Z W
|
|
91
|
+
```
|
|
92
|
+
# Rendering options
|
|
93
|
+
|
|
94
|
+
> Used to display the puzzle in different ways.
|
|
95
|
+
|
|
96
|
+
* `--color`, Indicates whether to display the output with color. Default value false.
|
|
97
|
+
* `--padding=LIST`, comma.separated list of characters to fill in the gaps in the puzzle. Default value A-Z.
|
|
98
|
+
* `--gaps=FILEPATH`, Filename with list of gaps coordinates. List of `row,col` integers.
|
|
99
|
+
|
|
100
|
+
## Color option
|
|
101
|
+
|
|
102
|
+
The `color` option, highlights the list of words within the puzzle, so we can easily identify their location.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
$ word-search-puzzle create --words=DEATH,STAR --color
|
|
106
|
+
```
|
|
107
|
+

|
|
108
|
+
|
|
109
|
+
## Padding option
|
|
110
|
+
|
|
111
|
+
In the puzzle creation process, we first place the word list inside the grid and then fill in the blanks with random letters until the grid is completely filled.
|
|
112
|
+
|
|
113
|
+
During this step, the letters A through Z will be used by default as random values.
|
|
114
|
+
|
|
115
|
+
However, in some cases, the words in our puzzle may use other characters set (for example, Japanese characters), so we use `padding` option set custom random character fill list
|
|
116
|
+
|
|
117
|
+
**Example**: Using `padding` option to custom random padding values.
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
$ word-search-puzzle create --words=DEATH,STAR --padding='+,*,x'
|
|
121
|
+
* x * + x x * * x x
|
|
122
|
+
* x x + x * * * * x
|
|
123
|
+
+ x * * + x * * + +
|
|
124
|
+
+ + x x + x + * x +
|
|
125
|
+
* * * + * + + + + x
|
|
126
|
+
+ * x + * + H x * x
|
|
127
|
+
+ * + + x T + + x *
|
|
128
|
+
+ x + x A * + + + +
|
|
129
|
+
x x x E * + R A T S
|
|
130
|
+
x x D * x + * * x x
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Gaps option
|
|
134
|
+
|
|
135
|
+
The grid is a group of cell into square or a rectangle shape. However, this program offers us to customize the grid shape.
|
|
136
|
+
|
|
137
|
+
To do this, first we start with a square grid and gradually remove the cells defined by `gaps` option to customize the shape.
|
|
138
|
+
|
|
139
|
+
**Example**: Using `gaps` to customize grid shape.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
$ word-search-puzzle create --words=DEATH,STAR --gaps=examples/ball-shape.txt
|
|
143
|
+
|
|
144
|
+
N L P T
|
|
145
|
+
O R P S P O
|
|
146
|
+
V E A S T D P Q
|
|
147
|
+
Y O B B A H C X
|
|
148
|
+
O P B M R T W K
|
|
149
|
+
V O I P K A F T
|
|
150
|
+
H H J N E X
|
|
151
|
+
U J D D
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
We can define gaps in two ways:
|
|
156
|
+
1. Using a [TXT file](../examples/ball-shape.txt), where the dot (`.`) character represents a gap and `@` represents an available cell.
|
|
157
|
+
2. Using a [CSV file](../examples/ball-gaps.csv), where each line contains the coordinates (row, column) of a gap.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Create puzzle with default options
|
|
3
|
+
|
|
4
|
+
require_relative "../lib/word-search-puzzle"
|
|
5
|
+
|
|
6
|
+
# 1. Initialize your words list
|
|
7
|
+
words = %w[STARWARS OBIWAN LUKE VADER R2D2 C3PO LEIA YODA EMPERADOR SITH]
|
|
8
|
+
|
|
9
|
+
# 2. Create puzzle (Default size 10x10)
|
|
10
|
+
puzzle = WordSearchPuzzle.create(words: words)
|
|
11
|
+
|
|
12
|
+
# 3. Show puzzle on screen
|
|
13
|
+
puts puzzle.render
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Create your puzzle reading words from external txt file
|
|
3
|
+
|
|
4
|
+
require_relative "../lib/word-search-puzzle"
|
|
5
|
+
|
|
6
|
+
# 1. Create puzzle (default size 10x10) reading words from text file
|
|
7
|
+
FILEPATH = File.join(File.dirname(__FILE__), "starwars.txt")
|
|
8
|
+
puzzle = WordSearchPuzzle.create(words: FILEPATH)
|
|
9
|
+
|
|
10
|
+
# 2. Check if exits solution
|
|
11
|
+
if puzzle.nil?
|
|
12
|
+
puts "I'm sorry! Can't create the puzzle!"
|
|
13
|
+
puts "Revise filepath, please! (#{filename})"
|
|
14
|
+
exit 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# 3. Show puzzle on screen
|
|
18
|
+
puts puzzle.render
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative "../lib/word-search-puzzle"
|
|
3
|
+
|
|
4
|
+
# 1. Define your word list
|
|
5
|
+
words = %w[STARWARS OBIWAN LUKE VADER R2D2 C3PO LEIA YODA EMPERADOR SITH]
|
|
6
|
+
|
|
7
|
+
# 2. Create your puzzle (10x20 size)
|
|
8
|
+
puzzle = WordSearchPuzzle.create(
|
|
9
|
+
words: words,
|
|
10
|
+
size: "10x20"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# 3. Show puzzle on screen:
|
|
14
|
+
# - color: Use colors to highlight the words
|
|
15
|
+
# - padding: define the characters set used to fill the grid
|
|
16
|
+
puts puzzle.render(color: true, padding: ["."])
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative "../lib/word-search-puzzle"
|
|
3
|
+
|
|
4
|
+
# 1. First desing your own grid shape and create the gaps
|
|
5
|
+
#
|
|
6
|
+
# 9x9 Grid example
|
|
7
|
+
#
|
|
8
|
+
# 0 1 2 3 4 5 6 7 8
|
|
9
|
+
# 0 | . @ @ . . . @ @ .
|
|
10
|
+
# 1 | @ @ @ @ . @ @ @ @
|
|
11
|
+
# 2 | @ @ @ @ @ @ @ @ @
|
|
12
|
+
# 3 | @ @ @ @ @ @ @ @ @
|
|
13
|
+
# 4 | . @ @ @ @ @ @ @ .
|
|
14
|
+
# 5 | . . @ @ @ @ @ . .
|
|
15
|
+
# 6 | . . . @ @ @ . . .
|
|
16
|
+
# 7 | . . . . @ . . . .
|
|
17
|
+
# 8 | . . . . . . . . .
|
|
18
|
+
#
|
|
19
|
+
# gaps:
|
|
20
|
+
# - Define gaps within the grid (row, col).
|
|
21
|
+
# - Gaps are positions within the grid that cannot be used for the puzzle.
|
|
22
|
+
gaps = [
|
|
23
|
+
[0, 0], [0, 3], [0, 4], [0, 5], [0, 8],
|
|
24
|
+
[1, 4],
|
|
25
|
+
[4, 0], [4, 8],
|
|
26
|
+
[5, 0], [5, 1], [5, 7], [5, 8],
|
|
27
|
+
[6, 0], [6, 1], [6, 2], [6, 6], [6, 7], [6, 8],
|
|
28
|
+
[7, 0], [7, 1], [7, 2], [7, 3], [7, 5], [7, 6], [7, 7], [7, 8],
|
|
29
|
+
[8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8]
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
# 2. Define words list
|
|
33
|
+
words = %w[DEATH STAR RETURN JEDI]
|
|
34
|
+
|
|
35
|
+
# 3. Create a puzzle with custom words, size and gaps
|
|
36
|
+
puzzle = WordSearchPuzzle.create(
|
|
37
|
+
words: words,
|
|
38
|
+
size: 9,
|
|
39
|
+
gaps: gaps
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# 4. Render puzzle on screen
|
|
43
|
+
puts puzzle.render(color: true, padding: ["@"])
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative "../lib/word-search-puzzle"
|
|
3
|
+
|
|
4
|
+
# 1. Read a CSV file with your gaps definition.
|
|
5
|
+
# Gaps positions within the grid that cannot be used for the puzzle.
|
|
6
|
+
FILEPATH = File.join(File.dirname(__FILE__), "ball-gaps.csv")
|
|
7
|
+
|
|
8
|
+
# 2. Define words list
|
|
9
|
+
words = %w[DEATH STAR RETURN JEDI]
|
|
10
|
+
|
|
11
|
+
# 3. Create puzzle with custom words, default size (10x10), and custom gaps
|
|
12
|
+
puzzle = WordSearchPuzzle.create(
|
|
13
|
+
words: words,
|
|
14
|
+
gaps: FILEPATH
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# 4. Render puzzle on screen
|
|
18
|
+
puts puzzle.render(color: true, padding: ["@"])
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
0,0
|
|
2
|
+
0,1
|
|
3
|
+
0,2
|
|
4
|
+
0,3
|
|
5
|
+
0,4
|
|
6
|
+
0,5
|
|
7
|
+
0,6
|
|
8
|
+
0,7
|
|
9
|
+
0,8
|
|
10
|
+
0,9
|
|
11
|
+
1,0
|
|
12
|
+
1,1
|
|
13
|
+
1,2
|
|
14
|
+
1,7
|
|
15
|
+
1,8
|
|
16
|
+
1,9
|
|
17
|
+
2,0
|
|
18
|
+
2,1
|
|
19
|
+
2,8
|
|
20
|
+
2,9
|
|
21
|
+
3,0
|
|
22
|
+
3,9
|
|
23
|
+
4,0
|
|
24
|
+
4,9
|
|
25
|
+
5,0
|
|
26
|
+
5,9
|
|
27
|
+
6,0
|
|
28
|
+
6,9
|
|
29
|
+
7,0
|
|
30
|
+
7,1
|
|
31
|
+
7,8
|
|
32
|
+
7,9
|
|
33
|
+
8,0
|
|
34
|
+
8,1
|
|
35
|
+
8,2
|
|
36
|
+
8,7
|
|
37
|
+
8,8
|
|
38
|
+
8,9
|
|
39
|
+
9,0
|
|
40
|
+
9,1
|
|
41
|
+
9,2
|
|
42
|
+
9,3
|
|
43
|
+
9,4
|
|
44
|
+
9,5
|
|
45
|
+
9,6
|
|
46
|
+
9,7
|
|
47
|
+
9,8
|
|
48
|
+
9,9
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module WordSearchPuzzle
|
|
2
|
+
class Cell
|
|
3
|
+
attr_reader :data, :count
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@count = 0
|
|
7
|
+
@data = :empty
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def empty?
|
|
11
|
+
@data == :empty
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def gap?
|
|
15
|
+
@data == :gap
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def gap!
|
|
19
|
+
@data = :gap
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def in_use?
|
|
23
|
+
@count > 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def push(data)
|
|
27
|
+
if empty? || @data == data
|
|
28
|
+
@data = data
|
|
29
|
+
@count += 1
|
|
30
|
+
else
|
|
31
|
+
raise "Cell.push: new data(#{data}) is not equal to current data(#{@data})!"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def pop
|
|
36
|
+
raise "Cell.pop: No data!" unless in_use?
|
|
37
|
+
|
|
38
|
+
@count -= 1
|
|
39
|
+
current_data = @data
|
|
40
|
+
@data = :empty if @count.zero?
|
|
41
|
+
current_data
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require_relative "../../word-search-puzzle"
|
|
2
|
+
|
|
3
|
+
module WordSearchPuzzle
|
|
4
|
+
class UserActions
|
|
5
|
+
def create(options)
|
|
6
|
+
puzzle = WordSearchPuzzle.create(
|
|
7
|
+
words: options["words"],
|
|
8
|
+
size: options["size"],
|
|
9
|
+
gaps: options["gaps"]
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
if puzzle.nil?
|
|
13
|
+
warn "Unable to create puzzle!"
|
|
14
|
+
exit 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
color = options["color"] || false
|
|
18
|
+
padding = options["padding"] ? options["padding"].split(",") : ("A".."Z").to_a
|
|
19
|
+
puts puzzle.render(color: color, padding: padding)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
require_relative "version"
|
|
5
|
+
require_relative "../word-search-puzzle"
|
|
6
|
+
require_relative "cli/user_actions"
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# Command Line User Interface
|
|
10
|
+
class CLI < Thor
|
|
11
|
+
map ["h", "-h", "--help"] => "help"
|
|
12
|
+
|
|
13
|
+
map ["v", "-v", "--version"] => "version"
|
|
14
|
+
desc "version", "Show the program version"
|
|
15
|
+
def version
|
|
16
|
+
puts "#{WordSearchPuzzle::NAME} version #{WordSearchPuzzle::VERSION}"
|
|
17
|
+
exit 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
map ["c", "-c", "--create"] => "create"
|
|
21
|
+
option :words, required: true
|
|
22
|
+
option :size
|
|
23
|
+
option :color, type: :boolean
|
|
24
|
+
option :padding
|
|
25
|
+
option :gaps
|
|
26
|
+
desc "create [--size=SIZE][--color]", "Create puzzle"
|
|
27
|
+
long_desc <<-LONGDESC
|
|
28
|
+
|
|
29
|
+
- [--words=LIST], comma-separated list of words or file name with the words
|
|
30
|
+
|
|
31
|
+
- [--size=SIZE], Grid size. Default value 10x10.
|
|
32
|
+
Examples 5:, sets rows=5 and cols=5.
|
|
33
|
+
Example 10x20: sets rows=10 and col=20.
|
|
34
|
+
|
|
35
|
+
- [--color], Indicates whether to display the output with color. Default value false
|
|
36
|
+
|
|
37
|
+
- [--padding=LIST], comma.separated list of characters to fill puzzle. Default value A-Z.
|
|
38
|
+
|
|
39
|
+
- [--gaps=FILEPATH], TEXT file with grid shape, or CSV file with gaps coordinates.
|
|
40
|
+
|
|
41
|
+
LONGDESC
|
|
42
|
+
def create
|
|
43
|
+
WordSearchPuzzle::UserActions.new.create(options)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def respond_to_missing?(_method_name)
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Thor stop and show messages on screen on failure
|
|
52
|
+
def self.exit_on_failure?
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require_relative "cell"
|
|
2
|
+
require "colorize"
|
|
3
|
+
|
|
4
|
+
module WordSearchPuzzle
|
|
5
|
+
class Grid
|
|
6
|
+
def self.directions
|
|
7
|
+
{
|
|
8
|
+
n: {row: -1, col: 0},
|
|
9
|
+
ne: {row: -1, col: 1},
|
|
10
|
+
e: {row: 0, col: 1},
|
|
11
|
+
se: {row: 1, col: 1},
|
|
12
|
+
s: {row: 1, col: 0},
|
|
13
|
+
sw: {row: 1, col: -1},
|
|
14
|
+
w: {row: 0, col: -1},
|
|
15
|
+
nw: {row: -1, col: -1}
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
Coord = Data.define(:row, :col, :data)
|
|
19
|
+
attr_reader :rows, :cols
|
|
20
|
+
|
|
21
|
+
def initialize(rows, cols, gaps = [])
|
|
22
|
+
@rows = rows
|
|
23
|
+
@cols = cols
|
|
24
|
+
@matrix = []
|
|
25
|
+
(0...rows).each do |row|
|
|
26
|
+
data = []
|
|
27
|
+
(0...cols).each { |col| data << Cell.new }
|
|
28
|
+
@matrix[row] = data
|
|
29
|
+
end
|
|
30
|
+
gaps.each { |x, y| @matrix[x][y].gap! }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def cell(row, col)
|
|
34
|
+
@matrix[row][col]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find_sequence(word, first_row, first_col, direction)
|
|
38
|
+
step = Grid.directions[direction]
|
|
39
|
+
row = first_row
|
|
40
|
+
col = first_col
|
|
41
|
+
coords = []
|
|
42
|
+
word.chars.each do |letter|
|
|
43
|
+
return [] if row >= @rows || col >= @cols || row < 0 || col < 0
|
|
44
|
+
|
|
45
|
+
cell = @matrix[row][col]
|
|
46
|
+
if cell.empty? || cell.data == letter
|
|
47
|
+
coords << Coord.new(row: row, col: col, data: letter)
|
|
48
|
+
row += step[:row]
|
|
49
|
+
col += step[:col]
|
|
50
|
+
else
|
|
51
|
+
return []
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
coords
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def set_sequence(coords)
|
|
58
|
+
coords.each { @matrix[it.row][it.col].push(it.data) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def unset_sequence(coords)
|
|
62
|
+
coords.each { @matrix[it.row][it.col].pop }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def render(color: false, padding: :default)
|
|
66
|
+
padding ||= ["."]
|
|
67
|
+
padding = ("A".."Z").to_a if padding == :default
|
|
68
|
+
|
|
69
|
+
lines = @matrix.map do |row|
|
|
70
|
+
row.map { render_cell(it, color, padding) }.join
|
|
71
|
+
end
|
|
72
|
+
lines.join("\n")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def render_cell(cell, color, padding)
|
|
78
|
+
return " " if cell.gap?
|
|
79
|
+
data = cell.data.to_s
|
|
80
|
+
data = padding.sample if cell.count.zero?
|
|
81
|
+
|
|
82
|
+
if color && cell.count.zero?
|
|
83
|
+
data = data.colorize(:gray)
|
|
84
|
+
elsif color
|
|
85
|
+
data = data.colorize(:ligth_white)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
" " + data
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module WordSearchPuzzle
|
|
2
|
+
class Input
|
|
3
|
+
DEFAULT_GRID_SIZE = 10
|
|
4
|
+
|
|
5
|
+
def self.read_words(words)
|
|
6
|
+
if words.is_a? Array
|
|
7
|
+
if words.empty?
|
|
8
|
+
warn "Input: empty parameter! (words)"
|
|
9
|
+
exit 1
|
|
10
|
+
end
|
|
11
|
+
return words
|
|
12
|
+
elsif File.exist?(words)
|
|
13
|
+
lines = File.readlines(words)
|
|
14
|
+
lines.map! { it.strip }
|
|
15
|
+
lines.delete("")
|
|
16
|
+
if lines.empty?
|
|
17
|
+
warn "Input: empty file! (#{words})!"
|
|
18
|
+
exit 1
|
|
19
|
+
end
|
|
20
|
+
return lines
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if words.nil? || words.empty?
|
|
24
|
+
warn "Input: empty parameter! (words)"
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
words.split(",").map { it.strip }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.read_size(size)
|
|
32
|
+
if size.nil?
|
|
33
|
+
rows = cols = DEFAULT_GRID_SIZE
|
|
34
|
+
elsif size.is_a? Integer
|
|
35
|
+
rows = cols = size
|
|
36
|
+
else
|
|
37
|
+
values = size.split("x")
|
|
38
|
+
rows = values[0].to_i
|
|
39
|
+
rows = (rows < 1) ? DEFAULT_GRID_SIZE : rows
|
|
40
|
+
cols = (values.size == 2) ? values[1].to_i : rows
|
|
41
|
+
end
|
|
42
|
+
[rows, cols]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.read_gaps(gaps)
|
|
46
|
+
return gaps if gaps.is_a? Array
|
|
47
|
+
return [] if gaps.nil?
|
|
48
|
+
|
|
49
|
+
if File.exist?(gaps)
|
|
50
|
+
lines = File.readlines(gaps)
|
|
51
|
+
lines.delete("")
|
|
52
|
+
|
|
53
|
+
if gaps.end_with?(".csv")
|
|
54
|
+
data = lines.map do |line|
|
|
55
|
+
items = line.split(",")
|
|
56
|
+
[items[0].to_i, items[1].to_i]
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
data = []
|
|
60
|
+
lines.each_with_index do |line, row|
|
|
61
|
+
line.chars.each_with_index do |char, col|
|
|
62
|
+
data << [row, col] if char == "."
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
return data
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
[]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.validate(words, rows, cols, gaps)
|
|
73
|
+
msg = []
|
|
74
|
+
|
|
75
|
+
words.each do |word|
|
|
76
|
+
msg << "E01: The word <#{word}> does not fit in the grid." if word.length > [rows, cols].max
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
if words.size == 1 && msg.size == 1
|
|
80
|
+
msg << "E02: If <#{words.first}> is a filepath then it was not found."
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
total_words_size = words.sum { it.length }
|
|
84
|
+
if total_words_size > (rows * cols - gaps.length)
|
|
85
|
+
msg << "E03: The grid is not large enough to contain all the words."
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
gaps.each do |y, x|
|
|
89
|
+
if y >= rows || x >= cols
|
|
90
|
+
msg << "E04: Gap [#{y}, #{x}] outside the grid size."
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
msg
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require_relative "grid"
|
|
2
|
+
|
|
3
|
+
module WordSearchPuzzle
|
|
4
|
+
class Strategy
|
|
5
|
+
def initialize(words, grid)
|
|
6
|
+
# Sort words from longest to smallest
|
|
7
|
+
@words = words.sort_by { it.length }.reverse
|
|
8
|
+
@initial_grid = grid
|
|
9
|
+
@final_grid = nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def grid
|
|
13
|
+
@final_grid
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def calculate
|
|
17
|
+
@final_grid = find_solution(@words.clone, @initial_grid.clone)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def find_solution(words, grid)
|
|
23
|
+
# Take the first word
|
|
24
|
+
word = words.delete_at(0)
|
|
25
|
+
available_word_locations = get_available_locations(word, grid)
|
|
26
|
+
return nil if available_word_locations.empty? # No solution
|
|
27
|
+
|
|
28
|
+
available_word_locations.shuffle!
|
|
29
|
+
available_word_locations.each do |sequence|
|
|
30
|
+
grid.set_sequence(sequence) # Push word into grid location
|
|
31
|
+
return grid if words.empty? # Solved puzzle. No more words to push
|
|
32
|
+
|
|
33
|
+
resolved_grid = find_solution(words.clone, grid.clone) # Find solution recursively
|
|
34
|
+
if resolved_grid
|
|
35
|
+
return resolved_grid # <new_grid> contains the solved puzzle
|
|
36
|
+
else
|
|
37
|
+
# The selected <sequence> of the word does not help to solve the puzzle.
|
|
38
|
+
# 1. Restore <grid> content
|
|
39
|
+
# 2. And try other sequence
|
|
40
|
+
grid.unset_sequence(sequence)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
if words.empty?
|
|
44
|
+
grid # All the words has been placed
|
|
45
|
+
else
|
|
46
|
+
nil # All possibilities have been tried and there are still words left unplaced.
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def get_available_locations(word, grid)
|
|
51
|
+
locations = []
|
|
52
|
+
(0...grid.rows).each do |row|
|
|
53
|
+
(0...grid.cols).each do |col|
|
|
54
|
+
Grid.directions.keys.each do |direction|
|
|
55
|
+
location = grid.find_sequence(word, row, col, direction)
|
|
56
|
+
locations << location unless location.empty?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
locations
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require_relative "word-search-puzzle/grid"
|
|
2
|
+
require_relative "word-search-puzzle/input"
|
|
3
|
+
require_relative "word-search-puzzle/strategy"
|
|
4
|
+
|
|
5
|
+
module WordSearchPuzzle
|
|
6
|
+
def self.create(words: [], size: "10x10", gaps: [])
|
|
7
|
+
# Read input values
|
|
8
|
+
words = WordSearchPuzzle::Input.read_words(words)
|
|
9
|
+
rows, cols = WordSearchPuzzle::Input.read_size(size)
|
|
10
|
+
gaps = WordSearchPuzzle::Input.read_gaps(gaps)
|
|
11
|
+
|
|
12
|
+
# Validate input values
|
|
13
|
+
errors = WordSearchPuzzle::Input.validate(words, rows, cols, gaps)
|
|
14
|
+
unless errors.empty?
|
|
15
|
+
puts "Unable to create puzzle:"
|
|
16
|
+
errors.each_with_index { |message, index| puts "#{index + 1}. #{message}" }
|
|
17
|
+
exit 1
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Create the grid ant try to find a puzzle
|
|
21
|
+
grid = Grid.new(rows, cols, gaps)
|
|
22
|
+
strategy = Strategy.new(words, grid)
|
|
23
|
+
strategy.calculate
|
|
24
|
+
strategy.grid
|
|
25
|
+
end
|
|
26
|
+
end
|
data/word-search-puzzle
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/word-search-puzzle/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "word-search-puzzle"
|
|
7
|
+
spec.version = WordSearchPuzzle::VERSION
|
|
8
|
+
spec.authors = ["David Vargas Ruiz"]
|
|
9
|
+
spec.email = ["dvarrui@proton.me"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Create word search puzzles"
|
|
12
|
+
# spec.description = "TODO: Write a longer description or delete this line."
|
|
13
|
+
spec.homepage = "https://github.com/dvarrui/word-search-puzzle"
|
|
14
|
+
spec.required_ruby_version = ">= 3.4.0"
|
|
15
|
+
|
|
16
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
|
17
|
+
|
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/dvarrui/word-search-puzzle/blob/main/CHANGELOG.md"
|
|
21
|
+
|
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
24
|
+
spec.files = Dir.chdir(__dir__) do
|
|
25
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
26
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
spec.bindir = "exe"
|
|
30
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
31
|
+
spec.require_paths = ["lib"]
|
|
32
|
+
|
|
33
|
+
spec.add_dependency "colorize", "~> 1.1.0"
|
|
34
|
+
spec.add_dependency "thor", "~> 1.4.0"
|
|
35
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: word-search-puzzle
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- David Vargas Ruiz
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: colorize
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.1.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 1.1.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: thor
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.4.0
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.4.0
|
|
40
|
+
email:
|
|
41
|
+
- dvarrui@proton.me
|
|
42
|
+
executables: []
|
|
43
|
+
extensions: []
|
|
44
|
+
extra_rdoc_files: []
|
|
45
|
+
files:
|
|
46
|
+
- ".ruby-version"
|
|
47
|
+
- ".standard.yml"
|
|
48
|
+
- CHANGELOG.md
|
|
49
|
+
- Gemfile
|
|
50
|
+
- Gemfile.lock
|
|
51
|
+
- README.md
|
|
52
|
+
- Rakefile
|
|
53
|
+
- docs/development.md
|
|
54
|
+
- docs/images/color-option.png
|
|
55
|
+
- docs/images/puzzle-01.png
|
|
56
|
+
- docs/images/puzzle-03.png
|
|
57
|
+
- docs/options.md
|
|
58
|
+
- examples/01-default.rb
|
|
59
|
+
- examples/02-read_words_file.rb
|
|
60
|
+
- examples/03-render_options.rb
|
|
61
|
+
- examples/04-custom_shape.rb
|
|
62
|
+
- examples/05-read_gaps_file.rb
|
|
63
|
+
- examples/ball-gaps.csv
|
|
64
|
+
- examples/ball-shape.txt
|
|
65
|
+
- examples/starwars.txt
|
|
66
|
+
- lib/word-search-puzzle.rb
|
|
67
|
+
- lib/word-search-puzzle/cell.rb
|
|
68
|
+
- lib/word-search-puzzle/cli.rb
|
|
69
|
+
- lib/word-search-puzzle/cli/user_actions.rb
|
|
70
|
+
- lib/word-search-puzzle/grid.rb
|
|
71
|
+
- lib/word-search-puzzle/input.rb
|
|
72
|
+
- lib/word-search-puzzle/strategy.rb
|
|
73
|
+
- lib/word-search-puzzle/version.rb
|
|
74
|
+
- sig/word-search-puzzle/cell.rbs
|
|
75
|
+
- sig/word-search-puzzle/version.rbs
|
|
76
|
+
- word-search-puzzle
|
|
77
|
+
- word-search-puzzle.gemspec
|
|
78
|
+
homepage: https://github.com/dvarrui/word-search-puzzle
|
|
79
|
+
licenses: []
|
|
80
|
+
metadata:
|
|
81
|
+
homepage_uri: https://github.com/dvarrui/word-search-puzzle
|
|
82
|
+
source_code_uri: https://github.com/dvarrui/word-search-puzzle
|
|
83
|
+
changelog_uri: https://github.com/dvarrui/word-search-puzzle/blob/main/CHANGELOG.md
|
|
84
|
+
rdoc_options: []
|
|
85
|
+
require_paths:
|
|
86
|
+
- lib
|
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - ">="
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: 3.4.0
|
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
requirements: []
|
|
98
|
+
rubygems_version: 3.7.2
|
|
99
|
+
specification_version: 4
|
|
100
|
+
summary: Create word search puzzles
|
|
101
|
+
test_files: []
|