-
Notifications
You must be signed in to change notification settings - Fork 0
/
tile.go
104 lines (90 loc) · 2.05 KB
/
tile.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
package day20
var seaMonster = []string{
" # ",
"# ## ## ###",
" # # # # # # ",
}
const (
seaMonsterHeight = 3
seaMonsterWidth = len("# ## ## ###")
)
type Tile [][]byte
func (t Tile) Permutations() []Tile {
return append(t.RotatePermutations(), t.Flip().RotatePermutations()...)
}
func (t Tile) RotatePermutations() []Tile {
ret := make([]Tile, 4)
ret[0] = t
for i := 0; i < 3; i++ {
t = t.RotateLeft()
ret[i+1] = t
}
return ret
}
func (t Tile) RotateLeft() Tile {
ret := make(Tile, len(t))
for i := 0; i < len(t); i++ {
ret[i] = make([]byte, len(t[0]))
}
for y := 0; y < len(t); y++ {
for x := 0; x < len(t[0]); x++ {
ret[y][x] = t[x][len(t[0])-y-1]
}
}
return ret
}
func (t Tile) Flip() Tile {
ret := make(Tile, len(t))
for i := 0; i < len(t); i++ {
ret[i] = t[len(t)-i-1]
}
return ret
}
func (t Tile) RightSideMatchesLeftOf(neighbour Tile) bool {
for y := 0; y < len(t); y++ {
if t[y][len(t[0])-1] != neighbour[y][0] {
return false
}
}
return true
}
func (t Tile) BottomSideMatchesTopOf(neighbour Tile) bool {
for x := 0; x < len(t[0]); x++ {
if t[len(t)-1][x] != neighbour[0][x] {
return false
}
}
return true
}
func (t Tile) ReplaceSeaMonsters() bool {
// (y, x) is the top left corner of our sliding window
var ok bool
for y := 0; y < len(t)-seaMonsterHeight; y++ {
for x := 0; x < len(t[0])-seaMonsterWidth; x++ {
if t.HaveMonsterAt(y, x) {
t.ReplaceMonsterAt(y, x)
ok = true
}
}
}
return ok
}
func (t Tile) HaveMonsterAt(y, x int) bool {
for monsterY := 0; monsterY < seaMonsterHeight; monsterY++ {
for monsterX := 0; monsterX < seaMonsterWidth; monsterX++ {
if seaMonster[monsterY][monsterX] == '#' && t[y+monsterY][x+monsterX] != '#' {
return false
}
}
}
return true
}
func (t Tile) ReplaceMonsterAt(y, x int) {
for monsterY := 0; monsterY < seaMonsterHeight; monsterY++ {
for monsterX := 0; monsterX < seaMonsterWidth; monsterX++ {
if seaMonster[monsterY][monsterX] == '#' {
t[y+monsterY][x+monsterX] = 'O'
}
}
}
}