mirror of
https://github.com/cjdenio/crossword.git
synced 2026-10-03 11:06:19 +00:00
make it possible to check puzzle in the future
This commit is contained in:
5 files changed
+59
-29
No files matched your search
@@ -6,3 +6,5 @@ todo
|
|||||||
- .puz checksums
|
- .puz checksums
|
||||||
- fix shift+enter / shift+tab in other terminals
|
- fix shift+enter / shift+tab in other terminals
|
||||||
- clear grid
|
- clear grid
|
||||||
|
- rebus (at least add message that rebus is not supported)
|
||||||
|
- .ipuz files
|
||||||
+53
-15
@@ -28,6 +28,17 @@ type State struct {
|
|||||||
LastKeySequence string
|
LastKeySequence string
|
||||||
DebugMode bool
|
DebugMode bool
|
||||||
SolveState SolveState
|
SolveState SolveState
|
||||||
|
CheckState []rune
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewState(puzzle *puz.Puzzle) *State {
|
||||||
|
return &State{
|
||||||
|
Puzzle: puzzle,
|
||||||
|
PuzzleState: []rune(puzzle.State),
|
||||||
|
SelectedClue: puzzle.Clues[0],
|
||||||
|
SelectedCell: puzzle.Clues[0].Cells[0],
|
||||||
|
CheckState: make([]rune, len(puzzle.State)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) MoveCursor(direction int) {
|
func (state *State) MoveCursor(direction int) {
|
||||||
@@ -186,7 +197,7 @@ func (state *State) GridFilled() bool {
|
|||||||
return !slices.Contains(state.PuzzleState, '-')
|
return !slices.Contains(state.PuzzleState, '-')
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) CheckPuzzle() bool {
|
func (state *State) PuzzleSolved() bool {
|
||||||
for i, cell := range state.PuzzleState {
|
for i, cell := range state.PuzzleState {
|
||||||
if cell == '.' {
|
if cell == '.' {
|
||||||
continue
|
continue
|
||||||
@@ -198,19 +209,31 @@ func (state *State) CheckPuzzle() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *State) RenderUI(w io.Writer) int {
|
func (state *State) CheckPuzzle() {
|
||||||
selectedClueCells := []int{}
|
result := make([]rune, len(state.PuzzleState))
|
||||||
if state.SelectedClue != nil {
|
|
||||||
selectedClueCells = state.SelectedClue.Cells
|
for i, cell := range state.PuzzleState {
|
||||||
|
if cell == '.' || cell == '-' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cell == rune(state.Puzzle.Solution[i]) {
|
||||||
|
result[i] = 'y'
|
||||||
|
} else {
|
||||||
|
result[i] = 'n'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.CheckState = result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (state *State) RenderUI(w io.Writer) int {
|
||||||
uiHeight := 0
|
uiHeight := 0
|
||||||
|
|
||||||
fmt.Fprintf(w, "\r\nTITLE: %s\r\n", state.Puzzle.Title)
|
fmt.Fprintf(w, "\r\nTITLE: %s\r\n", state.Puzzle.Title)
|
||||||
uiHeight += 2
|
uiHeight += 2
|
||||||
fmt.Fprintf(w, "AUTHOR: %s\r\n", state.Puzzle.Author)
|
fmt.Fprintf(w, "AUTHOR: %s\r\n", state.Puzzle.Author)
|
||||||
uiHeight += 1
|
uiHeight += 1
|
||||||
fmt.Fprint(w, RenderPuzzle(state.PuzzleState, state.Puzzle.Width, state.Puzzle.Height, selectedClueCells, state.SelectedCell)+"\r\n")
|
fmt.Fprint(w, state.RenderPuzzle()+"\r\n")
|
||||||
uiHeight += state.Puzzle.Height + 3
|
uiHeight += state.Puzzle.Height + 3
|
||||||
if state.SelectedClue != nil {
|
if state.SelectedClue != nil {
|
||||||
if state.SelectedClue.Direction == puz.DirectionAcross {
|
if state.SelectedClue.Direction == puz.DirectionAcross {
|
||||||
@@ -262,17 +285,22 @@ func AnsiRed(s string) string {
|
|||||||
return fmt.Sprintf("\x1b[31m%s\x1b[0m", s)
|
return fmt.Sprintf("\x1b[31m%s\x1b[0m", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderPuzzle(puzzle []rune, width, height int, selectedClueCells []int, selectedCell int) string {
|
func (state *State) RenderPuzzle() string {
|
||||||
|
selectedClueCells := []int{}
|
||||||
|
if state.SelectedClue != nil {
|
||||||
|
selectedClueCells = state.SelectedClue.Cells
|
||||||
|
}
|
||||||
|
|
||||||
b := strings.Builder{}
|
b := strings.Builder{}
|
||||||
|
|
||||||
b.WriteRune('┌')
|
b.WriteRune('┌')
|
||||||
for range (width * 2) + 1 {
|
for range (state.Puzzle.Width * 2) + 1 {
|
||||||
b.WriteRune('─')
|
b.WriteRune('─')
|
||||||
}
|
}
|
||||||
b.WriteString("┐\r\n")
|
b.WriteString("┐\r\n")
|
||||||
|
|
||||||
for index, char := range puzzle {
|
for index, char := range state.PuzzleState {
|
||||||
if index%width == 0 {
|
if index%state.Puzzle.Width == 0 {
|
||||||
b.WriteString("│ ")
|
b.WriteString("│ ")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,17 +314,26 @@ func RenderPuzzle(puzzle []rune, width, height int, selectedClueCells []int, sel
|
|||||||
cell = string(char)
|
cell = string(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
if selectedCell == index {
|
if state.SelectedCell == index {
|
||||||
cell = AnsiInverted(cell)
|
cell = AnsiInverted(cell)
|
||||||
} else if slices.Contains(selectedClueCells, index) {
|
} else if slices.Contains(selectedClueCells, index) {
|
||||||
cell = AnsiWhiteBackgrounded(cell)
|
cell = AnsiWhiteBackgrounded(cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(state.CheckState) == len(state.PuzzleState) {
|
||||||
|
switch state.CheckState[index] {
|
||||||
|
case 'y':
|
||||||
|
cell = AnsiGreen(cell)
|
||||||
|
case 'n':
|
||||||
|
cell = AnsiRed(cell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
b.WriteString(cell)
|
b.WriteString(cell)
|
||||||
|
|
||||||
if (index+1)%width == 0 {
|
if (index+1)%state.Puzzle.Width == 0 {
|
||||||
b.WriteString(" │\r\n")
|
b.WriteString(" │\r\n")
|
||||||
} else if char == '.' && puzzle[index+1] == '.' {
|
} else if char == '.' && state.PuzzleState[index+1] == '.' {
|
||||||
b.WriteRune(0x2588)
|
b.WriteRune(0x2588)
|
||||||
} else {
|
} else {
|
||||||
// inefficient
|
// inefficient
|
||||||
@@ -309,7 +346,7 @@ func RenderPuzzle(puzzle []rune, width, height int, selectedClueCells []int, sel
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.WriteRune('└')
|
b.WriteRune('└')
|
||||||
for range (width * 2) + 1 {
|
for range (state.Puzzle.Width * 2) + 1 {
|
||||||
b.WriteRune('─')
|
b.WriteRune('─')
|
||||||
}
|
}
|
||||||
b.WriteString("┘\r\n")
|
b.WriteString("┘\r\n")
|
||||||
@@ -385,6 +422,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
|
|||||||
if buffer[0] >= 0x61 && buffer[0] <= 0x7a {
|
if buffer[0] >= 0x61 && buffer[0] <= 0x7a {
|
||||||
cellWasFilled := state.PuzzleState[state.SelectedCell] != '-'
|
cellWasFilled := state.PuzzleState[state.SelectedCell] != '-'
|
||||||
state.PuzzleState[state.SelectedCell] = unicode.ToUpper(rune(buffer[0]))
|
state.PuzzleState[state.SelectedCell] = unicode.ToUpper(rune(buffer[0]))
|
||||||
|
state.CheckState[state.SelectedCell] = 0x00
|
||||||
|
|
||||||
i := slices.Index(state.SelectedClue.Cells, state.SelectedCell)
|
i := slices.Index(state.SelectedClue.Cells, state.SelectedCell)
|
||||||
|
|
||||||
@@ -404,7 +442,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if state.GridFilled() {
|
if state.GridFilled() {
|
||||||
if state.CheckPuzzle() {
|
if state.PuzzleSolved() {
|
||||||
state.SolveState = Solved
|
state.SolveState = Solved
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -50,12 +50,7 @@ func main() {
|
|||||||
|
|
||||||
defer term.Restore(int(os.Stdin.Fd()), termState)
|
defer term.Restore(int(os.Stdin.Fd()), termState)
|
||||||
|
|
||||||
state := game.State{
|
state := game.NewState(puzzle)
|
||||||
Puzzle: puzzle,
|
|
||||||
PuzzleState: []rune(puzzle.State),
|
|
||||||
SelectedClue: puzzle.Clues[0],
|
|
||||||
SelectedCell: puzzle.Clues[0].Cells[0],
|
|
||||||
}
|
|
||||||
if debugMode != nil {
|
if debugMode != nil {
|
||||||
state.DebugMode = *debugMode
|
state.DebugMode = *debugMode
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -87,9 +87,9 @@ func readText(b *bufio.Reader, version string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return decoded, nil
|
return strings.TrimSpace(decoded), nil
|
||||||
} else {
|
} else {
|
||||||
return string(text[:len(text)-1]), nil
|
return strings.TrimSpace(string(text[:len(text)-1])), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -31,12 +31,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
state := game.State{
|
state := game.NewState(puzzle)
|
||||||
Puzzle: puzzle,
|
|
||||||
PuzzleState: []rune(puzzle.State),
|
|
||||||
SelectedClue: puzzle.Clues[0],
|
|
||||||
SelectedCell: puzzle.Clues[0].Cells[0],
|
|
||||||
}
|
|
||||||
|
|
||||||
io.WriteString(s, "\x1b[?25l")
|
io.WriteString(s, "\x1b[?25l")
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user