#################################################################### # Eater "wall-and-loc" # v. 6 # Remembers wall and location of initial impact with an outer wall. # # Requirements: # 1. Eater must change direction in a clockwise manner # on impact with an interior or outer wall. # 2. Eater must remember location of initial "impact" # with an outer wall, and stop when eater reaches it. # 3. Eater must remember which wall it is currently by. # If eater is in a corner, eater must remember two walls. #################################################################### ### # Initialize some variables. # Possible values for ^stop: # - empty (no location stored) # - stored (location stored) # - wait (eater has moved away from location) # - halt (eater has returned to locaiton) ### sp {initialize*state*directions (state ^type state ^superstate nil) --> ( ^rotated-clockwise ) ( ^name north ^rotated east) ( ^name east ^rotated south) ( ^name south ^rotated west) ( ^name west ^rotated north) ( ^initial-location ) ( ^x 0 ^y 0 ^stop empty) ( ^wall none) ( ^coord-to-wall ) ( ^x 1 ^wall west) ( ^x 15 ^wall east) ( ^y 1 ^wall north) ( ^y 15 ^wall south) } ################################################################################## ########################### Remember initial location ############################ ################################################################################## ### # If eater reaches an outher wall for the first time, save eater's location. ### sp {propose*save-location (state ^initial-location ) ( ^io.input-link.eater ) ( ^x ^y ) ( ^x 0 ^y 0) ( ^wall <> none) --> ( ^operator + >) ( ^name save-location ^x ^y ) } sp {apply*save-location (state ^operator ) ( ^name save-location) ( ^x ^y ) ( ^initial-location ) --> ( ^x ^y ^stop stored) ( ^x 0 -) ( ^y 0 -) ( ^stop empty -) } ### # Once eater moves one cell away from the stored location, # switch the stop variable. Next time eater reaches this location, # eater will be forced to stop (i.e. a full circle). ### # Check for horizontal movement sp {propose*switch-stop*horizontally (state ^initial-location ) ( ^io.input-link.eater ) ( ^x ^y ) ( ^stop stored ^x <> ) --> ( ^operator + >) ( ^name switch-stop ^switch wait) } # Check for vertical movement sp {propose*switch-stop*vertically (state ^initial-location ) ( ^io.input-link.eater ) ( ^x ^y ) ( ^stop stored ^y <> ) --> ( ^operator + >) ( ^name switch-stop ^switch wait) } ### # Once eater reaches its initial position (full circle), halt. ### sp {propose*halt-eater (state ^initial-location ) ( ^io.input-link.eater ) ( ^x ^y ) ( ^x ^y ) ( ^stop wait) --> ( ^operator + >) ( ^name switch-stop ^switch halt) } # Change switch value sp {apply*switch-stop (state ^operator ) ( ^name switch-stop ^switch ) ( ^initial-location ) ( ^stop { <> }) --> ( ^stop ) ( ^stop -) } ################################################################################# ########################### Remember current wall(s) ############################ ################################################################################# ### # If eater is not by an outer wall, make sure that the only wall added is "none." ### sp {propose*no-walls (state ^io.input-link.eater ) ( ^x { > 1 < 15 }) ( ^y { > 1 < 15 }) - ( ^wall none) --> ( ^operator + >) ( ^name add-wall ^wall none) } ### # Eater is by an outer wall ("this"), but not in the corner. # Add this wall, make sure no other exists. ### # Horizontally (north or south) sp {propose*add-horizontal-wall (state ^io.input-link.eater ) ( ^y ^x { > 1 < 15 } ) ( ^coord-to-wall ) ( ^y ^wall ) - ( ^wall ) --> ( ^operator + >) ( ^name add-wall ^wall ) } # Horizontally (north or south): Remove other walls sp {propose*remove-but-horizontal-wall (state ^io.input-link.eater ) ( ^y ^x { > 1 < 15 } ) ( ^coord-to-wall ) ( ^y ^wall ) ( ^wall { <> }) --> ( ^operator + =) ( ^name remove-wall ^wall ) } # Vertically (east or west) sp {propose*add-vertical-wall (state ^io.input-link.eater ) ( ^x ^y { > 1 < 15 } ) ( ^coord-to-wall ) ( ^x ^wall ) - ( ^wall ) --> ( ^operator + >) ( ^name add-wall ^wall ) } # Vertically (east or west): Remove other walls. sp {propose*remove-but-vertical-wall (state ^io.input-link.eater ) ( ^x ^y { > 1 < 15 } ) ( ^coord-to-wall ) ( ^x ^wall ) ( ^wall { <> }) --> ( ^operator + =) ( ^name remove-wall ^wall ) } ### # Eater is in the corner. Make sure both walls are added. ### # Add vertical wall sp {propose*add-corner-vertical-wall (state ^io.input-link.eater ) ( ^x ^y ) ( ^coord-to-wall ^coord-to-wall ) ( ^x ^wall ) # Match vertical wall ( ^y ^wall ) # Match horizontal wall - ( ^wall ) --> ( ^operator + >) ( ^name add-wall-no-remove ^wall ) } # Add horizontal wall sp {propose*add-corner-horizontal-wall (state ^io.input-link.eater ) ( ^x ^y ) ( ^coord-to-wall ^coord-to-wall ) ( ^x ^wall ) # Match vertical wall ( ^y ^wall ) # Match horizontal wall - ( ^wall ) --> ( ^operator + >) ( ^name add-wall-no-remove ^wall ) } ### # Application. ### # Add one wall, removing any wall that is not "this" sp {apply*add-wall (state ^operator ) ( ^name add-wall ^wall ) ( ^wall { <> }) --> ( ^wall ) ( ^wall -) } # Add one wall, do not remove any walls sp {apply*add-wall-no-remove (state ^operator ) ( ^name add-wall-no-remove ^wall ) --> ( ^wall ) } # Remove any walls other than "this" (need after exiting a corner) sp {apply*remove-wall (state ^operator ) ( ^name remove-wall ^wall ) --> ( ^wall -) } ################################################################################# ################################### Movement #################################### ################################################################################# ### # If eater is facing a wall, rotate eater clockwise ### sp {propose*change-direction (state ^io.input-link ) ( ^eater.direction ) ( ^rotated-clockwise ) ( ^name ^rotated ) ( ^io.input-link.my-location..content wall) --> ( ^eater.direction ) } ### # Keep moving forward, if there is no "halt" signal. ### sp {propose*move (state ^io.input-link ) ( ^eater.direction ) ( ^my-location..content { <> wall }) ( ^initial-location.stop <> halt) --> ( ^operator + <) ( ^name move ^direction )} ### # Apply move ### sp {apply*move (state ^io.output-link
    ) (state ^operator ) ( ^name move ^direction ) --> (
      ^move.direction )} ### # Clean-up to allow next move to be applied ### sp {apply*move*remove-move (state ^io.output-link
        ) (state ^operator.name move) (
          ^move ) ( ^status complete) --> (
            ^move -)}