Complexify things
parent
4bc7642019
commit
7063656056
1
go.mod
1
go.mod
|
@ -13,4 +13,5 @@ require (
|
||||||
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5 // indirect
|
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5 // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
|
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
)
|
)
|
||||||
|
|
1
go.sum
1
go.sum
|
@ -67,6 +67,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
|
|
@ -3,12 +3,19 @@ package gwfc
|
||||||
import (
|
import (
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"gwfc/data"
|
"gwfc/data"
|
||||||
|
"image/color"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/opentype"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Game is our game structure.
|
// Game is our game structure.
|
||||||
|
@ -21,14 +28,32 @@ type Game struct {
|
||||||
tickDelay int
|
tickDelay int
|
||||||
tileWidth int
|
tileWidth int
|
||||||
tileHeight int
|
tileHeight int
|
||||||
|
processing bool
|
||||||
|
mode int
|
||||||
|
font font.Face
|
||||||
|
showText bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Init() {
|
func (g *Game) Init() {
|
||||||
|
ebiten.SetMaxTPS(500)
|
||||||
ebiten.SetWindowSize(1280, 720)
|
ebiten.SetWindowSize(1280, 720)
|
||||||
ebiten.SetWindowResizable(true)
|
ebiten.SetWindowResizable(true)
|
||||||
|
|
||||||
|
// Load our font
|
||||||
|
tt, err := opentype.Parse(fonts.MPlus1pRegular_ttf)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = 72
|
||||||
|
g.font, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||||
|
Size: 10,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingFull,
|
||||||
|
})
|
||||||
|
|
||||||
var b [8]byte
|
var b [8]byte
|
||||||
_, err := crand.Read(b[:])
|
_, err = crand.Read(b[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -64,6 +89,14 @@ func (g *Game) ResetMap() {
|
||||||
x, y := 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})
|
g.cTiles = append(g.cTiles, [2]int{x, y})
|
||||||
}
|
}
|
||||||
|
// ehh...
|
||||||
|
if g.mode == 1 {
|
||||||
|
for _, c := range g.cTiles {
|
||||||
|
t := g.Map.Get(c[0], c[1])
|
||||||
|
g.iterFunc(c, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.processing = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) getRandomTile(s []string) string {
|
func (g *Game) getRandomTile(s []string) string {
|
||||||
|
@ -81,6 +114,7 @@ func (g *Game) getMatchingValidAdjacentTiles(x, y int, s string) []string {
|
||||||
|
|
||||||
t := g.Map.Get(x+x2, y+y2)
|
t := g.Map.Get(x+x2, y+y2)
|
||||||
if t != nil {
|
if t != nil {
|
||||||
|
t.waveValue--
|
||||||
neighbors = append(neighbors, t)
|
neighbors = append(neighbors, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,15 +142,48 @@ func (g *Game) iterFunc(c [2]int, t *Tile) {
|
||||||
types := g.getMatchingValidAdjacentTiles(c[0], c[1], t.tile)
|
types := g.getMatchingValidAdjacentTiles(c[0], c[1], t.tile)
|
||||||
t.processed = true
|
t.processed = true
|
||||||
t.tile = g.getRandomTile(types)
|
t.tile = g.getRandomTile(types)
|
||||||
|
t.value = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the game state.
|
// Update updates the game state.
|
||||||
func (g *Game) Update() error {
|
func (g *Game) Update() error {
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyR) && len(g.cTiles) == 0 {
|
if inpututil.IsKeyJustPressed(ebiten.KeyM) {
|
||||||
|
if g.mode == 0 {
|
||||||
|
g.mode = 1
|
||||||
|
} else if g.mode == 1 {
|
||||||
|
g.mode = 0
|
||||||
|
}
|
||||||
g.ResetMap()
|
g.ResetMap()
|
||||||
}
|
}
|
||||||
if g.tickDelay > g.stepRate && len(g.cTiles) > 0 {
|
if inpututil.IsKeyJustPressed(ebiten.KeyR) {
|
||||||
g.cTiles = g.Map.Iterate(g.cTiles, g.iterFunc)
|
g.ResetMap()
|
||||||
|
}
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyMinus) {
|
||||||
|
if g.stepRate > 0 {
|
||||||
|
g.stepRate--
|
||||||
|
}
|
||||||
|
} else if inpututil.IsKeyJustPressed(ebiten.KeyEqual) {
|
||||||
|
if g.stepRate < 100 {
|
||||||
|
g.stepRate++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyT) {
|
||||||
|
g.showText = !g.showText
|
||||||
|
}
|
||||||
|
if g.tickDelay > g.stepRate {
|
||||||
|
if g.mode == 0 {
|
||||||
|
if len(g.cTiles) == 0 {
|
||||||
|
g.processing = false
|
||||||
|
} else {
|
||||||
|
g.cTiles = g.Map.Iterate(g.cTiles, g.iterFunc)
|
||||||
|
}
|
||||||
|
} else if g.mode == 1 {
|
||||||
|
if c, t := g.Map.getBestTile(); t == nil {
|
||||||
|
g.processing = false
|
||||||
|
} else {
|
||||||
|
g.iterFunc(c, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
g.tickDelay = 0
|
g.tickDelay = 0
|
||||||
}
|
}
|
||||||
g.tickDelay++
|
g.tickDelay++
|
||||||
|
@ -125,19 +192,25 @@ func (g *Game) Update() error {
|
||||||
|
|
||||||
// Draw draws the game state.
|
// Draw draws the game state.
|
||||||
func (g *Game) Draw(screen *ebiten.Image) {
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
|
tw := g.tileWidth * 2
|
||||||
|
th := g.tileHeight * 2
|
||||||
|
|
||||||
for x := range g.Map.tiles {
|
for x := range g.Map.tiles {
|
||||||
for y := range g.Map.tiles[x] {
|
for y := range g.Map.tiles[x] {
|
||||||
if img, ok := g.Images[g.Map.tiles[x][y].tile]; ok {
|
if img, ok := g.Images[g.Map.tiles[x][y].tile]; ok {
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
op.GeoM.Translate(float64(x*g.tileWidth), float64(y*g.tileHeight))
|
op.GeoM.Scale(2, 2)
|
||||||
|
op.GeoM.Translate(float64(x*tw), float64(y*th))
|
||||||
screen.DrawImage(img, op)
|
screen.DrawImage(img, op)
|
||||||
}
|
}
|
||||||
|
if g.showText {
|
||||||
|
text.Draw(screen, fmt.Sprintf("%d", g.Map.tiles[x][y].waveValue), g.font, x*tw+tw/4, y*th+th/2, color.White)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout does normal layout stuff.
|
// Layout does normal layout stuff.
|
||||||
func (g *Game) Layout(ow, oh int) (int, int) {
|
func (g *Game) Layout(ow, oh int) (int, int) {
|
||||||
return ow / 2, oh / 2
|
return ow, oh
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ func (m *Map) Size(w, h int) {
|
||||||
for x := range m.tiles {
|
for x := range m.tiles {
|
||||||
m.tiles[x] = make([]*Tile, h)
|
m.tiles[x] = make([]*Tile, h)
|
||||||
for y := range m.tiles[x] {
|
for y := range m.tiles[x] {
|
||||||
m.tiles[x][y] = &Tile{}
|
m.tiles[x][y] = &Tile{
|
||||||
|
waveValue: 4,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.w = w
|
m.w = w
|
||||||
|
@ -88,3 +90,22 @@ func (m *Map) Iterate(tiles [][2]int, f func(c [2]int, t *Tile)) [][2]int {
|
||||||
}
|
}
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Map) getBestTile() (lowestCoord [2]int, lowestTile *Tile) {
|
||||||
|
var lowestValue = 9
|
||||||
|
for x := range m.tiles {
|
||||||
|
for y := range m.tiles[x] {
|
||||||
|
if !m.tiles[x][y].processed {
|
||||||
|
if lowestValue > m.tiles[x][y].waveValue {
|
||||||
|
if lowestValue <= 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lowestValue = m.tiles[x][y].waveValue
|
||||||
|
lowestCoord = [2]int{x, y}
|
||||||
|
lowestTile = m.tiles[x][y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -4,4 +4,5 @@ type Tile struct {
|
||||||
tile string
|
tile string
|
||||||
processed bool
|
processed bool
|
||||||
value interface{}
|
value interface{}
|
||||||
|
waveValue int
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue