Skip to content

Commit

Permalink
Pathfinding command (#1523)
Browse files Browse the repository at this point in the history
Closes #836

# Tests
    scripts/run-tests.sh  --test-arguments '--pattern "Pathfinding"'

# Demo

    scripts/play.sh -i data/scenarios/Testing/836-pathfinding/836-automatic-waypoint-navigation.yaml --autoplay
  • Loading branch information
kostmo authored Sep 19, 2023
1 parent ab7e5b6 commit e06e04f
Show file tree
Hide file tree
Showing 40 changed files with 951 additions and 355 deletions.
2 changes: 1 addition & 1 deletion bench/Benchmark.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ circlerProgram =

-- | Initializes a robot with program prog at location loc facing north.
initRobot :: ProcessedTerm -> Location -> TRobot
initRobot prog loc = mkRobot () Nothing "" mempty (Just $ Cosmic DefaultRootSubworld loc) north defaultRobotDisplay (initMachine prog Context.empty emptyStore) [] [] False False 0
initRobot prog loc = mkRobot () Nothing "" mempty (Just $ Cosmic DefaultRootSubworld loc) north defaultRobotDisplay (initMachine prog Context.empty emptyStore) [] [] False False mempty 0

-- | Creates a GameState with numRobot copies of robot on a blank map, aligned
-- in a row starting at (0,0) and spreading east.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,131 +1,11 @@
// Algorithm:
// ----------
// Maintain current direction until a wall is encountered.
// Then enter "wall-following mode".
// This mode presumes the wall is not a loop.
// Wall-following mode exploits recursion to keep track of how many left turns were made
// and then unwinds them again by ensuring each is paired with a right turn.
// Once the recursion is fully unwound, the robot proceeds along its original direction
// (though it may now be laterally displaced).
//
// (If it was a loop, then an "oriented breadcrumb" would need to be left.
// The breadcrumb is oriented in case a single-width passage is backtracked
// along the opposite wall.)

/** A "gate" is walkable, so we need to supplement the "blocked" check with this function.
Since fences are "unwalkable", they do not need to be mentioned in this function.
*/
def isFenced =
s <- scan forward;
return (
case s
(\_. false)
(\x. x == "gate")
);
end;

def isBlockedOrFenced =
b <- blocked;
f <- isFenced;
return (b || f);
end;

// Returns true if we've already placed two
// breadcrumbs on a given tile, false otherwise.
def leaveBreadcrumbs =

let bc1 = "fresh breadcrumb" in
let bc2 = "treaded breadcrumb" in

wasTraversedOnce <- ishere bc1;
if wasTraversedOnce {
_crumb <- grab;
make bc2;
place bc2;
return false;
} {
wasTraversedTwice <- ishere bc2;
if wasTraversedTwice {
return true;
} {
// Make sure nothing's in the way before we place
// our breadcrumb:
x <- scan down;
case x return (\y.
// If we're on a water tile, get rid of
// it with our special "drilling" recipe
if (y == "water") {
drill down;
// Nothing will remain on the ground.
// after making the "steam" via
// the drilling recipe.
return ();
} {
grab;
return ();
};
);

make bc1;
place bc1;
return false;
};
};
end;

def goForwardToPatrol = \wasBlocked.
b <- isBlockedOrFenced;
if b {
turn left;
goForwardToPatrol true;
turn right;
goForwardToPatrol false;
} {
if wasBlocked {
isLoop <- leaveBreadcrumbs;
if isLoop {
fail "loop";
} {};
} {};
move;
};
end;

/**
There should only be one place in the
code where an exception is thrown: that is,
if a treaded breadcrumb is encountered.
*/
def checkIsEnclosedInner =
try {
goForwardToPatrol false;
// Water is the outer boundary
hasWater <- ishere "water";
if hasWater {
return false;
} {
checkIsEnclosedInner;
};
} {
return true;
};
return b;
end;

def checkIsEnclosed =

// The "evaporator" drill is used
// to clear water tiles.
let specialDrill = "evaporator" in
create specialDrill;
equip specialDrill;

// NOTE: System robots can walk on water
// so we only need this if we want to
// demo the algorithm with a player robot.
// create "boat";
// equip "boat";

checkIsEnclosedInner;
maybePath <- path (inL ()) (inR "water");
case maybePath (\_. return True) (\_. return False);
end;

def boolToInt = \b. if (b) {return 1} {return 0}; end;
Expand Down Expand Up @@ -215,35 +95,13 @@ def getValForSheepIndex = \predicateCmd. \i.
}
end;

/**
There are 3 sheep.
They have indices 1, 2, 3.
(The base has index 0).
THIS DOES NOT WORK!
*/
def countSheepWithRecursive = \predicateCmd. \i.

if (i > 0) {
val <- getValForSheepIndex predicateCmd i;
recursiveCount <- countSheepWithRecursive predicateCmd $ i - 1;
return $ val + recursiveCount;
} {
return 0;
}
end;


def countSheepWith = \predicateCmd.

val1 <- getValForSheepIndex predicateCmd 1;
val2 <- getValForSheepIndex predicateCmd 2;
val3 <- getValForSheepIndex predicateCmd 3;
return $ val1 + val2 + val3;

end;


justFilledGap <- as base {
isStandingOnBridge;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
// A "sheep" that wanders around randomly.

/** A "gate" is walkable, so we need to supplement the "blocked" check with this function.
Since fences are "unwalkable", they do not need to be mentioned in this function.
*/
def isFenced =
s <- scan forward;
return (
case s
(\_. false)
(\x. x == "gate")
);
end;

def isBlockedOrFenced =
b <- blocked;
f <- isFenced;
return (b || f);
end;

def elif = \p.\t.\e. {if p t e} end;


def turnToClover = \direction.

x <- scan direction;
Expand Down Expand Up @@ -95,7 +76,7 @@ forever (
dist <- random 3;
repeat dist (

b <- isBlockedOrFenced;
b <- blocked;
if b {} {
move;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ SCENARIO_FILE=$PARENT_DIR/gated-paddock.yaml

PROGRAM=$(cat $SCRIPT_DIR/enclosure-checking.sw | sed -e 's/[[:blank:]]\+$//') yq -i '.objectives[0].condition = strenv(PROGRAM) | .objectives[].condition style="literal"' $SCENARIO_FILE

stack run -- --scenario $SCENARIO_FILE --run $SCRIPT_DIR/fence-construction.sw --cheat
stack build --fast
stack exec swarm -- --scenario $SCENARIO_FILE --run $SCRIPT_DIR/fence-construction.sw --cheat
Loading

0 comments on commit e06e04f

Please sign in to comment.