require "big" require "random" require "../util.cr" struct AmongUs::Program < Flint::Program def interpret : Nil rand = Random.new code = Parser.new(@source_io).parse jumps = find_jumps(code) code_ptr = 0 stack = [] of BigInt acc1 = BigInt.new acc2 = BigInt.new color = code.find &.is_a?(Color) while code_ptr < code.size case code[code_ptr] in Color::RED color = Color::RED in Color::BLUE color = Color::BLUE in Color::PURPLE color = Color::PURPLE in Color::GREEN color = Color::GREEN in Color::YELLOW color = Color::YELLOW in Color::CYAN color = Color::CYAN in Color::BLACK color = Color::BLACK in Color::WHITE color = Color::WHITE in Color::BROWN color = Color::BROWN in Color::LIME color = Color::LIME in Color::PINK color = Color::PINK in Color::ORANGE color = Color::ORANGE in Command::SUS case color when Color::RED acc1 += 1 when Color::BLUE stack << BigInt.new(acc1) when Color::PURPLE stack.pop unless stack.empty? when Color::GREEN print (stack.pop % 256).to_u8.chr unless stack.empty? when Color::YELLOW c = STDIN.read_char stack << BigInt.new(c.ord) unless c.nil? when Color::CYAN r = rand.rand(acc1 + 1) r.times do break if stack.empty? stack.pop end when Color::BLACK print stack.pop when Color::WHITE acc1 -= 1 when Color::BROWN acc1 = stack.pop when Color::LIME stack[-1] *= 2 when Color::PINK acc1 = 0 when Color::ORANGE acc1 += 10 when nil raise Util::InterpreterError.new("Tried to use SUS command with no color.") end in Command::VENTED acc2 += 10 in Command::SUSSY acc2 -= 1 in Command::ELECTRICAL acc2 = 0 in Command::WHO code_ptr = jumps[code_ptr] if !stack.empty? && stack[-1] % 256 == acc2 % 256 in Command::WHERE code_ptr = jumps[code_ptr] if !stack.empty? && stack[-1] % 256 != acc2 % 256 end code_ptr += 1 end end private def find_jumps(code : Array(Instruction)) : Hash(Int32, Int32) jumps = {} of Int32 => Int32 stack = [] of Int32 code.each_index do |i| case code[i] when Command::WHO stack << i when Command::WHERE jumps[i] = stack.pop jumps[jumps[i]] = i end end return jumps end end