Last active
September 26, 2017 16:02
-
-
Save samsamm777/82c0f11d6cc06c2cb80bd17f3235f7b2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"strconv" | |
"time" | |
) | |
type Vector2D struct { | |
x int | |
y int | |
} | |
type TileMap struct { | |
width int | |
height int | |
tiles []int | |
seed int64 | |
fillPercentage int | |
} | |
const ( | |
tileWall int = 1 | |
tileEmpty int = 0 | |
) | |
// String will return our map as astring for debugging purposes. This can be printed | |
// to the cli output | |
func (t *TileMap) String() string { | |
str := "" | |
for i, val := range t.tiles { | |
str = str + strconv.Itoa(val) + " " | |
if (i+1)%t.width == 0 { | |
str = str + "\n" | |
} | |
} | |
return str | |
} | |
// generateTiles will generate the walls for the tile map | |
func (t *TileMap) generateTiles() { | |
for i := 0; i < len(t.tiles); i++ { | |
t.tiles[i] = tileEmpty | |
} | |
t.setSeed() | |
t.randomFillMap() | |
t.smoothMap(5) | |
tiles := t.getRegionTiles(15, 15) | |
fmt.Print(tiles) | |
} | |
// seed will set the seed value for a PRNG | |
func (t *TileMap) setSeed() { | |
if t.seed == 0 { | |
t.seed = time.Now().UTC().UnixNano() | |
} | |
rand.Seed(t.seed) | |
} | |
func (t *TileMap) tileFinder(ch chan Vector2D, done chan bool) { | |
chicken := 0 | |
for { | |
select { | |
case pos := <-ch: | |
fmt.Print(pos) | |
ch <- pos | |
fmt.Print("NEVER") | |
chicken++ | |
if chicken > 100 { | |
done <- true | |
} | |
} | |
} | |
} | |
func (t *TileMap) getRegionTiles(x int, y int) (tiles []Vector2D) { | |
ch := make(chan Vector2D, 10) | |
done := make(chan bool) | |
go t.tileFinder(ch, done) | |
ch <- Vector2D{x, y} | |
// block until the done channel is triggered | |
<-done | |
return tiles | |
} | |
// RandomFillMap will fill the map with random walls. We only set a wall if the | |
// prng is within our fillPercentage value | |
func (t *TileMap) randomFillMap() { | |
for i := 0; i < len(t.tiles); i++ { | |
r := rand.Intn(100) | |
x, y := t.getPosAtIndex(i) | |
if x == 0 || x == t.width-1 || y == 0 || y == t.height-1 { | |
t.tiles[i] = tileWall | |
} else { | |
if r < t.fillPercentage { | |
t.tiles[i] = tileWall | |
} | |
} | |
} | |
} | |
// SmoothMap will iteratively smooth the map. we simple check for the amount of walls | |
// nearby to decide whether we should smooth to walls or floors. | |
func (t *TileMap) smoothMap(iterations int) { | |
for k := 0; k < iterations; k++ { | |
for i := 0; i < len(t.tiles); i++ { | |
x, y := t.getPosAtIndex(i) | |
walls := t.calcWallCount(x, y) | |
if walls > 4 { | |
t.tiles[t.getIndexAtPosition(x, y)] = tileWall | |
} else if walls < 4 { | |
t.tiles[t.getIndexAtPosition(x, y)] = tileEmpty | |
} | |
} | |
} | |
} | |
// GetIndexAtPosition will get the index into the tile array using the coords | |
func (t *TileMap) getIndexAtPosition(x int, y int) int { | |
return x + (y * t.height) | |
} | |
// GetValueAtPosition will get the value of the tile at the given position | |
func (t *TileMap) getValueAtPosition(x int, y int) int { | |
return t.tiles[t.getIndexAtPosition(x, y)] | |
} | |
// GetPosAtIndex will get the x y positon at the given index | |
func (t *TileMap) getPosAtIndex(i int) (x int, y int) { | |
y = i % t.width | |
x = i / t.width | |
return x, y | |
} | |
func (t *TileMap) isInMapRange(x int, y int) bool { | |
return (x >= 0 && x < t.width && y >= 0 && y < t.height) | |
} | |
// calcWallCount calculates how many walls are nearby the coords | |
func (t *TileMap) calcWallCount(x int, y int) (numWalls int) { | |
numWalls = 0 | |
for nX := x - 1; nX <= x+1; nX++ { | |
for nY := y - 1; nY <= y+1; nY++ { | |
if t.isInMapRange(nX, nY) { | |
if nX != x || nY != y { | |
v := t.getValueAtPosition(nX, nY) | |
numWalls += v | |
} | |
} else { | |
numWalls++ | |
} | |
} | |
} | |
return numWalls | |
} | |
// NewMap will create a new tile map and return it | |
func NewMap(w int, h int, s int64, fp int) *TileMap { | |
tm := &TileMap{ | |
width: w, | |
height: h, | |
tiles: make([]int, w*h), | |
seed: s, | |
fillPercentage: fp, | |
} | |
tm.generateTiles() | |
return tm | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment