mirror of https://github.com/dirtbags/moth.git
Transpiler can now render individual puzles
This commit is contained in:
parent
890718e8bb
commit
506e0ace6b
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue