Skip to content

Commit e237038

Browse files
authored
Watch for robots as well (#2538)
* fix `wakeWatchingRobots` to allow calling it more than once * make Debug tutorial system robot more efficient using `watchRobots` * change ranching scenario solution to work with watching for robots (do not step on the watched space too soon) * move robot naming state to separate module * move robots state and lenses to an internal module * make gopher move silently * allow empty appear parameter making robot invisible * closes #2522 - **this PR is a rebased version with the new map and commands reverted** * closes #2518 * closes #2395
1 parent 2828a25 commit e237038

File tree

12 files changed

+326
-202
lines changed

12 files changed

+326
-202
lines changed

data/scenarios/Challenges/Ranching/_capture/opponent.sw

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ def getDirection = \n.
2222
};
2323
end;
2424

25+
def forDirs = \c.
26+
forwardRes <- c forward;
27+
rightRes <- c right;
28+
backRes <- c back;
29+
leftRes <- c left;
30+
pure (forwardRes, rightRes, backRes, leftRes)
31+
end;
32+
2533
def watchDir = \n.
2634
watch $ getDirection n;
2735
if (n > 0) {
@@ -51,6 +59,18 @@ def reWatch =
5159
watchDir 4;
5260
end;
5361

62+
def reWatchEntities = \instantCont.
63+
s1 <- instant (
64+
forDirs (\d. watch d; scan d)
65+
);
66+
wait 10000;
67+
instant (
68+
s2 <- forDirs scan;
69+
if (s1 != s2) {instantCont} {}
70+
);
71+
reWatchEntities instantCont
72+
end
73+
5474
def locationIsOpen =
5575
emptyHere <- isempty;
5676
blockedCount <- countBlocked 4;
@@ -104,9 +124,7 @@ def handleBlockage =
104124
end;
105125

106126
def go =
107-
instant reWatch;
108-
wait 1000;
109-
instant handleBlockage;
127+
reWatchEntities handleBlockage;
110128
go;
111129
end;
112130

data/scenarios/Challenges/Ranching/_capture/solution.sw

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,21 @@ def go =
106106
turn right;
107107
doN 2 move;
108108
turn back;
109+
log "building bots 1!"; // 4,-6
109110
buildBot right;
110-
turn back;
111+
112+
// walk around the watched place
113+
turn right;
111114
move;
112-
113-
turn left;
115+
turn right;
114116
move;
117+
turn left;
118+
119+
log "building bots 2!";
115120
buildBot left;
116121
turn back;
122+
wait 20;
123+
log "going back now!";
117124
move;
118125

119126
place obj;

data/scenarios/Challenges/_gopher/gopher.sw

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def goDir = \dist. \d1. \d2.
2020
turn d2;
2121
} {};
2222

23-
doN (abs dist) move;
23+
doN (abs dist) (instant (appear "" (inl ()); move; appear "o" (inl ())));
2424
end;
2525

2626
def randSwap = \f. \g.

data/scenarios/Tutorials/debug-hint.sw

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,96 +13,118 @@ def foreachF = \s.\e.\com.\state.
1313
}
1414
end;
1515

16+
def foldM : (rec l. Unit + a * l) -> b -> (b -> a -> Cmd b) -> Cmd b =
17+
\xs. \b. \f. case xs
18+
(\_. pure b)
19+
match \h. \t. b' <- f b h; foldM t b' f)
20+
end
21+
1622
// An infinite while cycle that carries a state.
17-
def iterate = \state.\com.
18-
n <- com state;
19-
iterate n com;
20-
end;
23+
def iterate = \state. \com. n <- com state; iterate n com end
2124

22-
tydef RobotState = [gave_win: Bool, said_log_missing: Bool, said_loc: (Int * Int)] end;
25+
// -------------------------------------------------------------------------
26+
// Robot State - this allows us to skip some commands, so that this hont robot
27+
// does not have to busy-wait to meet each robot
28+
tydef RobotState = [gave_win: Bool, said_loc: Int * Int, said_log_missing: Bool] end
2329

2430
// setters
25-
def set_gave_win : Bool -> RobotState -> RobotState = \v.\s. [gave_win=v, said_log_missing=s.said_log_missing, said_loc=s.said_loc] end;
26-
def set_said_log_missing : Bool -> RobotState -> RobotState = \v.\s. [gave_win=s.gave_win, said_log_missing=v, said_loc=s.said_loc] end;
27-
def set_said_loc : (Int * Int) -> RobotState -> RobotState = \v.\s. [gave_win=s.gave_win, said_log_missing=s.said_log_missing, said_loc=v ]end;
31+
def set_gave_win: Bool -> RobotState -> RobotState
32+
= \v. \s.
33+
[gave_win = v, said_loc = s.said_loc, said_log_missing = s.said_log_missing]
34+
end
2835

29-
tydef RobotsStateList = rec l. Unit + (Actor * RobotState * l) end;
36+
def set_said_log_missing: Bool -> RobotState -> RobotState
37+
= \v. \s.
38+
[gave_win = s.gave_win, said_loc = s.said_loc, said_log_missing = v]
39+
end
3040

31-
def emptyList = inl () end;
41+
def set_said_loc: (Int * Int) -> RobotState -> RobotState
42+
= \v. \s.
43+
[gave_win = s.gave_win, said_loc = v, said_log_missing = s.said_log_missing]
44+
end
3245

33-
// At the beginning all robots can be given Win.
46+
// At the beginning each robot can be given Win.
3447
def defaultState: RobotState =
35-
[gave_win=False, said_log_missing=False, said_loc=(-100,-100)]
36-
end;
48+
[gave_win = false, said_loc = (-100, -100), said_log_missing = false]
49+
end
3750

