module M { public Main () : void { def stmts = ants { vars (compass (6), { /* ------------------------------------------------------------------- */ /* -- ROLE DECIDER --------------------------------------------------- */ /* ------------------------------------------------------------------- */ if (rand (9)) { goto (anthill_worker_ant); } else { goto (wanderer_ant); }; /* ------------------------------------------------------------------- */ /* -- WANDERER ANT --------------------------------------------------- */ /* ------------------------------------------------------------------- */ label (wanderer_ant); if (home ^ here) { move_timeout (1); } else { // priority number one: the food we're standing on when (food ^ here) { goto (pick_up_food); }; // priority number two: the food ahead of us if (food ^ front) { goto (wanderer_ant_food_ahead); } else if (food ^ left) { turn (left); goto (wanderer_ant_food_ahead); } else when (food ^ right) { turn (right); goto (wanderer_ant_food_ahead); }; // priority number three: following the food paths when (marker (B_FOOD) ^ here) { goto (on_food_trail); }; // priority number four: build the map's DFS tree goto (dfs_find_unmarked_neighbour); }; /* -- WANDERER ANT: FOOD AHEAD --------------------------------------- */ label (wanderer_ant_food_ahead); mark (B_FOOD); if (move) { when (!(vector ^ here)) mark_rev_compass; goto (wanderer_ant); } else { if (rand (2)) { turn (left); move; when (!(vector ^ here)) mark_rev_compass; turn (right); } else { turn (right); move; when (!(vector ^ here)) mark_rev_compass; turn (left); }; goto (wanderer_ant); }; goto (wanderer_ant); /* -- WANDERER ANT: MOVE AWAY ---------------------------------------- */ label (wanderer_ant_move_away); if (move) { goto (wanderer_ant); } else { if (rand (2)) turn (left); else turn (right); goto (wanderer_ant_move_away); }; /* ------------------------------------------------------------------- */ /* -- DEPTH-FIRST-SEARCH --------------------------------------------- */ /* ------------------------------------------------------------------- */ // if we're still here -- no food was found, keep going label (dfs_find_unmarked_neighbour); vars (dfs_rotate (7), { vars (dfs_forbidden (7), { label (dfs_next_rotation); if (dfs_rotate <= 5) { if (vector ^ front) { turn (right); goto (dfs_rotate = dfs_rotate + 1, dfs_next_rotation) } else { if (rock ^ front || marker (B_FORBID) ^ front) { when (dfs_forbidden >= 2 && !(home ^ here)) { mark (B_FORBID); }; turn (right); goto (dfs_rotate = dfs_rotate + 1, dfs_forbidden = dfs_forbidden + 1, dfs_next_rotation) } else { if (! (friend ^ front || foe ^ front)) goto (dfs_move_and_mark) else goto (dfs_rotate = dfs_rotate + 1, dfs_next_rotation) } } } else { goto (dfs_all_neighbours_marked) } }) }); /* -- DEPTH-FIRST-SEARCH: ALL NEIGHBOURS MARKED ---------------------- */ // this could have happened when some neighbours are rock or forbidden label (dfs_all_neighbours_marked); if (rand (6)) { goto (dfs_move_and_mark); } else { if (rand (2)) turn (left); else turn (right); if (move) { when (!(vector ^ here)) mark_rev_compass; goto (wanderer_ant); } else { goto (dfs_all_neighbours_marked); } }; /* -- DEPTH-FIRST-SEARCH: MOVE AND MARK ------------------------------ */ label (dfs_move_and_mark); if (move) { mark_rev_compass; goto (wanderer_ant); } else { if (rand (2)) turn (left); else turn (right); goto (wanderer_ant); }; /* ------------------------------------------------------------------- */ /* -- HELP! CAN'T MOVE THE WANDERER! --------------------------------- */ /* ------------------------------------------------------------------- */ label (help_cannot_move_wanderer); /* ------------------------------------------------------------------- */ /* -- ON FOOD TRAIL -------------------------------------------------- */ /* ------------------------------------------------------------------- */ label (on_food_trail); align_to_rev_mark; when (!(marker (B_FOOD) ^ front)) { if (marker (B_FOOD) ^ left) { turn (left); goto (on_food_trail_move); } else if (marker (B_FOOD) ^ right) { turn (right); goto (on_food_trail_move); } else { goto (wanderer_ant); } }; /* -- ON FOOD TRAIL: MOVE -------------------------------------------- */ label (on_food_trail_move); if (move) { when (food ^ here) { goto (pick_up_food); }; goto (on_food_trail); } else { if (rand (2)) turn (left); else turn (right); move; goto (on_food_trail_move); }; /* ------------------------------------------------------------------- */ /* -- PICK UP FOOD --------------------------------------------------- */ /* ------------------------------------------------------------------- */ label (pick_up_food); turn (right); turn (right); turn (right); mark (B_FOOD); pickup; goto (return_with_food); /* ------------------------------------------------------------------- */ /* -- RETURN WITH FOOD ----------------------------------------------- */ /* ------------------------------------------------------------------- */ label (return_with_food); if (home ^ here) { drop; turn (right); turn (right); turn (right); move; goto (wanderer_ant); } else if (home ^ front) { move; goto (return_with_food); } else if (home ^ left) { turn (left); move; goto (return_with_food); } else if (home ^ right) { turn (right); move; goto (return_with_food); } else { mark (B_FOOD); if (move) { align_to_mark; goto (return_with_food); } else { if (friend ^ front) { drop; turn (right); turn (right); turn (right); goto (wanderer_ant_move_away); } else { if (rand (2)) turn (left); else turn (right); goto (return_with_food); } } }; /* ------------------------------------------------------------------- */ /* -- ANTHILL WORKER ANT --------------------------------------------- */ /* ------------------------------------------------------------------- */ // step one -- get on the edge of the anthill label (anthill_worker_ant); if (!(home ^ front)) { goto (anthill_worker_ant_at_perimeter); } else if (food ^ here && marker (B_ENEMY) ^ here) { pickup; goto (anthill_worker_ant_carrying_food); } else { move_timeout (1); goto (anthill_worker_ant); }; // step two -- walk around the anthill until some food is found label (anthill_worker_ant_at_perimeter); mark (B_ENEMY); if (food ^ here) { pickup; goto (anthill_worker_ant_carrying_food); } else { label (anthill_worker_ant_align_to_edge); if (home ^ front) { if (move) { goto (anthill_worker_ant_at_perimeter); } else { } } else { turn (left); goto (anthill_worker_ant_align_to_edge); } }; // step three -- carry the food into the anthill's interior label (anthill_worker_ant_carrying_food); vars (neighbourhood (7), rotations (7), { label (next_neighbourhood_rotation); if (rotations == 6) { if (neighbourhood == 6) goto (anthill_worker_ant_drop_food); else goto (anthill_worker_seek_interior); } else { turn (right); if (home ^ front && !(marker (B_ENEMY) ^ front)) { goto (neighbourhood = neighbourhood + 1, rotations = rotations + 1, next_neighbourhood_rotation); } else { goto (rotations = rotations + 1, next_neighbourhood_rotation); } } }); // drop the food and resume patroling label (anthill_worker_ant_drop_food); drop; goto (anthill_worker_ant); // go to the anthill's interior label (anthill_worker_seek_interior); when (rand (2)) turn (right); if (home ^ front && !(marker (B_ENEMY) ^ front)) { move; goto (anthill_worker_ant_carrying_food); } else { turn (right); goto (anthill_worker_seek_interior); } }); }; def cc = StmtCompiler (stmts); cc.Compile (); cc.Optimize (); cc.Output (); } }