-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathprint.go
More file actions
126 lines (116 loc) · 3.1 KB
/
print.go
File metadata and controls
126 lines (116 loc) · 3.1 KB
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
package main
import "container/list"
import "fmt"
const (
RESET = "\x1b[0m"
BOLD = "\x1b[1m"
BLACK = "\x1b[30m"
RED = "\x1b[31m"
GREEN = "\x1b[32m"
YELLOW = "\x1b[33m"
BLUE = "\x1b[34m"
MAGENTA = "\x1b[35m"
CYAN = "\x1b[36m"
WHITE = "\x1b[37m"
)
var (
TUBE = [16]rune{' ', '╵', '╶', '└', '╷', '│', '┌', '├', '╴', '┘', '─', '┴', '┐', '┤', '┬', '┼'}
)
// Print the paper by filling each flow with a character in [a-zA-Z0-9]
// If color is true, each flow will be colored by one of 16 terminal color
// codes
func PrintSimple(paper *Paper, color bool) {
colors := makeColorTable(paper, !color)
table := fillTable(paper)
fmt.Println(paper.Width-2, paper.Height-2)
for y := 1; y < paper.Height-1; y++ {
for x := 1; x < paper.Width-1; x++ {
pos := y*paper.Width + x
if col := colors[pos]; col == "" {
fmt.Printf("%c", table[pos])
} else {
fmt.Printf("%s%c%s", col, table[pos], RESET)
}
}
fmt.Println()
}
}
// Print the paper using unicode table characters such as └ and │
// If color is true, each flow will be colored by one of 16 terminal color
// codes
func PrintTubes(paper *Paper, color bool) {
colors := makeColorTable(paper, !color)
for y := 1; y < paper.Height-1; y++ {
for x := 1; x < paper.Width-1; x++ {
pos := y*paper.Width + x
val := paper.Table[pos]
var c rune
if val == EMPTY {
c = TUBE[paper.Con[pos]]
} else {
c = val
}
if col := colors[pos]; col == "" {
fmt.Printf("%c", c)
} else {
fmt.Printf("%s%c%s", col, c, RESET)
}
}
fmt.Println()
}
}
// Assigns a terminal color code to every position on the paper
// If empty is true, the table will be a dummy with all empty strings
func makeColorTable(paper *Paper, empty bool) []string {
color := make([]string, paper.Width*paper.Height)
if !empty {
table := fillTable(paper)
next := 0
available := []string{RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BLACK, WHITE}
for _, c := range available {
available = append(available, BOLD+c)
}
var mapping = make(map[rune]string)
for y := 1; y < paper.Height-1; y++ {
for x := 1; x < paper.Width-1; x++ {
c := table[y*paper.Width+x]
if _, found := mapping[c]; !found {
if len(available) >= 1 {
mapping[c] = available[next]
next = (next + 1) % len(available)
} else {
mapping[c] = BLACK
}
}
color[y*paper.Width+x] = mapping[c]
}
}
}
return color
}
// Does a bfs search on every source, filling out its connected nodes
// This is neccesary since we normally store only relative connection
// information
func fillTable(paper *Paper) []rune {
w, h := paper.Width, paper.Height
table := make([]rune, w*h)
copy(table, paper.Table)
for pos := 0; pos < w*h; pos++ {
if paper.source[pos] {
queue := list.New()
queue.PushBack(pos)
for queue.Len() != 0 {
pos := queue.Remove(queue.Front()).(int)
paint := table[pos]
for _, dir := range DIRS {
next := pos + paper.Vctr[dir]
if paper.Con[pos]&dir != 0 && table[next] == EMPTY {
table[next] = paint
queue.PushBack(next)
}
}
}
}
}
return table
}