symbol-holic 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|