-
Notifications
You must be signed in to change notification settings - Fork 0
/
world_builder.go
117 lines (94 loc) · 1.84 KB
/
world_builder.go
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
package main
type builder struct {
w *World
marked [][]bool
negateNext bool
}
func newBuilder(w *World) *builder {
marked := make([][]bool, w.SizeX)
for x := 0; x < w.SizeX; x++ {
marked[x] = make([]bool, w.SizeY)
}
return &builder{
w: w,
marked: marked,
}
}
func (b *builder) All() *builder {
defer b.afterCall()
for x := 0; x < b.w.SizeX; x++ {
for y := 0; y < b.w.SizeY; y++ {
b.mark(x, y)
}
}
return b
}
func (b *builder) Point(x, y int) *builder {
defer b.afterCall()
b.mark(x, y)
return b
}
func (b *builder) Rect(x1, y1, x2, y2 int) *builder {
defer b.afterCall()
return b.Line(x1, y1, x2, y1).
Line(x2, y1, x2, y2).
Line(x1, y2, x2, y2).
Line(x1, y1, x1, y2)
}
func (b *builder) RectFill(x1, y1, x2, y2 int) *builder {
defer b.afterCall()
for x := x1; x < x2; x++ {
for y := y1; y < y2; y++ {
b.mark(x, y)
}
}
return b
}
func (b *builder) Circle(x, y, r int) *builder {
defer b.afterCall()
points := CirclePoints(x, y, r)
for _, point := range points {
b.mark(point.X, point.Y)
}
return b
}
func (b *builder) CircleThick(x, y, r int) *builder {
defer b.afterCall()
points := CircleThickPoints(x, y, r)
for _, point := range points {
b.mark(point.X, point.Y)
}
return b
}
func (b *builder) Line(x1, y1, x2, y2 int) *builder {
defer b.afterCall()
points := LinePoints(x1, y1, x2, y2)
for _, point := range points {
b.mark(point.X, point.Y)
}
return b
}
func (b *builder) Except() *builder {
b.negateNext = true
return b
}
func (b *builder) Do(fn func(*Entity)) {
for x := 0; x < b.w.SizeX; x++ {
for y := 0; y < b.w.SizeY; y++ {
if !b.marked[x][y] {
continue
}
fn(b.w.At(x, y))
}
}
}
func (b *builder) mark(x, y int) {
val := true
if b.negateNext {
val = false
}
b.marked[x][y] = val
}
func (b *builder) afterCall() {
b.negateNext = false
}