Home > Net >  creates and starts a game from answers written in a file in Ruby
creates and starts a game from answers written in a file in Ruby

Time:08-03

I am currently working on improving my ruby skills.

I am working on a guess game and the game is playing well without writing it on a file.

And now I have introduced a file and the answers to the game are written on a file.

My problem now is that I am looking for a way to "starts the game from answers written in a file".

The from_file method is where I want to implement the solution to the problem. Though I have started with it but stucked and I need someone to assist me.

Below is the main code while the RSPEC test is below the code

class Game
  def initialize(answers:, input: $stdin, output: $stdout, max_attempts: 3)
    @answers = answers
    @correct_answers = 0
    @input = input
    @max_attempts = 3
    @output = output
  end

  def start
    if answers.size == 1
      word_anagram = "anagram"
    else
      word_anagram = "anagrams"
    end
    output.puts "Let's play a game. You will have to guess #{answers.size} # 
    {word_anagram}."
    answers.each.with_index(1) do |answer, index|
      output.puts "#{index}/#{answers.size}. Guess a word from an anagram # 
      {Anagram.create("#{answer.upcase}")}"
      evaluate_user_guesses(answer)
    end
    output.puts "Your final score: #{correct_answers}/#{answers.size}."
  end

  def evaluate_user_guesses(answer)
    guess = nil
    current_attempt = 1
    while guess != answer.upcase && current_attempt <= max_attempts
      guess = input.gets.to_s.strip
      if guess.upcase == answer.upcase
        output.puts "Correct! The answer is #{answer.upcase}."
        @correct_answers  = 1
        return output.puts "So far you have correctly guessed #{correct_answers} out of 
        #{answers.size}."
      else
        output.puts "The answer is not #{guess.upcase}."
        if current_attempt < max_attempts
          output.puts "Try again. Attempts left: #{max_attempts - current_attempt}" 
        else
          output.puts "You lost."
        end
      end
      current_attempt  = 1
    end
  end

  def self.from_file(path:, input: $stdin, output: $stdout, max_attempts: 3)
    self.new(answers: [], input: input, output: output, max_attempts: max_attempts)
  end

  private

  attr_reader :answers, :correct_answers, :input, :max_attempts, :output
end

This is an RSPEC test for how to create and start a game from an answer written in a file. I will appreciate your input.

describe "#from_file" do
    let(:output) { StringIO.new }
    it "creates and starts a game from answers written in a file" do
      file = Tempfile.new
      answers = %w(alpha beta)
      file_contents = answers.join("\n")
      begin
        file.write(file_contents)
        file.rewind
        guesses = %w(alpha beta)
        input = StringIO.new(guesses.join("\n"))
        game = Game.from_file(
          path: file.path,
          input: input,
          output: output,
          max_attempts: 3
        )

        game.start

        game_output_lines = output.string.split("\n").map(&:strip)

        aggregate_failures do
          expect(game_output_lines.size).to eq 8
          expect(game_output_lines[0]).to eq "Let's play a game. You will have to guess 
          2 anagrams."
          expect(game_output_lines[1]).to match(/^1\/2. Guess a word from an anagram 
          [ALPH]{5}$/)
          expect(game_output_lines[2]).to eq "Correct! The answer is ALPHA."
          expect(game_output_lines[3]).to eq "So far you have correctly guessed 1 out of 
          2."
          expect(game_output_lines[4]).to match(/^2\/2. Guess a word from an anagram 
          [BETA]{4}$/)
          expect(game_output_lines[5]).to eq "Correct! The answer is BETA."
          expect(game_output_lines[6]).to eq "So far you have correctly guessed 2 out of 
          2."
          expect(game_output_lines[7]).to eq "Your final score: 2/2."
        end
      ensure
        file.close
        file.unlink
      end
    end
  end

CodePudding user response:

According to your comments, you need to read your answers: [] from the file, so for a text file containing one answer per line

#answers.txt
one
two
three

> answers = File.read("answers.txt").split
=> ["one", "two", "three"]

  def self.from_file(path:, input: $stdin, output: $stdout, max_attempts: 3)
    answers = File.read("answers.txt").split
    self.new(answers: answers, input: input, output: output, max_attempts: max_attempts)
  end
  • Related