Class: Fretboard
- Inherits:
-
Object
- Object
- Fretboard
- Defined in:
- lib/fretboard.rb
Overview
Fretboard class for learning the guitar fretboard.
Constant Summary collapse
- FRETS =
12
- STRINGS =
6
- VERSION =
'0.0.10'
Class Method Summary collapse
Instance Method Summary collapse
-
#display(sharps = true) ⇒ Object
Display an ASCII chart of the guitar fretboard.
-
#initialize(args) ⇒ Fretboard
constructor
A new instance of Fretboard.
-
#run ⇒ Object
Run the main query loop for the fretboard trainer.
-
#to_s ⇒ Object
(also: #inspect)
Return string representation of Fretboard instance.
Constructor Details
#initialize(args) ⇒ Fretboard
Returns a new instance of Fretboard.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 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 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/fretboard.rb', line 123 def initialize(args) @timeout = args[:timeout] || 0 if args.has_key?(:fret) a = args[:fret] @first_fret = a[0].to_i @last_fret = a.size == 2 ? a[1].to_i : @first_fret else @first_fret = 0 @last_fret = FRETS end if @first_fret < 0 || @first_fret > FRETS || @last_fret < 0 || @last_fret > FRETS || @first_fret > @last_fret raise ArgumentError, "Invalid FRET value/range specified" end if args.has_key?(:string) a = args[:string] @first_string = a[0].to_i @last_string = a.size == 2 ? a[1].to_i : @first_string else @first_string = 1 @last_string = STRINGS end if @first_string < 1 || @first_string > STRINGS || @last_string < 1 || @last_string > STRINGS || @first_string > @last_string raise ArgumentError, "Invalid STRING value/range specified" end @logfile = nil if args.has_key?(:logfile) @logfile = File.open(args[:logfile], "a") end @frets=(0..FRETS) @strings=(0..STRINGS-1) scale_sharps = %w(A A# B C C# D D# E F F# G G#) scale_flats = %w(A Bb B C Db D Eb E F Gb G Ab) accidentals = [1, 4, 6, 9, 11] # This is for the standard EADGBE tuning scale_index = [7, 2, 10, 5, 0, 7] @fretboard = [] # # Fretboard is an array of strings indexed by fret number # row = [] @frets.each do |i| @strings.each do |j| s = (scale_index[j] + i) % 12 # For positions which contain accidentals, represent both # sharps and flats for the given string and fret with a # subarray. if accidentals.include?(s) row[j] = [scale_sharps[s], scale_flats[s]] else row[j] = scale_sharps[s] end s = (s == scale_sharps.size - 1) ? 0 : s + 1 end @fretboard << row row = [] end if args.has_key?(:show_fretboard) self.display(args[:show_fretboard] == "sharp" ? true : false) end # Select random fret and string numbers from within the specified # ranges @fret_max = @last_fret - @first_fret + 1 @string_max = @last_string - @first_string + 1 rescue => e puts "Error: " + e exit 1 end |
Class Method Details
.display_version ⇒ Object
72 73 74 |
# File 'lib/fretboard.rb', line 72 def self.display_version puts "#{File.basename(__FILE__)} version #{VERSION}" end |
.parse_args(args) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/fretboard.rb', line 76 def self.parse_args(args) = Hash.new op = OptionParser.new do |opts| opts.on("-t SECONDS", "--timeout SECONDS", "Set timeout on prompt") do |opt| [:timeout] = opt.to_i end opts.on("-f MIN[:MAX]", "--fret MIN[:MAX]", "Set fret number(s) to drill (default 0-12)") do |opt| o = opt.split(":") o.each { |s| s.strip! } [:fret] = o end opts.on("-s MIN[:MAX]", "--string MIN[:MAX]", "Set string number(s) on which to drill", "(default 1-6)") do |opt| o = opt.split(":") o.each { |s| s.strip! } [:string] = o end opts.on("-d [0|1]", "--display [FLAT|SHARP]", "Show fretboard") do |opt| [:show_fretboard] = opt end opts.on("-l LOGFILE", "--log LOGFILE", "Log score to LOGFILE") do |opt| [:logfile] = opt end opts.on("-v", "--version", "Show version") do display_version exit 0 end end begin op.parse!(args) rescue OptionParser::ParseError => e puts e exit 1 end end |
Instance Method Details
#display(sharps = true) ⇒ Object
Display an ASCII chart of the guitar fretboard
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/fretboard.rb', line 210 def display(sharps = true) nut = " ===============================\n" pos = " %2d | %-2s | %-2s | %-2s | %-2s | %-2s | %-2s |\n" fret = " +-----------------------------+\n" @fretboard.each_with_index do |row, i| r = *row.reverse r.each_with_index do |e, j| if r[j].is_a?(Array) slot = sharps ? 0 : 1 r[j, 1] = r[j][slot] end end if i == 0 printf(pos, i, *r) puts nut next end printf(pos, i, *r) puts fret end end |
#run ⇒ Object
Run the main query loop for the fretboard trainer.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/fretboard.rb', line 260 def run i = 1 errors = 0 at_exit do puts "\n\nYou missed #{errors} out of #{i}.\n\n" if @logfile t = Time.now @logfile.puts "[#{t}] String #{@first_string}:#{@last_string}, " + "Fret #{@first_fret}:#{@last_fret} -- Missed #{errors} out of #{i}" end end # Skip stack traceback on ctrl-c trap("SIGINT") { exit } loop do s = @first_string + rand(@string_max) f = @first_fret + rand(@fret_max) printf("\n[#{i}] String #{s}, fret #{f}\n") printf("? ") $stdout.flush ans, timed_out = gets ans = ans.chomp.downcase note = @fretboard[f][s-1] correct = false if note.is_a?(Array) puts " #{note[0]} / #{note[1]}" if ans == note[0].downcase || ans.downcase == note[1].downcase correct = true end else puts " #{@fretboard[f][s-1]}" if ans.upcase == @fretboard[f][s-1].to_s correct = true end end if correct puts green(bold("Correct.")) else errors += 1 puts red(bold("Incorrect.")) + (timed_out ? " [Timeout]" : "") if timed_out printf("\nContinue? ") $stdin.gets end end i += 1 end end |
#to_s ⇒ Object Also known as: inspect
Return string representation of Fretboard instance.
234 235 236 237 238 239 240 |
# File 'lib/fretboard.rb', line 234 def to_s str = "" @frets.each_with_index do |f, i| str << "#{i}: " + @fretboard[f].reverse.inspect + "\n" end str end |