Seed, templates, web-output and SVG-output optimizations
This commit is contained in:
parent
a1a65165ca
commit
3d58303936
9 changed files with 152 additions and 32 deletions
|
@ -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
2
go.mod
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
74
pkg/web/service.go
Normal 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)
|
||||
}
|
BIN
pkg/web/static/images/logo.jpg
Normal file
BIN
pkg/web/static/images/logo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
10
pkg/web/static/styles.css
Normal file
10
pkg/web/static/styles.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
p > img {
|
||||
float: right;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.map {
|
||||
margin: auto;
|
||||
display: block;
|
||||
width: 350px;
|
||||
}
|
24
pkg/web/templates/index.tpl.html
Normal file
24
pkg/web/templates/index.tpl.html
Normal 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>
|
Loading…
Reference in a new issue