Generating whole categories now

This commit is contained in:
Neale Pickett 2019-08-18 21:59:06 -06:00
parent 447bb3158f
commit fc79db677d
1 changed files with 116 additions and 5 deletions

View File

@ -4,15 +4,126 @@ import (
"os" "os"
"flag" "flag"
"fmt" "fmt"
"log"
"path/filepath"
"hash/fnv"
"encoding/binary"
"encoding/json"
"encoding/hex"
"strconv"
"math/rand"
) )
type PuzzleEntry struct {
Id string
Points int
Puzzle Puzzle
}
func HashHex(input ...string) (string) {
hasher := fnv.New64()
for _, s := range input {
fmt.Fprintln(hasher, s)
}
return hex.EncodeToString(hasher.Sum(nil))
}
func PrngOfStrings(input ...string) (*rand.Rand) {
hasher := fnv.New64()
for _, s := range input {
fmt.Fprint(hasher, s, "\n")
}
seed := binary.BigEndian.Uint64(hasher.Sum(nil))
source := rand.NewSource(int64(seed))
return rand.New(source)
}
func ParsePuzzle(puzzlePath string, seed string) (*Puzzle, error) {
puzzleFd, err := os.Open(puzzlePath)
if err != nil {
return nil, err
}
defer puzzleFd.Close()
puzzle, err := ParseMoth(puzzleFd)
if err != nil {
return nil, err
}
return puzzle, nil
}
func ParseCategory(categoryPath string, seed string) ([]PuzzleEntry, error) {
categoryFd, err := os.Open(categoryPath)
if err != nil {
return nil, err
}
defer categoryFd.Close()
puzzleDirs, err := categoryFd.Readdirnames(0)
if err != nil {
return nil, err
}
puzzleEntries := make([]PuzzleEntry, 0, len(puzzleDirs))
for _, puzzleDir := range puzzleDirs {
puzzlePath := filepath.Join(categoryPath, puzzleDir, "puzzle.moth")
puzzleSeed := fmt.Sprintf("%s/%s", seed, puzzleDir)
points, err := strconv.Atoi(puzzleDir)
if err != nil {
log.Printf("Skipping %s: %v", puzzlePath, err)
continue
}
puzzle, err := ParsePuzzle(puzzlePath, puzzleSeed)
if err != nil {
log.Printf("Skipping %s: %v", puzzlePath, err)
continue
}
prng := PrngOfStrings(puzzleSeed)
idBytes := make([]byte, 16)
prng.Read(idBytes)
id := hex.EncodeToString(idBytes)
puzzleEntry := PuzzleEntry{
Id: id,
Puzzle: *puzzle,
Points: points,
}
puzzleEntries = append(puzzleEntries, puzzleEntry)
}
return puzzleEntries, nil
}
func main() { func main() {
// XXX: We need a way to pass in "only run this one point value puzzle"
flag.Parse() flag.Parse()
baseSeedString := os.Getenv("SEED")
for _, dirname := range flag.Args() { for _, dirname := range flag.Args() {
f, _ := os.Open(dirname) categoryName := filepath.Base(dirname)
defer f.Close() categorySeed := fmt.Sprintf("%s/%s", baseSeedString, categoryName)
names, _ := f.Readdirnames(0) puzzles, err := ParseCategory(dirname, categorySeed)
fmt.Print(names) if err != nil {
log.Print(err)
continue
}
jpuzzles, err := json.MarshalIndent(puzzles, "", " ")
if err != nil {
log.Print(err)
continue
}
fmt.Println(string(jpuzzles))
} }
} }