Module: Karel::Commands

Included in:
Karel
Defined in:
lib/karel/commands.rb

Constant Summary collapse

INFINITE_LOOP_NUM_STEPS =
1000
CONDITIONS =
{
  :on_beeper    => lambda{ |world,karel,row,column| world.clear?(row,column) && world[row,column].beeper? },
  :front_clear  => lambda{ |world,karel,row,column| world.clear?(*Karel.coordinates_after_move_from(karel.direction,row,column)) },
  :left_clear   => lambda{ |world,karel,row,column| world.clear?(*Karel.coordinates_after_move_from(Karel.left_of(karel.direction),row,column)) },
  :right_clear  => lambda{ |world,karel,row,column| world.clear?(*Karel.coordinates_after_move_from(Karel.right_of(karel.direction),row,column)) },
  :facing_north => lambda{ |world,karel,row,column| karel.direction == :north },
  :facing_south => lambda{ |world,karel,row,column| karel.direction == :south },
  :facing_east  => lambda{ |world,karel,row,column| karel.direction == :east },
  :facing_west  => lambda{ |world,karel,row,column| karel.direction == :west },

  :not_on_beeper    => lambda{ |world,karel,row,column| !CONDITIONS[:on_beeper].call(world,karel,row,column) },
  :front_not_clear  => lambda{ |world,karel,row,column| !CONDITIONS[:front_clear].call(world,karel,row,column) },
  :left_not_clear   => lambda{ |world,karel,row,column| !CONDITIONS[:left_clear].call(world,karel,row,column) },
  :right_not_clear  => lambda{ |world,karel,row,column| !CONDITIONS[:right_clear].call(world,karel,row,column) },
  :not_facing_north => lambda{ |world,karel,row,column| !CONDITIONS[:facing_north].call(world,karel,row,column) },
  :not_facing_south => lambda{ |world,karel,row,column| !CONDITIONS[:facing_south].call(world,karel,row,column) },
  :not_facing_east  => lambda{ |world,karel,row,column| !CONDITIONS[:facing_east].call(world,karel,row,column) },
  :not_facing_west  => lambda{ |world,karel,row,column| !CONDITIONS[:facing_west].call(world,karel,row,column) },
}

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object

Handles calling subroutines defined



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/karel/commands.rb', line 66

def method_missing(sym,*args)
  if !args || args.size == 0
    if @subroutines[sym]
      puts "CALLING #{sym}" if @debug
      @subroutines[sym].call
    else
      super.method_missing(sym,args)
    end
  else
    super.method_missing(sym,args)
  end
end

Instance Method Details

#condition_met?(condition) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
112
# File 'lib/karel/commands.rb', line 109

def condition_met?(condition)
  raise "No such condition #{condition}" unless CONDITIONS[condition]
  CONDITIONS[condition].call(world_instance,karel_instance,*world_instance.karel)
end

#DEBUGObject



18
19
20
21
# File 'lib/karel/commands.rb', line 18

def DEBUG
  @debug = true
  @silent = false
end

#debug_command(command) ⇒ Object



118
119
120
121
122
123
# File 'lib/karel/commands.rb', line 118

def debug_command(command)
  if @debug
    puts "#{karel_instance.num_beepers} beepers> #{command}"
    puts world_instance.to_s
  end
end

#DEFINE(name, &block) ⇒ Object

Raises:



59
60
61
62
63
# File 'lib/karel/commands.rb', line 59

def DEFINE(name,&block)
  raise BadSubroutine unless subroutine_name_ok?(name)
  @subroutines ||= {}
  @subroutines[name.to_sym] = block;
end

#ELSE(&block) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/karel/commands.rb', line 100

def ELSE(&block)
  raise "No IF with this ELSE!" if @last_condition.nil?
  condition = @last_condition
  @last_condition = nil
  unless (condition_met? condition)
    block.call
  end
end

#IF(condition, &block) ⇒ Object



93
94
95
96
97
98
# File 'lib/karel/commands.rb', line 93

def IF(condition,&block)
  if condition_met? condition
    block.call
  end
  @last_condition = condition
end

#ITERATE(num, &block) ⇒ Object



79
80
81
# File 'lib/karel/commands.rb', line 79

def ITERATE(num,&block)
  num.times { block.call }
end

#karel_instanceObject



15
# File 'lib/karel/commands.rb', line 15

def karel_instance; KAREL; end

#MOVEObject

Moves Karel forward one square



29
30
31
32
33
# File 'lib/karel/commands.rb', line 29

def MOVE
  x,y = Karel.coordinates_after_move_from(karel_instance.direction,*world_instance.karel)
  world_instance.karel=[x,y]
  debug_command('MOVE')
end

#PICKBEEPERObject



41
42
43
44
45
46
47
48
49
50
# File 'lib/karel/commands.rb', line 41

def PICKBEEPER
  karel = world_instance.karel
  begin
  world_instance.remove_beeper(*karel)
  karel_instance.put_beeper_in_bag
  rescue NoBeeper => x
    raise Explosion
  end
  debug_command('PICKBEEPER')
end

#PUTBEEPERObject



52
53
54
55
56
57
# File 'lib/karel/commands.rb', line 52

def PUTBEEPER
  karel = world_instance.karel
  karel_instance.remove_beeper_from_bag
  world_instance.add_beeper(*karel)
  debug_command('PUTBEEPER')
end

#SILENTObject



23
24
25
26
# File 'lib/karel/commands.rb', line 23

def SILENT
  @silent = true
  @debug = false
end

#subroutine_name_ok?(name) ⇒ Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/karel/commands.rb', line 114

def subroutine_name_ok?(name)
  name =~ /^[A-Z][A-Z_0-9]*[A-Z]$/
end

#TURNLEFTObject

Turns karel to the left in place



36
37
38
39
# File 'lib/karel/commands.rb', line 36

def TURNLEFT
  karel_instance.turnleft
  debug_command('TURNLEFT')
end

#WHILE(condition, &block) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/karel/commands.rb', line 83

def WHILE(condition,&block)
  steps = 0
  while (condition_met? condition)
    block.call
    steps += 1
    raise PossibleInfiniteLoop if steps > INFINITE_LOOP_NUM_STEPS
  end
end

#WORLD(string) ⇒ Object

Create the world with the given initialization string



6
7
8
9
10
11
12
13
# File 'lib/karel/commands.rb', line 6

def WORLD(string)
  @subroutines ||= {}
  world_instance.create_from_string(string,karel_instance)
  unless @silent
    puts "Initial State"
    puts THE_WORLD.to_s
  end
end

#world_instanceObject



16
# File 'lib/karel/commands.rb', line 16

def world_instance; THE_WORLD; end