200 lines
3.5 KiB
Go
200 lines
3.5 KiB
Go
package tchart
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/derailed/tview"
|
|
)
|
|
|
|
var dots = []rune{' ', '⠂', '▤', '▥'}
|
|
|
|
const (
|
|
b = ' '
|
|
h = tview.BoxDrawingsHeavyHorizontal
|
|
v = tview.BoxDrawingsHeavyVertical
|
|
tl = tview.BoxDrawingsHeavyDownAndRight
|
|
tr = tview.BoxDrawingsHeavyDownAndLeft
|
|
bl = tview.BoxDrawingsHeavyUpAndRight
|
|
br = tview.BoxDrawingsHeavyUpAndLeft
|
|
teeL = tview.BoxDrawingsHeavyVerticalAndLeft
|
|
teeR = tview.BoxDrawingsHeavyVerticalAndRight
|
|
lh = '\u2578'
|
|
rh = '\u257a'
|
|
hv = '\u2579'
|
|
lv = '\u257b'
|
|
)
|
|
|
|
// Segment represents a dial segment.
|
|
type Segment []int
|
|
|
|
// Segments represents a collection of segments.
|
|
type Segments []Segment
|
|
|
|
// Matrix represents a number dial.
|
|
type Matrix [][]rune
|
|
|
|
// Orientation tracks char orientations.
|
|
type Orientation int
|
|
|
|
// DotMatrix tracks a char matrix.
|
|
type DotMatrix struct {
|
|
row, col int
|
|
}
|
|
|
|
// NewDotMatrix returns a new matrix.
|
|
func NewDotMatrix(row, col int) DotMatrix {
|
|
return DotMatrix{
|
|
row: row,
|
|
col: col,
|
|
}
|
|
}
|
|
|
|
// Print prints the matrix.
|
|
func (d DotMatrix) Print(n int) Matrix {
|
|
if d.row == d.col {
|
|
return To3x3Char(n)
|
|
}
|
|
m := make(Matrix, d.row)
|
|
segs := asSegments(n)
|
|
for row := 0; row < d.row; row++ {
|
|
for col := 0; col < d.col; col++ {
|
|
m[row] = append(m[row], segs.CharFor(row, col))
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
func asSegments(n int) Segment {
|
|
switch n {
|
|
case 0:
|
|
return Segment{1, 1, 1, 0, 1, 1, 1}
|
|
case 1:
|
|
return Segment{0, 0, 1, 0, 0, 1, 0}
|
|
case 2:
|
|
return Segment{1, 0, 1, 1, 1, 0, 1}
|
|
case 3:
|
|
return Segment{1, 0, 1, 1, 0, 1, 1}
|
|
case 4:
|
|
return Segment{0, 1, 0, 1, 0, 1, 0}
|
|
case 5:
|
|
return Segment{1, 1, 0, 1, 0, 1, 1}
|
|
case 6:
|
|
return Segment{0, 1, 0, 1, 1, 1, 1}
|
|
case 7:
|
|
return Segment{1, 0, 1, 0, 0, 1, 0}
|
|
case 8:
|
|
return Segment{1, 1, 1, 1, 1, 1, 1}
|
|
case 9:
|
|
return Segment{1, 1, 1, 1, 0, 1, 0}
|
|
|
|
default:
|
|
panic(fmt.Sprintf("NYI %d", n))
|
|
}
|
|
}
|
|
|
|
// CharFor returns a char based on row/col.
|
|
func (s Segment) CharFor(row, col int) rune {
|
|
c := dots[0]
|
|
segs := ToSegments(row, col)
|
|
if segs == nil {
|
|
return c
|
|
}
|
|
for _, seg := range segs {
|
|
if s[seg] == 1 {
|
|
c = charForSeg(seg, row, col)
|
|
}
|
|
}
|
|
return c
|
|
}
|
|
|
|
func charForSeg(seg, row, col int) rune {
|
|
switch seg {
|
|
case 0, 3, 6:
|
|
return dots[2]
|
|
}
|
|
if row == 0 && (col == 0 || col == 2) {
|
|
return dots[2]
|
|
}
|
|
|
|
return dots[3]
|
|
}
|
|
|
|
var segs = map[int][][]int{
|
|
0: {{1, 0}, {0}, {2, 0}},
|
|
1: {{1}, nil, {2}},
|
|
2: {{1, 3}, {3}, {2, 3}},
|
|
3: {{4}, nil, {5}},
|
|
4: {{4, 6}, {6}, {5, 6}},
|
|
}
|
|
|
|
// ToSegments return path segments.
|
|
func ToSegments(row, col int) []int {
|
|
return segs[row][col]
|
|
}
|
|
|
|
// To3x3Char returns 3x3 number matrix
|
|
func To3x3Char(numb int) Matrix {
|
|
switch numb {
|
|
case 1:
|
|
return Matrix{
|
|
[]rune{b, lv, b},
|
|
[]rune{b, v, b},
|
|
[]rune{b, hv, b},
|
|
}
|
|
case 2:
|
|
return Matrix{
|
|
[]rune{rh, h, tr},
|
|
[]rune{tl, h, br},
|
|
[]rune{bl, h, lh},
|
|
}
|
|
case 3:
|
|
return Matrix{
|
|
[]rune{h, h, tr},
|
|
[]rune{rh, h, teeL},
|
|
[]rune{h, h, br},
|
|
}
|
|
case 4:
|
|
return Matrix{
|
|
[]rune{lv, b, lv},
|
|
[]rune{bl, h, teeL},
|
|
[]rune{b, b, hv},
|
|
}
|
|
case 5:
|
|
return Matrix{
|
|
[]rune{tl, h, lh},
|
|
[]rune{bl, h, tr},
|
|
[]rune{rh, h, br},
|
|
}
|
|
case 6:
|
|
return Matrix{
|
|
[]rune{tl, h, lh},
|
|
[]rune{teeR, h, tr},
|
|
[]rune{bl, h, br},
|
|
}
|
|
case 7:
|
|
return Matrix{
|
|
[]rune{h, h, tr},
|
|
[]rune{b, b, v},
|
|
[]rune{b, b, hv},
|
|
}
|
|
case 8:
|
|
return Matrix{
|
|
[]rune{tl, h, tr},
|
|
[]rune{teeR, h, teeL},
|
|
[]rune{bl, h, br},
|
|
}
|
|
case 9:
|
|
return Matrix{
|
|
[]rune{tl, h, tr},
|
|
[]rune{bl, h, teeL},
|
|
[]rune{rh, h, br},
|
|
}
|
|
default:
|
|
return Matrix{
|
|
[]rune{tl, h, tr},
|
|
[]rune{v, b, v},
|
|
[]rune{bl, h, br},
|
|
}
|
|
}
|
|
}
|