Seed, templates, web-output and SVG-output optimizations

This commit is contained in:
Aaron Fischer 2021-03-17 14:39:40 +01:00
parent a1a65165ca
commit 3d58303936
9 changed files with 152 additions and 32 deletions

View File

@ -2,49 +2,59 @@ package main
import (
"f00860/kartograph-map-editor/pkg/generator"
"f00860/kartograph-map-editor/pkg/web"
"flag"
"fmt"
"time"
)
var (
format string
startWebserver bool
address string
port int
size int
output string
world generator.World
seed string
size int
wastelands int
mountains int
ruins int
filename string
)
func main() {
world := generator.New(size, wastelands, mountains, ruins)
if startWebserver {
web.Start(address, port)
return
}
switch format {
world := generator.New(size, wastelands, mountains, ruins, seed)
switch output {
case "svg":
fmt.Print(world.SVG())
fmt.Printf("%s", world.SVG())
case "ascii":
fmt.Print(world.Plot())
fmt.Printf("%s", world.Plot())
case "json":
fmt.Print(world.JSON())
case "pdf":
world.PDF(filename)
case "web":
panic("Not implemented yet")
fmt.Printf("%s", world.JSON())
default:
fmt.Printf("Output format '%v' not supported", output)
}
}
func init() {
flag.StringVar(&format, "format", "svg", "Output format (ascii, json, svg, pdf, web)")
flag.BoolVar(&startWebserver, "web", false, "Spawn a webserver")
flag.StringVar(&address, "address", "0.0.0.0", "IP to bin the service to")
flag.IntVar(&port, "port", 80, "Port to bind the service to")
flag.IntVar(&size, "size", 11, "The size of the map")
flag.StringVar(&output, "output", "svg", "Output format (svg, ascii, json)")
flag.StringVar(&seed, "seed", time.Now().String(), "A seed string for the map generation")
flag.IntVar(&wastelands, "wastelands", 7, "Number of wastelands")
flag.IntVar(&mountains, "mountains", 5, "Number of mountains")
flag.IntVar(&ruins, "ruins", 6, "Number of ruins")
flag.StringVar(&filename, "filename", "map.pdf", "The PDF filename")
flag.IntVar(&size, "size", 11, "The map size")
flag.IntVar(&wastelands, "wastelands", 7, "Number of wastelands to generate")
flag.IntVar(&mountains, "mountains", 5, "Number of mountains ot generate")
flag.IntVar(&ruins, "ruins", 6, "Number of ruins to generate")
flag.Parse()
}

2
go.mod
View File

@ -1,6 +1,6 @@
module f00860/kartograph-map-editor
go 1.15
go 1.16
require (
github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb

View File

@ -1,12 +1,7 @@
package generator
import (
"github.com/jung-kurt/gofpdf"
)
import ()
func (w World) PDF(filename string) {
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
func (w World) PDF() {
pdf.OutputFileAndClose(filename)
}

View File

@ -52,7 +52,7 @@ func (w World) SVG() string {
x, y := w.ToXY(pos)
switch tile.Territory {
case RuinsTerritory:
canvas.Text(hPadding+x*gridsize+3, vPadding+(y*gridsize)+16, "R", "stroke:lightgrey;fill:lightgrey")
canvas.Text(hPadding+x*gridsize+3, vPadding+(y*gridsize)+16, "R", "stroke:black;fill:black")
case MountainTerritory:
canvas.Rect(hPadding+x*gridsize, vPadding+y*gridsize, gridsize, gridsize, "fill:white; stroke:black")
canvas.Circle(hPadding+x*gridsize+gridsize/2, vPadding+y*gridsize+gridsize/2, gridsize/2-8, "fill:white; stroke:black")

View File

@ -1,12 +1,14 @@
package generator
import (
"crypto/md5"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"math"
"math/rand"
"time"
)
type TerritoryType int
@ -67,6 +69,7 @@ type World struct {
Mountains int `json:"mountains"`
World []Tile `json:"tiles"`
Seed int
}
func (w World) Plot() string {
@ -92,8 +95,12 @@ func (w World) ExportToPDF(filename string) error {
return nil
}
func New(size int, numWastelands int, numMountains int, numRuins int) World {
rand.Seed(time.Now().UnixNano())
func New(size int, numWastelands int, numMountains int, numRuins int, seed string) World {
// Fix seed
h := md5.New()
io.WriteString(h, seed)
var intSeed uint64 = binary.BigEndian.Uint64(h.Sum(nil))
rand.Seed(int64(intSeed))
w := World{
Size: size,

74
pkg/web/service.go Normal file
View File

@ -0,0 +1,74 @@
package web
import (
"embed"
"f00860/kartograph-map-editor/pkg/generator"
"html/template"
"io"
"log"
"net/http"
"strconv"
"time"
)
//go:embed templates
var templateFiles embed.FS
//go:embed static
var staticFiles embed.FS
func Start(address string, port int) {
http.Handle("/static/", http.FileServer(http.FS(staticFiles)))
http.HandleFunc("/", indexHandler)
http.HandleFunc("/map.svg", mapHandler)
addr := address + ":" + strconv.Itoa(port)
log.Printf("Server started on %v ...", addr)
err := http.ListenAndServe(addr, nil)
if err != nil {
log.Fatal(err)
}
}
func mapHandler(w http.ResponseWriter, req *http.Request) {
size, err := strconv.Atoi(req.URL.Query().Get("size"))
if err != nil {
size = 11
}
seed := req.URL.Query().Get("seed")
if seed == "" {
seed = time.Now().String()
}
wastelands, err := strconv.Atoi(req.URL.Query().Get("wastelands"))
if err != nil {
wastelands = 7
}
mountains, err := strconv.Atoi(req.URL.Query().Get("mountains"))
if err != nil {
mountains = 5
}
ruins, err := strconv.Atoi(req.URL.Query().Get("ruins"))
if err != nil {
ruins = 6
}
world := generator.New(size, wastelands, mountains, ruins, seed)
log.Printf("GET /map.svg?%v (%v)", req.URL.Query().Encode(), req.RemoteAddr)
w.Header().Set("Content-Type", "image/svg+xml")
w.Header().Set("Content-Length", strconv.Itoa(len(world.SVG())))
io.WriteString(w, world.SVG())
}
func indexHandler(w http.ResponseWriter, req *http.Request) {
log.Printf("GET / (%v)", req.RemoteAddr)
tpl, err := template.ParseFS(templateFiles, "templates/index.tpl.html")
if err != nil {
log.Fatal(err)
}
tpl.Execute(w, nil)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

10
pkg/web/static/styles.css Normal file
View File

@ -0,0 +1,10 @@
p > img {
float: right;
width: 250px;
}
.map {
margin: auto;
display: block;
width: 350px;
}

View File

@ -0,0 +1,24 @@
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Map Generator für "Der Kartograph"</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/static/styles.css" rel="stylesheet" type="text/css" media="all">
</head>
<body>
<h1>Map Generator für "Der Kartograph"</h1>
<p><img src="/static/images/logo.jpg">
Wem der beigelegte Block zu eintönig wird oder schon leergespielt hat, kann sich
entweder die Mini-Erweiterung kaufen, in dem ein weiterer Block enthalten ist,
oder aber diesen Generator nutzen, um sich zufällige Maps generieren zu lassen.
Die generierten Karten entsprechen den erweiterten Regeln, können aber für etwas
mehr Spaß angepasst werden.</p>
<a href="/">Neue Map generieren</a>
<br><br>
<img src="/map.svg" class="map">
</body>
</html>