Maze Generator
De DigiWiki.
Version du 18 décembre 2012 à 11:57 par Djphil (discuter | contributions)
- 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(); } }