June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -0,0 +1,68 @@
OPTION BASE 0
RANDOMIZE TIMER
REM must be even
width% = 40
height% = 20
REM make array and fill
DIM maze$(width%, height%)
FOR x% = 0 TO width%
FOR y% = 0 TO height%
maze$(x%, y%) = "#"
NEXT y%
NEXT x%
REM initial start location
currentx% = INT(RND * (width% - 1))
currenty% = INT(RND * (height% - 1))
REM value must be odd
IF currentx% MOD 2 = 0 THEN currentx% = currentx% + 1
IF currenty% MOD 2 = 0 THEN currenty% = currenty% + 1
maze$(currentx%, currenty%) = " "
REM generate maze
done% = 0
DO WHILE done% = 0
FOR i% = 0 TO 99
oldx% = currentx%
oldy% = currenty%
REM move in random direction
SELECT CASE INT(RND * 4)
CASE 0
IF currentx% + 2 < width% THEN currentx% = currentx% + 2
CASE 1
IF currenty% + 2 < height% THEN currenty% = currenty% + 2
CASE 2
IF currentx% - 2 > 0 THEN currentx% = currentx% - 2
CASE 3
IF currenty% - 2 > 0 THEN currenty% = currenty% - 2
END SELECT
REM if cell is unvisited then connect it
IF maze$(currentx%, currenty%) = "#" THEN
maze$(currentx%, currenty%) = " "
maze$(INT((currentx% + oldx%) / 2), ((currenty% + oldy%) / 2)) = " "
END IF
NEXT i%
REM check if all cells are visited
done% = 1
FOR x% = 1 TO width% - 1 STEP 2
FOR y% = 1 TO height% - 1 STEP 2
IF maze$(x%, y%) = "#" THEN done% = 0
NEXT y%
NEXT x%
LOOP
REM draw maze
FOR y% = 0 TO height%
FOR x% = 0 TO width%
PRINT maze$(x%, y%);
NEXT x%
PRINT
NEXT y%
REM wait
DO: LOOP WHILE INKEY$ = ""

View file

