forked from sarah/microworlds
131 lines
2.4 KiB
Go
131 lines
2.4 KiB
Go
package core
|
|
|
|
type Environment struct {
|
|
width,height int
|
|
state [][]float32
|
|
pstate [][]float32
|
|
value [][]bool
|
|
col [][]bool
|
|
}
|
|
|
|
func (e *Environment) Width() int {
|
|
return e.width
|
|
}
|
|
|
|
|
|
func (e *Environment) Height() int {
|
|
return e.height
|
|
}
|
|
|
|
func NewEnvironment(width int, height int) *Environment {
|
|
env := new(Environment)
|
|
env.width = width
|
|
env.height = height
|
|
env.state = make([][]float32, width)
|
|
for x := range env.state {
|
|
env.state[x] = make([]float32, height)
|
|
}
|
|
env.col = make([][]bool, width)
|
|
for x := range env.col {
|
|
env.col[x] = make([]bool, height)
|
|
}
|
|
|
|
env.value = make([][]bool, width)
|
|
for x := range env.value {
|
|
env.value[x] = make([]bool, height)
|
|
}
|
|
return env
|
|
}
|
|
|
|
func (e *Environment) Mark(x,y int,amount float32) {
|
|
e.state[x][y] = e.state[x][y] + amount
|
|
if e.state[x][y] > 255 {
|
|
e.state[x][y] = 255
|
|
}
|
|
//log.Debugf("Marking: %d %d %f", x, y, e.state[x][y])
|
|
}
|
|
|
|
|
|
|
|
func (e Environment) Occupy(x,y int) {
|
|
e.col[x][y] = true
|
|
}
|
|
|
|
func (e Environment) Check(x,y int) bool {
|
|
return e.col[x][y]
|
|
}
|
|
|
|
func (e Environment) Leave(x,y int) {
|
|
e.col[x][y] = false
|
|
}
|
|
|
|
|
|
func (e Environment) HasValue(x,y int) bool {
|
|
return e.value[x][y]
|
|
}
|
|
|
|
func (e Environment) PutValue(x,y int) {
|
|
e.value[x][y] = true
|
|
}
|
|
|
|
func (e Environment) TakeValue(x,y int) {
|
|
e.value[x][y] = false
|
|
}
|
|
|
|
func (e Environment) Sniff(x,y int) float32 {
|
|
return e.state[x][y]
|
|
}
|
|
|
|
|
|
func (e *Environment) normXY(x int, y int) (int,int) {
|
|
if x < 0 {
|
|
x = (e.width - 1)
|
|
} else if x >= e.width {
|
|
x = x % (e.width )
|
|
}
|
|
|
|
if y< 0 {
|
|
y = (e.height - 1)
|
|
} else if y >= e.height {
|
|
y = y % (e.height)
|
|
}
|
|
|
|
return x,y
|
|
}
|
|
|
|
func (e *Environment) Evaporate(rate float32) {
|
|
//log.Debugf("Evap")
|
|
|
|
|
|
e.pstate = make([][]float32, e.width)
|
|
for x := range e.pstate {
|
|
e.pstate[x] = make([]float32, e.height)
|
|
}
|
|
for x:=0;x<e.width;x++ {
|
|
for y := 0; y < e.height; y++ {
|
|
e.pstate[x][y] = e.state[x][y] * rate
|
|
}
|
|
}
|
|
|
|
|
|
for x:=0;x<e.width;x++ {
|
|
for y:=0;y<e.height;y++ {
|
|
amount := e.pstate[x][y]
|
|
|
|
totalAmount := amount + e.NormalizeSniff(x-1,y-1) + e.NormalizeSniff(x,y-1) + e.NormalizeSniff(x+1,y-1) + e.NormalizeSniff(x-1,y) + e.NormalizeSniff(x+1,y)
|
|
totalAmount += e.NormalizeSniff(x-1,y+1) + e.NormalizeSniff(x,y+1) +e.NormalizeSniff(x+1,y+1)
|
|
|
|
e.state[x][y] = totalAmount/9
|
|
}
|
|
}
|
|
}
|
|
|
|
func (e *Environment) SniffNormalized(x int, y int) float32 {
|
|
x,y = e.normXY(x,y)
|
|
return e.state[x][y]
|
|
}
|
|
|
|
func (e *Environment) NormalizeSniff(x int, y int) float32 {
|
|
x,y = e.normXY(x,y)
|
|
return e.pstate[x][y]
|
|
} |