7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
1/16
LESSON #2: UNDERSTANDING OBJECTS
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
TABLE OF CONTENTS
1. Comparing, Conditionals and Loops ............................................................................................2
Ruby Control Structures and Operators ............................................................................................. 2
2. The REAL Truth About Objects .....................................................................................................3
Classes and the Ruby Class Hierarchy ............................................................................................. 3
Object Instances, Instance Variables and Methods ........................................................................... 6
5. Lesson 2 Review Challenge .........................................................................................................16
Lesson 2 Review Challenge ............................................................................................................ 16
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
2/16
2
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
1. COMPARING, CONDITIONALS AND LOOPS
RUBY CONTROL STRUCTURES AND OPERATORS
Programming is an art. The subtle techniques that we use give us the feeling of satisfaction and meaning
behind the program in which we are building, just like an artist gets satisfaction from genius art. There are no
boundaries to the types of art that we can create, granted we understand what type of art we can make and
the tools we can use to create the art. For instance, some artists create art through realism, making the art
seem as visually natural as possible. Other artists create art through surrealism and abstraction hence their art
has a degree of independence from the real world. Although loosely coined, it is the conceptually the same
with programming. When we program, we are essentially creating abstract representations of real world
objects. So as programmers, we must control the way he creates his programs. Welcome to the (virtual) world
of control structures!
Control structures (also known as control flow) refers to the systematic order of the execution of a set of
statements. Control structures, by definition, create a lexical scope when programming and regulate how
properties within the scope are manipulated. A lexical scope is simply another name for the immediate localenvironment in the surrounding area. Another term forproperties is called members, which is widely used
and a conventionally valid synonym. We often use control structures to compare expressions against one
another. To do this we must understand some important operators in Ruby.
The = sign
A single = sign is used to assign the value on the rightto the object on the left. This is called the assignment
operator.
The == sign
A double == sign is used to compare the value on the rightto the object on the left. This is called comparison
operator, which is used in control structures.
The === sign
A triple === sign is used to check for equalitythat the value on the rightis the exactsame object as the one on
the left. This is called equality operator, which is also used in control structures.
a = 10
test = This is a test
iftest == This is a test
print Success
end
iftrue === true
print Both are true
end
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
3/16
3
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
It is important to know that the proper control structure to use ultimately depends on the type of objects
being evaluated and the programmers desired results. Control structures begin with the name of the
structure and end with the end keyword. There are, however, more advanced control structures that are
implemented which well discuss later. The syntax for creating basic control structures (conditional branches
and loops) are shown below:
Conditional Branches Expressions or conditions that are evaluated.
if / if-else Checks ifone or more conditions are met. else is an optional branch.
unlessThe exact opposite of if. The code-block will only be executed if the expression is false. There is no
elsif or elsunless.
if-elsif-else A three branch conditional block that can evaluate multiple conditions.
ternary operator The ternary operator is simply a short version of evaluating an expression and executing a
code (think of it as a shorter version of the if/else statement). The syntax is:
result = (condition) ? (expression-if-true) : (expression-if-false)
a = 10
ifa == 10
print A is 10
else
print No answer
a = 10
unless a == 5
print A is 10 # This will print A is 10 because the expression a== 5 is false
a = 10
ifa == 4
print A is 4
elsifa == 7
print A is 7
else
print A is 10
end
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
4/16
4
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Read it like this. The expression on the left of the : will be ran if the result equals the condition otherwise the
condition on the right of the : will be ran.
Use this with caution as it can get hard to read if you have large code. Also ? has another use so ambiguity
can be a problem in some cases. It is wise to use parenthesis for executing your code.
case The case conditional is another way to write an if-elsif-else statement (with more than one elsif). An
object is given a case and when a condition is met then something happens.
Loops Loops are blocks of code that are consecutively executed until a condition is met.
while The code block will be executed over and over again so long as the expression evaluates true.
untilThe code block will be executed over and over again so long as the expression evaluates false. When
the expression is evaluated to true the loop ends. It is the opposite of while.
Often times we will want to return something from a control structure or method and store that value in some
variable. We use the return keyword to return the values from control structures.
Note: To check more than one expression at a time in a control structure use the and (&&) and or (||)
operators between expressions.
true = true ? (puts 'a'): (puts 'b') #=> prints "a"
case a
when 0..4 then puts "#{a} is less than 5"when 5 then puts "#{a} equals 5"when 5..10 then puts "#{a} is greater than 5"else puts "unexpected value #{a}" # If a is bigger than 10 or negative.
end
while # if this is true# # do code
end
until # if this is false# # do code
end
if a = 5return true
end
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
5/16
5
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Lets do an exercise on control structures and comparison.
1. Open your OS command line prompt.
2. Navigate to the folder where you downloaded all the files folder that came with this lesson.
3. In the command prompt type: ruby files/control_structures.rb it will print the word No
4. Open control_structures.rb in your text editor and fix the code. Your job in this exercise is to make the
program print the word Thanks by fixing the 6 problems.5. After you have completed the exercise open files/answers/control_structures.rb for answers and
explanations.
control_structures.rb teaches you:
Conditional branches and nested conditional statements
Critical thinking and error checking
break keyword
Conditional branches and nested conditional statements Programming involves loops and conditions. There
is just no way around this truth. If you already come from a programming background then you understand
how crucial it is to understand control structures, which is why I taught them in this lesson, even if you may
have already known this. Control structures can be nested inside of each other, which is the basis of how
routing in a program is handled. You must understand conditional statements and when to use the
appropriate ones to have a bug free program.
Critical thinking and error checking The comments provided in the files are meant to be read for clarification.
Although slightly verbose, it is clear explanation of what is happening between the problems. This exercise is
intended to get you to think about how youre coding (and not necessarily why youre coding.).
2. THE REAL TRUTH ABOUT OBJECTS
CLASSES AND THE RUBY CLASS HIERARCHY
A very nice diagram of the current Ruby class hierarchy can be found here:
http://objectgraph.rubyforge.org/neatoOG.html
It is not necessary to know this diagram for now, but it explains one good concept Ive been waiting to solidify
in your brain. In its strictest sense, nearly everything in Ruby is an object (and treated as such). But what is an
object really? What is this abstract idea I keep mentioning? Lets look at how to make an object and why its soimportant in Ruby.
In order to make an object we must make a class of that object. A class is set of coding instructions that
defines an object andhow it should be presented in your ruby program. That class definition of an objectcan
then be instantiated(created) throughout our program and manipulated and interact with other objects
within our program. Every custom built class is an instance of the Class class in the Ruby class hierarchy.
Now armed with this knowledge, lets define a class and instantiate an object of that class.
http://objectgraph.rubyforge.org/neatoOG.htmlhttp://objectgraph.rubyforge.org/neatoOG.html7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
6/16
6
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
OBJECT INSTANCES, VARIABLES, AND METHODS
To create a new class we use the class keyword followed by a whitespace the name of the class. The first
letter of the class name must be capitalized. We then use the end keyword to explicitly close our class. We
can then assign a variable to the class by calling that classs new method (which instantiates the initial state
of an instance of that object). In our example above myVariable is an instance ofMyNewClass (i.e. an object).
All of the things that this class will do goes between class and endkeywords. Lets look at what those things
can be:
Variables Local variables, instance variables, class variables, global variables
Methods class methods, instance methods, inherited methods
The concept of sending/receiving messages
Constants
Some other things we will wait on explaining
VariablesWeve already defined what local variables are inLesson 1and we understand them pretty clearly
now. A refresher is that local variables are basic containers that can be used to store a value and can only be
manipulated within the scope in which it was declared inside of. A class variable can be used by a child of the
its parent class (more on this much later). A global variable can be used throughout the entire program (it is
not limited by scope at all. A global variable can be accessed anywhere and is seldom used). But what is an
instance variable? An instance variable is a variable defined in a class that stores a value and is associated
onlyto the current instance of the class (the variable that was assigned the new class again that particular
object). Below is an example using local and instance variables and two instances of a custom Person class.
classMyNewClass
#Coding instructions
end
myVariable = MyNewClass.new # an object instance of MyNewClass
classPerson
attr_accessor :name # allows @name to be read and written
def initialize(param) # Consider this the .new method w/ 1 parameter@name = param # instance variable is now equal to local variable
end
end
me = Person.new(Kadeem) # one instance object .new calls initialize method w/ 1 argument
you = Person.new(Your Name) # another instance w/ 1 argument
puts me.name # calls this instances name => prints Kadeemputs you.name # calls this instances name => prints Your Name
http://bit.ly/13NCsQrhttp://bit.ly/13NCsQrhttp://bit.ly/13NCsQrhttp://bit.ly/13NCsQr7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
7/16
7
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
To define an instance variable we declare a name preceded by an @ symbol. You use the same naming
conventions as a local variable. In the above example @name is an instance variable. This means that every
instance of a Person object that we create will have @name attribute that we can access.
attr_accessor will be fairly new to you but it is extremely easy to understand. attr_accessor is a type of Ruby
syntactical sugar (which is just a fancy name for a way of Ruby understanding what youre really implying).
What attr_accessor means is that we want our class (Person) to have the ability to read and write to aninstance variable (@name). Now we have the ability to not only access a Persons @name but we also have
the ability to overwrite a Persons @name. If we only wanted to accessan instance variables value (i.e. allow
access to it from the outside world external access only) we declare attr_reader and if we only wanted to
write to an instance variable (i.e. deny all access to it from the outside world - internal access to the class only)
we declare attr_writer.In our example we want to read and write so we chose to use attr_accessor so at
any time later in our program we can overwrite @name for that particular instance of that Person object.
Things like variables are the called attributes of a class. They can also be used for other things which we will
learn later. We will skip constants, class variables and global variables for now and save them for another day.
Methods A method is a simply set of instructions inside of a class that you as a programmer define. That
method can then be invoked and called upon in your program. For the sake of comprehension, a methodis
the same thing as afunction in other languages. Most programmers argue that a methodis a function defined
inside of a class whereas afunctionis not defined in any class (perhaps floating in a main namespace).
Methods are the actions and behaviors that your class will perform. Methods can be custom built and also
overwritten (Yes you can manipulate the behavior of a default Ruby classs methods!). To create a method we
use the def keyword followed by the name of the method (lowercase convention) and an end keyword to
close it. When we create an instance (object) of our Person class we set the variable equal to Person.new.
.new is a method of Rubys Class class (see Ruby hierarchy ) that calls that classs initialize method.
Every class in Ruby has an initialize method. Even if we dontexplicitly define the initialize method, Ruby will
create one for us automatically (it will be empty of course). The purpose of the initialize method is to create
the initial state of the object instance. Once the initial state of the object has been completed we have an
instance of our object that is referenced by our variable (in our example me and you are the variables
where we are referencing two separate instances of the Person class).
Some methods are public to the entire program, but some can be private and protected (we will discuss scope
and types of methods in another lesson). By default all custom methods are made public and can be accessed
anywhere in the program.
Methods can also have parameters associated with them. Aparameteris aplaceholderthat is associated with
an argument when the method is invoked. It is used to setup variables in a method, but has no explicit value.
In our example param is a methodparameterand Kadeem and Your Name are method call arguments.
Parameters become local variables once an argument has been given when we call the method. Thus, our
method initialize now contains a local variable called param that it can use inside of itself.
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
8/16
8
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Lets do two exercises on classes, objects, variables, and methods.
1. Navigate to the folder where you downloaded all the files folder that came with this lesson.
2. In your command prompt open: ruby files/game.rb
3. You are going to play a fighting game with an AI computer opponent for the chance to win $1,000,000.
4. After you have completed the game open were going to go step-by-step below to build this game.
The code behind game.rb teaches you:
Creating a standalone ruby program
Classes, object instances and initialization
Instances variables and methods
How classes can interact with each other
Accessibility and scope
Loops and conditional statements
Interpolation
A brief introduction to Array objects
sample method
A verybrief introduction to regular expressions
Creating random numbers
Creating a nave system of artificial intelligence
Exiting a program
Well go step by step in how to build this program.
Part 1: The concepts in our game
The first part is just to understand what will be in our program. We want to create a game and somefighters
in the game. Armed with this knowledge we know we are going to build two separate classes. The concept of
what afighterwill be goes in a Fighter class and the concept of the game itself will go in a Game class.
Part 2: Control and characteristics of each class
Now that we know the objects that our game lets identify control and some of the characteristics of classes.
classFighter
# Defines a Fighter object
end
classGame
# Defines a Game object
end
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
9/16
9
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
We want to have our Game class to be the center of control in our game. That means that our Game class will
need two instances (objects) of our Fighter class and will control how those two instances interact with each
other. This means that our Game class must havepublic access to the behaviors and attributes (sometimes
called members) of the Fighter class. Thispublic access is considered a type of class scope. Scope deals with
access to the members of a class. We want our Game class to have access to everything about a Fighter class.
When we start our game and create two Fighters we want to set the initialstate of those Fighters. So what are
some of those initial characteristics of a Fighter? Lets give our Fighter class some attributes for our game.
So when we create a new Fighter we initialize aname, weapon, health and statuses. To the outside world the
name and weapon can onlybe read (and cannot be overwritten), while the health and statuses can be read
and overwritten because of the scope restrictions.
Next lets define some of custom behaviors of a Fighter class. These will be our Fighterpublic methods.
Our Fighter can attack. The damage ensued is determined by the Fighters @weapon, therefore were going to
give @weapon a case statement and generate the damage by a Random number between a range of numbers
multiplied by a damage_factor that is controlled by Game (and finally explicitly convert that number to an
integer using .to_i). Because the randomly generated number is the last expression evaluated in the attack
method, that number gets returned to the receiver of the attack method (of course this will be handled by
our Game).
classFighter
attr_reader :nameattr_reader :weaponattr_accessor :healthattr_accessor :defenselessattr_accessor :dead
def initialize(name, weapon)@name = name # Sets Fighter name@weapon = weapon # Sets Fighter weapon@health =50 # Sets Fighter health@defenseless =true # By default he is not defending@dead =false # By default he is not dead
end
#...def attack(damage_factor)
case @weaponwhen "Longsword" then (Random.rand(7...29) * damage_factor).to_iwhen "Crossbow" then (Random.rand(9...22) * damage_factor).to_iwhen "Hammer" then (Random.rand(1...39) * damage_factor).to_iwhen "Shotgun" then (Random.rand(4...22) * damage_factor).to_i
endend
#...
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
10/16
10
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Our Fighter can take damage from an attack. In our Game class, the receiver from the attack method (the
number returned from the attack method) becomes the amount argument when the took_damage method is
called. When a Fighter takes damage we want to subtract the amount from the fighters @health. We would
not be able to do this if we didnt have the overwriting capabilities we specified earlier. We also want to check
if that Fighters @health is now 0 or less than 0. If it is, then we set @health to 0 and change the state of the
Fighter object to @dead. Our Game class will check whether a Fighter is dead at the beginning of the next turn
and route the state of the game appropriately.
Our Fighter can defend against an attack. This small method simply changes the status of our Fighter object.
When our opponent Fighter attacks us while @defenseless is truewewill take maximum damage, but when
our opponent attacks us while @defenseless is falsewe will only take 1/3 damage. This is the damage_factor
we defined earlier. Of course, a Fighter cannot defend forever so at the beginning of the Fighters turn, we
will have our Game class set @defenseless back to trueevery time. This decision making will controlled, of
course, by the Game class.
Finally, our Fighter can heal himself. Because our Game class can access a Fighters @health we can explicitly
increase @health by a random amount. We also set the Fighters @health to 100 if it ever goes over 100
(otherwise we could heal forever!). We then end our Fighter class.
Thats it! Thats all we need to define our Fighter class. You just learned some important concepts about
instance variables (@), scope (public and private), and some other neat things (randomly generated numbers
and also Range objects). Next lets define our Game class.
#...def took_damage(amount)
@health -=amountif @health = 100
@health = 100end
end
end #END of Fighter class
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
11/16
11
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
We said earlier that our Game class will control (i.e. have access to) the Fighter class. This means that our
Game class will have to create two instance objects of the Fighter class (one will be us, the other will be a
computer opponent).
We dont want anyone to access the behaviors of our Game class, so all of the methods inside of our Game
class will be private and inaccessible anywhere in our program (aside from initialize which is always public).
This is an important concept because we wouldnt want to directly alter the state ofthe Game by calling someof its methods, we want the Game to control itself (a concept I like to call self-containment).
One more thing about our Game class. For the sake of comprehension we will avoid handling Exceptions
(errors) in our program for now. We will spend an entire lesson on this later. Our program wont have any
bugs, but as a rule of thumb, once we cover exceptions and error handling you should implement them.
Lets build our Game class. We need to be able to create andmanipulate two Fighter object instances. We also
need a way to store which Fighter object has the current turn. Additionally, although not required, we should
specify the actions a Fighter can invoke in our Game and be able to read them (not overwrite them).
We now have the initial state of our Game. When Game.newis called, we need the name and weapon that
player 1 has entered. We want our Game to be able to read @actions that a Fighter can take. We also want to
store the weapons that a Fighter can choose (used for player 2 computer only). Both collections are stored in
Array objects ( using [ ] braces ) respectively. We then create a new Fighter called @player1 with the player 1s
name and weapon and also a @player2 object with a name ofBob the Grandmaster and a random weapon
from the weapons Array collection (weapons.sample does this for us). Remember that @player1 and
@player2 are now newly created object instances of our Fighter class that can be used inside our Game class.Finally after we have created our objects we call our (private) opening_sequence method of our Game.
The methods below this private declaration are now internally accessible to the Game class, but inaccessible
to the outside world (i.e. Fighter class cannot access these methods.). Lets start with opening_sequence.
classGame
attr_accessor :player1attr_accessor :player2attr_accessor :current_turnattr_reader :actions
def initialize(player1_name, player1_weapon)@current_turn = nil@actions = ["Attack", "Defend", "Heal", "Nothing"]weapons =["Longsword", "Crossbow", "Hammer", "Shotgun"]@player1 =Fighter.new(player1_name, player1_weapon)@player2 =Fighter.new("Bob the Grandmaster", weapons.sample)opening_sequence
end
#..private
#..
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
12/16
12
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Here we have defined our games opening sequence. At this point when this method is called we have fully
created our two Fighters as @player1 and @player2 objects. We print an introduction that the player will see
and supply gets in intermediate lines so that the player can read the lines. We also want to space out our
lines a little for readability so we need to put carriage returns. \n means newline in a string. We also use
interpolation inside of our strings to access members of our object (in this case we want to access @player1s
name attribute and will be printed thanks to puts). We do interpolation in a string by using a unique syntaxlike so: #{ stuff_goes_here }. We can put expressions, method calls, variables, classes, roughly anything
inside of interpolated expressions. Next lets have our player flip a coin heads or tails to see who goes first in
our game. The user input is stored in the choice local variable all lowercase. That value is then passed as an
argument to the coin_toss method in our Game class which well define later. coin_toss will store the new
value of our Games attribute @current_turn. Because we have set the Games @current_turn (remember we
can access @current_turn anywhere in our Game class) we will then call our main Games loop update
method and start our game! So lets first define coin_toss and then our update method.
Here we define our coin_toss that method that has one parameter. It checks if the choice selected is heads
and sets @current_turn equal to @player1 object, otherwise sets @current_turn equal to @player2 object.We didnt have to explicitly set @current_turn here; Ruby always returns the last expression evaluated in the
method. We could have written the last line as @player1 or @player2 and set a @current_turn equal to the
coin_toss method call in our opening_sequence. I did it like this because I like to explicitly know what my
methods are really doing and their purpose which means that my coin_toss method returns nil. Either way is
fine, and it is simply a matter of taste. When you begin to write your own programs you will find the best
procedures for yourself. Great now we know who goes first in our game. Lets create our games main loop.
#...def opening_sequence
puts "\nWelcome to Fight Club, #{@player1.name}!"; gets;puts "\nFight your opponent for the chance to win $1,000,000!"; gets;puts "\nPress Ctrl + C at anytime to exit the fight."; gets;puts "\nLet's flip a coin to see who goes first!"; gets;puts "\nChoose heads or tails!"choice = gets.chomp.downcase
coin_toss(choice)gets; puts "\nLet's fight!"; gets;update
end#...
#...def coin_toss(choice)
if choice == "heads"puts "\nGot it! #{@player1.name}, you go first!"@current_turn = @player1
elseputs "\n#{@player2.name} goes first!"@current_turn = @player2
endend
#...
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
13/16
13
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
This is the main loop of our program. It is a custom method called update. This loop first checks if the@current_turn (@player1 or @player2) object has a @dead attribute that is true. If it is truewe call the
Gamesgameover method with two parameters (the (losing) Fighter object, and a method call to switch_turn
which returns the (winning) Fighter object). We have not defined the switch_turn method yet, but its purpose
is to simply return the opposite Fighter object. So gameover will have two arguments and we will define that
method a little later as well. If that @current_turns @dead attribute is set to falsewe reset the
@current_turns @defenseless attribute back to true(since it is currently that Fighters turn and hes still
alive). Then we have another condition (we call this nested conditional statements).
If the @current_turn object the same as (note the === sign)@player1 we print their name and the actions in
which they can perform and wait for user input and do that action by calling do_action, passing it the action
choice. If the turn object is the same as @player2 we print its @name (i.e. Bob the Grandmaster). We then
call do_action passing it a random action from the Games @actions. Because @player1 or @player2 has
called do_action we will want our do_action method to recall update after it is done. So lets define our
switch_turn method first and then our do_action afterwards.
Here is Games switch_turn method that simply (explicitly) assigns the new @current_turn object. We have to
be careful with it because we dont want to ruin the update method and state of the game. We will call the
switch_turn method when necessary (before the calls to the update method throughout our program).
#...def update
if @current_turn.dead == truegameover(@current_turn, switch_turn)
else@current_turn.defenseless = trueif @current_turn === @player1
puts "\n\n\n\n#{@current_turn.name}, it's your turn."
puts "\nWhat do you want to do? 1: #{@actions[0]} 2:#{@actions[1]} 3: #{@actions[2]} 4: #{@actions[3]}"choice = gets.chomp.capitalizedo_action(choice)
else @current_turn === @player2puts "\n\n\n\nIt's now #{@current_turn.name}'s turn";gets;puts do_action(@actions.sample); gets;
endend
end#...
#...def switch_turn
if @current_turn === @player1
@current_turn = @player2
else@current_turn = @player1
endend
#...
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
14/16
14
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
Here is our do_action method with one parameter. It maps the either @player1s user input choice to an
action or @player2s randomly selected choice from the update method. We give the choice a case and a
corresponding call to the Fighter objects helper classes. If we are attacking, we grab a temporary instance of
the opposite opponent and call the opposite opponents took_damage method and supply a damage_factor
argument. Once the action method has been executed we call switch_turn again and recall update. As you can
see, control is passed back and forth between do_action, update, and Fighters helper methods. Finally we
need to define our gameover method when a Fighter is dead.
#...def do_action(choice)
if @current_turn ===@player1opponent =@player2
elseopponent =@player1
end
case choicewhen "Attack" then
puts "\n#{@current_turn.name} is attacking#{opponent.name} with a #{@current_turn.weapon}!"
if opponent.defenseless == truedamage = @current_turn.attack(1.0)
elsedamage = @current_turn.attack(0.3)
endgets; puts "#{opponent.name} took #{damage} damage!"opponent.took_damage(damage)puts "#{opponent.name}'s health has dropped to:
#{opponent.health}"; gets;
when "Defend" then puts "\n#{@current_turn.name} is nowdefending against #{opponent.name}'s next attack."
@current_turn.defend; gets;when "Heal" then puts "\n#{@current_turn.name} is now healing.";
@current_turn.healputs "#{@current_turn.name}'s health is now:
#{@current_turn.health}"; gets;else
puts "\n#{@current_turn.name} has dropped his guard andis defenseless this turn!"; gets;
end
switch_turn
update
end#...
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
15/16
7/29/2019 Learn Ruby - Lesson 2 - Understanding Objects
16/16
16
Learn Ruby: Lesson 2 Understanding Objects
www.soultheory.ne
3. LESSON 2 REVIEW CHALLENGE
LESSON 2 REVIEW CHALLENGE
Your challenge is to build a banking system. You can begin by defining an Account class (checking and savings)
and a Bank class. Maybe the bank can lend @loans to its members? You can use your imagination with it.
There is a couple of catches. One is that no Burglar should be able to access a Bank class or an Account class.
The Burglar could try to rob the bank during a random time of the day and if successful (at random) he steals
money from an Account! Perhaps the Bank can call the Police in the attempt of a burglary? The possibilities
here are endless but bring real world situations and program them from abstract concepts with the
information learned from this lesson.
Whats to come in the next lesson:
Rubys Secret Weapon: Blocks
A Closer Look At Arithmetic
The Beauty Of Arrays and Hashes
Inheritance, Modules, and Mixins
Instance Methods Vs. Class Methods
Useful Methods Cheat Sheet
Thanks for downloading. Contact me: [email protected]
Downloaded from:www.soultheory.net
Resources:
www.ruby-lang.org
http://www.ruby-doc.org/docs/ProgrammingRuby
http://apidock.com
http://www.skorks.com/
http://explainruby.net/ - An online Ruby code interpreter!
http://rubylearning.com/
http://www.soultheory.net/http://www.soultheory.net/http://www.soultheory.net/http://www.ruby-lang.org/http://www.ruby-lang.org/http://www.ruby-doc.org/docs/ProgrammingRubyhttp://www.ruby-doc.org/docs/ProgrammingRubyhttp://apidock.com/http://apidock.com/http://www.skorks.com/http://www.skorks.com/http://explainruby.net/http://explainruby.net/http://rubylearning.com/http://rubylearning.com/http://rubylearning.com/http://explainruby.net/http://www.skorks.com/http://apidock.com/http://www.ruby-doc.org/docs/ProgrammingRubyhttp://www.ruby-lang.org/http://www.soultheory.net/