@ -0,0 +1,94 @@
:amaze Rows Cols [wall char]
:: A stack-less, iterative, depth-first maze generator in native WinNT batch.
:: Rows and Cols must each be >1 and Rows*Cols cannot exceed 2096.
:: Default wall character is #, [wall char] is used if provided.
@ECHO OFF
SETLOCAL EnableDelayedExpansion
:: check for valid input, else GOTO :help
IF /I "%~2" EQU "" GOTO :amaze_help
FOR /F "tokens=* delims=0123456789" %%A IN ("%~1%~2") DO IF "%%~A" NEQ "" GOTO :amaze_help
SET /A "rows=%~1, cols=%~2, mTmp=rows*cols"
IF !rows! LSS 2 GOTO :amaze_help
IF !cols! LSS 2 GOTO :amaze_help
IF !mTmp! GTR 2096 GOTO :amaze_help
:: set map characters and use 1st character of %3 for wall, if defined
SET "wall=#"
SET "hall= "
SET "crumb=."
IF "%~3" NEQ "" SET "wall=%~3"
SET "wall=!wall:~0,1!"
:: assign width, height, cursor position, loop count, and offsets for NSEW
SET /A "cnt=0, wide=cols*2-1, high=rows*2-1, size=wide*high, N=wide*-2, S=wide*2, E=2, W=-2"
:: different random entrance points
:: ...on top
:: SET /A "start=(!RANDOM! %% cols)*2"
:: ...on bottom
:: SET /A "start=size-(!RANDOM! %% cols)*2-1"
:: ...on top or bottom
:: SET /A ch=cols*2, ch=!RANDOM! %% ch
:: IF !ch! GEQ !cols! ( SET /A "start=size-(ch-cols)*2-1"
:: ) ELSE SET /A start=ch*2
:: random entrance inside maze
SET /A "start=(!RANDOM! %% cols*2)+(!RANDOM! %% rows*2)*wide"
SET /A "curPos=start, cTmp=curPos+1, loops=cols*rows*2+1"
:: fill the maze with 8186 wall characters, clip to size, and open 1st cell
SET "mz=!wall!"
FOR /L %%A IN (1,1,6) DO SET mz=!mz!!mz!!mz!!mz!
SET bdr=!mz:~-%wide%!
SET mz=!mz:~3!!mz:~3!
SET mz=!mz:~-%size%!
SET mz=!mz:~0,%curPos%!!hall!!mz:~%cTmp%!
:: iterate #cells*2+1 steps of random depth-first search
FOR /L %%@ IN (1,1,%loops%) DO (
SET "rand=" & SET "crmPos="
REM set values for NSEW cell and wall positions
SET /A "rCnt=rTmp=0, cTmp=curPos+1, np=curPos+N, sp=curPos+S, ep=curPos+E, wp=curPos+W, wChk=curPos/wide*wide, eChk=wChk+wide, nw=curPos-wide, sw=curPos+wide, ew=curPos+1, ww=curPos-1"
REM examine adjacent cells, build direction list, and find last crumb position
FOR /F "tokens=1-8" %%A IN ("!np! !sp! !ep! !wp! !nw! !sw! !ew! !ww!") DO (
IF !np! GEQ 0 IF "!mz:~%%A,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=n !rand!"
) ELSE IF "!mz:~%%E,1!" EQU "!crumb!" SET /A crmPos=np, cw=nw
IF !sp! LEQ !size! IF "!mz:~%%B,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=s !rand!"
) ELSE IF "!mz:~%%F,1!" EQU "!crumb!" SET /A crmPos=sp, cw=sw
IF !ep! LEQ !eChk! IF "!mz:~%%C,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=e !rand!"
) ELSE IF "!mz:~%%G,1!" EQU "!crumb!" SET /A crmPos=ep, cw=ew
IF !wp! GEQ !wChk! IF "!mz:~%%D,1!" EQU "!wall!" ( SET /A rCnt+=1 & SET "rand=w !rand!"
) ELSE IF "!mz:~%%H,1!" EQU "!crumb!" SET /A crmPos=wp, cw=ww
)
IF DEFINED rand ( REM adjacent unvisited cell is available
SET /A rCnt=!RANDOM! %% rCnt
FOR %%A IN (!rand!) DO ( REM pick random cell + wall
IF !rTmp! EQU !rCnt! SET /A "curPos=!%%Ap!, cTmp=curPos+1, mw=!%%Aw!, mTmp=mw+1"
SET /A rTmp+=1
)
REM write the 2 new characters into the maze
FOR /F "tokens=1-4" %%A IN ("!mw! !mTmp! !curPos! !cTmp!") DO (
SET "mz=!mz:~0,%%A!!crumb!!mz:~%%B!"
SET "mz=!mz:~0,%%C!!hall!!mz:~%%D!"
)
) ELSE IF DEFINED crmPos ( REM follow the crumbs backward
SET /A mTmp=cw+1
REM erase the crumb character and set new cursor position
FOR /F "tokens=1-2" %%A IN ("!cw! !mTmp!") DO SET "mz=!mz:~0,%%A!!hall!!mz:~%%B!"
SET "curPos=!crmPos!"
)
)
SET /A open=cols/2*2, mTmp=open+1
ECHO !wall!!bdr:~0,%open%!!hall!!bdr:~%mTmp%!!wall!
FOR /L %%A IN (0,!wide!,!size!) DO IF %%A LSS !size! ECHO !wall!!mz:~%%A,%wide%!!wall!
ECHO !wall!!bdr:~0,%open%!!hall!!bdr:~%mTmp%!!wall!
ENDLOCAL
EXIT /B 0
:amaze_help
ECHO Usage: %~0 Rows Cols [wall char]
ECHO Rows^>1, Cols^>1, and Rows*Cols^<=2096
ECHO Example: %~0 11 39 @
ENDLOCAL
EXIT /B 0

View file

