Class: Typeking::GameController
- Inherits:
-
Object
- Object
- Typeking::GameController
- Defined in:
- lib/typeking/game_controller.rb
Instance Attribute Summary collapse
-
#currentUid ⇒ Object
attr_accessor used for testing purposes.
-
#currentUserData ⇒ Object
attr_accessor used for testing purposes.
-
#userData ⇒ Object
attr_accessor used for testing purposes.
-
#userHashes ⇒ Object
attr_accessor used for testing purposes.
Instance Method Summary collapse
- #attempt_login(username) ⇒ Object
- #attempt_registration(username) ⇒ Object
- #begin_typing(wordCount) ⇒ Object
- #calculate_results(elapsedTime, totalWordCount, wordsCorrect, wordsIncorrect) ⇒ Object
- #calculate_speed(elapsedTime, totalWordCount, wordsCorrect) ⇒ Object
- #count_worst_letters(incorrectWords) ⇒ Object
- #display_leaders(leaderCount) ⇒ Object
- #help ⇒ Object
- #home_screen ⇒ Object
-
#initialize ⇒ GameController
constructor
A new instance of GameController.
- #save_data(wpm, accuracy) ⇒ Object
- #setup_application ⇒ Object
- #show_leaderboards ⇒ Object
- #show_stats ⇒ Object
- #start_game ⇒ Object
- #start_screen ⇒ Object
- #user_login ⇒ Object
- #user_register ⇒ Object
Constructor Details
#initialize ⇒ GameController
Returns a new instance of GameController.
12 13 14 15 16 17 18 19 |
# File 'lib/typeking/game_controller.rb', line 12 def initialize() @userData = [] #database of user hashes @userHashes = {} #stores indexes for all users @currentUserData = {} #stores current stats @currentUid = 0 #current user id @leaderboardArr = [] setup_application end |
Instance Attribute Details
#currentUid ⇒ Object
attr_accessor used for testing purposes. App will still run if all variables changed to attr_reader
10 11 12 |
# File 'lib/typeking/game_controller.rb', line 10 def currentUid @currentUid end |
#currentUserData ⇒ Object
attr_accessor used for testing purposes. App will still run if all variables changed to attr_reader
10 11 12 |
# File 'lib/typeking/game_controller.rb', line 10 def currentUserData @currentUserData end |
#userData ⇒ Object
attr_accessor used for testing purposes. App will still run if all variables changed to attr_reader
10 11 12 |
# File 'lib/typeking/game_controller.rb', line 10 def userData @userData end |
#userHashes ⇒ Object
attr_accessor used for testing purposes. App will still run if all variables changed to attr_reader
10 11 12 |
# File 'lib/typeking/game_controller.rb', line 10 def userHashes @userHashes end |
Instance Method Details
#attempt_login(username) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/typeking/game_controller.rb', line 93 def attempt_login(username) if @userHashes[username] #check if user exists @currentUid = @userHashes[username] #update current user id to the username from the userhashes directory @currentUserData = @userData[currentUid] #user data hash becomes hash from database return "Hello #{@currentUserData[:name]}!" #user_login will puts this to terminal else return "You have not registered yet, please register first." #user_login will puts this to terminal end end |
#attempt_registration(username) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/typeking/game_controller.rb', line 70 def attempt_registration(username) if @userHashes[username] #check if user exists in @userHashes return "You already have an account, please login" #user_register will puts this to the terminal else user = User.new(username) #creates new user newHash = user.user_details #creates a new hash of user values @userhashes = @userHashes.merge!(newHash) #adds user to hash @userData << {:name => username, :high_score => 0, :accuracy => 0, :worst_character => "None!"} return "Thank you for registering, please login and have fun!" #user_register will puts this to the terminal end end |
#begin_typing(wordCount) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/typeking/game_controller.rb', line 159 def begin_typing(wordCount) wordsCorrect = [] #creates array of words that the user types correctly wordsIncorrect = [] #creates array of words that the user types incorrectly startingTime = Process.clock_gettime(Process::CLOCK_MONOTONIC) #gets current time and saves it in variable wordsLeft = wordCount.to_i #words left to type are the words passed in argument from previous def while wordsLeft > 0 #loops while there are words to type newWord = RandomWord.nouns.next #starts with a random noun while newWord.size > 8 #makes sure no words are over 8 characters long, generates a new word if the new word is longer than 8 characters random = rand(2) #generators a random number from 0-1 if random == 1 newWord = RandomWord.adjs.next #if random number is '1', next word is an adjective else newWord = RandomWord.nouns.next #if random number is not '1', next word is a noun end end puts newWord #prints word for user to type input = gets.chomp if newWord == input #checks if user has typed the word correctly wordsCorrect << newWord.colorize(:green) #changes colour of word to green and pushes it to correct words array else wordsIncorrect << newWord.colorize(:red) #changes colour of word to red and pushes it to incorrect words array end wordsLeft -= 1 #user has typed another word end finishTime = Process.clock_gettime(Process::CLOCK_MONOTONIC) #gets current time and stores it in variable elapsedTime = (finishTime - startingTime) #gets time elapsed by subtracting starting time from the finished time calculate_results(elapsedTime, wordCount, wordsCorrect, wordsIncorrect) #calculate results using elapsed time, how many words the user typed and words that the user got correct/incorrect end |
#calculate_results(elapsedTime, totalWordCount, wordsCorrect, wordsIncorrect) ⇒ Object
188 189 190 191 192 193 194 195 196 |
# File 'lib/typeking/game_controller.rb', line 188 def calculate_results(elapsedTime, totalWordCount, wordsCorrect, wordsIncorrect) puts "Your final time to type #{totalWordCount} words was #{elapsedTime.round} seconds" #tells the user how long it took them to type the designated words puts "Words typed correctly: #{wordsCorrect.join(" ")}" #shows all correctly typed words seperated by a space puts "Words typed incorrectly: #{wordsIncorrect.join(" ")}" #shows all incorrectly typed words seperated by a space puts "Calculating..." puts calculate_speed(elapsedTime, totalWordCount, wordsCorrect) #returns wpm and accuracy puts count_worst_letters(wordsIncorrect) #returns array of top 3 incorrect letters typed home_screen #return to home screen end |
#calculate_speed(elapsedTime, totalWordCount, wordsCorrect) ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/typeking/game_controller.rb', line 220 def calculate_speed(elapsedTime, totalWordCount, wordsCorrect) charactersTyped = 0 #checks how many characters were typed wordsCorrect.each do |word| word = word.green.uncolorize #uncolorizes words so that word size will revert to normal charactersTyped += word.size #adds characters of words to character count end timeMultiplier = 60 / elapsedTime #creates a multiplier to set typing rate to words per minute wordsNormalized = charactersTyped * timeMultiplier #converts characters typed to characters per minute wpm = ((wordsNormalized / 3)).round #wpm = characters typed per minute divided by average characters in words. Average is lower to be more accurate because user has to use the enter button and is not typing sentences accuracy = (wordsCorrect.size.to_f / totalWordCount.to_f) * 100 #accuracy = correct words / total words save_data(wpm, accuracy.to_i) unless wpm < @currentUserData[:high_score]#saves data if user has reached high score return "You type #{wpm.to_s.colorize(:green)} word(s) per minute with #{accuracy.to_i}% accuracy!" #returns wpm and accuracy, outputted by calculate_results end |
#count_worst_letters(incorrectWords) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/typeking/game_controller.rb', line 198 def count_worst_letters(incorrectWords) letter_count = {} #create new array of letters incorrectly typed incorrectWords.each do |word| #loop through each word word = word.red.uncolorize #uncolorize to remove colorize characters letterArr = word.split("") #split word into array of letters letterArr.each do |letter| #loop through each letter if !letter_count[letter] #if letter value is nil, add it to hash letter_count[letter] = 1 else letter_count[letter] += 1 #if letter exists, increment end end end if letter_count.empty? #check if hash is empty, meaning that they got everything correct return "Great job, you got all the words correct!" #calculate_results will puts this to application else final_letters = letter_count.sort_by {|char, c| c}.reverse #sort hash by descending order @currentUserData[:worst_character] = letter_count.max_by{|k, v| v} #change worst character in database to be the key with the highest value return "Here are some characters that you may want to practice: #{final_letters[0]}, #{final_letters[1]}, #{final_letters[2]}" #calculate_results will puts this to terminal end end |
#display_leaders(leaderCount) ⇒ Object
104 105 106 107 108 109 110 111 |
# File 'lib/typeking/game_controller.rb', line 104 def display_leaders(leaderCount) leaders = 0 #current number of users displayed on leaderboard while leaders < leaderCount #loop while displayed leaders is less than actual users leaderHash = @leaderboardArr[leaders] #creates new hash using leaders as the index as the highest score would start from index 0 puts "#{leaders+1}. #{leaderHash[:name]} - WPM: #{leaderHash[:high_score]}, Accuracy: #{leaderHash[:accuracy]}%, Worst Character: #{leaderHash[:worst_character]}" #uses hash to output leaderboards leaders += 1 #increment leaders end end |
#help ⇒ Object
56 57 58 59 60 61 |
# File 'lib/typeking/game_controller.rb', line 56 def help puts "1. Register" puts "2. Login" puts "3. Play" puts "4. Check your stats" end |
#home_screen ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/typeking/game_controller.rb', line 128 def home_screen entryPrompt = TTY::Prompt.new #creates new prompt entryChoices = {Play: 1, Stats: 2, "Log out": 3} #options to choose from choice = entryPrompt.select("Hello #{@currentUserData[:name]}, what would you like to do?", entryChoices) #receives choice input if choice == 1 #play game selected start_game #starts game elsif choice == 2 #stats selected puts show_stats #show user stats home_screen #restart method else start_screen #logs out end end |
#save_data(wpm, accuracy) ⇒ Object
234 235 236 237 238 |
# File 'lib/typeking/game_controller.rb', line 234 def save_data(wpm, accuracy) @currentUserData[:high_score] = wpm #updates highest wpm @currentUserData[:accuracy] = accuracy #updates accuracy @userData[@currentUid] = @currentUserData #updates database with current user data end |
#setup_application ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/typeking/game_controller.rb', line 21 def setup_application system("clear") #clears terminal artOpts = Artii::Base.new :font => 'slant' #create artii options using Artii Ruby gem puts artOpts.asciify('Type King').colorize(:blue) #apply artii style to string to output to the application if ARGV[0] == "-h" #command line argument that calls help function gameController.help else ARGV.each do |i| attempt_registration(i.chomp) #command line argument that registers each user end end while ARGV.size > 0 #loop while there are elements in ARGV ARGV.shift #delete ARGV so that application can get input later using 'gets' end start_screen end |
#show_leaderboards ⇒ Object
113 114 115 116 117 118 119 120 121 |
# File 'lib/typeking/game_controller.rb', line 113 def show_leaderboards @leaderboardArr = @userData.dup #creates a new duplicate array of all user data puts "No entries yet!" unless @leaderboardArr.count > 0 #output when no users in data @leaderboardArr.sort_by!{|w| w[:high_score]} #sort by ascending order @leaderboardArr = @leaderboardArr.reverse #reverse order to descending leaderCount = @leaderboardArr.count #checks how many users are in the array display_leaders(leaderCount) #calls method based on number of users start_screen #return to starting screen end |
#show_stats ⇒ Object
123 124 125 126 |
# File 'lib/typeking/game_controller.rb', line 123 def show_stats @currentUserData = @userData[@currentUid] #double check that the stats shown are the highest, this line is used for testing return "Name: #{@currentUserData[:name]}, WPM: #{@currentUserData[:high_score]}, Accuracy: #{@currentUserData[:accuracy]}, Least accurate letter: #{@currentUserData[:worst_character]}" #home_screen will puts this to application end |
#start_game ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/typeking/game_controller.rb', line 142 def start_game wordsPrompt = TTY::Prompt.new #creates new prompt words = wordsPrompt.ask("How many words do you want to type? (enter a number between 5 and 500)", default: 60) #asks user for number of words they would like to type. If no input, defaults to 30 if words.to_i < 5 || words.to_i > 499 #checks if entry is in range puts "Invalid entry, please enter a number larger than 5 and smaller than 500" start_game #restarts method else countdown = 3 #starts countdown to game while countdown > 0 #loops while countown is higher than 0 puts countdown countdown -= 1 sleep 1 #waits 1 second end begin_typing(words) #starts games with chosen number of words end end |
#start_screen ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/typeking/game_controller.rb', line 38 def start_screen startChoices = {Login: 1, "New User": 2, Leaderboards: 3, Help: 4, Exit: 5} #Options for starting screen startPrompt = TTY::Prompt.new #creates new prompt choice = startPrompt.select("Welcome to Type King", startChoices) #receive input for prompt if choice == 1 #user picked Login user_login elsif choice == 2 #user picked New User user_register elsif choice == 3 #user picked Leaderboards show_leaderboards elsif choice == 4 help start_screen else #user picked exit puts "Thank you for playing!" end end |
#user_login ⇒ Object
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/typeking/game_controller.rb', line 82 def user_login loginPrompt = TTY::Prompt.new #creates new prompt username = loginPrompt.ask("What is your name?", default: "Anonymous") #receive prompt input puts(attempt_login(username)) #attempt to login if @userHashes[username] home_screen #if user exists go to home screen else start_screen #otherwise go back to start screen end end |
#user_register ⇒ Object
63 64 65 66 67 68 |
# File 'lib/typeking/game_controller.rb', line 63 def user_register registerPrompt = TTY::Prompt.new #create new prompt username = registerPrompt.ask("What is your name?", default: "Anonymous") #ask for user name, default is 'anonymous' puts attempt_registration(username) #calls attempt_registration method with username to check if user exists start_screen #return to start screen so user can login end |