diff --git a/README.md b/README.md index 692b3f6..d847678 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ ## Current Capabilities - The game's current capabilities are that it will prompt at start to begin and react accordingly. After the instructions it will process guesses as valid or invalid and give instructions according to what was incorrect. The User will not receive feedback yet and it is impossible to win the game, but after all 10 guesses the secret code will be presented and the user will be prompted whether they'd like to restart. The user may also type 'quit' during the guess phase at any time and the game will exit. + The game's current capabilities are that it will prompt at start to begin and react accordingly. After the instructions it will process guesses as valid or invalid and give instructions according to what was incorrect. The User will receive feedback, but it is impossible to win the game. After all 10 guesses the secret code will be presented and the user will be prompted whether they'd like to restart. The user may also type 'quit' during the guess phase at any time and the game will exit. diff --git a/lib/game_functions.rb b/lib/game_functions.rb index 2dc4556..2d66834 100644 --- a/lib/game_functions.rb +++ b/lib/game_functions.rb @@ -1,4 +1,4 @@ -require './output' +require_relative 'output' class GameFunctions class << self diff --git a/lib/game_status.rb b/lib/game_status.rb index 37b0e0f..a55d722 100644 --- a/lib/game_status.rb +++ b/lib/game_status.rb @@ -1,5 +1,5 @@ -require './output' -require './game_functions' +require_relative 'output' +require_relative 'game_functions' module GameStatus # will have 0 params once I implement a class that holds all in-game info @@ -15,7 +15,7 @@ def game_over?(guesses_left) private def guesses_left?(guesses_left) - !guesses_left.zero? + guesses_left.positive? end def win? diff --git a/lib/input.rb b/lib/input.rb index 76d29a1..f15bdca 100644 --- a/lib/input.rb +++ b/lib/input.rb @@ -1,4 +1,4 @@ -require './output' +require_relative 'output' class Input end diff --git a/lib/main.rb b/lib/main.rb index e4b8d96..f0ff1f0 100644 --- a/lib/main.rb +++ b/lib/main.rb @@ -1,8 +1,8 @@ -require './user' -require './game_status' -require './colors' -require './secret_code' -require './output' +require_relative 'user' +require_relative 'game_status' +require_relative 'colors' +require_relative 'secret_code' +require_relative 'output' # infinite refactoring in progress # ironically it's messier than ever before @@ -20,8 +20,14 @@ def main Output.print_intro the_secret_code = SecretCode.new - the_user.take_input - the_user.give_feedback + the_secret_code.compare_to_guess(the_user.take_input) + ask_again(the_user, the_secret_code) +end + +def ask_again(user, code) + GameStatus.game_over?(user.guesses_left) + code.compare_to_guess(user.take_input) + again(user, code) end if __FILE__ == $PROGRAM_NAME diff --git a/lib/output.rb b/lib/output.rb index f662a05..c9ca4f1 100644 --- a/lib/output.rb +++ b/lib/output.rb @@ -1,6 +1,5 @@ -require_relative './user' -require_relative './colors' -require_relative './secret_code' +require_relative 'user' +require_relative 'colors' class Output class << self @@ -111,6 +110,10 @@ def print_win puts WIN end + def print_feedback(red_pin, white_pin) + puts "Red Pins: #{red_pin}\t White Pins: #{white_pin}" + end + private def instructions diff --git a/lib/secret_code.rb b/lib/secret_code.rb index 9aa9327..fe1bfee 100644 --- a/lib/secret_code.rb +++ b/lib/secret_code.rb @@ -1,7 +1,9 @@ -require './output' +require 'output' class SecretCode - attr_reader :code + attr_accessor :code + + LENGTH_OF_CODE = 4; def initialize @code = gen_secret_code @@ -11,8 +13,69 @@ def initialize def gen_secret_code randomness = Random.new Output.print_code_generated - return (1..4).map { |_| randomness.rand(1..6) } + return (1..LENGTH_OF_CODE).map { |_| randomness.rand(1..6) } + end + + # most of this is built to acompany the presence of a class that stores all data + # with that in mind there will be no params necessary as feedback and guess + # and all these vars will be referring to themselves as values within a hash + def compare_to_guess(guess_s) + guess = format_guess(guess_s) + + unless win?(guess, code) + feedback = Array.new(LENGTH_OF_CODE) {'blank'} + feedback = check_for_red(guess, feedback) + feedback = check_for_white(guess, feedback) + pins = count_pins(feedback) + Output.print_feedback(pins[0], pins[1]) + return pins + end + end + + private + + def check_for_red(guess, feedback) + LENGTH_OF_CODE.times do |guess_index| + feedback[guess_index] = 'red' if guess[guess_index] == code[guess_index] + end + + return feedback end - def compare_to_secret_code; end + def check_for_white(guess, feedback) + LENGTH_OF_CODE.times do |guess_index| + LENGTH_OF_CODE.times do |code_index| + if feedback[code_index] != 'blank' + guess_index += 1 if feedback[code_index] == 'red' + next + end + + feedback[code_index] = 'white' if guess[guess_index] == code[code_index] + end + end + return feedback + end + + def count_pins(feedback) + red_pin = feedback.count('red') + white_pin = feedback.count('white') + + return [red_pin, white_pin] + end + + def format_guess(guess_s) + guess = Array.new(LENGTH_OF_CODE) + + LENGTH_OF_CODE.times do |val| + guess[val] = guess_s[val].to_i + end + + return guess + end + + # this method is practically just a conditional statement + # should I move it to the case they in which it's used? + def win?(guess, code) + return guess == code + end end diff --git a/lib/user.rb b/lib/user.rb index c78f3d2..e4acb23 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -1,6 +1,6 @@ -require './output' -require './validate' -require './game_status' +require 'output' +require 'validate' +require 'game_status' # User class knows too much, i made a mess and now refactoring class User @@ -23,15 +23,15 @@ def take_input @guess = the_input @guesses_left -= 1 - next_command('input') + return @guess end - def give_feedback(p_input = @guess) - GameStatus.game_over?(@guesses_left) - - puts("I haven't coded the feedback yet :)") - next_command('feedback') - end + # def give_feedback(p_input = @guess) + # GameStatus.game_over?(@guesses_left) + # + # puts("I haven't coded the feedback yet :)") + # next_command('feedback') + # end def prompt_start system 'clear' @@ -41,19 +41,15 @@ def prompt_start return gets.chomp end - private + private - def next_command(previous) - if (previous.eql? 'input') - give_feedback - return - elsif (previous.eql? 'feedback') - take_input - return - else - return - end - end + # def next_command(previous) + # if (previous.eql? 'input') + # give_feedback + # elsif (previous.eql? 'feedback') + # take_input + # end + # end def is_quit?(user_input) if (user_input.downcase.eql? 'quit') diff --git a/lib/validate.rb b/lib/validate.rb index a2a8b0a..6519a00 100644 --- a/lib/validate.rb +++ b/lib/validate.rb @@ -1,4 +1,4 @@ -require './output' +require_relative 'output' module Validate def is_valid?(the_input) diff --git a/spec/secret_code_spec.rb b/spec/secret_code_spec.rb new file mode 100644 index 0000000..ec9050a --- /dev/null +++ b/spec/secret_code_spec.rb @@ -0,0 +1,60 @@ +require 'secret_code' + +RSpec.describe SecretCode do + let(:secret_code) {SecretCode.new} + + describe '#initialize' do + xit 'generates a secrect code when initialized' do + # mock to check that gen_secret_code is called + # but would that be testing behavior or simply ruby? + end + end + + describe '#gen_secret_code' do + context 'creates a code that' do + code = secret_code.gen_secret_code + it 'is 4 characters' do + expect(code.length).to_eq 4 + end + it 'only contains numbers 1-6' do + expect(code.all? { |val| val.to_i.between?(1, 6) }).to_eq true + end + end + end + + describe '#compare_to_guess' do + # am I just testing random cases at this point? is this ok? + context 'will correctly assign pins when' do + it '2 red and 2 white expected' do + secret_code.code = [1, 1, 2, 2] + guess_s = ['1', '2', '2', '1'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [2, 2] + end + it '2 red and 0 white expected' do + secret_code.code = [1, 1, 1, 1] + guess_s = ['1', '1', '2', '2'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [2, 0] + end + it '1 red and 2 white expected' do + secret_code.code = [1, 2, 3, 4] + guess_s = ['1', '3', '2', '1'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [1, 2] + end + it '3 red and 0 white expected' do + secret_code.code = [1, 1, 1, 2] + guess_s = ['1', '1', '1', '1'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [3, 0] + end + it '0 red and 4 white expected' do + secret_code.code = [1, 2, 3, 4] + guess_s = ['4', '3', '2', '1'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [0, 4] + end + it '4 red and 0 white expected' do + secret_code.code = [1, 1, 1, 1] + guess_s = ['1', '1', '1', '1'] + expect(secret_code.compare_to_guess(guess_s)).to_eq [4, 0] + end + end + end +end