@ -0,0 +1,19 @@
check(bound::Vector) = cell -> all([1, 1] .≤ cell .≤ bound)
neighbors(cell::Vector, bound::Vector, step::Int=2) =
filter(check(bound), map(dir -> cell + step * dir, [[0, 1], [-1, 0], [0, -1], [1, 0]]))
function walk(maze::Matrix, nxtcell::Vector, visited::Vector=[])
push!(visited, nxtcell)
for neigh in shuffle(neighbors(nxtcell, size(maze)))
if neigh ∉ visited
maze[round.(Int, (nxtcell + neigh) / 2)...] = 0
walk(maze, neigh, visited)
end
end
maze
end
function maze(w::Int, h::Int)
maze = collect(i % 2 | j % 2 for i in 1:2w+1, j in 1:2h+1)
firstcell = 2 * [rand(1:w), rand(1:h)]
return walk(maze, firstcell)
end

View file

@ -0,0 +1,13 @@
pprint(matrix) = for i = 1:size(matrix, 1) println(join(matrix[i, :])) end
function printmaze(maze)
walls = split("╹ ╸ ┛ ╺ ┗ ━ ┻ ╻ ┃ ┓ ┫ ┏ ┣ ┳ ╋")
h, w = size(maze)
f = cell -> 2 ^ ((3cell[1] + cell[2] + 3) / 2)
wall(i, j) = if maze[i,j] == 0 " " else
walls[Int(sum(f, filter(x -> maze[x...] != 0, neighbors([i, j], [h, w], 1)) .- [[i, j]]))]
end
mazewalls = collect(wall(i, j) for i in 1:2:h, j in 1:w)
pprint(mazewalls)
end
printmaze(maze(10, 10))

View file

@ -1,27 +0,0 @@
function walk(maze, cell, visited = Any[])
push!(visited, cell)
for neigh in shuffle(neighbors(cell, size(maze)))
if !(neigh in visited)
maze[round.(Int,(cell+neigh)/2)...] = 0
walk(maze, neigh, visited)
end
end
maze
end
neighbors(c,b,d=2)=filter(check(b),map(m->c+d*m, Any[[0,1],[-1,0],[0,-1],[1,0]]))
check(bound) = cell -> all([1,1] .<= cell .<= [bound...])
maze(w, h) = walk([i%2|j%2 for i=1:2w+1,j=1:2h+1], 2*[rand(1:w),rand(1:h)])
pprint(matrix) = for i = 1:size(matrix,1) println(join(matrix[i,:])) end
function printmaze(maze, wall = split("╹ ╸ ┛ ╺ ┗ ━ ┻ ╻ ┃ ┓ ┫ ┏ ┣ ┳ ╋"))
h,w = size(maze)
pprint([ maze[i,j] == 0 ? ' ' :
wall[Int(sum(c-> 2.0^.5(3c[1]+c[2]+3),
filter(x -> maze[x...] != 0,
neighbors([i,j],[h,w],1)) .- Any[[i,j]]))]
for i = 1:2:h, j = 1:w])
end

View file

@ -11,14 +11,9 @@ let () =
let nx = int_of_string Sys.argv.(1) in
let ny = int_of_string Sys.argv.(2) in
let rec random_order = function
| [] -> []
| [a] -> [a]
| x -> let i = Random.int (List.length x) in
let rec del i = function
| [] -> failwith "del"
| h::t -> if i = 0 then t else h :: del (i-1) t in
(List.nth x i) :: random_order (del i x) in
let shuffle lst =
let nl = List.map (fun c -> (Random.bits (), c)) lst in
List.map snd (List.sort compare nl) in
let get_neighbours (x,y) =
let lim n k = (0 <= k) && (k < n) in
@ -29,7 +24,7 @@ let () =
mark cell;
let check k =
if not (marked k) then (join cell k; visit k) in
List.iter check (random_order (get_neighbours cell)) in
List.iter check (shuffle (get_neighbours cell)) in
let print_maze () =
begin

View file

@ -1,17 +1,13 @@
import Foundation
extension Array {
mutating func swap(_ index1:Int, _ index2:Int) {
let temp = self[index1]
self[index1] = self[index2]
self[index2] = temp
}
mutating func shuffle() {
for _ in 0..<self.count {
let index1 = Int(arc4random()) % self.count
let index2 = Int(arc4random()) % self.count
self.swap(index1, index2)
guard count > 1 else { return }
for i in 0..<self.count - 1 {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
}