Initial commit
This commit is contained in:
commit
b3f3a77fc7
8 changed files with 242 additions and 0 deletions
32
simulation/simulation.go
Normal file
32
simulation/simulation.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
)
|
||||
|
||||
type Simulation struct {
|
||||
Grid *XelGrid
|
||||
}
|
||||
|
||||
func (sim *Simulation) Update() {
|
||||
for range 10 {
|
||||
// get all available xels with energy != 0
|
||||
available_positions := []Vector2{}
|
||||
for i, xel := range sim.Grid.Xels {
|
||||
if xel.Energy != 0 {
|
||||
available_positions = append(available_positions, Vector2{X: i % sim.Grid.Width, Y: i/sim.Grid.Height})
|
||||
}
|
||||
}
|
||||
// choose random pos
|
||||
pos := available_positions[rand.IntN(len(available_positions))]
|
||||
xel := sim.Grid.GetXel(pos)
|
||||
if xel.Energy == 0 { panic("xel energy null") }
|
||||
xel.Step(pos, sim.Grid)
|
||||
}
|
||||
}
|
||||
|
||||
func NewSimulation(width int, height int) *Simulation {
|
||||
return &Simulation{
|
||||
Grid: NewXelGrid(width, height),
|
||||
}
|
||||
}
|
6
simulation/vec2.go
Normal file
6
simulation/vec2.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package simulation
|
||||
|
||||
type Vector2 struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
69
simulation/xel.go
Normal file
69
simulation/xel.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
TurnNorth int = iota
|
||||
TurnEast
|
||||
TurnSouth
|
||||
TurnWest
|
||||
)
|
||||
|
||||
type Xel struct {
|
||||
Energy int64
|
||||
}
|
||||
|
||||
func (xel *Xel) Step(ownPos Vector2, grid *XelGrid) {
|
||||
// get other xel
|
||||
var otherXelPos Vector2
|
||||
switch rand.IntN(4) {
|
||||
case 0:
|
||||
otherXelPos = Vector2{X: ownPos.X + 1, Y: ownPos.Y}
|
||||
case 1:
|
||||
otherXelPos = Vector2{X: ownPos.X - 1, Y: ownPos.Y}
|
||||
case 2:
|
||||
otherXelPos = Vector2{X: ownPos.X, Y: ownPos.Y + 1}
|
||||
case 3:
|
||||
otherXelPos = Vector2{X: ownPos.X, Y: ownPos.Y - 1}
|
||||
}
|
||||
otherXel := grid.GetXel(otherXelPos)
|
||||
if otherXel == nil { return }
|
||||
// interact
|
||||
if (xel.Energy > 0 && otherXel.Energy > 0) || (xel.Energy < 0 && otherXel.Energy < 0) {
|
||||
if rand.IntN(4) == 0 {
|
||||
// create a higher energy xel and an inverted xel
|
||||
xel.Energy += (2 * otherXel.Energy)
|
||||
otherXel.Energy *= -1
|
||||
} else {
|
||||
xel.Energy += otherXel.Energy
|
||||
otherXel.Energy = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
if (xel.Energy < 0 && otherXel.Energy > 0) || (xel.Energy > 0 && otherXel.Energy < 0) {
|
||||
// cancel out
|
||||
xel.Energy += otherXel.Energy
|
||||
otherXel.Energy = 0
|
||||
return
|
||||
}
|
||||
if (xel.Energy == 0 && otherXel.Energy != 0) || (xel.Energy != 0 && otherXel.Energy == 0) {
|
||||
if xel.Energy > 1 || xel.Energy < -1 || otherXel.Energy > 1 || otherXel.Energy < -1 { // prevent integer 1 / 0
|
||||
// split
|
||||
splitE := (xel.Energy + otherXel.Energy) / 2
|
||||
xel.Energy = splitE + ((xel.Energy + otherXel.Energy) % 2)
|
||||
otherXel.Energy = splitE
|
||||
} else {
|
||||
// move
|
||||
if xel.Energy != 0 {
|
||||
otherXel.Energy = xel.Energy
|
||||
xel.Energy = 0
|
||||
} else {
|
||||
xel.Energy = otherXel.Energy
|
||||
otherXel.Energy = 0
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
36
simulation/xelgrid.go
Normal file
36
simulation/xelgrid.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package simulation
|
||||
|
||||
type XelGrid struct {
|
||||
Width int // do not overwrite this value after init!
|
||||
Height int // do not overwrite this value after init!
|
||||
Xels []*Xel
|
||||
}
|
||||
|
||||
func (grid *XelGrid) GetCenterPosition() Vector2 { // just a helper
|
||||
return Vector2{
|
||||
X: (grid.Width / 2) + (grid.Width % 2),
|
||||
Y: (grid.Height / 2) + (grid.Height % 2),
|
||||
}
|
||||
}
|
||||
|
||||
func (grid *XelGrid) GetXel(pos Vector2) *Xel {
|
||||
if pos.X < 0 || pos.X >= grid.Width || pos.Y < 0 || pos.Y >= grid.Height {
|
||||
return nil // out of bounds
|
||||
}
|
||||
i := (pos.Y * grid.Width) + pos.X
|
||||
return grid.Xels[i]
|
||||
}
|
||||
|
||||
func NewXelGrid(width int, height int) *XelGrid {
|
||||
grid := &XelGrid{
|
||||
Width: width,
|
||||
Height: height,
|
||||
Xels: make([]*Xel, width*height),
|
||||
}
|
||||
// init
|
||||
for i := range len(grid.Xels) {
|
||||
grid.Xels[i] = &Xel{}
|
||||
}
|
||||
//
|
||||
return grid
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue