mirror of
https://github.com/cjdenio/crossword.git
synced 2026-10-03 11:06:19 +00:00
progress
This commit is contained in:
4 files changed
+124
-33
No files matched your search
@@ -2,4 +2,9 @@ module github.com/cjdenio/crossword
|
|||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
require golang.org/x/text v0.41.0
|
require (
|
||||||
|
golang.org/x/term v0.45.0
|
||||||
|
golang.org/x/text v0.41.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.47.0 // indirect
|
||||||
@@ -1,2 +1,6 @@
|
|||||||
|
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||||
|
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
|
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
||||||
|
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||||
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
||||||
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
||||||
@@ -6,9 +6,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cjdenio/crossword/puz"
|
"github.com/cjdenio/crossword/puz"
|
||||||
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -31,7 +31,7 @@ func RenderPuzzle(puzzle string, width, height int, selectedClueCells []int, sel
|
|||||||
for range (width * 2) + 1 {
|
for range (width * 2) + 1 {
|
||||||
b.WriteRune('─')
|
b.WriteRune('─')
|
||||||
}
|
}
|
||||||
b.WriteString("┐\n")
|
b.WriteString("┐\r\n")
|
||||||
|
|
||||||
for index, char := range puzzle {
|
for index, char := range puzzle {
|
||||||
if index%width == 0 {
|
if index%width == 0 {
|
||||||
@@ -57,7 +57,7 @@ func RenderPuzzle(puzzle string, width, height int, selectedClueCells []int, sel
|
|||||||
b.WriteString(cell)
|
b.WriteString(cell)
|
||||||
|
|
||||||
if (index+1)%width == 0 {
|
if (index+1)%width == 0 {
|
||||||
b.WriteString(" │\n")
|
b.WriteString(" │\r\n")
|
||||||
} else if char == '.' && puzzle[index+1] == '.' {
|
} else if char == '.' && puzzle[index+1] == '.' {
|
||||||
b.WriteRune(0x2588)
|
b.WriteRune(0x2588)
|
||||||
} else {
|
} else {
|
||||||
@@ -74,19 +74,59 @@ func RenderPuzzle(puzzle string, width, height int, selectedClueCells []int, sel
|
|||||||
for range (width * 2) + 1 {
|
for range (width * 2) + 1 {
|
||||||
b.WriteRune('─')
|
b.WriteRune('─')
|
||||||
}
|
}
|
||||||
b.WriteString("┘\n")
|
b.WriteString("┘\r\n")
|
||||||
|
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
type State struct {
|
||||||
// fmt.Print("\x1b[?1049h")
|
Puzzle *puz.Puzzle
|
||||||
// fmt.Print("\x1b[?25l")
|
SelectedCell int
|
||||||
|
SelectedClue *puz.Clue
|
||||||
|
Goodbye bool
|
||||||
|
}
|
||||||
|
|
||||||
// defer func() {
|
func RenderUI(state *State) int {
|
||||||
// fmt.Print("\x1b[?1049l")
|
selectedClueCells := []int{}
|
||||||
// fmt.Print("\x1b[?25h")
|
if state.SelectedClue != nil {
|
||||||
// }()
|
selectedClueCells = state.SelectedClue.Cells
|
||||||
|
}
|
||||||
|
|
||||||
|
uiHeight := 0
|
||||||
|
|
||||||
|
fmt.Printf("\r\nTITLE: %s\r\n", state.Puzzle.Title)
|
||||||
|
uiHeight += 2
|
||||||
|
fmt.Printf("AUTHOR: %s\r\n", state.Puzzle.Author)
|
||||||
|
uiHeight += 1
|
||||||
|
fmt.Print(RenderPuzzle(state.Puzzle.State, state.Puzzle.Width, state.Puzzle.Height, selectedClueCells, state.SelectedCell) + "\r\n")
|
||||||
|
uiHeight += state.Puzzle.Height + 3
|
||||||
|
if state.SelectedClue != nil {
|
||||||
|
fmt.Printf("%d: %s\r\n\r\n", state.SelectedClue.Number, state.SelectedClue.Clue)
|
||||||
|
uiHeight += 2
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\r\n", state.Puzzle.Copyright)
|
||||||
|
uiHeight += 1
|
||||||
|
|
||||||
|
if state.Goodbye {
|
||||||
|
fmt.Print("\r\nsee ya\r\n")
|
||||||
|
uiHeight += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return uiHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Print("\x1b[?25l")
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
fmt.Print("\x1b[?25h")
|
||||||
|
}()
|
||||||
|
termState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer term.Restore(int(os.Stdin.Fd()), termState)
|
||||||
|
|
||||||
filename := os.Args[1]
|
filename := os.Args[1]
|
||||||
file, err := os.ReadFile(filename)
|
file, err := os.ReadFile(filename)
|
||||||
@@ -99,24 +139,47 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("TITLE: %s\n", puzzle.Title)
|
state := State{
|
||||||
fmt.Printf("AUTHOR: %s\n", puzzle.Author)
|
Puzzle: puzzle,
|
||||||
fmt.Println(RenderPuzzle(puzzle.Solution, puzzle.Width, puzzle.Height, puzzle.Clues[0].Cells, 1))
|
SelectedClue: puzzle.Clues[0],
|
||||||
fmt.Printf("%s\n", puzzle.Copyright)
|
SelectedCell: puzzle.Clues[0].Cells[0],
|
||||||
|
}
|
||||||
|
|
||||||
selectedCell := 1
|
uiHeight := RenderUI(&state)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
time.Sleep(500 * time.Millisecond)
|
buffer := make([]byte, 3)
|
||||||
|
_, err = os.Stdin.Read(buffer)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("\x1b[%dA", puzzle.Height+6)
|
if buffer[0] == 3 {
|
||||||
|
state.SelectedClue = nil
|
||||||
|
state.SelectedCell = -1
|
||||||
|
state.Goodbye = true
|
||||||
|
fmt.Printf("\r\x1b[%dA", uiHeight)
|
||||||
|
fmt.Print("\x1b[J")
|
||||||
|
RenderUI(&state)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch buffer[2] {
|
||||||
|
case 68:
|
||||||
|
state.SelectedCell--
|
||||||
|
case 67:
|
||||||
|
state.SelectedCell++
|
||||||
|
case 65:
|
||||||
|
state.SelectedCell -= puzzle.Width
|
||||||
|
case 66:
|
||||||
|
state.SelectedCell += puzzle.Width
|
||||||
|
}
|
||||||
|
|
||||||
|
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
|
||||||
|
|
||||||
|
fmt.Printf("\r\x1b[%dA", uiHeight)
|
||||||
fmt.Print("\x1b[J")
|
fmt.Print("\x1b[J")
|
||||||
|
|
||||||
fmt.Printf("TITLE: %s\n", puzzle.Title)
|
uiHeight = RenderUI(&state)
|
||||||
fmt.Printf("AUTHOR: %s\n", puzzle.Author)
|
|
||||||
fmt.Println(RenderPuzzle(puzzle.Solution, puzzle.Width, puzzle.Height, puzzle.Clues[selectedCell].Cells, 1))
|
|
||||||
fmt.Printf("%s\n", puzzle.Copyright)
|
|
||||||
|
|
||||||
selectedCell++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+27
-8
@@ -38,13 +38,18 @@ type Puzzle struct {
|
|||||||
Solution string
|
Solution string
|
||||||
State string
|
State string
|
||||||
|
|
||||||
Clues []Clue
|
Clues []*Clue
|
||||||
|
|
||||||
|
Cells [][2]*Clue
|
||||||
}
|
}
|
||||||
|
|
||||||
func startOfDownClue(puzzle string, width, index int) bool {
|
func startOfDownClue(puzzle string, width, height, index int) bool {
|
||||||
if puzzle[index] == '.' {
|
if puzzle[index] == '.' {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if int(math.Floor(float64(index/width)))+1 == height || puzzle[index+width] == '.' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if index < width {
|
if index < width {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -58,6 +63,9 @@ func startOfAcrossClue(puzzle string, width, index int) bool {
|
|||||||
if puzzle[index] == '.' {
|
if puzzle[index] == '.' {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if (index+1)%width == 0 || puzzle[index+1] == '.' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if index%width == 0 {
|
if index%width == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -137,7 +145,8 @@ func ParsePuz(file []byte) (*Puzzle, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assign clue numbers
|
// assign clue numbers
|
||||||
puzzle.Clues = make([]Clue, 0, puzzle.ClueCount)
|
puzzle.Clues = make([]*Clue, 0, puzzle.ClueCount)
|
||||||
|
puzzle.Cells = make([][2]*Clue, len(puzzle.Solution))
|
||||||
|
|
||||||
clueNumber := 1
|
clueNumber := 1
|
||||||
clueIndex := 0
|
clueIndex := 0
|
||||||
@@ -146,23 +155,27 @@ func ParsePuz(file []byte) (*Puzzle, error) {
|
|||||||
cellGetsNumber := false
|
cellGetsNumber := false
|
||||||
if startOfAcrossClue(puzzle.Solution, puzzle.Width, i) {
|
if startOfAcrossClue(puzzle.Solution, puzzle.Width, i) {
|
||||||
cellGetsNumber = true
|
cellGetsNumber = true
|
||||||
puzzle.Clues = append(puzzle.Clues, Clue{
|
clue := Clue{
|
||||||
Cells: []int{i},
|
Cells: []int{i},
|
||||||
Direction: DirectionAcross,
|
Direction: DirectionAcross,
|
||||||
Number: clueNumber,
|
Number: clueNumber,
|
||||||
Clue: clues[clueIndex],
|
Clue: clues[clueIndex],
|
||||||
})
|
}
|
||||||
|
puzzle.Clues = append(puzzle.Clues, &clue)
|
||||||
|
puzzle.Cells[i][0] = &clue
|
||||||
clueIndex++
|
clueIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
if startOfDownClue(puzzle.Solution, puzzle.Width, i) {
|
if startOfDownClue(puzzle.Solution, puzzle.Width, puzzle.Height, i) {
|
||||||
cellGetsNumber = true
|
cellGetsNumber = true
|
||||||
puzzle.Clues = append(puzzle.Clues, Clue{
|
clue := Clue{
|
||||||
Cells: []int{i},
|
Cells: []int{i},
|
||||||
Direction: DirectionDown,
|
Direction: DirectionDown,
|
||||||
Number: clueNumber,
|
Number: clueNumber,
|
||||||
Clue: clues[clueIndex],
|
Clue: clues[clueIndex],
|
||||||
})
|
}
|
||||||
|
puzzle.Clues = append(puzzle.Clues, &clue)
|
||||||
|
puzzle.Cells[i][1] = &clue
|
||||||
clueIndex++
|
clueIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +194,12 @@ func ParsePuz(file []byte) (*Puzzle, error) {
|
|||||||
|
|
||||||
if currentCell != clue.Cells[0] {
|
if currentCell != clue.Cells[0] {
|
||||||
clue.Cells = append(clue.Cells, currentCell)
|
clue.Cells = append(clue.Cells, currentCell)
|
||||||
|
switch clue.Direction {
|
||||||
|
case DirectionAcross:
|
||||||
|
puzzle.Cells[currentCell][0] = clue
|
||||||
|
case DirectionDown:
|
||||||
|
puzzle.Cells[currentCell][1] = clue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if clue.Direction == DirectionAcross {
|
if clue.Direction == DirectionAcross {
|
||||||
|
|||||||
Reference in new issue
Block a user