I have a simple program 'guessing game' written in Ruby. It asks for a 1-100 number and returns if the number you're guessing is higher or lower. Now I have to create a second program that can play that game optimally. What would be the best way to make them communicate with each other? I can also use bash script.
CodePudding user response:
It's an excellent idea to use bash for this exercise, because you can test each program individually using the shell, and then later easily connect the two also using the shell.
Simply read from stdin
as the input of a program, write the result to stdout
. Write to stderr
to log program behavior.
As a starting point, here is a program that checks the guessed number:
$ cat ./check_guess.rb
#!/usr/bin/ruby
# Ensure output is flushed when piping
STDOUT.sync = true
# Reference number, could be provided by the user or randomly generated, etc.
ref = 12
while true
# Get input
guess = gets
if guess.to_s != ""
STDERR.puts "Received guess = " guess
# Compare with ref. number
if guess.to_i > ref
STDERR.puts "Provided number is higher than " ref.to_s
puts "higher"
elsif guess.to_i < ref
STDERR.puts "Provided number is lower than " ref.to_s
puts "lower"
else
STDERR.puts "Provided number matches!"
puts "match" if ref == guess.to_i
break
end
end
end
Testing it manually:
$ ./check_guess.rb
10
Received guess = 10
Provided number is lower than 12
lower
13
Received guess = 13
Provided number is higher than 12
higher
12
Received guess = 12
Provided number matches!
match
Here a very crude guessing program:
$ cat guess.rb
#!/usr/bin/ruby
# Ensure output is flushed when piping
STDOUT.sync = true
# Initial guess. Could be provided by the user or randomly generated, etc.
guess = 5
# Loop until we guess correctly
while true
# Provide guess by simply writing to stdout
STDERR.puts "Guessing number is " guess.to_s
# Print current guess
puts guess.to_s
# Get guess result from stdin, that is, from the other program...
# Use chomp to remove the newline
result = gets.chomp
if result == "match"
STDERR.puts "Guessed!"
break
elsif result == "higher"
guess = guess - 1
STDERR.puts "Provided number is higher, trying smaller number"
else
guess = guess 1
STDERR.puts "Provided number is smaller, trying higher number"
end
end
This can also be tested manually:
$ ./guess.rb
Guessing number is 5
5
higher
Provided number is higher, trying smaller number
Guessing number is 4
4
match
Guessed!
Now, let's create pipes to connect the programs with each other:
$ mkfifo guess_out check_guess_out
And run them from two terminals. Note that the stderr
messages will still go to the terminal, the commands below just connect stdout
from one program to the stdin
of the other.
$ cat check_guess_out | ./guess.rb > ./guess_out | $ cat guess_out | ./check_guess.rb > check_guess_out
Guessing number is 5 | Received guess = 5
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 6 | Received guess = 6
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 7 | Received guess = 7
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 8 | Received guess = 8
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 9 | Received guess = 9
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 10 | Received guess = 10
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 11 | Received guess = 11
Provided number is smaller, trying higher number | Provided number is lower than 12
Guessing number is 12 | Received guess = 12
Guessed! | Provided number matches!
Now follows the real interesting part, which is to devise a guessing algorithm. Good luck!