- Review the Command Line Interface
- Run CLI applications
- Use
gets
to capture user input and store in a variable - Practice defining a method
- Implement flow control
In this lab, you are tasked with building guessing game. The game is simple: the computer will choose a random number between 1 and 6 and ask you to make a guess. If you guess right, you win, if not, you lose.
The implementation of this game is not so simple. You will need to utilize what
you've learned about methods and conditional logic. In addition, we will
also introduce a way to capture user input, gets
. First, though, let's refresh
on what a CLI application is.
A CLI, or command line interface, allows a user to interface, or interact with,
a computer's operating system or a particular application. You've already become
comfortable interacting with the command line to navigate files, connect with
GitHub and test your programs. Every lab so far has required you to run learn
and learn submit
in the command line.
In a command line application, the user will respond to a prompt that your program will output to the terminal. The user's response, or input, will be received by the application and the application will then carry out the programmed response based on that input.
For example, I might have a command line application which, once run, will ask the user for their location and, in return, output the current weather for that location to the terminal.
The work for this should be done in guessing_game_cli.rb
. In this file, you'll
need to write a method, run_guessing_game
, that will contain all of the code
we need for our guessing game.
However, when we want to run this application, we are not going to call on
this file directly. Instead, we will use a second file that is already provided,
bin/guessing_game_cli
. To start the application type the following in your
terminal from the main folder of this lesson:
ruby bin/guessing_game_cli
This is a Ruby file, and if you look inside, you'll see it has two lines of code:
require_relative "../guessing_game_cli"
run_guessing_game
All the file does is load guessing_game_cli.rb
so that is has access to the
run_guessing_game
method, then it calls that method to start the application.
You may be wondering: why is this necessary? Can't we just call
run_guessing_game
at the bottom of guessing_game_cli.rb
and achieve the same
result? Yes, you can. The problem here is that this set up isn't easily
scalable.
By separating out this action of starting an application, we can ensure that our application is being run in the correct environment. Building more complex applications may require many files to be loaded up before a particular method is called to start the app.
The guessing_game_cli.rb
file is for our implementation, our code, not really
for setting up the environment. Another way of putting it: the
guessing_game_cli.rb
should only be concerned with the guessing game code
itself. The bin/guessing_game_cli
file separates out the concern of running
that code. Separating concerns is a common design principle in
programming. By using bin/guessing_game_cli
, we have a clear, single entry
point for starting our application.
Note: You may be wondering why
bin/guessing_game_cli
doesn't have a.rb
file extension even though it is just Ruby inside. Files likebin/guessing_game_cli
are sometimes referred to as executables. This mirrors a convention in frameworks like Ruby on Rails where executable files are provided for setting up the environment for various tools used in the framework.
Start coding your solution by creating a run_guessing_game
method. Once
created, the method should be responsible for the following:
- Generate and store a random number between 1 and 6
- Prompts the user to guess their own number between 1 and 6
- Capture user input from the command line
- Compare that input to the random number that has been generated
- Print out one of three statements:
- If the user's input matches the random number:
You guessed the correct number!
- If the user's input DOES NOT matches the random number:
Sorry! The computer guessed <number>.
- It the user's input is equal to "exit":
Goodbye!
- If the user's input matches the random number:
Run learn
to see your progress and learn submit
when you've solved the lab.
In Ruby, to generate a random number, you can use rand
.
rand #=> Returns a random float like 0.39113137693072575
By default, rand
returns a random float. To get integers, we need to pass an
integer in as an argument for rand
:
rand(20) #=> Returns a random integer from 0 to 19
By passing an integer, rand
will return a random integer that is less than
the number it was given, including zero. Calling rand(20)
will never produce
the value 20
. If we wanted any random number between 1 and 20,
instead of 0 and 19, we could do something like:
rand(20) + 1 #=> Returns a random integer from 1 to 20
With
rand
, you can also pass in a Range as an argument to achieve the same result. However, as we haven't discussed ranges in depth yet, write code similar to the above example to pass the tests in this lab. Using a range will not produce the correct test results.
We've used puts
in a few labs already for outputting text. For
capturing user input, we use gets
.
input = gets
If we run the above code in IRB, we'll be given a new line to type in. Try
typing hello
and pressing enter:
2.6.1 :001 > input = gets
hello
=> "hello\n"
Whatever we write after calling gets
will be captured as a string. By having
gets
on the right hand side of a variable assignment, whatever gets
captures
will be assigned to the input
variable.
If we were to lookup input
, we'd see that it is now assigned to "hello\n"
:
2.6.1 :002 > input
=> "hello\n"
The \n
at the end is the string representation of newline (also referred to
as a carriage return), which was captured by gets
when Enter
was pressed.
For a number guessing game, we don't need \n
at the end of every user input.
Luckily, Ruby provides a built in method for removing these: chomp
.
The chomp
method is part of the String
class, so we can call it
on any string value or variable:
2.6.1 :003 > input.chomp
=> "hello"
When we use gets
, it returns a user's input as a string. This means that we
can actually use chomp
directly after gets:
2.6.1 :004 > input = gets.chomp
And our input
variable be set to whatever a user inputs, minus the newline
characters.
This is a challenging lab, so go through it slowly. Look at the RSpec tests and see what the tests are looking for. Talk to each other and communicate your way through roadblocks.
Run ruby bin/guessing_game_cli
as you build out your logic. This way, you can
develop based on the behavior of your code. The tests in this lab are also
focused on this. Rather than test for a particular implementation, the tests
will run the application and test for the appropriate outputs (when a user
wins, loses or exits).
This is a very small application that should play a single guessing game then end. There is no need to incorporate loops into your code.
A critical part of building CLI applications is capturing user input and setting up logic to handle that input. Equipped with only the skills you've demonstrated in this lab, it would be possible to build highly complex text based applications (or games!).
In addition to using gets
, we've also introduced the bin
folder and
the use of an executable file. A file like bin/guessing_game_cli
acts as the
starting point of our program. It ensures we load up the necessary files before
running the main method of our application.
View Build a Guessing Game in the CLI on Learn.co and start learning to code for free.