packages feed

swarm-0.7.0.0: data/scenarios/Challenges/_dna/lab.sw

def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;

def waypointByIndexRec : (rec l. Unit + (Int * Int) * l) -> Int -> (Int * Int) = \wps. \idx.

    case wps (\_. fail "invalid index") (\cons.
        match cons \hd. \tl.
        if (idx == 0) {
            hd;
        } {
            waypointByIndexRec tl $ idx - 1;
        }
    );
    end;

def waypointByIndex : Text -> Int -> (Int * Int) = \wpName. \idx.
    let wpList = waypoints wpName in
    waypointByIndexRec wpList idx;
    end;

def getBaseForNumber = \n.
    if (n == 0) {
        "guanine";
    } {
        if (n == 1) {
            "cytosine";
        } {
            if (n == 2) {
                "adenine";
            } {
                "thymine";
            };
        };
    };
    end;

def getNumberForBase = \n.
    if (n == "guanine") {
        0;
    } {
        if (n == "cytosine") {
            1;
        } {
            if (n == "adenine") {
                2;
            } {
                3;
            };
        };
    };
    end;

/** Toggle the lowest bit */
def getComplementNumber = \n.
    if (n == 0) {
        1;
    } {
        if (n == 1) {
            0;
        } {
            if (n == 2) {
                3;
            } {
                2;
            };
        };
    };
    end;

def waitUntilSomethingExists =
    maybeItemHere <- scan down;
    case maybeItemHere (\_. 
        watch down;
        wait 1000;
        waitUntilSomethingExists;
    ) pure;
    end;

def waitUntilHere = \item.
    hereNow <- ishere item;
    if hereNow {} {
        watch down;
        wait 1000;
        waitUntilHere item;
    };
    end;

def waitUntilOccupied =
    stillEmpty <- isempty;
    if stillEmpty {
        watch down;
        wait 1000;
        waitUntilOccupied;
    } {};
    end;

def myStandby = \receptacleLoc.
    teleport self receptacleLoc;
    entToClone <- grab;
    teleport self (36, -11);
    turn back;
    pure $ inR entToClone;
    end;

def placeBase = \standbyFunc. \n. 

    if (n > 0) {
        idx <- random 4;
        let entTemp = getBaseForNumber idx in
        let ent = entTemp in
        create ent;
        place ent;
        move;

        clonedOrganism <- placeBase standbyFunc $ n - 1;

        // Unwinds the stack; verifies the original placement order
        placedEnt <- instant waitUntilSomethingExists;
        let isGood = ent == placedEnt in
        move;

        if isGood {
            pure clonedOrganism;
        } {
            pure $ inL ();
        }
    } {
        // Returns the clonedOrganism
        standbyFunc;
    };
    end;

def makeDnaStrand = \receptacleLoc.
    teleport self (5, -2);

    dims <- floorplan "DNA decoder";
    match dims \decoderWidth. \_.
    eitherClonedOrganism <- placeBase (myStandby receptacleLoc) decoderWidth;

    case eitherClonedOrganism (\_.
        create "pixel (R)";
    ) (\clonedItem.
        instant $ (
            teleport self (0, -11);
            waitUntilHere "switch (on)";

            let receptacleLoc2 = waypointByIndex "receiver" 1 in
            teleport self receptacleLoc2;

            sow clonedItem;
            create clonedItem;
            k <- robotnamed "keeper";
            give k clonedItem;

            let slideBox = "slide box" in
            create slideBox;
            give base slideBox;
            say $ "You got a new \"" ++ slideBox ++ "\"";
        );
    );
    end;

def waitForCloneableOrganism =
    let receptacleLoc = waypointByIndex "receiver" 0 in
    organism <- instant (
        teleport self receptacleLoc;

        waitUntilOccupied;

        thingHere <- scan down;
        pure $ case thingHere (\x. inL x) (\item.
          if (hastag item "organism") {inR item} {inL ()}
        )
    );

    case organism (\_.
        say "Not a cloneable organism!";
        waitForCloneableOrganism;
    ) (\_.
        create "pixel (G)";
        makeDnaStrand receptacleLoc;
    );
    end;

def go =
    waitForCloneableOrganism;
    turn east;
    go;
    end;

go;