degica 0.1.0 → 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/Gemfile +2 -0
- data/README.md +13 -31
- data/bin/degica +5 -0
- data/data/doors.yml +7 -0
- data/data/images/degica_quest.txt +8 -0
- data/data/images/ruby.ansi +10 -0
- data/data/rooms.yml +35 -0
- data/degica.gemspec +7 -2
- data/lib/degica.rb +48 -1
- data/lib/degica/action.rb +25 -0
- data/lib/degica/actionable.rb +28 -0
- data/lib/degica/actor.rb +38 -0
- data/lib/degica/ansi.rb +20 -0
- data/lib/degica/collectable.rb +7 -0
- data/lib/degica/collection.rb +26 -0
- data/lib/degica/collections/door_collection.rb +16 -0
- data/lib/degica/collections/inventory_collection.rb +15 -0
- data/lib/degica/collections/object_collection.rb +18 -0
- data/lib/degica/context.rb +22 -0
- data/lib/degica/core_ext/did_you_mean.rb +8 -0
- data/lib/degica/core_ext/string.rb +5 -0
- data/lib/degica/door.rb +41 -0
- data/lib/degica/game.rb +59 -0
- data/lib/degica/generators/door_name_generator.rb +53 -0
- data/lib/degica/nil_actionable.rb +5 -0
- data/lib/degica/object.rb +26 -0
- data/lib/degica/objects/hacker.rb +15 -0
- data/lib/degica/objects/job_posting.rb +22 -0
- data/lib/degica/objects/people/chuck_norris.rb +18 -0
- data/lib/degica/objects/people/hacker.rb +18 -0
- data/lib/degica/objects/people/jack.rb +22 -0
- data/lib/degica/objects/people/matz.rb +27 -0
- data/lib/degica/objects/people/person.rb +65 -0
- data/lib/degica/objects/ruby.rb +24 -0
- data/lib/degica/objects/table.rb +18 -0
- data/lib/degica/room.rb +41 -0
- data/lib/degica/room_loader.rb +14 -0
- data/lib/degica/version.rb +1 -1
- metadata +67 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc9699abbf2b92ccbbe9175947fe8216740ccad0
|
4
|
+
data.tar.gz: aaa1e32f103f2d8411131f25fccba770a8bc805a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3dd1d07a076d54141ed729d237bc527d3c9690dfd76804fc7cc698105288532ff6b09014af5b6d1044842e7c6bd065289c29bed508cfb2183e03fd46291950e
|
7
|
+
data.tar.gz: 0473d0b53e4160521481e5783b4dd08f54a2d463b55eca1c6d5113f699e56d7787bf01d7f74e3b709c4fdea0fbe58be8870aff66450d4003a7163b14e3a56723
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,43 +1,25 @@
|
|
1
|
-
# Degica
|
1
|
+
# ⚔️ Degica Quest ⚔️
|
2
2
|
|
3
|
-
Welcome
|
3
|
+
Welcome brave Ruby warrior. An epic adventure awaits you.
|
4
4
|
|
5
|
-
|
5
|
+
## 🛠 How to Play
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
7
|
+
Install the rubygem
|
10
8
|
|
11
9
|
```ruby
|
12
|
-
gem
|
10
|
+
gem install degica
|
13
11
|
```
|
14
12
|
|
15
13
|
And then execute:
|
16
14
|
|
17
|
-
$
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
$ gem install degica
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
TODO: Write usage instructions here
|
26
|
-
|
27
|
-
## Development
|
28
|
-
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. 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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
|
-
## Contributing
|
34
|
-
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/shioyama/degica. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
|
-
|
37
|
-
## License
|
15
|
+
$ degica
|
16
|
+
|
17
|
+
## 💪 Contributing
|
38
18
|
|
39
|
-
|
19
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/degica/degica.
|
20
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors
|
21
|
+
are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org/) code of conduct.
|
40
22
|
|
41
|
-
##
|
23
|
+
## ©️ License
|
42
24
|
|
43
|
-
|
25
|
+
[MIT](http://opensource.org/licenses/MIT)
|
data/bin/degica
ADDED
data/data/doors.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
________ _______ ________ ___ ________ ________ ________ ___ ___ _______ ________ _________
|
2
|
+
|\ ___ \ |\ ___ \ |\ ____\ |\ \ |\ ____\ |\ __ \ |\ __ \ |\ \|\ \ |\ ___ \ |\ ____\ |\___ ___\
|
3
|
+
\ \ \_|\ \\ \ __/| \ \ \___| \ \ \\ \ \___| \ \ \|\ \ \ \ \|\ \\ \ \\\ \\ \ __/| \ \ \___|_\|___ \ \_|
|
4
|
+
\ \ \ \\ \\ \ \_|/__\ \ \ ___\ \ \\ \ \ \ \ __ \ \ \ \\\ \\ \ \\\ \\ \ \_|/__\ \_____ \ \ \ \
|
5
|
+
\ \ \_\\ \\ \ \_|\ \\ \ \|\ \\ \ \\ \ \____ \ \ \ \ \ \ \ \\\ \\ \ \\\ \\ \ \_|\ \\|____|\ \ \ \ \
|
6
|
+
\ \_______\\ \_______\\ \_______\\ \__\\ \_______\\ \__\ \__\ \ \_____ \\ \_______\\ \_______\ ____\_\ \ \ \__\
|
7
|
+
\|_______| \|_______| \|_______| \|__| \|_______| \|__|\|__| \|___| \__\\|_______| \|_______||\_________\ \|__|
|
8
|
+
\|__| \|_________|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
[49m[K[0m
|
2
|
+
[5C[48;5;217m [48;5;231m [48;5;217m [48;5;231m [48;5;217m [49m
|
3
|
+
[2C[48;5;210m [48;5;196m [48;5;217m [48;5;203m [48;5;210m [48;5;203m [48;5;217m [48;5;167m [48;5;124m [49m
|
4
|
+
[1C[48;5;217m [48;5;210m [48;5;217m [48;5;231m [48;5;124m [49m
|
5
|
+
[1C[48;5;217m [48;5;231m [48;5;196m [48;5;219m [48;5;196m [49m
|
6
|
+
[3C[48;5;217m [48;5;196m [48;5;219m [48;5;196m [48;5;217m [49m
|
7
|
+
[5C[48;5;217m [48;5;210m [48;5;196m [48;5;219m [48;5;196m [48;5;231m [48;5;217m [49m
|
8
|
+
[7C[48;5;217m [48;5;210m [48;5;196m [48;5;219m [48;5;196m [48;5;210m [49m
|
9
|
+
[9C[48;5;217m [49m
|
10
|
+
[0m
|
data/data/rooms.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
-
|
2
|
+
description: |
|
3
|
+
It's pretty dark in here. You can barely make out some (doors) in the room.
|
4
|
+
There's someone standing in the corner. As you get a little closer
|
5
|
+
you realize its (matz), the founder of the Ruby programming language.
|
6
|
+
objects: [Matz]
|
7
|
+
-
|
8
|
+
description: |
|
9
|
+
As you enter the room there is a layer of undisturbed dust.
|
10
|
+
There seems to be something posted on the wall. It looks like ruby job (postings).
|
11
|
+
You feel a sense of relief since you're currently looking for work.
|
12
|
+
objects: [JobPosting]
|
13
|
+
-
|
14
|
+
description: |
|
15
|
+
You see a faint glow from a computer screen coming from the corner of the room.
|
16
|
+
As you walk closer you realize there is a computer (hacker) sitting in front of the screen.
|
17
|
+
objects: [Hacker]
|
18
|
+
-
|
19
|
+
description: |
|
20
|
+
It's pitch black. You feel a cold chill as air rushes through the room.
|
21
|
+
There is nothing in this room except some (doors).
|
22
|
+
-
|
23
|
+
description: |
|
24
|
+
There's a small (table) in the center of the room. Maybe you should take a closer look.
|
25
|
+
objects: [Table]
|
26
|
+
-
|
27
|
+
description: |
|
28
|
+
There's someone standing in the center of the room.
|
29
|
+
He has a conference nametag on his shirt. It says (jack).
|
30
|
+
objects: [Jack]
|
31
|
+
-
|
32
|
+
description: |
|
33
|
+
There's a man doing situps in a corner of the room.
|
34
|
+
It looks like (chuck) norris.
|
35
|
+
objects: [ChuckNorris]
|
data/degica.gemspec
CHANGED
@@ -26,11 +26,16 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
27
|
f.match(%r{^(test|spec|features)/})
|
28
28
|
end
|
29
|
-
spec.bindir = "
|
30
|
-
spec.executables =
|
29
|
+
spec.bindir = "bin"
|
30
|
+
spec.executables = ["degica"]
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
|
+
spec.add_dependency "coderay", "~> 1.1.2"
|
34
|
+
spec.add_dependency "faker", "~> 1.8"
|
35
|
+
|
33
36
|
spec.add_development_dependency "bundler", "~> 1.15"
|
34
37
|
spec.add_development_dependency "rake", "~> 10.0"
|
35
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
39
|
+
|
40
|
+
spec.post_install_message = 'Type "degica" to launch the gem 🚀'
|
36
41
|
end
|
data/lib/degica.rb
CHANGED
@@ -1,5 +1,52 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "readline"
|
3
|
+
require "coderay"
|
4
|
+
require "ostruct"
|
5
|
+
|
6
|
+
# preload translations
|
7
|
+
require "faker"
|
8
|
+
Faker::Name.first_name
|
9
|
+
|
10
|
+
# core
|
11
|
+
require "degica/collectable"
|
12
|
+
require "degica/actionable"
|
13
|
+
require "degica/room_loader"
|
14
|
+
require "degica/actor"
|
15
|
+
require "degica/game"
|
16
|
+
require "degica/door"
|
17
|
+
require "degica/nil_actionable"
|
18
|
+
require "degica/action"
|
19
|
+
require "degica/context"
|
20
|
+
require "degica/room"
|
21
|
+
require "degica/ansi"
|
1
22
|
require "degica/version"
|
2
23
|
|
24
|
+
# generators
|
25
|
+
require "degica/generators/door_name_generator"
|
26
|
+
|
27
|
+
# objects
|
28
|
+
require "degica/object"
|
29
|
+
require "degica/objects/ruby"
|
30
|
+
require "degica/objects/job_posting"
|
31
|
+
require "degica/objects/table"
|
32
|
+
require "degica/objects/people/person"
|
33
|
+
require "degica/objects/people/matz"
|
34
|
+
require "degica/objects/people/hacker"
|
35
|
+
require "degica/objects/people/jack"
|
36
|
+
require "degica/objects/people/chuck_norris"
|
37
|
+
|
38
|
+
# collections
|
39
|
+
require "degica/collection"
|
40
|
+
require "degica/collections/object_collection"
|
41
|
+
require "degica/collections/door_collection"
|
42
|
+
require "degica/collections/inventory_collection"
|
43
|
+
|
44
|
+
# core extentions
|
45
|
+
require "degica/core_ext/string"
|
46
|
+
require "degica/core_ext/did_you_mean"
|
47
|
+
|
3
48
|
module Degica
|
4
|
-
|
49
|
+
def self.root
|
50
|
+
File.expand_path '../..', __FILE__
|
51
|
+
end
|
5
52
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Degica
|
2
|
+
# {Actionable} objects return actions. These actions
|
3
|
+
# can be invoked in the game REPL and delegate function calls
|
4
|
+
# to a +@target+ ruby object method.
|
5
|
+
class Action
|
6
|
+
attr_reader :name, :target
|
7
|
+
|
8
|
+
def initialize(name_, target_)
|
9
|
+
@name = name_
|
10
|
+
@target = target_
|
11
|
+
end
|
12
|
+
|
13
|
+
def do(*args)
|
14
|
+
if @target.respond_to?(name)
|
15
|
+
@target.send(name, *args)
|
16
|
+
else
|
17
|
+
@target
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"#{@name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Degica
|
2
|
+
# Allows objects to be actionable in the game REPL.
|
3
|
+
# Actionable objects can be focused, described,
|
4
|
+
# and can expose actions in the REPL.
|
5
|
+
module Actionable
|
6
|
+
# Customized REPL prompt for action. For example,
|
7
|
+
# if the prompt method returned "book"
|
8
|
+
#
|
9
|
+
# book> ...
|
10
|
+
def prompt
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# @returns [Array<Degica::Action>] a list of actions.
|
15
|
+
def actions
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
|
19
|
+
# @returns [String] string describing the object.
|
20
|
+
def describe
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def do(name, *args)
|
25
|
+
actions.find { |action| action.name == name }.do(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/degica/actor.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Degica
|
2
|
+
class Actor
|
3
|
+
include Actionable
|
4
|
+
|
5
|
+
attr_accessor :location, :focus
|
6
|
+
attr_reader :inventory
|
7
|
+
|
8
|
+
def initialize(location)
|
9
|
+
@location = location
|
10
|
+
@inventory = InventoryCollection.new
|
11
|
+
@focus = nil
|
12
|
+
@points = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def pickup(item)
|
16
|
+
puts "You picked up a (#{item.name}).".highlight
|
17
|
+
@inventory << item.collection.delete(item)
|
18
|
+
award(10)
|
19
|
+
end
|
20
|
+
|
21
|
+
def award(points)
|
22
|
+
@points += points
|
23
|
+
puts "You've gained #{ANSI.highlight('10 points', :white)} 💕"
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_item?(item)
|
27
|
+
@inventory.include?(item)
|
28
|
+
end
|
29
|
+
|
30
|
+
def actions
|
31
|
+
[Action.new(:describe, self), Action.new(:inventory, self)] + @location.actions
|
32
|
+
end
|
33
|
+
|
34
|
+
def describe
|
35
|
+
@focus&.describe || @location.describe
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/degica/ansi.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Degica
|
2
|
+
module ANSI
|
3
|
+
COLORS = {
|
4
|
+
none: "\e[0m",
|
5
|
+
yellow: "\e[1;33m",
|
6
|
+
red: "\e[31m",
|
7
|
+
white: "\e[3;1m"
|
8
|
+
}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def clear_screen
|
12
|
+
puts "\x1b[2J"
|
13
|
+
end
|
14
|
+
|
15
|
+
def highlight(word, color)
|
16
|
+
COLORS[color] + word + COLORS[:none]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Degica
|
2
|
+
class Collection < Array
|
3
|
+
# A collection is a group of {Degica::Collectable} instances which
|
4
|
+
# can expose actions in the current context.
|
5
|
+
#
|
6
|
+
# Since collections are actionable, custom descriptions and
|
7
|
+
# actions can be added when inheriting from this class.
|
8
|
+
include Actionable
|
9
|
+
|
10
|
+
def initialize(items = [])
|
11
|
+
items.each do |item|
|
12
|
+
item.collection = self
|
13
|
+
end
|
14
|
+
super(items)
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(item)
|
18
|
+
item.collection = self
|
19
|
+
push(item)
|
20
|
+
end
|
21
|
+
|
22
|
+
def actions
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Degica
|
2
|
+
class DoorCollection < Collection
|
3
|
+
def actions
|
4
|
+
[Action.new(:doors, self)]
|
5
|
+
end
|
6
|
+
|
7
|
+
def describe
|
8
|
+
return "The are no doors here..." if empty?
|
9
|
+
|
10
|
+
desc = []
|
11
|
+
desc << (size > 1 ? "You see #{size} doors:" : "You see one door:")
|
12
|
+
desc << map(&:describe)
|
13
|
+
desc.flatten.join("\n")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Degica
|
2
|
+
class ObjectCollection < Collection
|
3
|
+
def actions
|
4
|
+
map { |obj| Action.new(obj.name, obj) }
|
5
|
+
end
|
6
|
+
|
7
|
+
def describe
|
8
|
+
if empty?
|
9
|
+
nil
|
10
|
+
else
|
11
|
+
desc = []
|
12
|
+
desc << "There are some objects here:"
|
13
|
+
desc << "[" + map(&:name).join(',') + "]"
|
14
|
+
desc.join("\n")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Degica
|
2
|
+
class Context < BasicObject
|
3
|
+
def initialize(actor)
|
4
|
+
@actor = actor
|
5
|
+
@focus = actor.focus || NilActionable.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def actions
|
9
|
+
(@actor.actions + @focus.actions).uniq(&:name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(method, *args)
|
13
|
+
if match = @focus.actions.find { |action| action.name == method }
|
14
|
+
@focus.do(match.name, *args)
|
15
|
+
elsif match = @actor.actions.find { |action| action.name == method }
|
16
|
+
@actor.do(match.name, *args)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/degica/door.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Degica
|
2
|
+
class Door
|
3
|
+
include Actionable
|
4
|
+
include Collectable
|
5
|
+
|
6
|
+
attr_reader :description
|
7
|
+
|
8
|
+
def initialize(room1, room2)
|
9
|
+
@description = DoorNameGenerator.sample
|
10
|
+
@rooms = [room1, room2]
|
11
|
+
|
12
|
+
# connect rooms
|
13
|
+
room1.doors << self
|
14
|
+
room2.doors << self
|
15
|
+
end
|
16
|
+
|
17
|
+
def actions
|
18
|
+
[Action.new(:enter, self), Action.new(:open, self)]
|
19
|
+
end
|
20
|
+
|
21
|
+
def open
|
22
|
+
Game.objects.actor.focus = self
|
23
|
+
"You opened the door. Try to (enter) it.".highlight
|
24
|
+
end
|
25
|
+
|
26
|
+
def enter
|
27
|
+
next_room = (@rooms - [Game.objects.actor.location])[0]
|
28
|
+
Game.objects.actor.location = next_room
|
29
|
+
next_room.generate!
|
30
|
+
next_room
|
31
|
+
end
|
32
|
+
|
33
|
+
def describe
|
34
|
+
@description
|
35
|
+
end
|
36
|
+
|
37
|
+
def prompt
|
38
|
+
"door"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/degica/game.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Degica
|
2
|
+
class Game
|
3
|
+
def initialize
|
4
|
+
# setup rooms
|
5
|
+
rooms = RoomLoader.load
|
6
|
+
|
7
|
+
# spawn actor in random room
|
8
|
+
starting_room = rooms.sample
|
9
|
+
@actor = Actor.new(starting_room)
|
10
|
+
|
11
|
+
# game objects
|
12
|
+
@@objects = OpenStruct.new(rooms: rooms, actor: @actor)
|
13
|
+
|
14
|
+
# generate starting room
|
15
|
+
starting_room.generate!
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.objects
|
19
|
+
@@objects
|
20
|
+
end
|
21
|
+
|
22
|
+
def start
|
23
|
+
ANSI.clear_screen
|
24
|
+
puts "Welcome to"
|
25
|
+
puts ANSI.highlight(File.read(Degica.root + '/data/images/degica_quest.txt'), :yellow)
|
26
|
+
puts "Type (actions) to see what actions you can perform.".highlight
|
27
|
+
puts "\n" + @@objects.actor.describe + "\n\n"
|
28
|
+
|
29
|
+
loop do
|
30
|
+
input = Readline.readline("#{prompt}> ", true)
|
31
|
+
exit if input == "exit"
|
32
|
+
begin
|
33
|
+
context = Context.new(@actor)
|
34
|
+
case output = context.instance_eval(input)
|
35
|
+
when String # remove quotes in console i.e. > "string"
|
36
|
+
puts output
|
37
|
+
when Actionable
|
38
|
+
@actor.focus = output
|
39
|
+
message = output.describe
|
40
|
+
puts message unless message.nil?
|
41
|
+
when NilClass
|
42
|
+
puts @actor.describe
|
43
|
+
else
|
44
|
+
puts CodeRay.scan(output.inspect, :ruby).terminal
|
45
|
+
end
|
46
|
+
rescue Exception => e
|
47
|
+
puts e.message
|
48
|
+
end
|
49
|
+
puts
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def prompt
|
56
|
+
@actor.focus&.prompt
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Degica
|
2
|
+
module DoorNameGenerator
|
3
|
+
COLORS = [
|
4
|
+
'blue',
|
5
|
+
'red',
|
6
|
+
'green',
|
7
|
+
'black',
|
8
|
+
'white',
|
9
|
+
'brown',
|
10
|
+
]
|
11
|
+
|
12
|
+
MATERIAL = [
|
13
|
+
'wooden',
|
14
|
+
'metal',
|
15
|
+
'granite',
|
16
|
+
'bronze',
|
17
|
+
'copper',
|
18
|
+
'gold',
|
19
|
+
'steel'
|
20
|
+
]
|
21
|
+
|
22
|
+
ADJECTIVES = [
|
23
|
+
'battered',
|
24
|
+
'shiny',
|
25
|
+
'round',
|
26
|
+
'old',
|
27
|
+
'cracked',
|
28
|
+
'shattered',
|
29
|
+
'rusty',
|
30
|
+
'worn out',
|
31
|
+
'striped',
|
32
|
+
'wide',
|
33
|
+
'short',
|
34
|
+
'sturdy',
|
35
|
+
'tiny'
|
36
|
+
]
|
37
|
+
|
38
|
+
class << self
|
39
|
+
def sample
|
40
|
+
desc = sample_with_order([ADJECTIVES.sample, MATERIAL.sample, COLORS.sample]).join(' ')
|
41
|
+
"A #{desc} door."
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def sample_with_order(words)
|
47
|
+
size = words.size
|
48
|
+
indexes = [*0..size-1].sample(rand(1..size)).sort
|
49
|
+
indexes.collect { |i| words[i] }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Degica
|
2
|
+
class Object
|
3
|
+
include Actionable
|
4
|
+
include Collectable
|
5
|
+
|
6
|
+
def initialize(objects = [])
|
7
|
+
@objects = ObjectCollection.new(objects)
|
8
|
+
end
|
9
|
+
|
10
|
+
def actions
|
11
|
+
@objects.actions
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
def describe
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def prompt
|
23
|
+
name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Degica
|
2
|
+
class JobPosting < Object
|
3
|
+
def name
|
4
|
+
:postings
|
5
|
+
end
|
6
|
+
|
7
|
+
def describe
|
8
|
+
desc = <<~DESC
|
9
|
+
|
10
|
+
Open Positions
|
11
|
+
==============
|
12
|
+
|
13
|
+
(Ruby Developer)
|
14
|
+
|
15
|
+
We are currently hiring junior and senior level Ruby developers.
|
16
|
+
Please e-mail a resume and CV to recruit@degica.com
|
17
|
+
|
18
|
+
DESC
|
19
|
+
desc.highlight(:red)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Degica
|
2
|
+
class ChuckNorris < Person
|
3
|
+
def name
|
4
|
+
:chuck
|
5
|
+
end
|
6
|
+
|
7
|
+
def quote
|
8
|
+
Faker::ChuckNorris.fact
|
9
|
+
end
|
10
|
+
|
11
|
+
def description
|
12
|
+
desc = []
|
13
|
+
desc << "He's flexing his muscles."
|
14
|
+
desc << "He has a ruby." if holding?(:ruby)
|
15
|
+
desc
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Degica
|
2
|
+
class Hacker < Person
|
3
|
+
def name
|
4
|
+
:hacker
|
5
|
+
end
|
6
|
+
|
7
|
+
def quote
|
8
|
+
Faker::Hacker.say_something_smart
|
9
|
+
end
|
10
|
+
|
11
|
+
def description
|
12
|
+
desc = []
|
13
|
+
desc << "He looks like he could hack into anything."
|
14
|
+
desc << "He is holding a ruby." if holding?(:ruby)
|
15
|
+
desc
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Degica
|
2
|
+
class Jack < Person
|
3
|
+
def name
|
4
|
+
:jack
|
5
|
+
end
|
6
|
+
|
7
|
+
def quote
|
8
|
+
[
|
9
|
+
"To understand VR, you absolutely have to experience it, to immerse yourself in it.",
|
10
|
+
"We’ve dealt with all the hassle and complication of Japanese payments so that companies don’t have to",
|
11
|
+
"Komoju helps companies quickly accept payments in Japan, and lets consumers pay the way that they want to pay."
|
12
|
+
].sample
|
13
|
+
end
|
14
|
+
|
15
|
+
def description
|
16
|
+
desc = []
|
17
|
+
desc << "It's Jack Momose. He's the CEO of Degica."
|
18
|
+
desc << "He is holding a ruby. He doesn't seem to know what he should do with it." if holding?(:ruby)
|
19
|
+
desc
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Degica
|
2
|
+
class Matz < Person
|
3
|
+
def name
|
4
|
+
:matz
|
5
|
+
end
|
6
|
+
|
7
|
+
def quote
|
8
|
+
Faker::Matz.quote
|
9
|
+
end
|
10
|
+
|
11
|
+
def give(object = nil)
|
12
|
+
super.tap do
|
13
|
+
if object.name == :ruby
|
14
|
+
puts "He thanks you for bringing him the ruby."
|
15
|
+
Game.objects.actor.award(20)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
desc = []
|
22
|
+
desc << "He's smiling at you. You smile back."
|
23
|
+
desc << "He is holding a ruby." if holding?(:ruby)
|
24
|
+
desc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Degica
|
2
|
+
class Person < Object
|
3
|
+
def initialize
|
4
|
+
@talked = false
|
5
|
+
@inventory = InventoryCollection.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
def quote
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
def description
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
def actions
|
21
|
+
[Action.new(:talk, self), Action.new(:give, self)]
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"#{name.capitalize} says: \"Don't inspect me!\""
|
26
|
+
end
|
27
|
+
|
28
|
+
def talk
|
29
|
+
@talked = true
|
30
|
+
desc = []
|
31
|
+
desc << "#{name} says:".capitalize
|
32
|
+
desc << '"' + quote + '"'
|
33
|
+
desc.join(" ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def give(object = nil)
|
37
|
+
if object.nil?
|
38
|
+
return "What do you want to give?"
|
39
|
+
elsif !object.is_a?(::Degica::Object)
|
40
|
+
return "\"#{object}\" is not in your (inventory).".highlight
|
41
|
+
end
|
42
|
+
|
43
|
+
if object.collection.delete(object)
|
44
|
+
@inventory << object
|
45
|
+
puts "You gave the (#{object.name}) to #{name}.".highlight
|
46
|
+
else
|
47
|
+
puts "You don't have any #{object.name}."
|
48
|
+
end
|
49
|
+
NilActionable.new
|
50
|
+
end
|
51
|
+
|
52
|
+
def describe
|
53
|
+
desc = []
|
54
|
+
desc << description
|
55
|
+
desc << "Maybe you should (talk) with him.".highlight unless @talked
|
56
|
+
desc.join("\n")
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def holding?(name)
|
62
|
+
!!@inventory.find { |item| item.name == name }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Degica
|
2
|
+
class Ruby < Object
|
3
|
+
def name
|
4
|
+
:ruby
|
5
|
+
end
|
6
|
+
|
7
|
+
def actions
|
8
|
+
if Game.objects.actor.has_item?(self)
|
9
|
+
[]
|
10
|
+
else
|
11
|
+
[Action.new(:take, self)]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def take
|
16
|
+
Game.objects.actor.pickup(self)
|
17
|
+
NilActionable.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def describe
|
21
|
+
File.read(Degica.root + '/data/images/ruby.ansi')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Degica
|
2
|
+
class Table < Object
|
3
|
+
def name
|
4
|
+
:table
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(objects = [Ruby.new])
|
8
|
+
super(objects)
|
9
|
+
end
|
10
|
+
|
11
|
+
def describe
|
12
|
+
desc = []
|
13
|
+
desc << "The table is quite old."
|
14
|
+
desc << @objects.describe
|
15
|
+
desc.join("\n")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/degica/room.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Degica
|
2
|
+
class Room
|
3
|
+
include Actionable
|
4
|
+
attr_accessor :description, :doors
|
5
|
+
|
6
|
+
def initialize(description, objects = [])
|
7
|
+
@description = description.highlight
|
8
|
+
@doors = DoorCollection.new
|
9
|
+
@objects = ObjectCollection.new(objects)
|
10
|
+
@generated = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate!
|
14
|
+
return if @generated
|
15
|
+
@generated = true
|
16
|
+
|
17
|
+
rooms = Game.objects.rooms.select do |room|
|
18
|
+
room.doors.empty? && room != self
|
19
|
+
end.sample(rand(1..2))
|
20
|
+
|
21
|
+
rooms.map { |r| make_door(r) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def actions
|
25
|
+
actions = @doors.actions + @objects.actions
|
26
|
+
actions << Action.new(:room, self)
|
27
|
+
actions << Action.new(:door, @doors.first) if @doors.size == 1
|
28
|
+
actions
|
29
|
+
end
|
30
|
+
|
31
|
+
def describe
|
32
|
+
@description
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def make_door(room)
|
38
|
+
Door.new(self, room)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Degica
|
2
|
+
class RoomLoader
|
3
|
+
def self.load
|
4
|
+
# load rooms.xml
|
5
|
+
@rooms = YAML::load_file( File.dirname(__FILE__) + "/../../data/rooms.yml" )
|
6
|
+
@rooms.collect do |room|
|
7
|
+
objects = (room["objects"] || []).map do |o|
|
8
|
+
Kernel.const_get("Degica::" + o).new
|
9
|
+
end
|
10
|
+
Room.new(room["description"], objects)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/degica/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: degica
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Salzberg
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: coderay
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faker
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.8'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,7 +83,8 @@ dependencies:
|
|
55
83
|
description: Degica
|
56
84
|
email:
|
57
85
|
- chris@dejimata.com
|
58
|
-
executables:
|
86
|
+
executables:
|
87
|
+
- degica
|
59
88
|
extensions: []
|
60
89
|
extra_rdoc_files: []
|
61
90
|
files:
|
@@ -68,15 +97,48 @@ files:
|
|
68
97
|
- README.md
|
69
98
|
- Rakefile
|
70
99
|
- bin/console
|
100
|
+
- bin/degica
|
71
101
|
- bin/setup
|
102
|
+
- data/doors.yml
|
103
|
+
- data/images/degica_quest.txt
|
104
|
+
- data/images/ruby.ansi
|
105
|
+
- data/rooms.yml
|
72
106
|
- degica.gemspec
|
73
107
|
- lib/degica.rb
|
108
|
+
- lib/degica/action.rb
|
109
|
+
- lib/degica/actionable.rb
|
110
|
+
- lib/degica/actor.rb
|
111
|
+
- lib/degica/ansi.rb
|
112
|
+
- lib/degica/collectable.rb
|
113
|
+
- lib/degica/collection.rb
|
114
|
+
- lib/degica/collections/door_collection.rb
|
115
|
+
- lib/degica/collections/inventory_collection.rb
|
116
|
+
- lib/degica/collections/object_collection.rb
|
117
|
+
- lib/degica/context.rb
|
118
|
+
- lib/degica/core_ext/did_you_mean.rb
|
119
|
+
- lib/degica/core_ext/string.rb
|
120
|
+
- lib/degica/door.rb
|
121
|
+
- lib/degica/game.rb
|
122
|
+
- lib/degica/generators/door_name_generator.rb
|
123
|
+
- lib/degica/nil_actionable.rb
|
124
|
+
- lib/degica/object.rb
|
125
|
+
- lib/degica/objects/hacker.rb
|
126
|
+
- lib/degica/objects/job_posting.rb
|
127
|
+
- lib/degica/objects/people/chuck_norris.rb
|
128
|
+
- lib/degica/objects/people/hacker.rb
|
129
|
+
- lib/degica/objects/people/jack.rb
|
130
|
+
- lib/degica/objects/people/matz.rb
|
131
|
+
- lib/degica/objects/people/person.rb
|
132
|
+
- lib/degica/objects/ruby.rb
|
133
|
+
- lib/degica/objects/table.rb
|
134
|
+
- lib/degica/room.rb
|
135
|
+
- lib/degica/room_loader.rb
|
74
136
|
- lib/degica/version.rb
|
75
137
|
homepage: https://degica.com
|
76
138
|
licenses:
|
77
139
|
- MIT
|
78
140
|
metadata: {}
|
79
|
-
post_install_message:
|
141
|
+
post_install_message: "Type \"degica\" to launch the gem \U0001F680"
|
80
142
|
rdoc_options: []
|
81
143
|
require_paths:
|
82
144
|
- lib
|