burger_game 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/burger_game.rb +196 -0
- data/lib/customer_request.rb +123 -0
- data/lib/game_state.rb +61 -0
- data/lib/player_option.rb +86 -0
- data/lib/recipe.rb +67 -0
- data/lib/score_comparison.rb +67 -0
- data/lib/screen_message.rb +139 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2aeb621f3767f9fa5546de913ecc2664bdcb60b816d83cd2584324cac0d902a4
|
4
|
+
data.tar.gz: 894c119e9f395894d4894d783e291eb530261e6069ae227f6bd2ee10dee99efe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9352af04496853df1e5819959a03f3e5fcf2a1902d6e2f287c2be8e2e876cba2f62c1a0f1d70c02a279830883fc0f82398b14b22892e946de8af42cb7b8f72a3
|
7
|
+
data.tar.gz: e7a326175f54be8a31136ab7a0780cd9c6bb327e302a01c3253092f46e3ea7fdcd7c0d3325f206292e03c12dc44e126438e12fe0d9124ebf89ae831d1cbc1424
|
data/lib/burger_game.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
# For command line argument
|
2
|
+
require 'optparse'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
require_relative './game_state'
|
6
|
+
require_relative './screen_message'
|
7
|
+
require_relative './recipe'
|
8
|
+
require_relative './customer_request'
|
9
|
+
require_relative './player_option'
|
10
|
+
require_relative './score_comparison'
|
11
|
+
|
12
|
+
class BurgerGame
|
13
|
+
# Initialise
|
14
|
+
game_state = GameState.new
|
15
|
+
show_menu = Recipe.new
|
16
|
+
no_of_recipe = Recipe.all_recipes.length
|
17
|
+
screen = ScreenMessage.new
|
18
|
+
player_options = PlayerOption.new
|
19
|
+
customer = CustomerRequest.new
|
20
|
+
options = OpenStruct.new
|
21
|
+
|
22
|
+
# Handle command line argument
|
23
|
+
opt_parser = OptionParser.new do |opt|
|
24
|
+
opt.banner = "Usage: main.rb [options]"
|
25
|
+
|
26
|
+
opt.on("-h", "--help", "Print this Help menu for Ruby Burger Game.") do |arg|
|
27
|
+
puts opt
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
opt.on("-m", "--money TARGET_MONEY", screen.display_h_money) { |arg| options.target_money = arg }
|
32
|
+
|
33
|
+
opt.on("-r", "--reputation MAX_REPUTATION", screen.display_h_reputation) { |arg| options.max_reputation = arg }
|
34
|
+
end
|
35
|
+
|
36
|
+
# ERROR HANDLING for command line argument
|
37
|
+
begin
|
38
|
+
opt_parser.parse!
|
39
|
+
rescue OptionParser::InvalidOption => e
|
40
|
+
puts "You have entered an invalid option. Please check the available options in our Help menu '-h' or '--help'."
|
41
|
+
puts e.message
|
42
|
+
exit
|
43
|
+
rescue OptionParser::MissingArgument => e
|
44
|
+
puts "You have not entered the argument for your option."
|
45
|
+
puts e.message
|
46
|
+
exit
|
47
|
+
rescue OptionParser::ParseError => e
|
48
|
+
puts "Error when parsing argument."
|
49
|
+
puts e.message
|
50
|
+
exit
|
51
|
+
rescue => e
|
52
|
+
puts "Something went wrong."
|
53
|
+
puts "Error message: " + e.message
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
57
|
+
if (options.target_money)
|
58
|
+
if ((options.target_money.to_i >= 10 ) && (options.target_money.to_i <= 99 ))
|
59
|
+
puts "Change TARGET_MONEY to: $#{options.target_money}.00."
|
60
|
+
# Set target money in GameState
|
61
|
+
game_state.set_target_money(options.target_money.to_f)
|
62
|
+
else
|
63
|
+
puts screen.display_invalid("for TARGET_MONEY.")
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
if (options.max_reputation)
|
69
|
+
if ((options.max_reputation.to_i >= 1 ) && (options.max_reputation.to_i <= 10 ))
|
70
|
+
puts "Change MAX_REPUTATION to: #{options.max_reputation}."
|
71
|
+
# Set max reputation in GameState
|
72
|
+
game_state.set_max_reputation(options.max_reputation.to_i)
|
73
|
+
else
|
74
|
+
puts screen.display_invalid("for MAX_REPUTATION.")
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Ask user if they want to launch the game or exit
|
80
|
+
puts
|
81
|
+
launch_game = player_options.get_launch_game
|
82
|
+
|
83
|
+
# Exit command line if user select Exit
|
84
|
+
exit if launch_game === false
|
85
|
+
|
86
|
+
# Show welcome message
|
87
|
+
puts
|
88
|
+
puts screen.display_welcome
|
89
|
+
puts
|
90
|
+
screen.go_to_next
|
91
|
+
|
92
|
+
# Feature 1: Options to see instructions or to start the game
|
93
|
+
loop do
|
94
|
+
puts
|
95
|
+
start_game = player_options.get_start_game
|
96
|
+
|
97
|
+
break if start_game === true
|
98
|
+
|
99
|
+
# Show instructions
|
100
|
+
puts
|
101
|
+
puts screen.display_instructions
|
102
|
+
|
103
|
+
puts
|
104
|
+
screen.go_to_next
|
105
|
+
end
|
106
|
+
|
107
|
+
# Show prologue
|
108
|
+
puts
|
109
|
+
puts screen.display_prologue
|
110
|
+
|
111
|
+
puts
|
112
|
+
screen.go_to_next
|
113
|
+
|
114
|
+
# Loop game until WIN / GAME OVER
|
115
|
+
loop do
|
116
|
+
# Display current money and reputation status
|
117
|
+
puts game_state.display_game_state
|
118
|
+
|
119
|
+
puts
|
120
|
+
screen.go_to_next
|
121
|
+
|
122
|
+
# Feature 2: Formatted display for showing shop's menu
|
123
|
+
puts
|
124
|
+
puts "Ruby Burger's Menu"
|
125
|
+
puts
|
126
|
+
puts
|
127
|
+
puts "We have #{no_of_recipe} recipes. Try to remember the recipe name, the stack order of ingredients and the quantity. We will build the burger from bottom to top."
|
128
|
+
puts
|
129
|
+
|
130
|
+
# Loop to display all recipes
|
131
|
+
i = 0
|
132
|
+
loop do
|
133
|
+
puts show_menu.display_recipe(i)
|
134
|
+
|
135
|
+
puts
|
136
|
+
screen.go_to_next
|
137
|
+
|
138
|
+
i += 1
|
139
|
+
break if i > (no_of_recipe - 1)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Feature 3: Randomised customers with set of request (and associated preferences) and responses
|
143
|
+
# Display customer request
|
144
|
+
puts
|
145
|
+
puts "There is a customer in the queue..."
|
146
|
+
puts
|
147
|
+
# Randomise customer
|
148
|
+
customer_no = rand(0..9)
|
149
|
+
puts customer.display_request(customer_no)
|
150
|
+
puts
|
151
|
+
|
152
|
+
puts
|
153
|
+
screen.go_to_next
|
154
|
+
|
155
|
+
# Feature 4: Selectable options for list of ingredients, so no manual entry (typing) is needed.
|
156
|
+
# Quantity input as integer within a pre-set range.
|
157
|
+
# Display player's options
|
158
|
+
player_recipe = player_options.get_options
|
159
|
+
customer_recipe = customer.get_request(customer_no)
|
160
|
+
|
161
|
+
# Feature 5: Score calculation based on customer's request and preferences compared to player's input
|
162
|
+
# Calculate score
|
163
|
+
compare = ScoreComparison.new(player_recipe, customer_recipe)
|
164
|
+
score = compare.get_score
|
165
|
+
mood = compare.get_mood(score)
|
166
|
+
|
167
|
+
# Feautre 6: Get customers' responses from a JSON file
|
168
|
+
# Display customer's response
|
169
|
+
puts
|
170
|
+
puts "The customer wants to say something..."
|
171
|
+
puts
|
172
|
+
puts customer.display_response(customer_no, mood)
|
173
|
+
|
174
|
+
puts
|
175
|
+
screen.go_to_next
|
176
|
+
puts
|
177
|
+
|
178
|
+
# Update game state
|
179
|
+
compare.calculate_state(mood)
|
180
|
+
|
181
|
+
# Feature 7: Lose/win criteria based on reputation and money
|
182
|
+
# GAME OVER condition
|
183
|
+
if GameState.current_reputation == 0
|
184
|
+
puts screen.display_game_over
|
185
|
+
puts
|
186
|
+
break
|
187
|
+
end
|
188
|
+
|
189
|
+
# WIN condition
|
190
|
+
if GameState.current_money >= GameState.target_money
|
191
|
+
puts screen.display_win
|
192
|
+
puts
|
193
|
+
break
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative './recipe'
|
2
|
+
require_relative './screen_message'
|
3
|
+
|
4
|
+
class CustomerRequest
|
5
|
+
# ERROR HANDLING for reading files
|
6
|
+
begin
|
7
|
+
# Read customer_request.JSON file
|
8
|
+
customer_file = File.read('./lib/data/customer_request.json')
|
9
|
+
rescue Errno::ENOENT => e
|
10
|
+
puts "Could not find customer_request.json file. Please put customer_request.json in the 'data' directory."
|
11
|
+
puts e.message
|
12
|
+
exit
|
13
|
+
rescue => e
|
14
|
+
puts "Something went wrong."
|
15
|
+
puts "Error message: " + e.message
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
begin
|
20
|
+
# Read customer_response.JSON file
|
21
|
+
response_file = File.read('./lib/data/customer_response.json')
|
22
|
+
rescue Errno::ENOENT => e
|
23
|
+
puts "Could not find customer_response.json file. Please put customer_response.json in the 'data' directory."
|
24
|
+
puts e.message
|
25
|
+
exit
|
26
|
+
rescue => e
|
27
|
+
puts "Something went wrong."
|
28
|
+
puts "Error message: " + e.message
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
# Parse JSON file into array
|
33
|
+
@@all_customers = JSON.parse(customer_file)
|
34
|
+
@@customer_responses = JSON.parse(response_file)
|
35
|
+
|
36
|
+
# Collect customer names (array of strings)
|
37
|
+
# and customer recipe names request (array of strings)
|
38
|
+
# and customer ingredient changes (array of hashes)
|
39
|
+
# and customer requests text (array of strings)
|
40
|
+
# and customer preferences text (array of strings)
|
41
|
+
@@customer_names = []
|
42
|
+
@@customer_recipe_names = []
|
43
|
+
@@customer_ingredient_changes = []
|
44
|
+
@@customer_requests_text = []
|
45
|
+
@@customer_preferences_text = []
|
46
|
+
@@all_customers.each do |customer|
|
47
|
+
customer.each do |name, request|
|
48
|
+
@@customer_names << name
|
49
|
+
@@customer_recipe_names << request[0].keys[0]
|
50
|
+
@@customer_ingredient_changes << request[0].values[0][0]
|
51
|
+
@@customer_requests_text << request[1].values.join
|
52
|
+
@@customer_preferences_text << request[2].values.join
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Collect customer responses (array of arrays of hashes)
|
57
|
+
@@responses = []
|
58
|
+
@@customer_responses.each do |responses|
|
59
|
+
@@responses << responses.values
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_request(customer_no)
|
66
|
+
# Get all original recipes for base recipes (array of hashes)
|
67
|
+
base_recipes = Recipe.all_recipes
|
68
|
+
|
69
|
+
# Create customer recipe based on preference (array of hashes)
|
70
|
+
customer_recipe = []
|
71
|
+
requested_recipe_name = @@customer_recipe_names[customer_no]
|
72
|
+
requested_ingredient = @@customer_ingredient_changes[customer_no]
|
73
|
+
base_recipes.each do |recipe|
|
74
|
+
if recipe.key?(requested_recipe_name)
|
75
|
+
customer_recipe = recipe[requested_recipe_name].dup # => Not yet changed
|
76
|
+
# Change here
|
77
|
+
customer_recipe.each_with_index do |list, i|
|
78
|
+
if list.keys === requested_ingredient.keys
|
79
|
+
customer_recipe[i] = requested_ingredient
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Array of ingredient-quantity hashes
|
86
|
+
customer_recipe
|
87
|
+
end
|
88
|
+
|
89
|
+
def display_request(customer_no)
|
90
|
+
# Initialise frame for output formatting
|
91
|
+
dialog_box = ScreenMessage.new
|
92
|
+
customer_name = @@customer_names[customer_no]
|
93
|
+
customer_request_text = @@customer_requests_text[customer_no]
|
94
|
+
customer_preference_text = @@customer_preferences_text[customer_no]
|
95
|
+
|
96
|
+
# Put all string output lines in a variable
|
97
|
+
msg = ""
|
98
|
+
msg += customer_request_text
|
99
|
+
msg += "\n"
|
100
|
+
msg += customer_preference_text
|
101
|
+
|
102
|
+
# Format output using frame
|
103
|
+
dialog_box.msg_frame(customer_name, msg)
|
104
|
+
end
|
105
|
+
|
106
|
+
def display_response(customer_no, mood)
|
107
|
+
# Initialise frame for output formatting
|
108
|
+
dialog_box = ScreenMessage.new
|
109
|
+
customer_name = @@customer_names[customer_no]
|
110
|
+
customer_response = @@responses[customer_no]
|
111
|
+
|
112
|
+
# Put all string output lines in a variable
|
113
|
+
msg = ""
|
114
|
+
customer_response.each do |response|
|
115
|
+
response.each do |type, text|
|
116
|
+
msg += text if mood === type
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Format output using frame
|
121
|
+
dialog_box.msg_frame(customer_name, msg)
|
122
|
+
end
|
123
|
+
end
|
data/lib/game_state.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative './screen_message'
|
2
|
+
|
3
|
+
class GameState
|
4
|
+
# Constant variables to hold target money and max reputation for gameplay
|
5
|
+
TARGET_MONEY = 50.0
|
6
|
+
MAX_REPUTATION = 10
|
7
|
+
PAYMENT = 10.0
|
8
|
+
|
9
|
+
def initialize()
|
10
|
+
@@current_money = 0.0
|
11
|
+
@@current_reputation = MAX_REPUTATION
|
12
|
+
@@target_money = TARGET_MONEY
|
13
|
+
@@max_reputation = MAX_REPUTATION
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_target_money(cl_target_money)
|
17
|
+
@@target_money = cl_target_money
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_max_reputation(cl_max_reputation)
|
21
|
+
@@max_reputation = cl_max_reputation
|
22
|
+
@@current_reputation = @@max_reputation
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.target_money
|
26
|
+
@@target_money
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.max_reputation
|
30
|
+
@@max_reputation
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.current_money
|
34
|
+
@@current_money
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.current_reputation
|
38
|
+
@@current_reputation
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.update_money(payment)
|
42
|
+
@@current_money += payment
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.update_reputation(reputation)
|
46
|
+
@@current_reputation += reputation
|
47
|
+
end
|
48
|
+
|
49
|
+
def display_game_state
|
50
|
+
state_frame = ScreenMessage.new
|
51
|
+
spacing = ScreenMessage::SPACING
|
52
|
+
|
53
|
+
game_state = "MONEY / ".rjust((spacing / 2) + 1) + "Goal".ljust(spacing / 2)
|
54
|
+
game_state += "$#{sprintf('%.2f', @@current_money)} / ".rjust((spacing / 2) + 1) + "$#{sprintf('%.2f', @@target_money)}".ljust(spacing / 2) + "\n\n"
|
55
|
+
game_state += "+".colorize(:red) * spacing + "\n\n"
|
56
|
+
game_state += "REPUTATION / ".rjust((spacing / 2) + 1) + "Max Reputation".ljust(spacing / 2)
|
57
|
+
game_state += "#{@@current_reputation} / ".rjust((spacing / 2) + 1) + "#{@@max_reputation}".ljust(spacing / 2) + "\n\n "
|
58
|
+
|
59
|
+
state_frame.recipe_frame(game_state)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Import Gems
|
2
|
+
require 'tty-prompt'
|
3
|
+
|
4
|
+
require_relative './recipe'
|
5
|
+
|
6
|
+
class PlayerOption
|
7
|
+
def initialize
|
8
|
+
# Create instance of TTY Prompt
|
9
|
+
@prompt = TTY::Prompt.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_launch_game
|
13
|
+
player_response = @prompt.select("Do you want to launch the game?") do |menu|
|
14
|
+
menu.choice "Launch Game"
|
15
|
+
menu.choice "Exit"
|
16
|
+
end
|
17
|
+
|
18
|
+
if player_response == "Launch Game"
|
19
|
+
true
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_start_game
|
26
|
+
player_response = @prompt.select("What would you like to do?") do |menu|
|
27
|
+
menu.choice "View 'How to Play'"
|
28
|
+
menu.choice "Start Game"
|
29
|
+
end
|
30
|
+
|
31
|
+
if player_response == "Start Game"
|
32
|
+
true
|
33
|
+
else
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_options
|
39
|
+
# Get ingredient names (array of strings)
|
40
|
+
ingredient_names = []
|
41
|
+
Recipe.ingredient_lists[0].each do |list|
|
42
|
+
ingredient_names << list.keys.join
|
43
|
+
end
|
44
|
+
|
45
|
+
# Remove duplicate last value
|
46
|
+
ingredient_names.pop
|
47
|
+
|
48
|
+
# Variable to collect user input of item and quntity
|
49
|
+
player_recipe = []
|
50
|
+
|
51
|
+
# Loop prompt until player done selecting ingredients
|
52
|
+
loop do
|
53
|
+
# Loop through ingredients for player to choose
|
54
|
+
puts
|
55
|
+
item = @prompt.select("What would you like to add? (stack from bottom up)") do |item|
|
56
|
+
ingredient_names.each do |ingredient|
|
57
|
+
item.choice ingredient
|
58
|
+
end
|
59
|
+
|
60
|
+
# Option to finish selecting
|
61
|
+
item.choice "Done"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Exit loop if Done
|
65
|
+
break if item === "Done"
|
66
|
+
|
67
|
+
# Ask for quantity
|
68
|
+
puts "How many \"#{item}\"? (Enter 0 to 5)"
|
69
|
+
# Quantity input validation loop
|
70
|
+
while quantity = gets.strip do
|
71
|
+
# Must be a whole number 0 to 5
|
72
|
+
if (quantity =~ /^[0-5]$/)
|
73
|
+
break
|
74
|
+
else
|
75
|
+
puts "Please enter a number from 0 to 5:"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Collect player's selections
|
80
|
+
player_recipe << { item => quantity.to_i }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Array of ingredient-quantity hashes
|
84
|
+
player_recipe
|
85
|
+
end
|
86
|
+
end
|
data/lib/recipe.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Import Gems
|
2
|
+
require 'json'
|
3
|
+
require 'colorize'
|
4
|
+
|
5
|
+
require_relative './screen_message'
|
6
|
+
|
7
|
+
class Recipe
|
8
|
+
# ERROR HANDLING for reading files
|
9
|
+
begin
|
10
|
+
# Read recipe.JSON file
|
11
|
+
file = File.read('./lib/data/recipe.json')
|
12
|
+
rescue Errno::ENOENT => e
|
13
|
+
puts "Could not find recipe.json file. Please put recipe.json in the 'data' directory."
|
14
|
+
puts e.message
|
15
|
+
exit
|
16
|
+
rescue => e
|
17
|
+
puts "Something went wrong."
|
18
|
+
puts "Error message: " + e.message
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
# Parse JSON file into array
|
23
|
+
@@all_recipes = JSON.parse(file)
|
24
|
+
|
25
|
+
# Collect recipe names (array of strings)
|
26
|
+
# and ingredient lists (array of arrays of hashes)
|
27
|
+
@@recipe_names = []
|
28
|
+
@@ingredient_lists = []
|
29
|
+
@@all_recipes.each do |recipe|
|
30
|
+
@@recipe_names << recipe.keys[0]
|
31
|
+
recipe.each do |name, list|
|
32
|
+
@@ingredient_lists << list
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.all_recipes
|
40
|
+
all_recipes_copy = @@all_recipes.dup
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.recipe_names
|
44
|
+
@@recipe_names
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.ingredient_lists
|
48
|
+
@@ingredient_lists
|
49
|
+
end
|
50
|
+
|
51
|
+
def display_recipe(recipe_index)
|
52
|
+
recipe_box = ScreenMessage.new
|
53
|
+
spacing = ScreenMessage::SPACING
|
54
|
+
|
55
|
+
# Put all string output lines in a variable
|
56
|
+
recipe = @@recipe_names[recipe_index].center(spacing, " ").upcase + "\n\n" + "*".colorize(:blue) * spacing + "\n\n"
|
57
|
+
|
58
|
+
@@ingredient_lists[recipe_index].each do |list|
|
59
|
+
list.each do |item, quantity|
|
60
|
+
recipe += "#{item}".rjust(spacing * 0.6) + " x #{quantity}".ljust(spacing * 0.4) + "\n"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Format output using frame
|
65
|
+
recipe_box.recipe_frame(recipe)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative './customer_request'
|
2
|
+
require_relative './player_option'
|
3
|
+
require_relative './game_state'
|
4
|
+
|
5
|
+
class ScoreComparison
|
6
|
+
# Constant variable for max score and threshold
|
7
|
+
MAX_SCORE = 6
|
8
|
+
THRESHOLD = 3
|
9
|
+
|
10
|
+
def initialize(player_recipe, customer_recipe)
|
11
|
+
@player_recipe = player_recipe
|
12
|
+
@customer_recipe = customer_recipe
|
13
|
+
@score = 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_score
|
17
|
+
# Reverse customer recipe (stacked from bottom up)
|
18
|
+
r_customer_recipe = @customer_recipe.dup
|
19
|
+
r_customer_recipe.reverse!
|
20
|
+
|
21
|
+
# Compare recipe, score +1 for every correct ingredient-quantity (in order)
|
22
|
+
@player_recipe.each_with_index do |line, i|
|
23
|
+
line == r_customer_recipe[i] ? @score += 1 : @score
|
24
|
+
end
|
25
|
+
|
26
|
+
@score
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_mood(score)
|
30
|
+
# 6 happy
|
31
|
+
# 3-5 neutral
|
32
|
+
# <2 || >6 angry
|
33
|
+
if (score <= MAX_SCORE)
|
34
|
+
if (score == MAX_SCORE)
|
35
|
+
"happy"
|
36
|
+
elsif (score >= THRESHOLD)
|
37
|
+
"neutral"
|
38
|
+
else
|
39
|
+
"angry"
|
40
|
+
end
|
41
|
+
else
|
42
|
+
"angry"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def calculate_state(mood)
|
47
|
+
max_reputation = GameState.max_reputation
|
48
|
+
reputation = GameState.current_reputation
|
49
|
+
payment = GameState::PAYMENT
|
50
|
+
|
51
|
+
if mood == "happy"
|
52
|
+
GameState.update_money(payment)
|
53
|
+
if reputation < max_reputation
|
54
|
+
GameState.update_reputation(1)
|
55
|
+
end
|
56
|
+
elsif mood == "neutral"
|
57
|
+
GameState.update_money(payment / 2)
|
58
|
+
else
|
59
|
+
GameState.update_reputation(-1)
|
60
|
+
end
|
61
|
+
|
62
|
+
money = GameState.current_money
|
63
|
+
reputation = GameState.current_reputation
|
64
|
+
|
65
|
+
return money, reputation
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# Import Gems
|
2
|
+
require 'tty-box'
|
3
|
+
require 'tty-screen'
|
4
|
+
require 'tty-prompt'
|
5
|
+
|
6
|
+
class ScreenMessage
|
7
|
+
# Constant variable for display formatting space
|
8
|
+
SPACING = 30
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
end
|
12
|
+
|
13
|
+
def display_h_money
|
14
|
+
msg = "Change TARGET_MONEY.\n\t\t\t\t\tThe lower the value, the easier to WIN.\n\t\t\t\t\tDefault is 50. Enter number 10 to 99.\n\t\t\t\t\tUsage example: -m 10"
|
15
|
+
end
|
16
|
+
|
17
|
+
def display_h_reputation
|
18
|
+
msg = "Change MAX_REPUTATION.\n\t\t\t\t\tThe lower the value, the easier to GAME OVER.\n\t\t\t\t\tDefault is 10. Enter number 1 to 10.\n\t\t\t\t\tUsage example: -r 2"
|
19
|
+
end
|
20
|
+
|
21
|
+
def display_invalid(input = "")
|
22
|
+
msg = "You have entered an invalid value #{input}\nPlease enter the value in a valid format. Use -h or --help to view Help menu.\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def go_to_next
|
26
|
+
# Create instance of TTY Prompt
|
27
|
+
prompt = TTY::Prompt.new
|
28
|
+
|
29
|
+
prompt.select("Press enter to continue.", %w(Next))
|
30
|
+
end
|
31
|
+
|
32
|
+
# Method for displaying message frame
|
33
|
+
def msg_frame(title, msg, height = 10)
|
34
|
+
msg_box = TTY::Box.frame({
|
35
|
+
enable_color: true, # force to always color output
|
36
|
+
width: 150,
|
37
|
+
height: height,
|
38
|
+
align: :center,
|
39
|
+
padding: 3,
|
40
|
+
style: {
|
41
|
+
border: {
|
42
|
+
fg: :white
|
43
|
+
}
|
44
|
+
},
|
45
|
+
border: :thick,
|
46
|
+
title: {
|
47
|
+
top_left: title
|
48
|
+
}
|
49
|
+
}) do
|
50
|
+
msg
|
51
|
+
end
|
52
|
+
|
53
|
+
msg_box
|
54
|
+
end
|
55
|
+
|
56
|
+
# Method for displaying recipe frame
|
57
|
+
def recipe_frame(recipe)
|
58
|
+
recipe_box = TTY::Box.frame({
|
59
|
+
enable_color: true, # force to always color output
|
60
|
+
width: SPACING + 10,
|
61
|
+
align: :center,
|
62
|
+
padding: 3,
|
63
|
+
style: {
|
64
|
+
border: {
|
65
|
+
fg: :white
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}) do
|
69
|
+
recipe
|
70
|
+
end
|
71
|
+
|
72
|
+
recipe_box
|
73
|
+
end
|
74
|
+
|
75
|
+
def display_welcome
|
76
|
+
title = " WELCOME "
|
77
|
+
msg = "Hello there... Welcome to Ruby Burger!\n\n\n~ END ~"
|
78
|
+
height = 13
|
79
|
+
|
80
|
+
# Format output using frame
|
81
|
+
msg_frame(title, msg, height)
|
82
|
+
end
|
83
|
+
|
84
|
+
def display_instructions
|
85
|
+
title = " HOW TO PLAY "
|
86
|
+
msg = "Instructions:\n\n1. When shop's Menu is displayed, memorise burger names, ingredients and quantity needed, and ingredients stack order.\n\n2. Customer's request will consists of the name of the burger, and custom preferences, such as 'no sauce' or 'extra 1 patty'.\n\n3. Enter ingredient and quantity needed in order, from bottom of the stack to the top.\n\n4. Keep customers happy and earn money to meet the target (You Win).\n\n5. Be careful not to make the customer angry and let your reputation get to 0 (Game Over).\n\n\n~ END ~"
|
87
|
+
height = 23
|
88
|
+
|
89
|
+
# Format output using frame
|
90
|
+
msg_frame(title, msg, height)
|
91
|
+
end
|
92
|
+
|
93
|
+
def display_prologue
|
94
|
+
title = " PROLOGUE "
|
95
|
+
msg = "Ruby Burger is dedicated in fulfilling the ever growing customers' demand of customised and personalised burgers.\n\nOur job is to build a burger following our shop's Menu recipes, while adjusting into different customers' preferences.\n\n In the next scene, we will memorise our Menu and recipes.\n\nHint: Memorise burger names, ingredients and quantity needed, and ingredients stack order. Build burger from bottom up. Enter ingredients from the bottom of the stack to the top as seen in the recipes.\n\n\n~ END ~"
|
96
|
+
height = 19
|
97
|
+
|
98
|
+
# Format output using frame
|
99
|
+
msg_frame(title, msg, height)
|
100
|
+
end
|
101
|
+
|
102
|
+
def display_win
|
103
|
+
title = " YOU WIN "
|
104
|
+
msg = "Ruby Burger has reached its goal!\n\nAll thanks to you and your brilliant burger stacking skill.\nNow is time to celebrate and give yourself a reward..." + "\n\n"
|
105
|
+
msg += "A burger... and chips!" + "\n\n"
|
106
|
+
|
107
|
+
msg += " |\\ /| /|_/|" + "\n"
|
108
|
+
msg += " |\\||-|\\||-/|/|" + "\n"
|
109
|
+
msg += " \\\\|\\|//||///" + "\n"
|
110
|
+
msg += " _..----.._ |\\/\\||//||||" + "\n"
|
111
|
+
msg += " .' o '. |||\\\\|/\\\\ ||" + "\n"
|
112
|
+
msg += " / o o \\ | './\\_/.' |" + "\n"
|
113
|
+
msg += " |o o o| | |" + "\n"
|
114
|
+
msg += " /'-.._o __.-'\\ | |" + "\n"
|
115
|
+
msg += " \\ ````` / | |" + "\n"
|
116
|
+
msg += " |``--........--'`| '.______.'" + "\n"
|
117
|
+
msg += "\\ / " + "\n"
|
118
|
+
msg += "jgs `'----------'` " + "\n\n"
|
119
|
+
|
120
|
+
msg += "-- all ASCII artwork copyrighted ©1996-01 -- Joan G. Stark -- All Rights Reserved --" + "\n\n"
|
121
|
+
msg += "\n\n\n~ END ~"
|
122
|
+
|
123
|
+
height = 35
|
124
|
+
|
125
|
+
# Format output using frame
|
126
|
+
msg_frame(title, msg, height)
|
127
|
+
end
|
128
|
+
|
129
|
+
def display_game_over
|
130
|
+
title = " GAME OVER "
|
131
|
+
msg = "Oh no! Everyone is leaving because you didn't stack the right burgers!\n\nOwning a burger shop, especially a Ruby one, is tough.\nYou need to practice hard (or just use the handicap ARGV in command line, read the instruction in the installation guide in README.md).\n\nDon't give up! You can always try again next time!" + "\n\n"
|
132
|
+
msg += "You are lucky this is just a game..."
|
133
|
+
msg += "\n\n\n~ END ~"
|
134
|
+
height = 20
|
135
|
+
|
136
|
+
# Format output using frame
|
137
|
+
msg_frame(title, msg, height)
|
138
|
+
end
|
139
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: burger_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jessica Gozali
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-22 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple text-based Ruby terminal game, that simulates a burger shop,
|
14
|
+
where you need to build the meal for the customers with different requests and preferences.
|
15
|
+
email: gcas012115@coderacademy.edu.au
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- "./lib/burger_game.rb"
|
21
|
+
- "./lib/customer_request.rb"
|
22
|
+
- "./lib/game_state.rb"
|
23
|
+
- "./lib/player_option.rb"
|
24
|
+
- "./lib/recipe.rb"
|
25
|
+
- "./lib/score_comparison.rb"
|
26
|
+
- "./lib/screen_message.rb"
|
27
|
+
homepage: https://rubygems.org/gems/burger_game
|
28
|
+
licenses:
|
29
|
+
- GPL-3.0
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.1.6
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: A Ruby Burger Game
|
50
|
+
test_files: []
|