Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hannah Gray #634

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## Flash Cards

This is the starter repository for the [Flash Cards](http://backend.turing.io/module1/projects/flashcards) project.
Hi! Welcome to my FlashCards project. This is a simple command-line game I created to practice Ruby and object-oriented programming. The game is designed to simulate flashcards, where you answer questions, get feedback, and see how well you did at the end.

I also learned how to load questions dynamically from a text file, making the game super flexible. Let me show you how it works!

What's in this Project?
Flashcards: Each card has a question, an answer, and a category.
Gameplay: You play through a deck of cards, answer questions, and get immediate feedback.
Score Tracking: The game keeps track of your correct answers and shows a breakdown by category at the end.
Dynamic Questions: Flashcards are loaded from a .txt file, so you can change the questions without touching the code.
6 changes: 6 additions & 0 deletions cards.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
What is 5 + 5?,10,STEM
What is Rachel's favorite animal?,red panda,Turing Staff
What is Mike's middle name?,nobody knows,Turing Staff
What cardboard cutout lives at Turing?,Justin bieber,PopCulture
What is the capital of Alaska?,Juneau,Geography
Which planet is closest to the sun?,Mercury,STEM
19 changes: 19 additions & 0 deletions flashcard_runner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Load the necessary classes
require './lib/card'
require './lib/turn'
require './lib/deck'
require './lib/round'
require './lib/card_generator'

# Step 1: Generate cards from the text file
filename = 'cards.txt'
cards = CardGenerator.new(filename).cards

# Step 2: Create a Deck with the generated cards
deck = Deck.new(cards)

# Step 3: Create a new Round using the Deck
round = Round.new(deck)

# Step 4: Start the game
round.start
14 changes: 14 additions & 0 deletions lib/card.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# The Card class represents a single flashcard.
# It has a question, an answer, and a category.
class Card
# Provides read-only access to the card's attributes
attr_reader :question, :answer, :category

# Initializes a new Card with a question, answer, and category
def initialize(question, answer, category)
@question = question
@answer = answer
@category = category
end
end
20 changes: 20 additions & 0 deletions lib/card_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The CardGenerator class reads a text file and creates Card objects.
class CardGenerator
attr_reader :filename, :cards

# Initialize with the filename of the text file
def initialize(filename)
@filename = filename
@cards = generate_cards
end

private

# Reads the file and creates Card objects
def generate_cards
File.readlines(@filename).map do |line|
question, answer, category = line.chomp.split(',')
Card.new(question, answer, category.strip)
end
end
end
16 changes: 16 additions & 0 deletions lib/class Turn.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Turn
attr_reader :guess, :card

def initialize(guess, card)
@guess = guess
@card = card
end

def correct?
@guess.downcase == @card.answer.downcase
end

def feedback
correct? ? "Correct!" : "Incorrect."
end
end
21 changes: 21 additions & 0 deletions lib/deck.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# The Deck class represents a collection of cards.
# It provides functionality to count cards and filter them by category.
class Deck
# Provides read-only access to the cards in the deck
attr_reader :cards

# Initializes a new Deck with an array of Card objects
def initialize(cards)
@cards = cards
end

# Returns the total number of cards in the deck
def count
@cards.length
end

# Returns an array of cards that belong to the specified category
def cards_in_category(category)
@cards.select { |card| card.category == category }
end
end
74 changes: 74 additions & 0 deletions lib/round.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# The Round class handles the flow of the game.
# It manages turns, tracks guesses, and provides feedback and results.
class Round
attr_reader :deck, :turns, :current_card_index

def initialize(deck)
@deck = deck
@turns = []
@current_card_index = 0
end

# Returns the current card being played
def current_card
@deck.cards[@current_card_index]
end

# Processes a guess, creates a Turn, and moves to the next card
def take_turn(guess)
turn = Turn.new(guess, current_card)
@turns << turn
@current_card_index += 1
turn
end

# Returns the total number of correct guesses
def number_correct
@turns.count { |turn| turn.correct? }
end

# Returns the number of correct guesses in a specific category
def number_correct_by_category(category)
@turns.count { |turn| turn.correct? && turn.card.category == category }
end

# Returns the percentage of correct guesses
def percent_correct
(number_correct.to_f / @turns.count * 100).round(1)
end

# Returns the percentage of correct guesses in a specific category
def percent_correct_by_category(category)
total_in_category = @turns.count { |turn| turn.card.category == category }
return 0.0 if total_in_category.zero?

(number_correct_by_category(category).to_f / total_in_category * 100).round(1)
end

# CLI: Starts the game and handles user interaction
def start
puts "Welcome! You're playing with #{deck.count} cards."
puts "-------------------------------------------------"

deck.cards.each_with_index do |card, index|
puts "This is card number #{index + 1} out of #{deck.count}."
puts "Question: #{card.question}"

# Get user input for their guess
guess = gets.chomp
turn = take_turn(guess)

# Provide feedback on their guess
puts turn.feedback
end

# Display final results
puts "****** Game over! ******"
puts "You had #{number_correct} correct guesses out of #{turns.count} for a total score of #{percent_correct}%."

# Display performance by category
deck.cards.map(&:category).uniq.each do |category|
puts "#{category} - #{percent_correct_by_category(category)}% correct"
end
end
end
22 changes: 22 additions & 0 deletions lib/turn.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# The Turn class represents a user's guess at a question.
# It evaluates if the guess is correct and provides feedback.
class Turn
# Provides read-only access to the guess and the associated card
attr_reader :guess, :card

# Initializes a new Turn with a guess and a Card object
def initialize(guess, card)
@guess = guess
@card = card
end

# Checks if the guess matches the card's answer (case insensitive)
def correct?
@guess.downcase == @card.answer.downcase
end

# Returns feedback based on whether the guess is correct
def feedback
correct? ? "Correct!" : "Incorrect."
end
end
20 changes: 20 additions & 0 deletions spec/card_generator_spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require './lib/card_generator'
require './lib/card'

RSpec.describe CardGenerator do
it 'generates cards from a text file' do
# Arrange: Use the cards.txt file
filename = 'cards.txt'

# Act: Create a CardGenerator and generate cards
card_generator = CardGenerator.new(filename)
cards = card_generator.cards

# Assert: Verify the cards were generated correctly
expect(cards.length).to eq(4)
expect(cards.first).to be_a(Card)
expect(cards.first.question).to eq("What is 5 + 5?")
expect(cards.first.answer).to eq("10")
expect(cards.first.category).to eq("STEM")
end
end
28 changes: 10 additions & 18 deletions spec/card_spec.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
require './lib/card'
# Test file for the Card class
require './lib/card' # Require the Card class for testing

RSpec.describe Card do
it 'exists' do
card = Card.new("What is the capital of Alaska?", "Juneau", :Geography)

expect(card).to be_instance_of(Card)
end

it 'has a question' do
# Test: Ensure the Card object is created with correct attributes
it 'exists and has attributes' do
# Create a new Card instance
card = Card.new("What is the capital of Alaska?", "Juneau", :Geography)

# Check that the card is an instance of the Card class
expect(card).to be_a(Card)
# Verify the question, answer, and category are set correctly
expect(card.question).to eq("What is the capital of Alaska?")
end

it 'has an answer' do
card = Card.new("What is the capital of Alaska?", "Juneau", :Geography)

expect(card.answer).to eq("Juneau")
end

it 'has a category' do
card = Card.new("What is the capital of Alaska?", "Juneau", :Geography)

expect(card.category).to eq(:Geography)
end
end


45 changes: 45 additions & 0 deletions spec/deck_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Test file for the Deck class
require './lib/card' # Require the Card class
require './lib/deck' # Require the Deck class

RSpec.describe Deck do
# Test: Ensure the Deck object is created with correct attributes
it 'exists and has attributes' do
# Create some Card instances
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("The Viking spacecraft sent back to Earth photos of which planet?", "Mars", :STEM)
card_3 = Card.new("What is 5 + 5?", "10", :Math)

# Create a Deck instance with the cards
deck = Deck.new([card_1, card_2, card_3])

# Check that the deck is an instance of the Deck class
expect(deck).to be_a(Deck)
# Verify the cards attribute contains the correct cards
expect(deck.cards).to eq([card_1, card_2, card_3])
end

# Test: Count the number of cards in the deck
it 'counts the cards in the deck' do
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("The Viking spacecraft sent back to Earth photos of which planet?", "Mars", :STEM)
card_3 = Card.new("What is 5 + 5?", "10", :Math)

deck = Deck.new([card_1, card_2, card_3])

expect(deck.count).to eq(3)
end

# Test: Filter cards by category
it 'filters cards by category' do
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("The Viking spacecraft sent back to Earth photos of which planet?", "Mars", :STEM)
card_3 = Card.new("What is 5 + 5?", "10", :Math)

deck = Deck.new([card_1, card_2, card_3])

expect(deck.cards_in_category(:STEM)).to eq([card_2])
expect(deck.cards_in_category(:Geography)).to eq([card_1])
expect(deck.cards_in_category(:History)).to eq([])
end
end
52 changes: 52 additions & 0 deletions spec/round_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require './lib/card'
require './lib/deck'
require './lib/turn'
require './lib/round'

RSpec.describe Round do
it 'exists and has attributes' do
# Arrange: Create cards and a Deck
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("What is 5 + 5?", "10", :Math)
deck = Deck.new([card_1, card_2])

# Arrange: Create a Round with the Deck
round = Round.new(deck)

# Assert: Check the Round attributes
expect(round).to be_a(Round)
expect(round.deck).to eq(deck)
expect(round.turns).to eq([])
end

it 'takes a turn and provides feedback' do
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("What is 5 + 5?", "10", :Math)
deck = Deck.new([card_1, card_2])
round = Round.new(deck)

# Act: Take a turn
turn = round.take_turn("Juneau")

# Assert: Verify the Turn object and feedback
expect(turn).to be_a(Turn)
expect(turn.correct?).to eq(true)
expect(round.turns).to eq([turn])
expect(round.number_correct).to eq(1)
end

it 'calculates percent correct and filters by category' do
card_1 = Card.new("What is the capital of Alaska?", "Juneau", :Geography)
card_2 = Card.new("What is 5 + 5?", "10", :Math)
deck = Deck.new([card_1, card_2])
round = Round.new(deck)

round.take_turn("Juneau")
round.take_turn("5")

# Assert: Verify percentages
expect(round.percent_correct).to eq(50.0)
expect(round.percent_correct_by_category(:Geography)).to eq(100.0)
expect(round.percent_correct_by_category(:Math)).to eq(0.0)
end
end
Loading