demigod_game 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 +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/demigod +5 -0
- data/demigodGame.gemspec +23 -0
- data/lib/demigodGame.rb +25 -0
- data/lib/demigodGame/Demigod.rb +109 -0
- data/lib/demigodGame/GameData.rb +59 -0
- data/lib/demigodGame/Tile.rb +129 -0
- data/lib/demigodGame/UiHandler.rb +61 -0
- data/lib/demigodGame/World.rb +155 -0
- data/lib/demigodGame/version.rb +3 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MGY1ZWFlYWE0Mjk4MjU2MTg5OWYwYzMwZDY0YTM4ZjcyMWQwZDZhMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDc5MGM0MjU3MzNhOGFjNDgyOWVlM2JlY2Q2YjY4MzlkNmU4MjcyZQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZmRjYmIzNWU1OTFlYzJlYzc2OWYwMDE4ZGVkMjdhMzU0YjI2OWIxZmY5MTNm
|
10
|
+
ZDdlY2NjOWVhMzZkYzFmOGQ4MDJlMGEwMGE4MWI4YzI5MTZiN2YxYmE1NTVj
|
11
|
+
NzEzOWVjNGFhZmYwOTYyZWRhYTBkNGQwMTYzNzA3NzYyZWM0YmU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZmVmODM1NGFlNWNhNWFlZDUzOWUzYmNjZTBlNzQ2YWUwNDMyYWQ3OTNkNjhl
|
14
|
+
YTY0YzZhOGI0MmI1ODA0NjY2YmY2MzE3ZWY1MGNkYWIxODU3MDI1NTFhYWM5
|
15
|
+
OTQwZTNhN2ExODJkMzRhYTIwODhlYTdlNDgyZDI0NTM5MjBjOTI=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Yuval
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# DemigodGame
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'demigodGame'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install demigodGame
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/demigod
ADDED
data/demigodGame.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'demigodGame/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "demigod_game"
|
8
|
+
spec.version = DemigodGame::VERSION
|
9
|
+
spec.authors = ["Yuval"]
|
10
|
+
spec.email = ["yvw.bor@gmail.com"]
|
11
|
+
spec.description = %q{A learning project game, build your own island and unleash the dragons from the dragon shrine!}
|
12
|
+
spec.summary = %q{Build your own island and unleash the dragons!}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/lib/demigodGame.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'demigodGame/version'
|
2
|
+
require_relative 'demigodGame/Demigod'
|
3
|
+
require_relative 'demigodGame/World'
|
4
|
+
|
5
|
+
module DemigodGame
|
6
|
+
@demigod
|
7
|
+
def self.new
|
8
|
+
puts UiHandler::NEW_GAME
|
9
|
+
until (size = gets.chomp).match(/^\d+$/) && size.to_i >= 3
|
10
|
+
puts "Invalid world size"
|
11
|
+
end
|
12
|
+
|
13
|
+
@demigod = Demigod.new(World.new(size.to_i))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.run
|
17
|
+
while true
|
18
|
+
@demigod.turn
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
DemigodGame.new
|
25
|
+
DemigodGame.run
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# This file will handle the Demigod class, which is the heart of the game
|
2
|
+
# = as it's the player controlled class
|
3
|
+
#
|
4
|
+
# Turn order:
|
5
|
+
#- First resources are calculater for the turn and printed on the screen
|
6
|
+
#- The player then needs to answer in event, not all of them are interactive
|
7
|
+
#- The player can either choose a tile to build on or skip by returning an empty line
|
8
|
+
#- If the player chose a tile he now needs to input his action for the tile
|
9
|
+
# =============================================================================
|
10
|
+
|
11
|
+
require_relative 'UiHandler'
|
12
|
+
require_relative 'GameData'
|
13
|
+
require_relative 'World'
|
14
|
+
|
15
|
+
class Demigod
|
16
|
+
attr_reader :resources
|
17
|
+
@world
|
18
|
+
|
19
|
+
# Starts a new game - each demigod has one world to rule
|
20
|
+
# accepts different starting resources as a parameter
|
21
|
+
def initialize (world, resources = GameData::STARTING_RESOURCES)
|
22
|
+
@world = world
|
23
|
+
@resources = resources
|
24
|
+
system "clear" or system "cls"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Handles a turn, main function of the game
|
28
|
+
def turn
|
29
|
+
|
30
|
+
# calculates new amount of resources using the production function
|
31
|
+
# world.production accepts a resources hash and returns a newly
|
32
|
+
# calculated resource hash based on production
|
33
|
+
@resources = @world.production(@resources)
|
34
|
+
p @resources
|
35
|
+
|
36
|
+
#do_event # ========= TODO ========= #
|
37
|
+
|
38
|
+
# part 2 of every turn
|
39
|
+
UiHandler.print_world(@world)
|
40
|
+
UiHandler.print_turn_message
|
41
|
+
|
42
|
+
# Asks the user for a tile to do his action on
|
43
|
+
decision = gets.chomp
|
44
|
+
|
45
|
+
until (@world.exists?(decision) || decision == '')
|
46
|
+
UiHandler.print_error(UiHandler::NO_TILE)
|
47
|
+
UiHandler.print_turn_message
|
48
|
+
decision = gets.chomp
|
49
|
+
end
|
50
|
+
|
51
|
+
unless decision == ''
|
52
|
+
tile = @world.get_tile decision # returns the tile at decision
|
53
|
+
tile.print_options
|
54
|
+
|
55
|
+
# asks for action on tile
|
56
|
+
decision = gets.chomp
|
57
|
+
|
58
|
+
# tile.accepts? uses number of resources to decide if a move is valid
|
59
|
+
until tile.accepts?(decision, @resources)
|
60
|
+
break if decision == ''
|
61
|
+
UiHandler.print_error(UiHandler::INVALID)
|
62
|
+
tile.print_options
|
63
|
+
decision = gets.chomp
|
64
|
+
end
|
65
|
+
|
66
|
+
if decision != ''
|
67
|
+
price = GameData.get_price(decision)
|
68
|
+
@resources = reduce(price)
|
69
|
+
@world.advance(tile, decision)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Clears the screen
|
74
|
+
system "clear" or system "cls"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# calls and handles a new event # === TODO === #
|
80
|
+
def do_event
|
81
|
+
=begin
|
82
|
+
|
83
|
+
event = Events.new(@resources[:luck])
|
84
|
+
# starts an event
|
85
|
+
event.start
|
86
|
+
decision = gets.chomp
|
87
|
+
|
88
|
+
until event.accepts? decision # Requires valid input
|
89
|
+
UiHandler.print_error(event.valid_range)
|
90
|
+
decision = gets.chomp
|
91
|
+
end
|
92
|
+
|
93
|
+
# event.dispatch accepts player decision and affects the world
|
94
|
+
# returning new number of resources
|
95
|
+
@resources = event.dispatch(decision)
|
96
|
+
|
97
|
+
=end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reduces resources
|
101
|
+
def reduce(amount)
|
102
|
+
amount.each do |name, value|
|
103
|
+
@resources[name] -= value
|
104
|
+
end
|
105
|
+
@resources
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# GameData module Holds all important and CONSTANT game GameData
|
2
|
+
# Includes methods to return specific prices
|
3
|
+
# ==============================================================
|
4
|
+
|
5
|
+
module GameData
|
6
|
+
STARTING_RESOURCES = {:wood => 2,
|
7
|
+
:food => 2,
|
8
|
+
:population => 1,
|
9
|
+
:iron => 0,
|
10
|
+
:favor => 20,
|
11
|
+
:luck => 0
|
12
|
+
}
|
13
|
+
|
14
|
+
RAISE_PLAINS_PRICE = {:favor => 5}
|
15
|
+
RAISE_FOREST_PRICE = {:favor => 5}
|
16
|
+
RAISE_RIDGE_PRICE = {:favor => 10}
|
17
|
+
|
18
|
+
=begin
|
19
|
+
RAISE_PRICES = {:p => RAISE_PLAINS_PRICE,
|
20
|
+
:f => RAISE_FOREST_PRICE,
|
21
|
+
:r => RAISE_RIDGE_PRICE
|
22
|
+
}
|
23
|
+
RAISE_PRICES.default = nil
|
24
|
+
=end
|
25
|
+
|
26
|
+
BUILD_WOODCUTTER_PRICE = {:food => 3}
|
27
|
+
BUILD_SHEEP_PRICE = {:food => 0} # Sheeps are free, yay!
|
28
|
+
BUILD_DRAGONSHRINE_PRICE = {:food => 10, :iron => 10, :wood => 10, :favor => 100}
|
29
|
+
BUILD_MINE_PRICE = {:wood => 5}
|
30
|
+
BUILD_CHAPEL_PRICE = {:wood => 2, :food => 3}
|
31
|
+
BUILD_HOUSE_PRICE = {:wood => 2}
|
32
|
+
|
33
|
+
=begin
|
34
|
+
BUILD_PRICES = {:w => BUILD_WOODCUTTER_PRICE,
|
35
|
+
:s => BUILD_SHEEP_PRICE,
|
36
|
+
:d => BUILD_DRAGONSHRINE_PRICE,
|
37
|
+
:m => BUILD_MINE_PRICE,
|
38
|
+
:c => BUILD_CHAPEL_PRICE,
|
39
|
+
:h => BUILD_HOUSE_PRICE
|
40
|
+
}
|
41
|
+
BUILD_PRICES.default = nil
|
42
|
+
=end
|
43
|
+
|
44
|
+
PRICES = {:w => BUILD_WOODCUTTER_PRICE,
|
45
|
+
:s => BUILD_SHEEP_PRICE,
|
46
|
+
:d => BUILD_DRAGONSHRINE_PRICE,
|
47
|
+
:m => BUILD_MINE_PRICE,
|
48
|
+
:c => BUILD_CHAPEL_PRICE,
|
49
|
+
:h => BUILD_HOUSE_PRICE,
|
50
|
+
:p => RAISE_PLAINS_PRICE,
|
51
|
+
:f => RAISE_FOREST_PRICE,
|
52
|
+
:r => RAISE_RIDGE_PRICE
|
53
|
+
}
|
54
|
+
|
55
|
+
def self.get_price(sym)
|
56
|
+
return PRICES[sym.to_sym]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# Includes the base Tile class and all subsequent Tile types
|
2
|
+
# Handles the work with tiles, checks which values are valid for current tile
|
3
|
+
#
|
4
|
+
# Subclasses are: Sea, Mountain, Plain and Forest
|
5
|
+
# ================================================================
|
6
|
+
require_relative 'GameData'
|
7
|
+
class Tile
|
8
|
+
|
9
|
+
attr_reader :raisable, :buildable, :built_on, :x, :y
|
10
|
+
def initialize(x, y)
|
11
|
+
@x = x
|
12
|
+
@y = y
|
13
|
+
@raisable = []
|
14
|
+
@buildable = []
|
15
|
+
@type = '.'
|
16
|
+
end
|
17
|
+
|
18
|
+
# The base tile class is abstract and therfore accepts no value
|
19
|
+
# Should probably be overriden in subclasses
|
20
|
+
def accepts?(order, resources)
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_options
|
25
|
+
|
26
|
+
if @raisable != [] # raising options
|
27
|
+
print "You can raise with:"
|
28
|
+
@raisable.each do |name|
|
29
|
+
print " #{name.to_s} | "
|
30
|
+
end
|
31
|
+
puts
|
32
|
+
end
|
33
|
+
|
34
|
+
if @buildable != [] # building options
|
35
|
+
print "You can build with:"
|
36
|
+
@buildable.each do |name|
|
37
|
+
print " #{name.to_s} | "
|
38
|
+
end
|
39
|
+
puts
|
40
|
+
end
|
41
|
+
|
42
|
+
puts UiHandler::RAISE_WARNING if @built_on
|
43
|
+
puts UiHandler::BACK
|
44
|
+
|
45
|
+
|
46
|
+
print UiHandler::PROMPT
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
"#{@type}#{@built_on}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Adds building to tile, doesn't check if valid building
|
54
|
+
def build(building)
|
55
|
+
@built_on = building
|
56
|
+
@buildable = []
|
57
|
+
end
|
58
|
+
|
59
|
+
# Checks if an order is valid
|
60
|
+
def accepts?(order, resources)
|
61
|
+
return false if !order.match( /\A\w\Z/ ) # vaild command
|
62
|
+
|
63
|
+
(@raisable + @buildable).each do |check| # checks which order was given
|
64
|
+
if (check.to_s == order)
|
65
|
+
cost = GameData.get_price(check)
|
66
|
+
puts "This costs #{cost}"
|
67
|
+
if !check_cost(cost, resources)
|
68
|
+
puts "Not enough resources!"
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def check_cost(cost, resources)
|
80
|
+
|
81
|
+
# checks each resource for the correct amount
|
82
|
+
cost.each do |resource, amount|
|
83
|
+
return false if amount > resources[resource]
|
84
|
+
end
|
85
|
+
return true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sea class, can raise plains, can't be built on
|
90
|
+
class Sea < Tile
|
91
|
+
|
92
|
+
def initialize(x, y)
|
93
|
+
super(x, y)
|
94
|
+
@raisable = [:p]
|
95
|
+
@type = '-'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Ridge class, can't be raised, can build mine, chapel and dragon shrine
|
100
|
+
class Ridge < Tile
|
101
|
+
|
102
|
+
def initialize(x, y)
|
103
|
+
super(x, y)
|
104
|
+
@buildable = [:m, :c, :d]
|
105
|
+
@type = 'R'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Plains class, can be raised to ridge or forest, can build house, chapel and sheeps
|
110
|
+
class Plains < Tile
|
111
|
+
|
112
|
+
def initialize(x, y)
|
113
|
+
super(x, y)
|
114
|
+
@raisable = [:r, :f]
|
115
|
+
@buildable = [:h, :c, :s]
|
116
|
+
@type = 'P'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Forst class, can be raised to ridge, can build woodcutter, chapel, house
|
121
|
+
class Forest < Tile
|
122
|
+
|
123
|
+
def initialize(x, y)
|
124
|
+
super(x, y)
|
125
|
+
@buildable = [:w, :c, :h]
|
126
|
+
@raisable = [:r]
|
127
|
+
@type = 'F'
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Module to handle most of the output to the screen
|
2
|
+
# =================================================
|
3
|
+
|
4
|
+
module UiHandler
|
5
|
+
|
6
|
+
NEW_GAME = "Welcome to Demigod! What size would you want your world to be?"
|
7
|
+
PROMPT = '>'
|
8
|
+
NO_TILE = "There is no such tile"
|
9
|
+
NOT_ENOUGH_FOOD = "Your people lack food! Some have died of starvation!"
|
10
|
+
RAISE_WARNING = "Warning: Raising the ground here will destroy the existing building!"
|
11
|
+
BACK = "Press enter on an empty line to go back"
|
12
|
+
INVALID = "That's an invalid move!"
|
13
|
+
LOST = "You ran out of resources, I guess you lose..."
|
14
|
+
WIN = "The dragon shrine is built and so the dragons grant you all the powers of immortality"
|
15
|
+
|
16
|
+
def self.print_world(world)
|
17
|
+
puts
|
18
|
+
print ' -'
|
19
|
+
(world.size).times { |i| print "-#{i+1}--"}
|
20
|
+
puts
|
21
|
+
|
22
|
+
row_number = 1
|
23
|
+
world.tiles.each do |row|
|
24
|
+
print "#{row_number}"
|
25
|
+
row.each do |tile|
|
26
|
+
print "| #{tile.to_s}"
|
27
|
+
print " " if tile.to_s.length == 1
|
28
|
+
end
|
29
|
+
puts '|'
|
30
|
+
row_number += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
print ' -'
|
34
|
+
(world.size).times { |i| print "----"}
|
35
|
+
|
36
|
+
puts ''
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.print_status(resources, buildings)
|
40
|
+
print_hash resources
|
41
|
+
print_hash buildings
|
42
|
+
puts
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.print_hash(hash)
|
46
|
+
hash. each do |name, amount|
|
47
|
+
print "#{name}: #{amount} | " if name != :luck
|
48
|
+
end
|
49
|
+
puts
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.print_turn_message
|
53
|
+
puts "Choose a tile to work on. Enter 2 numbers with a space in between i.e. \"1 1\""
|
54
|
+
print PROMPT
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.print_error(error_str)
|
58
|
+
puts "Oops! #{error_str}"
|
59
|
+
puts
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# This file will handle the World class, which holds the world map and all relevant functions
|
2
|
+
# =============================================================================
|
3
|
+
require_relative 'Tile'
|
4
|
+
require_relative 'UiHandler'
|
5
|
+
require_relative 'GameData'
|
6
|
+
|
7
|
+
class World
|
8
|
+
BUILDABLE = {:wood_cutter => 'w', :sheep => 's', :mines => 'm', :chapel => 'c', :house => 'h', :dragon => 'd'}
|
9
|
+
DECISIONS = {:build => {:w => 'wood_cutter', :s => 'sheep', :m => 'mines', :c => 'chapel', :h => 'house', :d => 'dragon'},
|
10
|
+
:raise => {:r => 'ridge', :f => 'forest', :p => 'plains'}}
|
11
|
+
DECISIONS.default = nil
|
12
|
+
|
13
|
+
attr_reader :tiles, :buildings, :size
|
14
|
+
|
15
|
+
def initialize(size = 5)
|
16
|
+
@buildings = {:wood_cutter => 0, :sheep => 0, :mines => 0, :chapel => 0, :house => 0, :dragon => 0}
|
17
|
+
@size = size
|
18
|
+
|
19
|
+
generate_tiles(size)
|
20
|
+
end
|
21
|
+
|
22
|
+
# returns a specific tile from an str with a space
|
23
|
+
def get_tile(str)
|
24
|
+
str.strip!
|
25
|
+
str = str.split(" ")
|
26
|
+
x = str[0].to_i - 1
|
27
|
+
y = str[1].to_i - 1
|
28
|
+
@tiles[x][y]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Advances the world map based on given 1-letter instruction
|
32
|
+
# Assumes all given decisions were checked by tile.accept
|
33
|
+
def advance(tile, order)
|
34
|
+
if order.match(/\A[rfp]\Z/) # for raise of Ridge, Forest or Plain
|
35
|
+
raise_tile(tile.x, tile.y, DECISIONS[:raise][order.to_sym])
|
36
|
+
|
37
|
+
elsif order.match(/\A[wsmchd]\Z/) # for build of any building
|
38
|
+
build_on_tile(tile, DECISIONS[:build][order.to_sym])
|
39
|
+
else
|
40
|
+
puts "Error occured, continuing but turn skipped."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Adds to resources by number of buildings. Also checks the only lose condition in the game
|
45
|
+
def production(resources)
|
46
|
+
resources[:wood] += @buildings[:wood_cutter]
|
47
|
+
resources[:food] += @buildings[:sheep] -resources[:population]
|
48
|
+
resources[:iron] += @buildings[:mines]
|
49
|
+
resources[:favor] += @buildings[:chapel] * (resources[:population] / 10 + 1)
|
50
|
+
resources[:favor] = (resources[:favor] * 0.9).to_i
|
51
|
+
|
52
|
+
if resources[:population] < resources[:food]
|
53
|
+
resources[:population] += @buildings[:house]
|
54
|
+
else
|
55
|
+
puts UiHandler::NOT_ENOUGH_FOOD
|
56
|
+
resources[:population] -= resources[:population] - resources[:food]
|
57
|
+
end
|
58
|
+
UiHandler.print_status(resources, @buildings)
|
59
|
+
|
60
|
+
resources.each do |name, value| # lose condition
|
61
|
+
if value < 0
|
62
|
+
system "clear" or system "cls"
|
63
|
+
puts "#{name} is negative!"
|
64
|
+
puts UiHandler::LOST
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
resources
|
69
|
+
end
|
70
|
+
|
71
|
+
def exists? (str)
|
72
|
+
str.strip!
|
73
|
+
return false if !str.match(/\A\d+\s\d+\Z/)
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# generates a starting grid based on size
|
80
|
+
def generate_tiles(size)
|
81
|
+
|
82
|
+
@tiles = [] # starts from fresh
|
83
|
+
|
84
|
+
size.times do |x|
|
85
|
+
@tiles << [] # Creates a multi dimensional array
|
86
|
+
size.times do |y|
|
87
|
+
tiles[x] << Sea.new(x, y) # Adds the sea
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
middle = size / 2
|
92
|
+
|
93
|
+
# raises an initial cross of plains
|
94
|
+
(-1..1).step(1) do |i|
|
95
|
+
raise_tile(middle + i, middle, :plains)
|
96
|
+
raise_tile(middle, middle + i, :plains)
|
97
|
+
end
|
98
|
+
|
99
|
+
# puts initial buildings
|
100
|
+
build_on_tile(@tiles[middle][middle], :house)
|
101
|
+
random1, random2 = (rand(0..1) * 2 - 1), (rand(0..1) * 2 - 1)
|
102
|
+
build_on_tile(@tiles[middle + random1][middle], :chapel)
|
103
|
+
build_on_tile(@tiles[middle][middle + random2], :sheep)
|
104
|
+
|
105
|
+
# initial forest
|
106
|
+
raise_tile(middle - random1, middle - random2, :forest)
|
107
|
+
end
|
108
|
+
|
109
|
+
# creates a new tile, placing it in given location
|
110
|
+
# does not check for compatibility
|
111
|
+
def raise_tile(x, y, tile_type)
|
112
|
+
case tile_type.to_sym
|
113
|
+
when :ridge
|
114
|
+
new_tile = Ridge.new(x, y)
|
115
|
+
when :plains
|
116
|
+
new_tile = Plains.new(x, y)
|
117
|
+
when :sea
|
118
|
+
new_tile = Sea.new(x, y)
|
119
|
+
when :forest
|
120
|
+
new_tile = Forest.new(x, y)
|
121
|
+
end
|
122
|
+
@tiles[x][y] = new_tile
|
123
|
+
end
|
124
|
+
|
125
|
+
# builds given building on given location, and updates building count
|
126
|
+
# does not check tile compatability
|
127
|
+
# does check for empty tile
|
128
|
+
def build_on_tile(tile , building)
|
129
|
+
if !tile.built_on
|
130
|
+
|
131
|
+
tile.build(BUILDABLE[building.to_sym])
|
132
|
+
@buildings[building.to_sym] += 1
|
133
|
+
if building.to_sym == :dragon
|
134
|
+
puts UiHandler::WIN
|
135
|
+
exit
|
136
|
+
end
|
137
|
+
else # This shouldn't happen normally
|
138
|
+
puts "There's already a building here"
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
# debugging purpose print world function
|
144
|
+
def temp_print_world
|
145
|
+
puts "======================================="
|
146
|
+
@tiles.each do |row|
|
147
|
+
row.each do |tile|
|
148
|
+
print "#{tile.to_s}\t"
|
149
|
+
end
|
150
|
+
puts
|
151
|
+
end
|
152
|
+
puts "======================================="
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: demigod_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yuval
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: A learning project game, build your own island and unleash the dragons
|
42
|
+
from the dragon shrine!
|
43
|
+
email:
|
44
|
+
- yvw.bor@gmail.com
|
45
|
+
executables:
|
46
|
+
- demigod
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gitignore
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- bin/demigod
|
56
|
+
- demigodGame.gemspec
|
57
|
+
- lib/demigodGame.rb
|
58
|
+
- lib/demigodGame/Demigod.rb
|
59
|
+
- lib/demigodGame/GameData.rb
|
60
|
+
- lib/demigodGame/Tile.rb
|
61
|
+
- lib/demigodGame/UiHandler.rb
|
62
|
+
- lib/demigodGame/World.rb
|
63
|
+
- lib/demigodGame/version.rb
|
64
|
+
homepage: ''
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.2.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Build your own island and unleash the dragons!
|
88
|
+
test_files: []
|