Transpiler can now render individual puzles

This commit is contained in:
Neale Pickett 2019-08-25 18:50:38 -06:00
parent 890718e8bb
commit 506e0ace6b
2 changed files with 110 additions and 58 deletions

View File

@ -2,7 +2,6 @@ package main
import ( import (
"os" "os"
"flag"
"fmt" "fmt"
"log" "log"
"path/filepath" "path/filepath"
@ -37,7 +36,7 @@ func PrngOfStrings(input ...string) (*rand.Rand) {
func runPuzzleGen(puzzlePath string, seed string) (*Puzzle, error) { func runPuzzleGen(puzzlePath string, seed string) (*Puzzle, error) {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() defer cancel()
cmd := exec.CommandContext(ctx, puzzlePath) cmd := exec.CommandContext(ctx, puzzlePath)
@ -61,6 +60,38 @@ func runPuzzleGen(puzzlePath string, seed string) (*Puzzle, error) {
return puzzle, nil return puzzle, nil
} }
func ParsePuzzle(puzzlePath string, puzzleSeed string) (*Puzzle, error) {
var puzzle *Puzzle
// Try the .moth file first
puzzleMothPath := filepath.Join(puzzlePath, "puzzle.moth")
puzzleFd, err := os.Open(puzzleMothPath)
if err == nil {
defer puzzleFd.Close()
puzzle, err = ParseMoth(puzzleFd)
if err != nil {
return nil, err
}
} else if os.IsNotExist(err) {
var genErr error
puzzleGenPath := filepath.Join(puzzlePath, "mkpuzzle")
puzzle, genErr = runPuzzleGen(puzzleGenPath, puzzlePath)
if genErr != nil {
bigErr := fmt.Errorf(
"%v; (%s: %v)",
genErr,
filepath.Base(puzzleMothPath), err,
)
return nil, bigErr
}
} else {
return nil, err
}
return puzzle, nil
}
func ParseCategory(categoryPath string, seed string) ([]PuzzleEntry, error) { func ParseCategory(categoryPath string, seed string) ([]PuzzleEntry, error) {
categoryFd, err := os.Open(categoryPath) categoryFd, err := os.Open(categoryPath)
@ -76,41 +107,20 @@ func ParseCategory(categoryPath string, seed string) ([]PuzzleEntry, error) {
puzzleEntries := make([]PuzzleEntry, 0, len(puzzleDirs)) puzzleEntries := make([]PuzzleEntry, 0, len(puzzleDirs))
for _, puzzleDir := range puzzleDirs { for _, puzzleDir := range puzzleDirs {
var puzzle *Puzzle
puzzlePath := filepath.Join(categoryPath, puzzleDir) puzzlePath := filepath.Join(categoryPath, puzzleDir)
puzzleSeed := fmt.Sprintf("%s/%s", seed, puzzleDir)
// Determine point value from directory name puzzle, err := ParsePuzzle(puzzlePath, puzzleSeed)
points, err := strconv.Atoi(puzzleDir)
if err != nil { if err != nil {
log.Printf("Skipping %s: %v", puzzlePath, err) log.Printf("Skipping %s: %v", puzzlePath, err)
continue continue
} }
// Try the .moth file first
puzzleMothPath := filepath.Join(puzzlePath, "puzzle.moth")
puzzleFd, err := os.Open(puzzleMothPath)
if err == nil {
defer puzzleFd.Close()
puzzle, err = ParseMoth(puzzleFd)
if err != nil {
log.Printf("Skipping %s: %v", puzzleMothPath, err)
continue
}
} else if os.IsNotExist(err) {
var genErr error
puzzleGenPath := filepath.Join(puzzlePath, "mkpuzzle")
puzzle, genErr = runPuzzleGen(puzzleGenPath, puzzlePath)
if genErr != nil {
log.Printf("Skipping %20s: %v", puzzleMothPath, err)
log.Printf("Skipping %20s: %v", puzzleGenPath, genErr)
continue
}
} else {
log.Printf("Skipping %s: %v", puzzleMothPath, err)
continue
}
// Determine point value from directory name
points, err := strconv.Atoi(puzzleDir)
if err != nil {
return nil, err
}
// Create a category entry for this // Create a category entry for this
prng := PrngOfStrings(puzzlePath) prng := PrngOfStrings(puzzlePath)
idBytes := make([]byte, 16) idBytes := make([]byte, 16)
@ -126,30 +136,3 @@ func ParseCategory(categoryPath string, seed string) ([]PuzzleEntry, error) {
return puzzleEntries, nil return puzzleEntries, nil
} }
func main() {
// XXX: We need a way to pass in "only run this one point value puzzle"
// XXX: Convert puzzle.py to standalone thingies
flag.Parse()
baseSeedString := os.Getenv("SEED")
jsenc := json.NewEncoder(os.Stdout)
jsenc.SetEscapeHTML(false)
jsenc.SetIndent("", " ")
for _, dirname := range flag.Args() {
categoryName := filepath.Base(dirname)
categorySeed := fmt.Sprintf("%s/%s", baseSeedString, categoryName)
puzzles, err := ParseCategory(dirname, categorySeed)
if err != nil {
log.Print(err)
continue
}
if err := jsenc.Encode(puzzles); err != nil {
log.Print(err)
continue
}
}
}

69
cmd/transpile/main.go Normal file
View File

@ -0,0 +1,69 @@
package main
import (
"flag"
"encoding/json"
"path/filepath"
"strconv"
"strings"
"os"
"log"
"fmt"
)
func seedJoin(parts ...string) string {
return strings.Join(parts, "::")
}
func usage() {
out := flag.CommandLine.Output()
name := flag.CommandLine.Name()
fmt.Fprintf(out, "Usage: %s [OPTIONS] CATEGORY [CATEGORY ...]\n", name)
flag.PrintDefaults()
}
func main() {
// XXX: We need a way to pass in "only run this one point value puzzle"
// XXX: Convert puzzle.py to standalone thingies
flag.Usage = usage
points := flag.Int("points", 0, "Transpile only this point value puzzle")
flag.Parse()
baseSeedString := os.Getenv("MOTH_SEED")
jsenc := json.NewEncoder(os.Stdout)
jsenc.SetEscapeHTML(false)
jsenc.SetIndent("", " ")
for _, categoryPath := range flag.Args() {
categoryName := filepath.Base(categoryPath)
categorySeed := seedJoin(baseSeedString, categoryName)
if *points > 0 {
puzzleDir := strconv.Itoa(*points)
puzzleSeed := seedJoin(categorySeed, puzzleDir)
puzzlePath := filepath.Join(categoryPath, puzzleDir)
puzzle, err := ParsePuzzle(puzzlePath, puzzleSeed)
if err != nil {
log.Print(err)
continue
}
if err := jsenc.Encode(puzzle); err != nil {
log.Fatal(err)
}
} else {
puzzles, err := ParseCategory(categoryPath, categorySeed)
if err != nil {
log.Print(err)
continue
}
if err := jsenc.Encode(puzzles); err != nil {
log.Print(err)
continue
}
}
}
}