summaryrefslogtreecommitdiffhomepage
path: root/samples/00_learn_ruby_optional
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2020-09-11 02:02:01 -0500
committerAmir Rajan <[email protected]>2020-09-11 02:02:57 -0500
commit33ec37b141e896b47ed642923fd33b0c658ae9fb (patch)
treea40d3e5d41beeb06508200078f6f26b0ee57d6a4 /samples/00_learn_ruby_optional
parent958cf43779d2bf528869e80511c4c4f2a433b2db (diff)
downloaddragonruby-game-toolkit-contrib-33ec37b141e896b47ed642923fd33b0c658ae9fb.tar.gz
dragonruby-game-toolkit-contrib-33ec37b141e896b47ed642923fd33b0c658ae9fb.zip
synced samples
Diffstat (limited to 'samples/00_learn_ruby_optional')
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/automation.rb120
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/main.rb317
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/license-for-sample.txt9
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_0.pngbin0 -> 12896 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_1.pngbin0 -> 2964 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_2.pngbin0 -> 3047 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_3.pngbin0 -> 2655 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_4.pngbin0 -> 2725 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_5.pngbin0 -> 2655 bytes
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/02_printing_to_the_console.txt31
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/03_strings.txt15
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/04_numbers.txt21
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/05_booleans.txt32
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/06_conditionals.txt114
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/07_looping.txt55
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/08_functions.txt69
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/09_powerful_arrays.txt210
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/main.rb3
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/repl.rb0
-rw-r--r--samples/00_learn_ruby_optional/00_intermediate_ruby_primer/license-for-sample.txt9
20 files changed, 1005 insertions, 0 deletions
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/automation.rb b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/automation.rb
new file mode 100644
index 0000000..014c14c
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/automation.rb
@@ -0,0 +1,120 @@
+# ==========================================================================
+# _ _ ________ __ _ _____ _____ _______ ______ _ _ _ _ _ _
+# | | | | ____\ \ / / | | |_ _|/ ____|__ __| ____| \ | | | | | |
+# | |__| | |__ \ \_/ / | | | | | (___ | | | |__ | \| | | | | |
+# | __ | __| \ / | | | | \___ \ | | | __| | . ` | | | | |
+# | | | | |____ | | | |____ _| |_ ____) | | | | |____| |\ |_|_|_|_|
+# |_| |_|______| |_| |______|_____|_____/ |_| |______|_| \_(_|_|_|_)
+#
+#
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# \ | /
+# \ | /
+# +
+#
+# If you are new to the programming language Ruby, then you may find the
+# following code a bit overwhelming. Come back to this file when you have
+# a better grasp of Ruby and Game Toolkit.
+#
+# What follows is an automations script # that can be run via terminal:
+# ./samples/00_beginner_ruby_primer $ ../../dragonruby . --eval app/automation.rb
+# ==========================================================================
+
+$gtk.reset
+$gtk.scheduled_callbacks.clear
+$gtk.schedule_callback 10 do
+ $gtk.console.set_command 'puts "Hello DragonRuby!"'
+end
+
+$gtk.schedule_callback 20 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 30 do
+ $gtk.console.set_command 'outputs.solids << [910, 200, 100, 100, 255, 0, 0]'
+end
+
+$gtk.schedule_callback 40 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 50 do
+ $gtk.console.set_command 'outputs.solids << [1010, 200, 100, 100, 0, 0, 255]'
+end
+
+$gtk.schedule_callback 60 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 70 do
+ $gtk.console.set_command 'outputs.sprites << [1110, 200, 100, 100, "sprites/dragon_fly_0.png"]'
+end
+
+$gtk.schedule_callback 80 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 90 do
+ $gtk.console.set_command "outputs.labels << [1210, 200, state.tick_count, 0, 255, 0]"
+end
+
+$gtk.schedule_callback 100 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 110 do
+ $gtk.console.set_command "state.sprite_frame = state.tick_count.idiv(4).mod(6)"
+end
+
+$gtk.schedule_callback 120 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 130 do
+ $gtk.console.set_command "outputs.labels << [1210, 170, state.sprite_frame, 0, 255, 0]"
+end
+
+$gtk.schedule_callback 140 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 150 do
+ $gtk.console.set_command "state.sprite_path = \"sprites/dragon_fly_\#{state.sprite_frame}.png\""
+end
+
+$gtk.schedule_callback 160 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 170 do
+ $gtk.console.set_command "outputs.labels << [910, 330, \"path: \#{state.sprite_path}\", 0, 255, 0]"
+end
+
+$gtk.schedule_callback 180 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 190 do
+ $gtk.console.set_command "outputs.sprites << [910, 330, 370, 370, state.sprite_path]"
+end
+
+$gtk.schedule_callback 200 do
+ $gtk.console.eval_the_set_command
+end
+
+$gtk.schedule_callback 300 do
+ $gtk.console.set_command ":wq"
+end
+
+$gtk.schedule_callback 400 do
+ $gtk.console.eval_the_set_command
+end
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/main.rb b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/main.rb
new file mode 100644
index 0000000..6822cf3
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/app/main.rb
@@ -0,0 +1,317 @@
+# ==========================================================================
+# _ _ ________ __ _ _____ _____ _______ ______ _ _ _ _ _ _
+# | | | | ____\ \ / / | | |_ _|/ ____|__ __| ____| \ | | | | | |
+# | |__| | |__ \ \_/ / | | | | | (___ | | | |__ | \| | | | | |
+# | __ | __| \ / | | | | \___ \ | | | __| | . ` | | | | |
+# | | | | |____ | | | |____ _| |_ ____) | | | | |____| |\ |_|_|_|_|
+# |_| |_|______| |_| |______|_____|_____/ |_| |______|_| \_(_|_|_|_)
+#
+#
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# |
+# \ | /
+# \ | /
+# +
+#
+# If you are new to the programming language Ruby, then you may find the
+# following code a bit overwhelming. This sample is only designed to be
+# run interactively (as opposed to being manipulated via source code).
+#
+# Start up this sample and follow along by visiting:
+# https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-primer.mp4
+#
+# It is STRONGLY recommended that you work through all the samples before
+# looking at the code in this file.
+# ==========================================================================
+
+class TutorialOutputs
+ attr_accessor :solids, :sprites, :labels, :lines, :borders
+
+ def initialize
+ @solids = []
+ @sprites = []
+ @labels = []
+ @lines = []
+ @borders = []
+ end
+
+ def tick
+ @solids ||= []
+ @sprites ||= []
+ @labels ||= []
+ @lines ||= []
+ @borders ||= []
+ @solids.each { |p| $gtk.args.outputs.reserved << p.solid }
+ @sprites.each { |p| $gtk.args.outputs.reserved << p.sprite }
+ @labels.each { |p| $gtk.args.outputs.reserved << p.label }
+ @lines.each { |p| $gtk.args.outputs.reserved << p.line }
+ @borders.each { |p| $gtk.args.outputs.reserved << p.border }
+ end
+
+ def clear
+ @solids.clear
+ @sprites.clear
+ @labels.clear
+ @borders.clear
+ end
+end
+
+def defaults
+ state.reset_button ||=
+ state.new_entity(
+ :button,
+ label: [1190, 68, "RESTART", -2, 0, 0, 0, 0].label,
+ background: [1160, 38, 120, 50, 255, 255, 255].solid
+ )
+ $gtk.log_level = :off
+end
+
+def tick_reset_button
+ return unless state.hello_dragonruby_confirmed
+ $gtk.args.outputs.reserved << state.reset_button.background
+ $gtk.args.outputs.reserved << state.reset_button.label
+ if inputs.mouse.click && inputs.mouse.click.point.inside_rect?(state.reset_button.background)
+ restart_tutorial
+ end
+end
+
+def seperator
+ @seperator = "=" * 80
+end
+
+def tick_intro
+ queue_message "Welcome to the DragonRuby GTK primer! Try typing the
+code below and press ENTER:
+
+ puts \"Hello DragonRuby!\"
+"
+end
+
+def tick_hello_dragonruby
+ return unless console_has? "Hello DragonRuby!"
+
+ $gtk.args.state.hello_dragonruby_confirmed = true
+
+ queue_message "Well HELLO to you too!
+
+If you ever want to RESTART the tutorial, just click the \"RESTART\"
+button in the bottom right-hand corner.
+
+Let's continue shall we? Type the code below and press ENTER:
+
+ outputs.solids << [910, 200, 100, 100, 255, 0, 0]
+"
+
+end
+
+def tick_explain_solid
+ return unless $tutorial_outputs.solids.any? {|s| s == [910, 200, 100, 100, 255, 0, 0]}
+
+ queue_message "Sweet!
+
+The code: outputs.solids << [910, 200, 100, 100, 255, 0, 0]
+Does the following:
+1. GET the place where SOLIDS go: outputs.solids
+2. Request that a new SOLID be ADDED: <<
+3. The DEFINITION of a SOLID is the ARRAY:
+ [910, 200, 100, 100, 255, 0, 0]
+
+ GET ADD X Y WIDTH HEIGHT RED GREEN BLUE
+ | | | | | | | | |
+ | | | | | | | | |
+outputs.solids << [910, 200, 100, 100, 255, 0, 0]
+ |_________________________________________|
+ |
+ |
+ ARRAY
+
+Now let's create a blue SOLID. Type:
+
+ outputs.solids << [1010, 200, 100, 100, 0, 0, 255]
+"
+
+ state.explain_solid_confirmed = true
+end
+
+def tick_explain_solid_blue
+ return unless state.explain_solid_confirmed
+ return unless $tutorial_outputs.solids.any? {|s| s == [1010, 200, 100, 100, 0, 0, 255]}
+ state.explain_solid_blue_confirmed = true
+
+ queue_message "And there is our blue SOLID!
+
+The ARRAY is the MOST important thing in DragonRuby GTK.
+
+Let's create a SPRITE using an ARRAY:
+
+ outputs.sprites << [1110, 200, 100, 100, 'sprites/dragon_fly_0.png']
+"
+end
+
+def tick_explain_tick_count
+ return unless $tutorial_outputs.sprites.any? {|s| s == [1110, 200, 100, 100, 'sprites/dragon_fly_0.png']}
+ return if $tutorial_outputs.labels.any? {|l| l == [1210, 200, state.tick_count, 255, 255, 255]}
+ state.explain_tick_count_confirmed = true
+
+ queue_message "Look at the cute little dragon!
+
+We can create a LABEL with ARRAYS too. Let's create a LABEL showing
+THE PASSAGE OF TIME, which is called TICK_COUNT.
+
+ outputs.labels << [1210, 200, state.tick_count, 0, 255, 0]
+"
+end
+
+def tick_explain_mod
+ return unless $tutorial_outputs.labels.any? {|l| l == [1210, 200, state.tick_count, 0, 255, 0]}
+ state.explain_mod_confirmed = true
+ queue_message "
+The code: outputs.labels << [1210, 200, state.tick_count, 0, 255, 0]
+Does the following:
+1. GET the place where labels go: outputs.labels
+2. Request that a new label be ADDED: <<
+3. The DEFINITION of a LABEL is the ARRAY:
+ [1210, 200, state.tick_count, 0, 255, 0]
+
+ GET ADD X Y TEXT RED GREEN BLUE
+ | | | | | | | |
+ | | | | | | | |
+outputs.labels << [1210, 200, state.tick_count, 0, 255, 0]
+ |______________________________________________|
+ |
+ |
+ ARRAY
+
+Now let's do some MATH, save the result to STATE, and create a LABEL:
+
+ state.sprite_frame = state.tick_count.idiv(4).mod(6)
+ outputs.labels << [1210, 170, state.sprite_frame, 0, 255, 0]
+
+Type the lines above (pressing ENTER after each line).
+"
+end
+
+def tick_explain_string_interpolation
+ return unless state.explain_mod_confirmed
+ return unless state.sprite_frame == state.tick_count.idiv(4).mod(6)
+ return unless $tutorial_outputs.labels.any? {|l| l == [1210, 170, state.sprite_frame, 0, 255, 0]}
+
+ queue_message "Here is what the mathematical computation you just typed does:
+
+1. Create an item of STATE named SPRITE_FRAME: state.sprite_frame =
+2. Set this SPRITE_FRAME to the PASSAGE OF TIME (tick_count),
+ DIVIDED EVENLY (idiv) into 4,
+ and then compute the REMAINDER (mod) of 6.
+
+ STATE SPRITE_FRAME PASSAGE OF HOW LONG HOW MANY
+ | | TIME TO SHOW IMAGES
+ | | | AN IMAGE TO FLIP THROUGH
+ | | | | |
+state.sprite_frame = state.tick_count.idiv(4).mod(6)
+ | |
+ | +- REMAINDER OF DIVIDE
+ DIVIDE EVENLY
+ (NO DECIMALS)
+
+With the information above, we can animate a SPRITE
+using STRING INTERPOLATION: \#{}
+which creates a unique SPRITE_PATH:
+
+ state.sprite_path = \"sprites/dragon_fly_\#{state.sprite_frame}.png\"
+ outputs.labels << [910, 330, \"path: \#{state.sprite_path}\", 0, 255, 0]
+ outputs.sprites << [910, 330, 370, 370, state.sprite_path]
+
+Type the lines above (pressing ENTER after each line).
+"
+end
+
+def tick_reprint_on_error
+ return unless console.last_command_errored
+ puts $gtk.state.messages.last
+ puts "\nWhoops! Try again."
+ console.last_command_errored = false
+end
+
+def tick_evals
+ state.evals ||= []
+ if console.last_command && (console.last_command.start_with?("outputs.") || console.last_command.start_with?("state."))
+ state.evals << console.last_command
+ console.last_command = nil
+ end
+
+ state.evals.each do |l|
+ Kernel.eval l
+ end
+rescue Exception => e
+ state.evals = state.evals[0..-2]
+end
+
+$tutorial_outputs ||= TutorialOutputs.new
+
+def tick args
+ $gtk.log_level = :off
+ defaults
+ console.show
+ $tutorial_outputs.clear
+ $tutorial_outputs.solids << [900, 37, 480, 700, 0, 0, 0, 255]
+ $tutorial_outputs.borders << [900, 37, 380, 683, 255, 255, 255]
+ tick_evals
+ $tutorial_outputs.tick
+ tick_intro
+ tick_hello_dragonruby
+ tick_reset_button
+ tick_explain_solid
+ tick_explain_solid_blue
+ tick_reprint_on_error
+ tick_explain_tick_count
+ tick_explain_mod
+ tick_explain_string_interpolation
+end
+
+def console
+ $gtk.console
+end
+
+def queue_message message
+ $gtk.args.state.messages ||= []
+ return if $gtk.args.state.messages.include? message
+ $gtk.args.state.messages << message
+ last_three = [$gtk.console.log[-3], $gtk.console.log[-2], $gtk.console.log[-1]].reject_nil
+ $gtk.console.log.clear
+ puts seperator
+ $gtk.console.log += last_three
+ puts seperator
+ puts message
+ puts seperator
+end
+
+def console_has? message
+ console.log.map(&:upcase).include? "#{message.upcase}\n"
+end
+
+def restart_tutorial
+ $tutorial_outputs.clear
+ $gtk.console.log.clear
+ $gtk.reset
+ puts "Starting the tutorial over!"
+end
+
+def state
+ $gtk.args.state
+end
+
+def inputs
+ $gtk.args.inputs
+end
+
+def outputs
+ $tutorial_outputs
+end
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/license-for-sample.txt b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/license-for-sample.txt
new file mode 100644
index 0000000..100dcec
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/license-for-sample.txt
@@ -0,0 +1,9 @@
+Copyright 2019 DragonRuby LLC
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_0.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_0.png
new file mode 100644
index 0000000..fb179af
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_0.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_1.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_1.png
new file mode 100644
index 0000000..8cfe531
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_1.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_2.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_2.png
new file mode 100644
index 0000000..cb462e1
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_2.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_3.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_3.png
new file mode 100644
index 0000000..04c4977
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_3.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_4.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_4.png
new file mode 100644
index 0000000..b29fa3d
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_4.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_5.png b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_5.png
new file mode 100644
index 0000000..99f4e74
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_beginner_ruby_primer/sprites/dragon_fly_5.png
Binary files differ
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/02_printing_to_the_console.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/02_printing_to_the_console.txt
new file mode 100644
index 0000000..dd86367
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/02_printing_to_the_console.txt
@@ -0,0 +1,31 @@
+# ====================================================================================
+# Commenting Code
+# ====================================================================================
+#
+# Prefixing text with a pound sign (#) is how you comment code in Ruby. Example:
+#
+# I am commented code. And so are the lines above.
+#
+# I you want more than a quick primer on Ruby, check out https://poignant.guide/. It's
+# an entertaining read. Otherwise, go to the next txt file.
+#
+# Follow along by visiting:
+# https://s3.amazonaws.com/s3.dragonruby.org/dragonruby-gtk-intermediate.mp4
+
+# ====================================================================================
+# Printing to the Console:
+# ====================================================================================
+#
+# Every time you save repl.rb file, DragonRuby runs the code within it. Copy this text
+# to repl.rb and save to see Hello World printed to the console.
+
+repl do
+ puts '* RUBY PRIMER: Printing to the console using the ~puts~ function.'
+ puts '===='
+ puts '======'
+ puts '================================'
+ puts 'Hello World'
+ puts '================================'
+ puts '======'
+ puts '===='
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/03_strings.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/03_strings.txt
new file mode 100644
index 0000000..34ea252
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/03_strings.txt
@@ -0,0 +1,15 @@
+# ====================================================================================
+# Strings
+# ====================================================================================
+#
+# Here is how you work with strings in Ruby. Take the text
+# in this file and paste it into repl.rb and save:
+
+repl do
+ puts '* RUBY PRIMER: strings'
+ message = "Hello World"
+ puts "The value of message is: " + message
+ puts "Any value can be interpolated within a string using \#{}."
+ puts "Interpolated message: #{message}."
+ puts 'This #{message} is not interpolated because the string uses single quotes.'
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/04_numbers.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/04_numbers.txt
new file mode 100644
index 0000000..dfdf04d
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/04_numbers.txt
@@ -0,0 +1,21 @@
+# ====================================================================================
+# Numerics
+# ====================================================================================
+#
+# Here is how you work with numbers in Ruby. Take the text
+# in this file and paste it into repl.rb and save:
+
+repl do
+ puts '* RUBY PRIMER: Fixnum and Floats'
+ a = 10
+ puts "The value of a is: #{a}"
+ puts "a + 1 is: #{a + 1}"
+ puts "a / 3 is: #{a / 3}"
+ puts ''
+
+ b = 10.12
+ puts "The value of b is: #{b}"
+ puts "b + 1 is: #{b + 1}"
+ puts "b as an integer is: #{b.to_i}"
+ puts ''
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/05_booleans.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/05_booleans.txt
new file mode 100644
index 0000000..2a9060f
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/05_booleans.txt
@@ -0,0 +1,32 @@
+# ====================================================================================
+# Booleans
+# ====================================================================================
+#
+# Here is how you work with numbers in Ruby. Take the text
+# in this file and paste it into repl.rb and save:
+
+repl do
+ puts '* RUBY PRIMER: TrueClass, FalseClass, NilClass (truthy / falsey values)'
+ puts "Anything that *isn't* false or nil is true."
+
+ c = 30
+ puts "The value of c is #{c}."
+
+ if c
+ puts "This if statement ran because c is truthy."
+ end
+
+ d = false
+ puts "The value if d is #{d}. The type for d is #{d.class}."
+
+ if !d
+ puts "This if statement ran because d is falsey, using the not operator (!)."
+ end
+
+ e = nil
+ puts "Nil is also considered falsey. The value of e is: #{e} (a blank string when printed). Which is of type #{e.class}."
+
+ if !e
+ puts "This if statement ran because e is nil and the if statement applied the NOT operator. !e yields a type of #{(!e).class}."
+ end
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/06_conditionals.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/06_conditionals.txt
new file mode 100644
index 0000000..8a0c172
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/06_conditionals.txt
@@ -0,0 +1,114 @@
+# ====================================================================================
+# Conditionals
+# ====================================================================================
+#
+# Here is how you create conditionals in Ruby. Take the text
+# in this file and paste it into repl.rb and save:
+
+repl do
+ puts "* RUBY PRIMER: Conditionals"
+end
+
+# ====================================================================================
+# if
+# ====================================================================================
+
+repl do
+ puts "** INFO: if statement"
+ i_am_one = 1
+ if i_am_one
+ puts "This was printed because i_am_one is truthy."
+ end
+end
+
+# ====================================================================================
+# if/else
+# ====================================================================================
+
+repl do
+ puts "** INFO: if/else statement"
+ i_am_false = false
+ if i_am_false
+ puts "This will NOT get printed because i_am_false is false."
+ else
+ puts "This was printed because i_am_false is false."
+ end
+end
+
+
+# ====================================================================================
+# if/elsif/else
+# ====================================================================================
+
+repl do
+ puts "** INFO: if/elsif/else statement"
+ i_am_false = false
+ i_am_true = true
+ if i_am_false
+ puts "This will NOT get printed because i_am_false is false."
+ elsif i_am_true
+ puts "This was printed because i_am_true is true."
+ else
+ puts "This will NOT get printed i_am_true was true."
+ end
+end
+
+# ====================================================================================
+# case
+# ====================================================================================
+
+repl do
+ puts "** INFO case statement"
+ i_am_one = 1 # change this value to see different results
+
+ case i_am_one
+ when 10
+ puts "the value of i_am_one is 10"
+ when 9
+ puts "the value of i_am_one is 9"
+ when 5
+ puts "the value of i_am_one is 5"
+ when 1
+ puts "the value of i_am_one is 1"
+ else
+ puts "Value wasn't cased."
+ end
+end
+
+# ====================================================================================
+# comparison operators
+# ====================================================================================
+
+repl do
+ puts "** INFO: Different types of comparisons"
+ if 4 == 4
+ puts "4 equals 4 (==)"
+ end
+
+ if 4 != 3
+ puts "4 does not equal 3 (!=)"
+ end
+
+ if 3 < 4
+ puts "3 is less than 4 (<)"
+ end
+
+ if 4 > 3
+ puts "4 is greater than 3 (>)"
+ end
+end
+
+# ====================================================================================
+# and/or conditionals
+# ====================================================================================
+
+repl do
+ puts "** INFO: AND, OR operator (&&, ||)"
+ if (4 > 3) || (3 < 4) || false
+ puts "print this if 4 is greater than 3 OR 3 is less than 4 OR false is true (||)"
+ end
+
+ if (4 > 3) && (3 < 4)
+ puts "print this if 4 is greater than 3 AND 3 is less than 4 (&&)"
+ end
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/07_looping.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/07_looping.txt
new file mode 100644
index 0000000..03c3d28
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/07_looping.txt
@@ -0,0 +1,55 @@
+# ====================================================================================
+# Looping
+# ====================================================================================
+#
+# Looping looks a whole lot different than other languages.
+# But it's pretty awesome when you get used to it.
+
+repl do
+ puts "* RUBY PRIMER: Loops"
+end
+
+# ====================================================================================
+# times
+# ====================================================================================
+
+repl do
+ puts "** INFO: ~Numeric#times~ (for loop)"
+ 3.times do |i|
+ puts i
+ end
+end
+
+# ====================================================================================
+# foreach
+# ====================================================================================
+
+repl do
+ puts "** INFO: ~Array#each~ (for each loop)"
+ array = ["a", "b", "c", "d"]
+ array.each do |char|
+ puts char
+ end
+
+ puts "** INFO: ~Array#each_with_index~ (for each loop)"
+ array = ["a", "b", "c", "d"]
+ array.each do |char, i|
+ puts "index #{i}: #{char}"
+ end
+end
+
+# ====================================================================================
+# ranges
+# ====================================================================================
+
+repl do
+ puts "** INFO: range block exclusive (three dots)"
+ (0...3).each do |i|
+ puts i
+ end
+
+ puts "** INFO: range block inclusive (two dots)"
+ (0..3).each do |i|
+ puts i
+ end
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/08_functions.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/08_functions.txt
new file mode 100644
index 0000000..9ad38de
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/08_functions.txt
@@ -0,0 +1,69 @@
+# ====================================================================================
+# Functions
+# ====================================================================================
+
+# The last statement of a function is implictly returned. Parenthesis for functions
+# are optional as long as the statement can be envaluated disambiguously.
+
+repl do
+ puts "* RUBY PRIMER: Functions"
+end
+
+# ====================================================================================
+# Functions single parameter
+# ====================================================================================
+
+repl do
+ puts "* INFO: Function with one parameter"
+
+ # function definition
+ def add_one_to n
+ n + 1
+ end
+
+ # Parenthesis are optional in Ruby as long as the
+ # parsing is disambiguous. Here are a couple of variations.
+ # Generally speaking, don't put parenthesis is you don't have to.
+
+ # Conventional Usage of Parenthesis.
+ puts add_one_to(3)
+
+ # DragonRuby's recommended use of parenthesis (inner function has parenthesis).
+ puts (add_one_to 3)
+
+ # Full parens.
+ puts(add_one_to(3))
+
+ # Outer function has parenthesis
+ puts(add_one_to 3)
+end
+
+# ====================================================================================
+# Functions with default parameter values
+# ====================================================================================
+
+repl do
+ puts "* INFO: Function with default value"
+ def function_with_default_value v = 10
+ v * 10
+ end
+
+ puts "Passing the argument three yields: #{function_with_default_value 3}"
+ puts "Passing no argument yields: #{function_with_default_value}"
+end
+
+# ====================================================================================
+# Nil default parameter value and ||= operator.
+# ====================================================================================
+
+repl do
+ puts "* INFO: Using the OR EQUAL operator (||=)"
+ def function_with_nil_default_with_local a = nil
+ result = a
+ result ||= "DEFAULT_VALUE_OF_A_IS_NIL_OR_FALSE"
+ "value is #{result}."
+ end
+
+ puts "Passing 'hi' as the argument yields: #{function_with_nil_default_with_local 'hi'}"
+ puts "Passing nil: #{function_with_nil_default_with_local}"
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/09_powerful_arrays.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/09_powerful_arrays.txt
new file mode 100644
index 0000000..9904686
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/09_powerful_arrays.txt
@@ -0,0 +1,210 @@
+# ====================================================================================
+# Arrays
+# ====================================================================================
+
+# Arrays are incredibly powerful in Ruby. Learn to use them well.
+
+repl do
+ puts "* RUBY PRIMER: ARRAYS"
+end
+
+# ====================================================================================
+# Enumerable ranges and .to_a
+# ====================================================================================
+
+repl do
+ puts "** INFO: Create an array with the numbers 1 to 10."
+ one_to_ten = (1..10).to_a
+ puts one_to_ten
+end
+
+# ====================================================================================
+# Finding elements
+# ====================================================================================
+
+repl do
+ puts "** INFO: Finding elements in an array using ~Array#find_all~."
+ puts "Create a new array that only contains even numbers from the previous array."
+
+ one_to_ten = (1..10).to_a
+ evens = one_to_ten.find_all do |number|
+ number % 2 == 0
+ end
+
+ puts evens
+end
+
+# ====================================================================================
+# Rejecting elements
+# ====================================================================================
+
+repl do
+ puts "** INFO: Removing elements in an array using ~Array#reject~."
+ puts "Create a new array that rejects odd numbers."
+
+ one_to_ten = (1..10).to_a
+ also_even = one_to_ten.reject do |number|
+ number % 2 != 0
+ end
+
+ puts also_even
+end
+
+# ====================================================================================
+# Array transform using the map function.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Creating new derived values from an array using ~Array#map~."
+ puts "Create an array that doubles every number."
+
+ one_to_ten = (1..10).to_a
+ doubled = one_to_ten.map do |number|
+ number * 2
+ end
+
+ puts doubled
+end
+
+# ====================================================================================
+# Combining array functions.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Combining ~Array#find_all~ along with ~Array#map~."
+ puts "Create an array that selects only odd numbers and then multiply those by 10."
+
+ one_to_ten = (1..10).to_a
+ odd_doubled = one_to_ten.find_all do |number|
+ number % 2 != 0
+ end.map do |odd_number|
+ odd_number * 10
+ end
+
+ puts odd_doubled
+end
+
+# ====================================================================================
+# Product function.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Create all combinations of array values using ~Array#product~."
+ puts "All two-item pairs of numbers 1 to 10."
+ one_to_ten = (1..10).to_a
+ all_combinations = one_to_ten.product(one_to_ten)
+ puts all_combinations
+end
+
+# ====================================================================================
+# Uniq and sort function.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Providing uniq values using ~Array#uniq~ and ~Array#sort~."
+ puts "All uniq combinations of numbers regardless of order."
+ puts "For example: [1, 2] is the same as [2, 1]."
+ one_to_ten = (1..10).to_a
+ uniq_combinations =
+ one_to_ten.product(one_to_ten)
+ .map do |unsorted_number|
+ unsorted_number.sort
+ end.uniq
+ puts uniq_combinations
+end
+
+# ====================================================================================
+# Example of an advanced array transform.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Advanced chaining. Combining ~Array's ~map~, ~find_all~, ~sort~, and ~sort_by~."
+ puts "All unique Pythagorean Triples between 1 and 100 sorted by area of the triangle."
+
+ one_to_hundred = (1..100).to_a
+
+ triples =
+ one_to_hundred.product(one_to_hundred).map do |width, height|
+ [width, height, Math.sqrt(width ** 2 + height ** 2)]
+ end.find_all do |_, _, hypotenuse|
+ hypotenuse.to_i == hypotenuse
+ end.map do |triangle|
+ triangle.map(&:to_i)
+ end.uniq do |triangle|
+ triangle.sort
+ end.map do |width, height, hypotenuse|
+ [width, height, hypotenuse, (width * height) / 2]
+ end.sort_by do |_, _, _, area|
+ area
+ end
+
+ triples.each do |width, height, hypotenuse, _|
+ puts "(#{width}, #{height}, #{hypotenuse})"
+ end
+end
+
+# ====================================================================================
+# Example of an sorting.
+# ====================================================================================
+
+repl do
+ puts "** INFO: Implementing a custom sort function that operates on the ~Hash~ datatype."
+
+ things_to_sort = [
+ { type: :background, order: 1 },
+ { type: :foreground, order: 1 },
+ { type: :foreground, order: 2 }
+ ]
+ puts "*** Original array."
+ puts things_to_sort
+
+ puts "*** Simple sort using key."
+ # For a simple sort, you can use sort_by
+ results = things_to_sort.sort_by do |hash|
+ hash[:order]
+ end
+
+ puts results
+
+ puts "*** Custom sort."
+ puts "**** Sorting process."
+ # for a more complicated sort, you can provide a block that returns
+ # -1, 0, 1 for a left and right operand
+ results = things_to_sort.sort do |l, r|
+ sort_result = 0
+ puts "here is l: #{l}"
+ puts "here is r: #{r || "nil"}"
+ # if either value is nil/false return 0
+ if !l || !r
+ sort_result = 0
+ # if the type of "left" is background and the
+ # type of "right" is foreground, then return
+ # -1 (which means "left" is less than "right"
+ elsif l[:type] == :background && r[:type] == :foreground
+ sort_result = -1
+ # if the type of "left" is foreground and the
+ # type of "right" is background, then return
+ # 1 (which means "left" is greater than "right"
+ elsif l[:type] == :foreground && r[:type] == :background
+ sort_result = 1
+ # if "left" and "right"'s type are the same, then
+ # use the order as the tie breaker
+ elsif l[:order] < r[:order]
+ sort_result = -1
+ elsif l[:order] > r[:order]
+ sort_result = 1
+ # returning 0 means both values are equal
+ else
+ sort_result = 0
+ end
+ sort_result
+ end.to_a
+
+ puts "**** Sort result."
+ puts results
+end
+
+# ====================================================================================
+# Api documention for Array that is worth commiting to memory because arrays are so
+# awesome in Ruby: https://docs.ruby-lang.org/en/2.0.0/Array.html
+# ====================================================================================
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/main.rb b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/main.rb
new file mode 100644
index 0000000..96461aa
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/main.rb
@@ -0,0 +1,3 @@
+def tick args
+ args.outputs.labels << [640, 380, "Open repl.rb in the text editor of your choice and follow the document.", 0, 1]
+end
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/repl.rb b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/repl.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/repl.rb
diff --git a/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/license-for-sample.txt b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/license-for-sample.txt
new file mode 100644
index 0000000..100dcec
--- /dev/null
+++ b/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/license-for-sample.txt
@@ -0,0 +1,9 @@
+Copyright 2019 DragonRuby LLC
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.