Maze Generator

De DigiWiki.

  • Créer un Prim nomé "Wall" de 1x1x3 et placer le script "Maze Wall" dedans.
  • Créer un prim nomé "Maze Generator" et placer le prim "Wall" dedans.
  • Placer le script "Maze Generator" dans le prim "Maze Generator"
  • Dites "maze build 10x10" dans le chat (10x10 ou n'importe quelle valeur).
// Maze Wall v1.0 by Apotheus Silverman
 
vector UnpackVector(integer vectorInt)
{
    integer x = vectorInt / 1000000;
    integer y = (vectorInt - (x * 1000000)) / 1000;
    integer z = vectorInt - (x * 1000000) - (y * 1000);
    return(<x,y,z>);
}
 
SetPos(vector dest)
{
    float dist = llVecDist(dest,llGetPos());
    vector prevPos;
    while(dist > 0)
    {
        prevPos = llGetPos();
        llSetPos(dest);
        if(llGetPos() == prevPos)
        {
            return;
        }
        dist = llVecDist(dest,llGetPos());
    }
}
 
default
{
    // state_entry() {;}
 
    on_rez(integer startParam)
    {
        if (startParam == 0)
        {
            // llDie();
        } 
 
        else
        {
            vector myPos = UnpackVector(startParam);
            SetPos(myPos);
            llRemoveInventory(llGetScriptName());
        }
    }
}
// Maze Generator v1.0 by Apotheus Silverman
 
integer mazeWidth = 6;
integer mazeHeight = 6;
float relativeZ = 0.0;
integer packBits = 32;
list westWalls;
list southWalls;
 
integer PackVector(vector vec)
{
    return((integer)vec.x * 1000000 + (integer)vec.y * 1000 + (integer)vec.z);
}
 
RezWall(integer mazeWidth, integer mazeHeight, integer x, integer y)
{
    vector rezPos = <-mazeWidth + x - 2, -mazeHeight + y - 2, relativeZ> + llGetPos();
    integer packedRezPos = PackVector(rezPos);
    llRezObject("Wall", llGetPos() + <0,0,1>, ZERO_VECTOR, ZERO_ROTATION, packedRezPos);
}
 
list ListReplaceList(list dest, list src, integer pos)
{
    if (pos > llGetListLength(dest))
    {
        llSay(0, "Error: Index " + (string)pos + " is greater than list length " + (string)llGetListLength(dest));
        return(dest);
    }
 
    if (pos < 0) {pos = llGetListLength(dest) + pos;}
    return llListInsertList(llDeleteSubList(dest, pos, pos), src, pos);
}
 
integer SetBit(integer x, integer bit) {return(x | ((integer)llPow(2, (float)bit)));}
 
integer ClearBit(integer x, integer bit) {return(x & (~(integer)llPow(2, (float)bit)));}
 
integer GetBit(integer x, integer bit)
{
    if(x & (integer)llPow(2, bit))
        return(TRUE);
    else
        return(FALSE);
}
 
Usage()
{
    llSay(0, "Usage: maze build [XxY]");
    llSay(0, "Build a maze with the default size of " + (string)(mazeWidth * 2) + "x" + (string)(mazeHeight * 2) + ".");
    llSay(0, "maze build 10x10 will build a maze that is 10 meters on each side.");
}
 
GenerateMaze (integer mazeWidth, integer mazeHeight)
{
    integer i;
    integer j;
    integer k;
    integer exitCount;
    integer selection;
    integer unvisitedRoomCount;
    integer currentRoom;
    integer count;
    integer element;
    list visited;
    list exits;
    list paths;
 
    for (i = 0; i < 4; i++) {exits += 0;}
 
    for (i = 0; i < (integer)((((mazeWidth + 2) * (mazeHeight + 2)) + 15) / packBits); i++)
    {
        westWalls += [0];
        southWalls += [0];
        visited += [0];
        paths += [0];
    }
 
    j = (mazeWidth + 2) * (mazeHeight + 1) - 1;
    for (i = 0; i <= mazeWidth + 2; i++)
    {
        element = i / packBits;
        visited = ListReplaceList(visited, [SetBit(llList2Integer(visited, element), i % packBits)], element);
        element = (i + j) / packBits;
        visited = ListReplaceList(visited, [SetBit(llList2Integer(visited, element), (i + j) % packBits)], element);
    }
 
    j = mazeWidth + mazeWidth + 3;
 
    for (i = 1; i <= mazeHeight; i++)
    {
        element = j / packBits;
        visited = ListReplaceList(visited, [SetBit(llList2Integer(visited, element), j % packBits)], element);
        element = (j + 1) / packBits;
        visited = ListReplaceList(visited, [SetBit(llList2Integer(visited, element), (j + 1) % packBits)], element);
        j += mazeWidth + 2;
    }
 
    unvisitedRoomCount = mazeWidth * mazeHeight;
    j = (integer)llFrand(unvisitedRoomCount);
    currentRoom = (1 + i / mazeWidth) * (mazeWidth + 2) + (i % mazeWidth) + 1;
 
 
    while (unvisitedRoomCount > 1)
    {
        unvisitedRoomCount -= 1;
        element = currentRoom / packBits;
        visited = ListReplaceList(visited, [SetBit(llList2Integer(visited, element), currentRoom % packBits)], element);
 
        while (TRUE)
        {
            exitCount = 0;
            element = (currentRoom - mazeWidth - 2) / packBits;
 
            if (!GetBit(llList2Integer(visited, element), (currentRoom - mazeWidth - 2) % packBits))
            {
                exits = ListReplaceList(exits, [1], exitCount);
                exitCount += 1;
            }
 
            element = (currentRoom + mazeWidth + 2) / packBits;
 
            if (!GetBit(llList2Integer(visited, element), (currentRoom + mazeWidth + 2) % packBits))
            {
                exits = ListReplaceList(exits, [2], exitCount);
                exitCount += 1;
            }
 
            element = (currentRoom - 1) / packBits;
 
            if (!GetBit(llList2Integer(visited, element), (currentRoom - 1) % packBits))
            {
                exits = ListReplaceList(exits, [3], exitCount);
                exitCount += 1;
            }
 
            element = (currentRoom + 1) / packBits;
 
            if (!GetBit(llList2Integer(visited, element), (currentRoom + 1) % packBits))
            {
                exits = ListReplaceList(exits, [4], exitCount);
                exitCount += 1;
            }
 
            if (exitCount >= 1)
            {
                jump endLoop;
            }
 
            j = (integer)llFrand(mazeWidth * mazeHeight);
            k = ((1 + j / mazeWidth) * (mazeWidth + 2) + (j % mazeWidth) + 1) / packBits;
 
            while (!llList2Integer(paths, k))
            {
                k -= 1;
 
                if (k < 0)
                {
                    k = ((mazeWidth + 2) * (mazeHeight + 2) - 1) / packBits;
                }
            }
            for (i = 0; i < packBits; i++) {
                if (GetBit(llList2Integer(paths, k), i)) {
                    jump endFor;
                }
            }
            @endFor;
            paths = ListReplaceList(paths, [ClearBit(llList2Integer(paths, k), i)], k);
            currentRoom = k * packBits + i;
        }
 
        @endLoop;
 
        if (exitCount > 1)
        {
            element = currentRoom / packBits;
            paths = ListReplaceList(paths, [SetBit(llList2Integer(paths, element), currentRoom % packBits)], element);
        }
 
        selection = (integer)llFrand(exitCount);
 
        if (llList2Integer(exits, selection) == 1)
        {
            currentRoom -= mazeWidth + 2;
            element = currentRoom / packBits;
            southWalls = ListReplaceList(southWalls, [SetBit(llList2Integer(southWalls, element), currentRoom % packBits)], element);
        }
 
        else if (llList2Integer(exits, selection) == 2)
        {
            element = currentRoom / packBits;
            southWalls = ListReplaceList(southWalls, [SetBit(llList2Integer(southWalls, element), currentRoom % packBits)], element);
            currentRoom += mazeWidth + 2;
        }
 
        else if (llList2Integer(exits, selection) == 3)
        {
            element = currentRoom / packBits;
            westWalls = ListReplaceList(westWalls, [SetBit(llList2Integer(westWalls, element), currentRoom % packBits)], element);
            currentRoom -= 1;
        }
 
        else if (llList2Integer(exits, selection) == 4)
        {
            currentRoom += 1;
            element = currentRoom / packBits;
            westWalls = ListReplaceList(westWalls, [SetBit(llList2Integer(westWalls, element), currentRoom % packBits)], element);
        }
    }
 
    southWalls = ListReplaceList(southWalls, [SetBit(llList2Integer(southWalls, 0), 1)], 0);
    j = (mazeHeight + 1) * (mazeWidth + 2) - 2;
    element = j / packBits;
    southWalls = ListReplaceList(southWalls, [SetBit(llList2Integer(southWalls, element), j % packBits)], element);
}
 
BuildMaze(integer mazeWidth, integer mazeHeight)
{
    integer i;
    integer j;
    integer p;
    integer element;
 
    for (i = 1; i <= mazeWidth; i++)
    {
        RezWall(mazeWidth, mazeHeight, i * 2, 1);
        element = i / packBits;
        if (!GetBit(llList2Integer(southWalls, element), i % packBits)) {
            RezWall(mazeWidth, mazeHeight, (i * 2) + 1, 1);
        }
    }
 
    RezWall(mazeWidth, mazeHeight, (mazeWidth * 2) + 2, 1);
 
    p = 0;
    for (i = 1; i <= mazeHeight; i++)
    {
        p += mazeWidth + 2;
 
        for (j = 1; j <= mazeWidth; j++)
        {
            element = (p + j) / packBits;
            if (!GetBit(llList2Integer(westWalls, element), (p + j) % packBits))
            {
                RezWall(mazeWidth, mazeHeight, j * 2, i * 2);
            }
        }
 
        element = (p + mazeWidth + 1) / packBits;
 
        if (!GetBit(llList2Integer(westWalls, element), (p + mazeWidth + 1) % packBits))
        {
            RezWall(mazeWidth, mazeHeight, (mazeWidth * 2) + 2, i * 2);
        }
 
        for (j = 1; j <= mazeWidth; j++)
        {
            RezWall(mazeWidth, mazeHeight, j * 2, (i * 2) + 1);
            element = (p + j) / packBits;
 
            if (!GetBit(llList2Integer(southWalls, element), (p + j) % packBits))
            {
                RezWall(mazeWidth, mazeHeight, (j * 2) + 1, (i * 2) + 1);
            }
        }
 
        RezWall(mazeWidth, mazeHeight, (mazeWidth * 2) + 2, (i * 2) + 1);
    }
}
 
 
default
{
    state_entry()
    {
        llSetText("", <1,1,1>, 1.0);
        llListen(0, "", llGetOwner(), "");
    }
 
    listen(integer channel, string name, key id, string message)
    {
        string myMessage = llToLower(message);
 
        if (myMessage == "maze reset")
        {
            llResetScript();
        }
 
        else if (llGetSubString(myMessage, 0, 9) == "maze build")
        {
            integer myMazeWidth = mazeWidth * 2;
            integer myMazeHeight = mazeHeight * 2;
 
            if (llStringLength(myMessage) > 13)
            {
                if (llGetSubString(myMessage, 10, 10) == " " && llSubStringIndex(myMessage, "x") > -1)
                {
                    list dimensions = llParseString2List(llGetSubString(myMessage, 11, -1), ["x"], []);
 
                    if (llGetListLength(dimensions) == 2)
                    {
                        myMazeWidth = llList2Integer(dimensions, 0);
                        myMazeHeight = llList2Integer(dimensions, 1);
                    }
 
                    else {myMazeWidth = 0;}
                } 
 
                else {myMazeWidth = 0;}
            }
 
            if (myMazeWidth == 0 || myMazeHeight == 0)
            {
                llSay(0, "Invalid parameter " + llGetSubString(myMessage, 11, -1));
                Usage();
            }
 
            else
            {
                llSay(0, "Generating " + (string)myMazeWidth + " x " + (string)myMazeHeight + " maze. Please wait...");
                GenerateMaze(myMazeWidth / 2, myMazeHeight / 2);
                BuildMaze(myMazeWidth / 2, myMazeHeight / 2); 
                llResetScript();
            }
        }
    }
 
    on_rez(integer start_param)
    {
        Usage();
        llResetScript();
    }
}
Outils personnels
  • Cette page a été consultée 985 fois.
donate
Google Ads