-- learn and randomly walk a grid -- keep a record of the pathway home -- if find food return home, leaving a scent trail -- once home, follow scent trail back to food (approximately) -- if find food again, return home, adding to the scent trail -- when reach home, store the food, switch off scent trail, and start randomly walking again -- need three walk types: -- randomly -- return home -- follow scent trail (inside random-walk for now) -- learn map: |null> => learn-map[30, 30] |> -- learn current location: current |cell> => |grid: 10: 22> -- learn home location: home |cell> => current |cell> -- start with no food at home: stored-food home |cell> => 0| > -- learn path home: store-direction (*) #=> path |home> +=> |__self> -- find return path return-path |home> #=> invert-direction expand path |home> -- NB: |_self> works here, so don't need the slower |__self> invert-direction |*> #=> if(is-less-than[0] push-float |_self>, - |_self>, reverse-dir |_self> ) -- learn the list of directions: list-of |directions> => |op: N> + |op: NE> + |op: E> + |op: SE> + |op: S> + |op: SW> + |op: W> + |op: NW> -- choose a heading when leaving the nest: heading |ops> => pick-elt list-of |directions> -- start by not carrying any food: carry |food> => 0| > -- start with scent trail off: lay |scent> => |no> -- start with random walk type: type |walk> => |op: random-walk> -- place some food: food |grid: 2: 2> => 3| > food |grid: 2: 3> => 3| > food |grid: 2: 4> => 3| > food |grid: 2: 5> => 3| > food |grid: 3: 5> => 3| > food |grid: 4: 5> => 3| > food |grid: 5: 6> => 3| > food |grid: 6: 6> => 3| > food |grid: 29: 29> => 20| > food |grid: 28: 3> => 20| > -- show food and stored-food operators: show-food |*> #=> display-map[30, 30, food] |> show-stored-food |*> #=> display-map[30, 30, stored-food] |> -- carry-the and drop-the food operators: -- currently assumes food current |cell> is greater than 0. carry-the |food> #=> food current |cell> => decrement food current |cell> carry |food> => increment carry |food> drop-the |food> #=> stored-food current |cell> +=> carry |food> carry |food> => 0| > -- if there is food at the current cell, and not already carrying food, then |found food>: if-find-food |*> #=> process-if if( and(is-greater-than[0] push-float food current |cell>, is-equal[0] push-float carry |food>), |found food>, |not found food> ) process-if |found food> #=> -- carry the food: food current |cell> => decrement food current |cell> carry |food> => increment carry |food> lay |scent> => |yes> type |walk> => |op: return-home> process-if |not found food> #=> |> -- if reach home operator: -- ie, if current cell is home cell then |reached home>: if-reach-home |*> #=> process-if if(is-equal( current |cell>, home |cell>), |reached home>, |not reached home>) process-if |reached home> #=> -- drop and store any food you are carrying: stored-food current |cell> +=> carry |food> carry |food> => 0| > lay |scent> => |no> type |walk> => |op: random-walk> path |home> => |home> process-if |not reached home> #=> |> record-scent |*> #=> process-if if(lay |scent>, |yes to scent>, |no to scent>) process-if |yes to scent> #=> value current |cell> => plus[1] value current |cell> process-if |no to scent> #=> |> if-find-scent-change-heading |*> #=> process-if if(is-greater-than[0] value |_self>, |found scent> , |not found scent>) process-if |found scent> #=> heading |ops> => random-if-zero reverse-dir return-path |home> process-if |not found scent> #=> |> random-if-zero (*) #=> if(do-you-know sdrop |_self>, |_self>, pick-elt list-of |directions>) switch-on-random |*> #=> type |walk> => |op: random-walk> switch-on-return |*> #=> type |walk> => |op: return-home> take-a-step |*> #=> current |direction> => apply( type |walk>, current |cell>) path |home> +=> current |direction> current |cell> => apply( current |direction>, current |cell>) if-find-food |> if-reach-home |> -- random-walk input is a grid location: -- random-walk has to return a direction: random-walk |*> #=> if-find-scent-change-heading |__self> -- blur heading: heading |ops> => normalize ( 0.1 turn-left^2 + 0.25 turn-left + 15 + 0.25 turn-right + 0.1 turn-right^2 ) heading |ops> -- try a direction: try |direction> => clean weighted-pick-elt heading |ops> -- if valid direction, step, else turn right: process-if if(do-you-know apply( try |direction>, |__self>), |valid step>, |not valid step>) process-if |valid step> #=> try |direction> process-if |not valid step> #=> -- turn heading right: heading |ops> => pick-elt ( turn-right + turn-right^2 ) heading |ops> |op: id> -- define turn-heading-right operator: turn-heading-right |*> #=> heading |ops> => pick-elt ( turn-right + turn-right^2 ) heading |ops> -- define blur-heading operator: blur-heading |*> #=> heading |ops> => ( 0.1 turn-left^2 + 0.25 turn-left + 10 + 0.25 turn-right + 0.1 turn-right^2 ) heading |ops> -- return-home input is a grid location (which we ignore, instead making use of return-path |home>): -- return-home returns a direction one step closer to home: return-home |*> #=> clean weighted-pick-elt return-path |home> -- define identity direction operator: id |*> #=> |_self> -- define turn-right operators: turn-right |op: S> => |op: SW> turn-right |op: SW> => |op: W> turn-right |op: W> => |op: NW> turn-right |op: NW> => |op: N> turn-right |op: N> => |op: NE> turn-right |op: NE> => |op: E> turn-right |op: E> => |op: SE> turn-right |op: SE> => |op: S> -- define turn-left operators: turn-left |op: S> => |op: SE> turn-left |op: SW> => |op: S> turn-left |op: W> => |op: SW> turn-left |op: NW> => |op: W> turn-left |op: N> => |op: NW> turn-left |op: NE> => |op: N> turn-left |op: E> => |op: NE> turn-left |op: SE> => |op: E> -- define reverse operators: reverse-dir |op: S> => |op: N> reverse-dir |op: SW> => |op: NE> reverse-dir |op: W> => |op: E> reverse-dir |op: NW> => |op: SE> reverse-dir |op: N> => |op: S> reverse-dir |op: NE> => |op: SW> reverse-dir |op: E> => |op: W> reverse-dir |op: SE> => |op: NW> -- define expand operators: expand |op: S> => - |op: N> expand |op: SW> => - |op: N> - |op: E> expand |op: W> => - |op: E> expand |op: NW> => |op: N> - |op: E> expand |op: N> => |op: N> expand |op: NE> => |op: N> + |op: E> expand |op: E> => |op: E> expand |op: SE> => - |op: N> + |op: E> d |*> #=> display-map[30,30] -- single map update: update |*> #=> record-scent |> take-a-step |> d |> |> -- set max steps: max |steps> => |20> -- walk max steps: walk |*> #=> update range(|1>, max |steps>)