From e796ea2d6d3aabe84ff165d8be110506482f895d Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Tue, 7 May 2024 21:27:05 +0100 Subject: Two levels! --- 01-hub2.rb | 3 +- 02-hub3.rb | 34 ++++++++++++++++ forward-please | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ forward-please.rb | 95 --------------------------------------------- frame.rb | 1 + level.rb | 9 +++++ 6 files changed, 159 insertions(+), 96 deletions(-) create mode 100644 02-hub3.rb create mode 100755 forward-please delete mode 100644 forward-please.rb diff --git a/01-hub2.rb b/01-hub2.rb index 40f54bc..2a88ad9 100644 --- a/01-hub2.rb +++ b/01-hub2.rb @@ -1,11 +1,12 @@ require './level' require './frame' -class L1_Hub2 < Level +class Level interfaces %w(1 2) description <<~EOD You are a two-port hub. Your job is to forward frames from one interface to the other. EOD + clicks 3 def self.target(frame) case frame.iface diff --git a/02-hub3.rb b/02-hub3.rb new file mode 100644 index 0000000..8750027 --- /dev/null +++ b/02-hub3.rb @@ -0,0 +1,34 @@ +require './level' +require './frame' + +class Level + interfaces %w(1 2 3) + description <<~EOD + You are now a three-port hub. Your job is to forward frames from one interface to all the others. + EOD + clicks 5 + + def self.target(frame) + case frame.iface + when ?1 + [frame.to(?2), frame.to(?3)] + when ?2 + [frame.to(?1), frame.to(?3)] + when ?3 + [frame.to(?1), frame.to(?2)] + else + puts "ERR" + [] + end + end + + def self.generate + frames = {} + @@interfaces.each do |iface| + next if rand < 0.3 + frames[@@count.to_s] = Frame.new(iface, "Frame #{@@count}") + @@count += 1 + end + frames + end +end diff --git a/forward-please b/forward-please new file mode 100755 index 0000000..70c6986 --- /dev/null +++ b/forward-please @@ -0,0 +1,113 @@ +#!/usr/bin/env ruby + +$levels = %w(01-hub2 02-hub3) +require "./#{$levels.shift}" + +puts Level.description + +def help + puts <<~EOF + Commands: + f {frame} {iface}: forward a frame to iface + h: this help + c: click on + d: show the level description + i: show the interfaces + a: show the click frames and actions + q: quit + EOF +end + +$instructions = [] + +def forward(frame, iface) + $instructions << [frame, $clickframes[frame].to(iface)] +end + +def clickactions + puts "Click #{$click}:" + puts "Frames:" + $clickframes.each do |id, frame| + puts " #{id}: #{frame.description} from Interface #{frame.iface}" + end + + i = 1 + puts "Actions:" + $instructions.each do |instr| + puts " #{i}: Forward frame #{instr[0]} to interface #{instr[1].iface}" + end +end + +$click = 1 + +def click + right = 0 + wrong = 0 + + targetframes = [] + $clickframes.each do |id, frame| + targetframes += Level.target(frame) + end + targetframes.flatten! + + $instructions.each do |id, frame| + if targetframes.include?(frame) + right += 1 + targetframes.delete(frame) + else + wrong += 1 + end + end + wrong += targetframes.count + + puts "#{right} out of #{right+wrong} correct" + + $instructions = [] + + $click += 1 + if $click > Level.clicks + $click = 1 + level = $levels.shift + if level.nil? + puts "Demo all done" + exit 0 + end + require "./#{level}" + puts Level.description + end + + $clickframes = Level.generate + clickactions +end + +def handle(cmd) + case cmd[0] + when ?h + help + when ?f + args = cmd.split[1..] + if args.count == 2 + forward(*args) + else + puts "f {frame} {iface}" + end + when ?d + puts Level.description + when ?i + puts Level.interfaces + when ?a + clickactions + when ?c + click + when ?q + exit 0 + end +end + +$clickframes = Level.generate + +clickactions +loop do + print ">: " + handle(gets.strip) +end diff --git a/forward-please.rb b/forward-please.rb deleted file mode 100644 index c919079..0000000 --- a/forward-please.rb +++ /dev/null @@ -1,95 +0,0 @@ -require './01-hub2.rb' - -$level = L1_Hub2 - -puts $level.description - -def help - puts <<~EOF - Commands: - f {frame} {iface}: forward a frame to iface - h: this help - c: click on - d: show the level description - i: show the interfaces - a: show the click frames and actions - q: quit - EOF -end - -$instructions = [] - -def forward(frame, iface) - $instructions << [frame, $clickframes[frame].to(iface)] -end - -def clickactions - puts "Frames:" - $clickframes.each do |id, frame| - puts " #{id}: #{frame.description} from Interface #{frame.iface}" - end - - i = 1 - puts "Actions:" - $instructions.each do |instr| - puts " #{i}: Forward frame #{instr[0]} to interface #{instr[1].iface}" - end -end - -def click - right = 0 - wrong = 0 - - targetframes = [] - $clickframes.each do |id, frame| - targetframes += $level.target(frame) - end - - $instructions.each do |id, frame| - if targetframes.include?(frame) - right += 1 - targetframes.delete(frame) - else - wrong += 1 - end - end - wrong += targetframes.count - - puts "#{right} out of #{right+wrong} correct" - - $instructions = [] - $clickframes = $level.generate - clickactions -end - -def handle(cmd) - case cmd[0] - when ?h - help - when ?f - args = cmd.split[1..] - if args.count == 2 - forward(*args) - else - puts "f {frame} {iface}" - end - when ?d - puts $level.description - when ?i - puts $level.interfaces - when ?a - clickactions - when ?c - click - when ?q - exit 0 - end -end - -$clickframes = $level.generate - -clickactions -loop do - print ">: " - handle(gets.strip) -end diff --git a/frame.rb b/frame.rb index a8d23e6..a61c547 100644 --- a/frame.rb +++ b/frame.rb @@ -13,6 +13,7 @@ class Frame end def ==(oth) + @description == oth.description && @iface == oth.iface end end diff --git a/level.rb b/level.rb index 21ebc61..1a5cfee 100644 --- a/level.rb +++ b/level.rb @@ -2,6 +2,7 @@ class Level @@interfaces = [] @@description = "" @@count = 0 + @@clicks = 5 attr_accessor :description @@ -20,4 +21,12 @@ class Level @@description = desc end end + + def self.clicks(clicks = nil) + if clicks.nil? + @@clicks + else + @@clicks = clicks + end + end end -- cgit v1.2.1