Compare commits

..
4 Commits
Author SHA1 Message Date
cjdenio 644ce0d273 fix bug 2026-09-11 22:00:00 -05:00
cjdenio c1d024a97e fix text encoding for utf-8 puz files 2026-09-11 17:38:37 -05:00
cjdenio 0f1da4c461 some SSH logging 2026-09-11 14:35:53 -05:00
cjdenio e6798b1a67 jump backwards 2026-09-11 14:25:51 -05:00
5 changed files with 55 additions and 27 deletions

No files matched your search

+1 -3
View File
@@ -1,10 +1,8 @@
todo
- fix bug with that one 6x6 puzzle
- correctly calculate uiHeight with multi-line clues
- timer
- reveal grid/word
- .puz checksums
- fix shift+enter / short+tab in other terminals
- after entering letter, jump to next unfilled cell (even if it's backwards)
- fix shift+enter / shift+tab in other terminals
- clear grid
+30 -14
View File
@@ -348,6 +348,23 @@ func (state *State) LoadSaveFile(f []byte) error {
return nil
}
func (state *State) SwitchDirections() bool {
switch state.SelectedClue.Direction {
case puz.DirectionAcross:
if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
return true
case puz.DirectionDown:
if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
return true
}
return false
}
func (state *State) HandleInput(buffer []byte) (exited bool) {
if len(buffer) == 0 {
return false
@@ -360,16 +377,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
}
if buffer[0] == ' ' {
switch state.SelectedClue.Direction {
case puz.DirectionAcross:
if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
case puz.DirectionDown:
if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
}
state.SwitchDirections()
}
if buffer[0] >= 0x61 && buffer[0] <= 0x7a {
@@ -380,7 +388,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
if !cellWasFilled {
// jump to next unfilled cell in clue
for x := i + 1; x < len(state.SelectedClue.Cells); x++ {
for x := (i + 1) % len(state.SelectedClue.Cells); x != i; x = ((x + 1) % len(state.SelectedClue.Cells)) {
if state.PuzzleState[state.SelectedClue.Cells[x]] == '-' {
state.SelectedCell = state.SelectedClue.Cells[x]
break
@@ -427,9 +435,9 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
if string(buffer[0:2]) == "\x1b[" {
if (buffer[2] == 68 || buffer[2] == 67) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionDown {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
state.SwitchDirections()
} else if (buffer[2] == 65 || buffer[2] == 66) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionAcross {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
state.SwitchDirections()
} else {
switch buffer[2] {
case 68: // left
@@ -444,10 +452,18 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
switch state.SelectedClue.Direction {
case puz.DirectionAcross:
if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
case puz.DirectionDown:
} else {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
case puz.DirectionDown:
if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
} else {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
}
}
}
return false
-1
View File
@@ -103,7 +103,6 @@ func main() {
}
state.SelectedClue = nil
state.SelectedCell = -1
state.Goodbye = true
fmt.Printf("\r\x1b[%dA", uiHeight)
fmt.Print("\x1b[J")
state.RenderUI(os.Stdout)
+10 -5
View File
@@ -75,18 +75,22 @@ func startOfAcrossClue(puzzle string, width, index int) bool {
return false
}
func readText(b *bufio.Reader) (string, error) {
func readText(b *bufio.Reader, version string) (string, error) {
text, err := b.ReadString(0x00)
if err != nil {
return "", err
}
if version == "1" {
decoded, err := charmap.ISO8859_1.NewDecoder().String(text[:len(text)-1])
if err != nil {
return "", err
}
return decoded, nil
} else {
return string(text[:len(text)-1]), nil
}
}
func ParsePuz(file []byte) (*Puzzle, error) {
@@ -99,6 +103,7 @@ func ParsePuz(file []byte) (*Puzzle, error) {
puzzle := new(Puzzle)
// read header
version := string(file[0x18:0x1B])
puzzle.Width = int(file[0x2C])
puzzle.Height = int(file[0x2D])
puzzle.ClueCount = int(binary.LittleEndian.Uint16(file[0x2E:0x30]))
@@ -116,19 +121,19 @@ func ParsePuz(file []byte) (*Puzzle, error) {
// read text
buf := bufio.NewReader(bytes.NewReader(file[stateEnd:]))
title, err := readText(buf)
title, err := readText(buf, string(version[0]))
if err != nil {
return nil, err
}
puzzle.Title = title
author, err := readText(buf)
author, err := readText(buf, string(version[0]))
if err != nil {
return nil, err
}
puzzle.Author = author
copyright, err := readText(buf)
copyright, err := readText(buf, string(version[0]))
if err != nil {
return nil, err
}
@@ -137,7 +142,7 @@ func ParsePuz(file []byte) (*Puzzle, error) {
// read clues
clues := make([]string, 0, puzzle.ClueCount)
for range puzzle.ClueCount {
clue, err := readText(buf)
clue, err := readText(buf, string(version[0]))
if err != nil {
return nil, err
}
+14 -4
View File
@@ -13,11 +13,19 @@ import (
)
func main() {
ssh.Handle(func(s ssh.Session) {
file, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
port := ":2222"
if portEnv, ok := os.LookupEnv("PORT"); ok && portEnv != "" {
port = ":" + portEnv
}
ssh.Handle(func(s ssh.Session) {
log.Printf("new connection from %s (username %s)\n", s.RemoteAddr().String(), s.User())
puzzle, err := puz.ParsePuz(file)
if err != nil {
log.Fatal(err)
@@ -66,11 +74,10 @@ func main() {
if exited {
state.SelectedClue = nil
state.SelectedCell = -1
state.Goodbye = true
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
fmt.Fprint(s, "\x1b[J")
state.RenderUI(s)
return
break
}
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
@@ -78,6 +85,9 @@ func main() {
uiHeight = state.RenderUI(s)
}
log.Printf("%s disconnected\n", s.RemoteAddr().String())
})
log.Fatal(ssh.ListenAndServe(":1234", nil))
log.Printf("starting on port %s...\n", port)
log.Fatal(ssh.ListenAndServe(port, nil))
}