symbol-holic 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/symbol_holic +40 -0
- data/lib/menu.rb +90 -0
- data/lib/statistics_helper.rb +52 -0
- data/lib/typing_game.rb +81 -0
- data/lib/typing_statistics.rb +128 -0
- data/public/key_scores.json +191 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f7ba03bfbf0a27d6d8529ea8f6c7538f821c9ca7b08328fd9dca2de0ac8d803c
|
4
|
+
data.tar.gz: 7acd1c5ad2ebb6ab5869d6091687129d47d7df5e98bf2848a6c0c4678c294d26
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5332ec3c505c5270194f07beef3d9324756f06511024e23b660780de4867ca20804150963b239e21907865581a9752c4f1e1a9aaedffc99a64cdb6572e4bda5a
|
7
|
+
data.tar.gz: 5c3efa0b5c6f589de8cac9255484efd7aa82bab433556ade8208068ad8dce0820bbf16631cf655d29c181017b6d14c66700c7a5e6129fd4bb6de6d12c146183c
|
data/bin/symbol_holic
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'optparse'
|
3
|
+
require_relative '../lib/menu'
|
4
|
+
require_relative '../lib/typing_statistics'
|
5
|
+
|
6
|
+
# create an instance to display the menu
|
7
|
+
@symbolic = Menu.new
|
8
|
+
|
9
|
+
# Display the menu if there in no arguments passed to the command-line
|
10
|
+
@symbolic.display_menu if ARGV.empty?
|
11
|
+
|
12
|
+
# Set the options for the OptionParser
|
13
|
+
parser = OptionParser.new do |opts|
|
14
|
+
# Print banner for users
|
15
|
+
opts.banner = 'Welcome to Symbol-holic! To run the program type: symbolic [options]'
|
16
|
+
# If user passes in -h or --help then display the help menu
|
17
|
+
opts.on('-h', '--help', 'Display the help menu') do
|
18
|
+
puts opts
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
# If user passes in -d or --display then display their statistics
|
22
|
+
opts.on('-d', '--display', 'Displays the users statistics to the terminal') do
|
23
|
+
@symbolic.display_statistics
|
24
|
+
end
|
25
|
+
# If user passes in -r or --run then start the standard typing game
|
26
|
+
opts.on('-r', '--run', 'Run the standard typing game') do
|
27
|
+
@symbolic.run_game
|
28
|
+
end
|
29
|
+
# If user passes in -t or --targeted then start the targeted typing game
|
30
|
+
opts.on('-t', '--targeted', 'Run the targeted typing game') do
|
31
|
+
@symbolic.targeted_game
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Execute the parser
|
36
|
+
begin
|
37
|
+
parser.parse!
|
38
|
+
rescue OptionParser::InvalidOption
|
39
|
+
puts 'That is an invalid option. Please type -h or --help to see a list of valid options.'
|
40
|
+
end
|
data/lib/menu.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'tty-prompt'
|
2
|
+
require 'json'
|
3
|
+
require 'colorize'
|
4
|
+
require 'tty-pie'
|
5
|
+
require_relative 'typing_game'
|
6
|
+
require_relative 'typing_statistics'
|
7
|
+
|
8
|
+
class Menu
|
9
|
+
def initialize
|
10
|
+
@typing_statistics = TypingStatistics.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def menu_selection
|
14
|
+
# Choices for the user to select at the menu
|
15
|
+
menu_choices = [
|
16
|
+
{ name: 'Start typing', value: '1' },
|
17
|
+
{ name: 'Start targeted typing practice', value: '2' },
|
18
|
+
{ name: 'Display your typing statistics', value: '3' },
|
19
|
+
{ name: 'Reset your typing statistics', value: '4' },
|
20
|
+
{ name: 'Exit', value: '5' }
|
21
|
+
]
|
22
|
+
# TTY prompt with the menu choices, users can select one of these items
|
23
|
+
TTY::Prompt.new.select('Welcome to Symbol-holic!', menu_choices)
|
24
|
+
end
|
25
|
+
|
26
|
+
# This is the loop which runs and displays the menu to the user
|
27
|
+
def display_menu
|
28
|
+
loop do
|
29
|
+
choice = menu_selection.to_i
|
30
|
+
# Start typing game if user selects 'Start Typing'
|
31
|
+
if choice == 1
|
32
|
+
run_game
|
33
|
+
# Start the targeted typing game if user selects 'Start targeted typing practice'
|
34
|
+
elsif choice == 2
|
35
|
+
targeted_game
|
36
|
+
# Display the users statistics if they select 'Display your typing statistics'
|
37
|
+
elsif choice == 3
|
38
|
+
display_statistics
|
39
|
+
# Reset users statistics if they want to
|
40
|
+
elsif choice == 4
|
41
|
+
reset_statistics
|
42
|
+
# Exit the program if the user selects 'Exit'
|
43
|
+
elsif choice == 5
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Added in for the command line arguments. We can call display_statistics on menu and not create a new TypingStatistics instance
|
50
|
+
def display_statistics
|
51
|
+
# If the user hasn't played a game yet, there is no need to display their typing scores
|
52
|
+
# It throws a JSON::ParserError as the file is empty and cannot be parsed
|
53
|
+
@typing_statistics.display_statistics
|
54
|
+
# If it is not empty, display their statistics
|
55
|
+
# If it is empty, display a prompt and let them choose another menu item
|
56
|
+
rescue JSON::ParserError
|
57
|
+
puts
|
58
|
+
puts "You haven't played a game yet. Please play one game and then try again.".colorize(:red)
|
59
|
+
puts
|
60
|
+
end
|
61
|
+
|
62
|
+
# Method for running the game
|
63
|
+
def run_game
|
64
|
+
@typing_game = TypingGame.new
|
65
|
+
@scores = @typing_game.run_game
|
66
|
+
# @scores eg {";"=>[1, 1, 51.413921326711545], ":"=>[1, 0, 79.55781654849564], "#"=>[2, 0, 164.6563074129133]}
|
67
|
+
@typing_statistics.statistics(@scores)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Method for running the targeted typing game
|
71
|
+
def targeted_game
|
72
|
+
@typing_game = TypingGame.new
|
73
|
+
@scores = @typing_game.targeted_game
|
74
|
+
@typing_statistics.statistics(@scores)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Menu option and TTY prompt for deleting all typing statistics
|
78
|
+
def reset_statistics
|
79
|
+
reset_choices = [
|
80
|
+
{ name: 'Yes', value: '1' },
|
81
|
+
{ name: 'No', value: '2' }
|
82
|
+
]
|
83
|
+
choice = TTY::Prompt.new.select('Are you sure?', reset_choices).to_i
|
84
|
+
if choice == 1
|
85
|
+
@typing_statistics.wipe_file
|
86
|
+
elsif choice == 2
|
87
|
+
display_menu
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative 'typing_statistics'
|
2
|
+
|
3
|
+
module StatisticsHelper
|
4
|
+
# An array of all the symbols to be availble to the user
|
5
|
+
SYMBOLS = ['#', '`', '%', '&', '[', '{', '}', '(', '=', '*', ')', '+', ']', '!', '|', '-', '_', '@', '^', '/', '?', '<', '>', '$', '~', ';', ':'].freeze
|
6
|
+
|
7
|
+
# create a randomized array of symbols to guess
|
8
|
+
def self.create_symbol_array
|
9
|
+
randomized_array = []
|
10
|
+
# choose a random symbol out of the array and append to a new array.
|
11
|
+
15.times do
|
12
|
+
randomized_array << SYMBOLS.sample
|
13
|
+
end
|
14
|
+
# ensure that all elements in the array are unique
|
15
|
+
randomized_array
|
16
|
+
end
|
17
|
+
|
18
|
+
# This is a method to get the last 8 keys from the user to make into a new array for targeted practice
|
19
|
+
def self.create_targeted_array
|
20
|
+
worst_key_array = []
|
21
|
+
# Read the users statistics from the file, if there is no data in the file, create an object with 0 as values
|
22
|
+
begin
|
23
|
+
typing_statistics = TypingStatistics.new.read_statistics
|
24
|
+
rescue JSON::ParserError
|
25
|
+
typing_statistics = add_symbols_to_hash
|
26
|
+
end
|
27
|
+
# Get the last 8 hash elements (The users worst keys), by revesing hash and getting the first 8 elements
|
28
|
+
worst_keys = typing_statistics.reverse_each.to_h.first(8)
|
29
|
+
worst_keys.each do |key|
|
30
|
+
worst_key_array << key[0]
|
31
|
+
end
|
32
|
+
worst_key_array
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method creates a randomized array with the worst 8 keys, all represented 3 times and shuffled.
|
36
|
+
def self.randomized_targeted_array
|
37
|
+
randomized_array = []
|
38
|
+
3.times do
|
39
|
+
randomized_array << create_targeted_array.shuffle
|
40
|
+
end
|
41
|
+
randomized_array.flatten
|
42
|
+
end
|
43
|
+
|
44
|
+
# This is called when there is no data stored in the JSON file. It outputs a hash with all the symbols and sets all values to 0
|
45
|
+
def self.add_symbols_to_hash
|
46
|
+
typing_statistics = {}
|
47
|
+
SYMBOLS.each do |item|
|
48
|
+
typing_statistics[item] = [0, 0, 0, 0, 0]
|
49
|
+
end
|
50
|
+
typing_statistics
|
51
|
+
end
|
52
|
+
end
|
data/lib/typing_game.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'json'
|
3
|
+
require 'io/console'
|
4
|
+
require_relative 'statistics_helper'
|
5
|
+
|
6
|
+
class TypingGame
|
7
|
+
# Bring in the StatisticsHelper module
|
8
|
+
# include StatisticsHelper
|
9
|
+
|
10
|
+
# Initialize the typing game
|
11
|
+
def initialize
|
12
|
+
@symbol_array = StatisticsHelper.create_symbol_array
|
13
|
+
@targeted_array = StatisticsHelper.randomized_targeted_array
|
14
|
+
@keypress_statistics = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Run the stardard typing game
|
18
|
+
def run_game
|
19
|
+
# Print each item from the generated symbol array
|
20
|
+
@symbol_array.each do |item|
|
21
|
+
game_logic(item)
|
22
|
+
end
|
23
|
+
@keypress_statistics
|
24
|
+
end
|
25
|
+
|
26
|
+
# Run the targeted typing game
|
27
|
+
def targeted_game
|
28
|
+
@targeted_array.each do |item|
|
29
|
+
game_logic(item)
|
30
|
+
end
|
31
|
+
@keypress_statistics
|
32
|
+
end
|
33
|
+
|
34
|
+
# Calculate the words per minute of each keypress the user types
|
35
|
+
def words_per_min(first_time, second_time)
|
36
|
+
words_per_min = 60 / (second_time - first_time)
|
37
|
+
words_per_min
|
38
|
+
end
|
39
|
+
|
40
|
+
# Calculate the statistics to put into the hash, need to add the values each loop now that you can do multiple keys each run
|
41
|
+
def calculate_statistics(item, wrong_keys, words_per_min)
|
42
|
+
# If there is no value for the key in the hash, then add the current values in
|
43
|
+
if @keypress_statistics[item].nil?
|
44
|
+
# add the words per min, accuracy and 1 (for the amount of times the symbol has been shown)
|
45
|
+
@keypress_statistics[item] = [1, wrong_keys, words_per_min]
|
46
|
+
else
|
47
|
+
# Get the values in the hash and add the values to make a total to pass to the statistics
|
48
|
+
symbol_count = @keypress_statistics[item][0] + 1
|
49
|
+
wrong_keys_count = @keypress_statistics[item][1] + wrong_keys
|
50
|
+
wpm_total = @keypress_statistics[item][2] + words_per_min
|
51
|
+
|
52
|
+
@keypress_statistics[item] = [symbol_count, wrong_keys_count, wpm_total]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# The logic for running the game
|
57
|
+
def game_logic(item)
|
58
|
+
wrong_keys = 0
|
59
|
+
print "#{item} ---> "
|
60
|
+
|
61
|
+
# Get the time at the start of each loop
|
62
|
+
first_time = Time.new.to_f
|
63
|
+
# Get the current user input key, without having to press enter
|
64
|
+
current_input = STDIN.getch
|
65
|
+
|
66
|
+
# Until the user gets the right key, keep prompting them, add keep a total for the amount of wrong keys hit before the correct one
|
67
|
+
while current_input != item
|
68
|
+
print "#{current_input.colorize(:red)}, "
|
69
|
+
current_input = STDIN.getch
|
70
|
+
wrong_keys += 1
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get the time when the user types the correct key
|
74
|
+
second_time = Time.new.to_f if current_input == item
|
75
|
+
puts current_input
|
76
|
+
|
77
|
+
# Call and return the words per minute of each symbol
|
78
|
+
# The game logic returns the calculated statistics of each key each loop
|
79
|
+
calculate_statistics(item, wrong_keys, words_per_min(first_time, second_time))
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'terminal-table'
|
3
|
+
require 'tty-pie'
|
4
|
+
require 'colorize'
|
5
|
+
require 'colorized_string'
|
6
|
+
require_relative 'typing_game'
|
7
|
+
require_relative 'statistics_helper'
|
8
|
+
require 'byebug'
|
9
|
+
class TypingStatistics
|
10
|
+
# The method for taking in the score of the game that the user just played
|
11
|
+
# It then inputs the score into the average statistics for the user
|
12
|
+
# include StatisticsHelper
|
13
|
+
def statistics(scores)
|
14
|
+
# If there is already a hash in the JSON File, then read it or else create a new blank hash (Will only be first time user runs game)
|
15
|
+
begin
|
16
|
+
read_statistics
|
17
|
+
rescue JSON::ParserError
|
18
|
+
# Create an instanced empty hash so the score can be appended to it, as it will be nil otherwise and throw an error
|
19
|
+
@averaged_statistics = StatisticsHelper.add_symbols_to_hash if @averaged_statistics.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Take the scores hash of the last completed typing game and append them to the averaged_statistics hash
|
23
|
+
scores.each do |key, val|
|
24
|
+
# Storing the amount of times each symbol has been displayed to the averaged hash
|
25
|
+
@averaged_statistics[key][0] = total_count(@averaged_statistics[key][0], val[0])
|
26
|
+
# Storing the total amount of errors the user has made
|
27
|
+
@averaged_statistics[key][1] = total_count(@averaged_statistics[key][1], val[1])
|
28
|
+
# Storing the average accuracy for the user
|
29
|
+
@averaged_statistics[key][2] = average_accuracy(@averaged_statistics[key][0], @averaged_statistics[key][1])
|
30
|
+
# Storing the total wpm
|
31
|
+
@averaged_statistics[key][3] = total_count(@averaged_statistics[key][3], val[2])
|
32
|
+
# Storing the average WPM to the averaged hash
|
33
|
+
@averaged_statistics[key][4] = average_wpm(@averaged_statistics[key][3], @averaged_statistics[key][0])
|
34
|
+
end
|
35
|
+
# Write the statistics at the end of each game into the JSON file
|
36
|
+
write_statistics(sort_averaged_statistics(@averaged_statistics))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Total counter method to assist with setting the key values
|
40
|
+
def total_count(total, addition)
|
41
|
+
total += addition
|
42
|
+
total
|
43
|
+
end
|
44
|
+
|
45
|
+
# Average accuracy method to assist with setting the key values
|
46
|
+
def average_accuracy(total_symbol_count, total_error_count)
|
47
|
+
((total_symbol_count / (total_symbol_count + total_error_count).to_f) * 100).round(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Average Words Per Minute method to assist with setting the key values
|
51
|
+
def average_wpm(total_wpm, total_symbol_count)
|
52
|
+
(total_wpm / total_symbol_count).round(1)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sort the users average scores by adding the average speed and accuracy, this is the indication of a good key
|
56
|
+
def sort_averaged_statistics(averaged_statistics)
|
57
|
+
# This converts the hash into a sorted array
|
58
|
+
sorted_array = averaged_statistics.sort_by { |_key, val| -(val[2] + val[4]) }
|
59
|
+
# Convert the array back to a hash for processing
|
60
|
+
@averaged_statistics = sorted_array.to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
# Used for getting the absolute file path, wherever the user is. For when the user runs program from anywhere.
|
64
|
+
def file_path
|
65
|
+
path = File.dirname(__FILE__).split('/')
|
66
|
+
path.pop
|
67
|
+
json_file = "#{path.join('/')}/public/key_scores.json"
|
68
|
+
json_file
|
69
|
+
end
|
70
|
+
|
71
|
+
# Read and parse the averaged_statistics hash from the JSON file
|
72
|
+
def read_statistics
|
73
|
+
file = File.read(file_path)
|
74
|
+
@averaged_statistics = JSON.parse(file)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Write the averaged_statistics hash to the JSON file
|
78
|
+
def write_statistics(averaged_statistics)
|
79
|
+
File.write(file_path, JSON.pretty_generate(averaged_statistics))
|
80
|
+
end
|
81
|
+
|
82
|
+
# Make a pie chart for the hit and miss count
|
83
|
+
def make_pie_chart(total_hit, total_miss)
|
84
|
+
data = [
|
85
|
+
{ value: total_hit, color: :bright_green, fill: '•' },
|
86
|
+
{ value: total_miss, color: :bright_red, fill: '•' }
|
87
|
+
]
|
88
|
+
# Create the pie chart
|
89
|
+
pie_chart = TTY::Pie.new(data: data, radius: 2)
|
90
|
+
pie_chart.render
|
91
|
+
# It will throw a type error for nil values, in that case return a string
|
92
|
+
rescue TypeError
|
93
|
+
'no data yet'
|
94
|
+
end
|
95
|
+
|
96
|
+
# Display the statistics in a terminal table, for the users to read.
|
97
|
+
def display_statistics
|
98
|
+
# Read the current JSON file to get the averaged_statistics hash
|
99
|
+
read_statistics
|
100
|
+
# Make a terminal table and add in values from averaged_statistics hash
|
101
|
+
@rows = []
|
102
|
+
counter = 0
|
103
|
+
@averaged_statistics.each do |key, val|
|
104
|
+
# Set the color of the accuracy to red if the users accuracy is less than 60
|
105
|
+
val[2] = val[2].to_s.colorize(:red) if val[2].positive? && val[2] < 60
|
106
|
+
# Set the color of the WPM if the user WPM is under 50
|
107
|
+
val[4] = val[4].to_s.colorize(:yellow) if val[4] < 40 && val[4] != 0
|
108
|
+
|
109
|
+
# Add each symbol and associated data to the terminal-table row
|
110
|
+
@rows << [key, val[4], val[2], val[0], make_pie_chart(val[0], val[1])]
|
111
|
+
counter += 1
|
112
|
+
# Print a seperator for each symbol apart from the last
|
113
|
+
@rows << :separator if counter < @averaged_statistics.size
|
114
|
+
end
|
115
|
+
table = Terminal::Table.new title: 'Your Typing Statistics', headings: ['Symbol', 'Average WPM', 'Average Accuracy %', 'Symbol Count', 'Hit/Miss'], rows: @rows
|
116
|
+
table.align_column(0, :center)
|
117
|
+
table.align_column(1, :center)
|
118
|
+
table.align_column(2, :center)
|
119
|
+
table.align_column(3, :center)
|
120
|
+
puts table
|
121
|
+
end
|
122
|
+
|
123
|
+
# The method for wiping the JSON file if the user wants to.
|
124
|
+
def wipe_file
|
125
|
+
File.truncate(file_path, 0)
|
126
|
+
@averaged_statistics = StatisticsHelper.add_symbols_to_hash
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
{
|
2
|
+
"]": [
|
3
|
+
1,
|
4
|
+
0,
|
5
|
+
100.0,
|
6
|
+
80.65385007368056,
|
7
|
+
80.7
|
8
|
+
],
|
9
|
+
"+": [
|
10
|
+
1,
|
11
|
+
0,
|
12
|
+
100.0,
|
13
|
+
80.44000343932484,
|
14
|
+
80.4
|
15
|
+
],
|
16
|
+
"=": [
|
17
|
+
1,
|
18
|
+
0,
|
19
|
+
100.0,
|
20
|
+
70.5913716690042,
|
21
|
+
70.6
|
22
|
+
],
|
23
|
+
":": [
|
24
|
+
1,
|
25
|
+
0,
|
26
|
+
100.0,
|
27
|
+
69.76731497920217,
|
28
|
+
69.8
|
29
|
+
],
|
30
|
+
"?": [
|
31
|
+
1,
|
32
|
+
0,
|
33
|
+
100.0,
|
34
|
+
65.65189953827343,
|
35
|
+
65.7
|
36
|
+
],
|
37
|
+
"!": [
|
38
|
+
1,
|
39
|
+
0,
|
40
|
+
100.0,
|
41
|
+
61.146865271855916,
|
42
|
+
61.1
|
43
|
+
],
|
44
|
+
"~": [
|
45
|
+
2,
|
46
|
+
0,
|
47
|
+
100.0,
|
48
|
+
121.33804636798443,
|
49
|
+
60.7
|
50
|
+
],
|
51
|
+
"<": [
|
52
|
+
1,
|
53
|
+
1,
|
54
|
+
50.0,
|
55
|
+
74.72060190202465,
|
56
|
+
74.7
|
57
|
+
],
|
58
|
+
"[": [
|
59
|
+
1,
|
60
|
+
1,
|
61
|
+
50.0,
|
62
|
+
48.07993942871095,
|
63
|
+
48.1
|
64
|
+
],
|
65
|
+
"#": [
|
66
|
+
1,
|
67
|
+
1,
|
68
|
+
50.0,
|
69
|
+
43.6055298977032,
|
70
|
+
43.6
|
71
|
+
],
|
72
|
+
";": [
|
73
|
+
1,
|
74
|
+
1,
|
75
|
+
50.0,
|
76
|
+
35.173707560569056,
|
77
|
+
35.2
|
78
|
+
],
|
79
|
+
"-": [
|
80
|
+
1,
|
81
|
+
1,
|
82
|
+
50.0,
|
83
|
+
33.937701778754736,
|
84
|
+
33.9
|
85
|
+
],
|
86
|
+
"|": [
|
87
|
+
2,
|
88
|
+
3,
|
89
|
+
40.0,
|
90
|
+
58.942454911783514,
|
91
|
+
29.5
|
92
|
+
],
|
93
|
+
"`": [
|
94
|
+
0,
|
95
|
+
0,
|
96
|
+
0,
|
97
|
+
0,
|
98
|
+
0
|
99
|
+
],
|
100
|
+
"%": [
|
101
|
+
0,
|
102
|
+
0,
|
103
|
+
0,
|
104
|
+
0,
|
105
|
+
0
|
106
|
+
],
|
107
|
+
"&": [
|
108
|
+
0,
|
109
|
+
0,
|
110
|
+
0,
|
111
|
+
0,
|
112
|
+
0
|
113
|
+
],
|
114
|
+
"{": [
|
115
|
+
0,
|
116
|
+
0,
|
117
|
+
0,
|
118
|
+
0,
|
119
|
+
0
|
120
|
+
],
|
121
|
+
"}": [
|
122
|
+
0,
|
123
|
+
0,
|
124
|
+
0,
|
125
|
+
0,
|
126
|
+
0
|
127
|
+
],
|
128
|
+
"(": [
|
129
|
+
0,
|
130
|
+
0,
|
131
|
+
0,
|
132
|
+
0,
|
133
|
+
0
|
134
|
+
],
|
135
|
+
"*": [
|
136
|
+
0,
|
137
|
+
0,
|
138
|
+
0,
|
139
|
+
0,
|
140
|
+
0
|
141
|
+
],
|
142
|
+
")": [
|
143
|
+
0,
|
144
|
+
0,
|
145
|
+
0,
|
146
|
+
0,
|
147
|
+
0
|
148
|
+
],
|
149
|
+
"_": [
|
150
|
+
0,
|
151
|
+
0,
|
152
|
+
0,
|
153
|
+
0,
|
154
|
+
0
|
155
|
+
],
|
156
|
+
"@": [
|
157
|
+
0,
|
158
|
+
0,
|
159
|
+
0,
|
160
|
+
0,
|
161
|
+
0
|
162
|
+
],
|
163
|
+
"^": [
|
164
|
+
0,
|
165
|
+
0,
|
166
|
+
0,
|
167
|
+
0,
|
168
|
+
0
|
169
|
+
],
|
170
|
+
"/": [
|
171
|
+
0,
|
172
|
+
0,
|
173
|
+
0,
|
174
|
+
0,
|
175
|
+
0
|
176
|
+
],
|
177
|
+
">": [
|
178
|
+
0,
|
179
|
+
0,
|
180
|
+
0,
|
181
|
+
0,
|
182
|
+
0
|
183
|
+
],
|
184
|
+
"$": [
|
185
|
+
0,
|
186
|
+
0,
|
187
|
+
0,
|
188
|
+
0,
|
189
|
+
0
|
190
|
+
]
|
191
|
+
}
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: symbol-holic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rory Musinskas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.3.1
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.3'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.3.1
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: terminal-table
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.8'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.8'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: tty-pie
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.4.0
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.4.0
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: tty-prompt
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.22.0
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.22.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: tty-reader
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.8.0
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.8.0
|
103
|
+
description: A simple symbol typing game
|
104
|
+
email:
|
105
|
+
executables:
|
106
|
+
- symbol_holic
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- bin/symbol_holic
|
111
|
+
- lib/menu.rb
|
112
|
+
- lib/statistics_helper.rb
|
113
|
+
- lib/typing_game.rb
|
114
|
+
- lib/typing_statistics.rb
|
115
|
+
- public/key_scores.json
|
116
|
+
homepage:
|
117
|
+
licenses: []
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
- public
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '2.4'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubygems_version: 3.1.4
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Symbolic!
|
139
|
+
test_files: []
|