-
Notifications
You must be signed in to change notification settings - Fork 16
/
PNllvm.nim
131 lines (110 loc) · 3.11 KB
/
PNllvm.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Compile with nimrod c -d:release --threads:on PNllvm.nim
import os, strutils, unsigned
const
TileDim = 50
Miw = 2
MaxWid = 8
NumLevs = 800
NumThreads = 4
type
TTile = object
x, y, t: int32
TRoom = object
x, y, w, h, n: int32
TLev = object
ts: array[2500, TTile]
rs: array[100, TRoom]
lenRs: int32
proc genRand(gen: ptr uint32): int32 {.raises: [], noSideEffect.} =
var g = gen[]
g += g
g = g xor 1
var tgen = cast[int32](g)
if tgen < 0:
g = g xor 0x88888eef
gen[] = g
return cast[int32](g)
proc checkColl(x, y, w, h: int32, rs: array[100, TRoom], lenRs: int32): int32 =
result = 0
for i in 0 .. <lenRs:
let
rx = rs[i].x
ry = rs[i].y
rw = rs[i].w
rh = rs[i].h
var roomOkay = ord((rx + rw + 1) < x) or ord(rx > (x + w + 1)) or
ord((ry + rh + 1) < y) or ord(ry > (y + h + 1))
if roomOkay == 0: return 1
proc makeRoom(rs: var array[100, TRoom], lenRs: ptr int32, gen: ptr uint32) =
var newLenRs = lenRs[]
for ii in 0 .. <50000:
let
x = genRand(gen) mod TileDim
y = genRand(gen) mod TileDim
w = genRand(gen) mod MaxWid+Miw
h = genRand(gen) mod MaxWid+Miw
if x + w >= TileDim or y + h >= TileDim or x == 0 or y == 0: continue
let noCrash = checkColl(x, y, w, h, rs, newLenRs)
if noCrash == 0:
var r = TRoom(x: x, y: y, w: w, h: h, n: newLenRs)
rs[newLenRs] = r
newLenRs = newLenRs + 1
if newLenRs == 99: break
lenRs[] = newLenRs
proc room2Tiles(r: ptr TRoom, ts: var array[2500, TTile]) =
let
x = r.x
y = r.y
w = r.w
h = r.h
for xi in x .. x + w:
for yi in y .. y + h:
var num = yi * TileDim + xi
ts[num].t = 1
proc printLev(lvl: ptr TLev) =
for i in 0 .. <2500:
stdout.write(lvl.ts[i].t)
if i mod TileDim == 49 and i != 0: stdout.write("\n")
var
ls: array[NumLevs, TLev]
gens: array[NumThreads, array[8, uint32]]
proc makeLevs(threadNum: int32) {.thread.} =
var
loopStart = threadNum * (NumLevs div NumThreads)
pGen = addr(gens[threadNum][0])
for i in loopStart .. <(loopStart + (NumLevs div NumThreads)):
var
rs {.noinit.}: array[100, TRoom]
lenRs = 0'i32
pLenRs = addr(lenRs)
makeRoom(rs, pLenRs, pGen)
var ts {.noinit.}: array[2500, TTile]
for ii in 0 .. <2500:
let imod = ii mod TileDim
let idiv = ii.int32 div TileDim
ts[ii].x = imod
ts[ii].y = idiv
ts[ii].t = 0
for ii in 0 .. <lenRs:
room2Tiles(addr(rs[ii]), ts)
var lvl: TLev
lvl.rs = rs
lvl.ts = ts
lvl.lenRs = lenRs
ls[i] = lvl
when isMainModule:
let v = paramStr(1).parseInt()
echo("The random seed is: ", v)
var threads: array[NumThreads, TThread[int32]]
var gen = v
for i in 0 .. <NumThreads:
gens[i][0] = uint32(gen * (i+1) * (i+1))
echo "The seed of thread $1 is: $2" % [$(i+1), $gens[i][0]]
for i in 0 .. <NumThreads:
createThread(threads[i], makeLevs, i.int32)
joinThreads(threads)
var templ: TLev
templ.lenRs = 0
for i in 0 .. <100:
if ls[i].lenRs > templ.lenRs: templ = ls[i]
printLev(addr(templ))