38-
def query : Actor -> RobotsStateList -> RobotState = \rob.\l.
39-
case l (\_. defaultState) (λmatch \r. λmatch \s.\tail.
40-
if (r == rob) {s} {query rob tail}
41-
)
42-
end;
51+
// The list of met robots
52+
tydef RobotsStateList = rec l. Unit + (Actor * RobotState * l) end
4353

44-
def update : Actor -> RobotState -> RobotsStateList -> RobotsStateList = \rob.\s.\l.
45-
case l (\_. inr (rob, s, emptyList)) (λmatch \nr. λmatch \ns. \tail.
46-
if (nr == rob) {
47-
inr (rob, s, tail)
48-
} {
49-
inr (nr, ns, update rob s tail)
50-
}
51-
)
52-
end;
54+
def emptyList = inl () end
5355

54-
myLoc <- whereami;
56+
def query: Actor -> RobotsStateList -> RobotState
57+
= \rob. λcase
58+
(\_. defaultState)
59+
match \r. λmatch \s. \rest.
60+
if (r == rob) {s} {query rob rest}
61+
)
62+
end
5563

56-
def foldM : (rec l. Unit + a * l) -> b -> (b -> a -> Cmd b) -> Cmd b =
57-
\xs. \b. \f. case xs
58-
(\_. pure b)
59-
match \h.\t. b2 <- f b h; foldM t b2 f)
64+
def update: Actor -> RobotState -> RobotsStateList -> RobotsStateList
65+
= \rob. \s. λcase
66+
(\_. inr (rob, s, emptyList))
67+
match \r. λmatch \os. \rest.
68+
if (r == rob) {inr (rob, s, rest)} {inr (r, os, update rob s rest)}
69+
)
70+
end
71+
72+
// -------------------------------------------------------------------------
73+
// Running state
74+
tydef State = [can_wait: Bool, list: RobotsStateList] end
75+
76+
def updateList: Actor -> RobotState -> State -> State
77+
= \rob. \rs. \state.
78+
[can_wait = true, list = update rob rs state.list]
6079
end
6180

81+
// -------------------------------------------------------------------------
82+
// Running state
83+
myLoc <- whereami;
84+
6285
// Try to give a robot a Win, filtering out those that were already given a Win.
6386
// The robot will also receive instructions, so it **must have a logger!**
64-
def tryGive: Text -> RobotsStateList -> Cmd RobotsStateList = \msg. \ok.
87+
def tryGive: Text -> State -> Cmd State
88+
= \msg. \state.
89+
if (state.can_wait) {watch down; wait 2048} {};
6590
instant (
66-
rs <- meetAll;
67-
foldM rs ok (\stateList.\rob.
68-
let state = query rob stateList in
91+
rs <- meetall;
92+
foldM rs state (
93+
\stateAcc. \rob. let state = query rob stateAcc.list in
6994
robLoc <- as rob {whereami};
7095
hasLog <- as rob {try {log "test"; pure true} {pure false}};
7196
if (state.gave_win) {
72-
// log $ "skipping the robot " ++ format rob ++ "because it already has a Win";
73-
pure stateList
97+
pure stateAcc
7498
}
75-
$elif (robLoc != myLoc && state.said_loc != robLoc) {
76-
log $ "the robot " ++ format rob ++ " is not in my cell";
77-
pure (update rob (set_said_loc robLoc state) stateList);
99+
$ elif (robLoc != myLoc && state.said_loc != robLoc) {
100+
log ("the robot" ++ format rob ++ "is not in my cell");
101+
pure (updateList rob (set_said_loc robLoc state) stateAcc)
78102
}
79-
$elif (not hasLog && state.said_log_missing)
80-
{
81-
say $ "the robot " ++ format rob ++ " is missing a logger!";
82-
pure (update rob (set_said_log_missing true state) stateList)
83-
}
84-
{ // else
103+
$ elif (not hasLog && state.said_log_missing) {
104+
say ("the robot " ++ format rob ++ "is missing a logger!");
105+
pure (updateList rob (set_said_log_missing true state) stateAcc)
106+
} // else
107+
{
85108
try {
86-
reprogram rob { log msg; };
87-
log $ "successfully reprogrammed robot " ++ format rob;
109+
reprogram rob {log msg};
110+
log ("successfully reprogrammed robot " ++ format rob);
88111
give rob "Win";
89-
log $ "successfully gave Win to robot " ++ format rob;
90-
pure (update rob (set_gave_win true state) stateList)
112+
log ("successfully gave Win to robot " ++ format rob);
113+
pure (updateList rob (set_gave_win true state) stateAcc)
91114
} {
92-
log $ "the robot " ++ format rob ++ " is probably still active!";
93-
pure stateList
94-
};
115+
log ("the robot " ++ format rob ++ "is probably still active!");
116+
pure [can_wait = false, list = stateAcc.list]
117+
}
95118
}
96119
)
97120
)
98-
end;
121+
end
99122

100123
// -------------------------------------------------------------------------
101124
// RUN
102125
// -------------------------------------------------------------------------
103-
104126
log "Hi, I am the system hint robot";
105-
iterate emptyList (tryGive
127+
iterate [can_wait=true, list=emptyList] (tryGive
106128
$ "Send a robot to `salvage` me and come back to"
107129
++ " `give base \"Win\"`. When the rescue robot stands"
108130
++ " where I am and executes `salvage`, all my inventory"
@@ -111,4 +133,4 @@ iterate emptyList (tryGive
111133
++ "NOTE: if you are still viewing me when I am salvaged,"
112134
++ " you will be in for a surprise! If this happens just"
113135
++ " type `view base` to return to viewing your base."
114-
)
136+
)

0 commit comments

Comments
 (0)