Actually make it decent

master
kts of kettek 2022-04-19 20:53:36 -07:00
parent d9bbef3831
commit 4bc7642019
8 changed files with 112 additions and 24 deletions

View File

@ -2,6 +2,7 @@ package data
import ( import (
"embed" "embed"
"encoding/json"
"image" "image"
"log" "log"
"path/filepath" "path/filepath"
@ -9,10 +10,12 @@ import (
) )
// FS is our exported FS. // FS is our exported FS.
//go:embed images/* //go:embed images/* mapping.json
var fs embed.FS var fs embed.FS
var Images map[string]image.Image var Images map[string]image.Image
var Mapping map[string][]string
var Tiles []string
func Init() { func Init() {
Images = make(map[string]image.Image) Images = make(map[string]image.Image)
@ -37,4 +40,19 @@ func Init() {
Images[name] = img Images[name] = img
} }
} }
// Load mapping.
f, err := fs.Open("mapping.json")
if err != nil {
log.Fatal(err)
}
d := json.NewDecoder(f)
err = d.Decode(&Mapping)
if err != nil {
log.Fatal(err)
}
// Add all types to the common map.
for k := range Mapping {
Mapping[""] = append(Mapping[""], k)
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

40
data/mapping.json 100644
View File

@ -0,0 +1,40 @@
{
"deep-water": [
"water",
"deep-water"
],
"water": [
"sand",
"deep-water",
"water"
],
"sand": [
"sand",
"water",
"dirt"
],
"dirt": [
"dirt",
"grass",
"sand"
],
"grass": [
"dirt",
"grass",
"saplings",
"flowers"
],
"flowers": [
"grass",
"saplings"
],
"saplings": [
"grass",
"saplings",
"trees"
],
"trees": [
"saplings",
"trees"
]
}

View File

@ -12,7 +12,7 @@ func main() {
Exec("./gwfc") Exec("./gwfc")
Task("watch"). Task("watch").
Watch("internal/*/*.go", "data/*.go", "data/images/*"). Watch("internal/*/*.go", "data/*", "data/images/*").
Signaler(SigQuit). Signaler(SigQuit).
Run("build"). Run("build").
Run("run") Run("run")

View File

@ -1,9 +1,11 @@
package gwfc package gwfc
import ( import (
crand "crypto/rand"
"encoding/binary"
"gwfc/data" "gwfc/data"
"log"
"math/rand" "math/rand"
"time"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@ -14,6 +16,7 @@ type Game struct {
Images map[string]*ebiten.Image Images map[string]*ebiten.Image
Map Map Map Map
cTiles [][2]int cTiles [][2]int
maxSources int
stepRate int stepRate int
tickDelay int tickDelay int
tileWidth int tileWidth int
@ -24,11 +27,17 @@ func (g *Game) Init() {
ebiten.SetWindowSize(1280, 720) ebiten.SetWindowSize(1280, 720)
ebiten.SetWindowResizable(true) ebiten.SetWindowResizable(true)
rand.Seed(time.Now().UnixMilli()) var b [8]byte
_, err := crand.Read(b[:])
if err != nil {
log.Fatal(err)
}
rand.Seed(int64(binary.LittleEndian.Uint64(b[:])))
g.Images = make(map[string]*ebiten.Image) g.Images = make(map[string]*ebiten.Image)
g.stepRate = 0 g.stepRate = 0
g.maxSources = 1
data.Init() data.Init()
@ -50,9 +59,10 @@ func (g *Game) ResetMap() {
g.Map.Size(w/2/g.tileWidth, h/2/g.tileHeight) g.Map.Size(w/2/g.tileWidth, h/2/g.tileHeight)
g.cTiles = nil g.cTiles = nil
t := rand.Intn(8) t := 1 + rand.Intn(g.maxSources)
for i := 0; i < t; i++ { for i := 0; i < t; i++ {
g.cTiles = append(g.cTiles, [2]int{rand.Intn(g.Map.w), rand.Intn(g.Map.h)}) x, y := rand.Intn(g.Map.w), rand.Intn(g.Map.h)
g.cTiles = append(g.cTiles, [2]int{x, y})
} }
} }
@ -60,24 +70,44 @@ func (g *Game) getRandomTile(s []string) string {
return s[rand.Intn(len(s))] return s[rand.Intn(len(s))]
} }
func (g *Game) iterFunc(c [2]int, t *Tile) { func (g *Game) getMatchingValidAdjacentTiles(x, y int, s string) []string {
types := g.Map.GetAdjacentTypes(c[0], c[1]) neighbors := make([]*Tile, 0)
t.processed = true possible := data.Mapping[""]
if len(types) == 0 { for x2 := -1; x2 < 2; x2++ {
t.tile = g.getRandomTile([]string{"sand", "water", "grass", "saplings", "trees"}) for y2 := -1; y2 < 2; y2++ {
} else if slices.Contains(types, "water") { if (x2 == -1 && y2 == -1) || (x2 == 1 && y2 == 1) || (x2 == -1 && y2 == 1) || (x2 == 1 && y2 == -1) || (x2 == 0 && y2 == 0) {
t.tile = g.getRandomTile([]string{"water", "sand"}) continue
} else if slices.Contains(types, "sand") { }
t.tile = g.getRandomTile([]string{"sand", "water", "grass"})
} else if slices.Contains(types, "grass") { t := g.Map.Get(x+x2, y+y2)
t.tile = g.getRandomTile([]string{"saplings", "grass", "sand"}) if t != nil {
} else if slices.Contains(types, "trees") { neighbors = append(neighbors, t)
t.tile = g.getRandomTile([]string{"trees", "saplings", "grass"}) }
} else if slices.Contains(types, "saplings") { }
t.tile = g.getRandomTile([]string{"trees", "saplings", "grass"})
} else {
t.tile = g.getRandomTile([]string{"sand", "water", "grass", "saplings", "trees"})
} }
for _, t := range neighbors {
var temp []string
for _, s := range possible {
if slices.Contains(data.Mapping[t.tile], s) {
temp = append(temp, s)
}
}
possible = temp
}
if len(possible) == 0 {
possible = data.Mapping[""]
}
return possible
}
func (g *Game) iterFunc(c [2]int, t *Tile) {
types := g.getMatchingValidAdjacentTiles(c[0], c[1], t.tile)
t.processed = true
t.tile = g.getRandomTile(types)
} }
// Update updates the game state. // Update updates the game state.

View File

@ -49,7 +49,7 @@ func (m *Map) GetAdjacentTypes(x, y int) (s []string) {
} }
t := m.Get(x+x2, y+y2) t := m.Get(x+x2, y+y2)
if t != nil { if t != nil && t.tile != "" {
s = append(s, t.tile) s = append(s, t.tile)
} }
} }