aboutsummaryrefslogtreecommitdiff
path: root/forward-please
blob: ebb6d4bdcd42cd07ea6ed6b142237caf6655f3b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env ruby

$levels = []

%w(
  01-hub2 02-hub3
  03-switch3
).each do |file|
  require "./#{file}"
end

$level = $levels.shift

def help
  puts <<~EOF
    Commands:
      f {frame} {iface}: forward a frame to iface
      h: this help
      c: click on
      d: show the level description
      a: show the click frames and actions
      q: quit
  EOF
end

$instructions = []

def forward(frame, iface)
  if !$clickframes.keys.include?(frame)
    puts "#{frame} is not a frame in this click"
    return
  end

  if !$level.interfaces.include?(iface)
    puts "#{iface} is not an interface in this device"
    return
  end

  $instructions << [frame, $clickframes[frame].to(iface)]
end

def clickactions
  puts "Click #{$click}:"

  puts "  Interfaces:"
  puts "    #{$level.interfaces.join(", ")}"

  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 = []

  $level.click

  $click += 1
  if $click > $level.clicks
    $click = 1
    $level = $levels.shift
    if $level.nil?
      puts "Demo all done"
      exit 0
    end
    puts
    puts $level.description
    puts
  end

  $clickframes = $level.generate
  clickactions
end

def handle(cmd)
  case cmd.split[0]
  when ?f
    args = cmd.split[1..]
    if args.count == 2
      forward(*args)
    else
      puts "f {frame} {iface}"
    end
  when ?d
    puts $level.description
  when ?a
    clickactions
  when ?c
    click
  when ?q
    exit 0
  when nil
  else
    help
  end
end

puts $level.description
puts

$clickframes = $level.generate
clickactions

loop do
  print ">: "
  handle(gets.strip)
end