swarm-0.4: data/scenarios/Challenges/Ranching/_capture/opponent.sw
/**
If any blocking entity is touching me, escape.
*/
def elif = \t. \then. \else. {if t then else} end
def else = \t. t end
def abs = \n. if (n < 0) {-n} {n} end;
def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;
def until = \p. \c. q <- p; if q {} {c; until p c} end;
def getDirection = \n.
if (n == 0) {
forward;
} $ elif (n == 1) {
right;
} $ elif (n == 2) {
back;
} $ elif (n == 3) {
left;
} $ else {
down;
};
end;
def watchDir = \n.
watch $ getDirection n;
if (n > 0) {
watchDir $ n - 1;
} {};
end;
def boolToInt = \b.
if b {1} {0}
end;
/**
Iterate 4 times (once for each direction)
*/
def countBlocked = \n.
if (n > 0) {
isBlocked <- blocked;
// This assignment has to happen before the recursive
// "countBlocked" call due to #1032
let localBlockCount = boolToInt isBlocked in
turn left;
lastCount <- countBlocked $ n - 1;
return $ lastCount + localBlockCount;
} {
return 0;
}
end;
def reWatch =
watchDir 4;
end;
def locationIsOpen =
emptyHere <- isempty;
blockedCount <- countBlocked 4;
return $ emptyHere && blockedCount == 0;
end;
def faceAwayFrom = \loc.
myLoc <- whereami;
let x = fst loc - fst myLoc in
let y = snd loc - snd myLoc in
let d = if (abs x > abs y) {
if (x > 0) {west} {east}
} {
if (y > 0) {south} {north}
} in
turn d;
end;
/**
Move in opposite direction from base to
find a cross-shaped region that has zero blockages.
*/
def findOpenArea =
baseLoc <- as base {whereami};
faceAwayFrom baseLoc;
until locationIsOpen move;
end;
def relocateAway =
marker <- grab;
findOpenArea;
try {
swap marker;
return ();
} {
place marker;
};
end;
def handleBlockage =
blockedCount <- countBlocked 4;
if (blockedCount > 0) {
if (blockedCount < 4) {
relocateAway;
} {
selfdestruct;
}
} {};
end;
def go =
instant reWatch;
wait 1000;
instant handleBlockage;
go;
end;
go;