Added click to toggle cells to alive or dead.
Additionally improved neighbor counting code and edges now wrap.
This commit is contained in:
parent
4e04f853dc
commit
db71b4c9b9
1 changed files with 75 additions and 66 deletions
|
@ -24,46 +24,55 @@ type Cell struct {
|
||||||
type Game struct {
|
type Game struct {
|
||||||
ScreenWidth int32
|
ScreenWidth int32
|
||||||
ScreenHeight int32
|
ScreenHeight int32
|
||||||
|
Cols int32
|
||||||
|
Rows int32
|
||||||
FramesCounter int32
|
FramesCounter int32
|
||||||
Playing bool
|
Playing bool
|
||||||
Cells [][]*Cell
|
Cells [][]*Cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
||||||
game := Game{}
|
game := Game{}
|
||||||
game.Init()
|
game.Init(false)
|
||||||
|
|
||||||
raylib.InitWindow(game.ScreenWidth, game.ScreenHeight, "Conway's Game of Life")
|
raylib.InitWindow(game.ScreenWidth, game.ScreenHeight, "Conway's Game of Life")
|
||||||
raylib.SetTargetFPS(20)
|
raylib.SetTargetFPS(20)
|
||||||
|
|
||||||
for !raylib.WindowShouldClose() {
|
for !raylib.WindowShouldClose() {
|
||||||
if game.Playing {
|
if game.Playing {
|
||||||
game.Update()
|
game.Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
game.Input()
|
game.Input()
|
||||||
|
|
||||||
game.Draw()
|
game.Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib.CloseWindow()
|
raylib.CloseWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init - Initialize game
|
// Init - Initialize game
|
||||||
func (g *Game) Init() {
|
func (g *Game) Init(clear bool) {
|
||||||
g.ScreenWidth = 1024
|
g.ScreenWidth = 1920
|
||||||
g.ScreenHeight = 768
|
g.ScreenHeight = 1100
|
||||||
g.FramesCounter = 0
|
g.FramesCounter = 0
|
||||||
|
|
||||||
g.Cells = make([][]*Cell, g.ScreenWidth/squareSize+1)
|
g.Cols = g.ScreenWidth / squareSize
|
||||||
for i := int32(0); i <= g.ScreenWidth/squareSize; i++ {
|
g.Rows = g.ScreenHeight / squareSize
|
||||||
g.Cells[i] = make([]*Cell, g.ScreenHeight/squareSize+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
|
|
||||||
for x := int32(0); x <= g.ScreenWidth/squareSize; x++ {
|
g.Cells = make([][]*Cell, g.Cols+1)
|
||||||
for y := int32(0); y <= g.ScreenHeight/squareSize; y++ {
|
for i := int32(0); i <= g.Cols; i++ {
|
||||||
|
g.Cells[i] = make([]*Cell, g.Rows+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for x := int32(0); x <= g.Cols; x++ {
|
||||||
|
for y := int32(0); y <= g.Rows; y++ {
|
||||||
g.Cells[x][y] = &Cell{}
|
g.Cells[x][y] = &Cell{}
|
||||||
g.Cells[x][y].Position = raylib.NewVector2((float32(x) * squareSize), (float32(y)*squareSize)+1)
|
g.Cells[x][y].Position = raylib.NewVector2((float32(x) * squareSize), (float32(y)*squareSize)+1)
|
||||||
g.Cells[x][y].Size = raylib.NewVector2(squareSize-1, squareSize-1)
|
g.Cells[x][y].Size = raylib.NewVector2(squareSize-1, squareSize-1)
|
||||||
if rand.Float64() < 0.1 {
|
if rand.Float64() < 0.1 && clear == false {
|
||||||
g.Cells[x][y].Alive = true
|
g.Cells[x][y].Alive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,11 +83,17 @@ func (g *Game) Init() {
|
||||||
func (g *Game) Input() {
|
func (g *Game) Input() {
|
||||||
// control
|
// control
|
||||||
if raylib.IsKeyPressed(raylib.KeyR) {
|
if raylib.IsKeyPressed(raylib.KeyR) {
|
||||||
g.Init()
|
g.Init(false)
|
||||||
|
}
|
||||||
|
if raylib.IsKeyPressed(raylib.KeyC) {
|
||||||
|
g.Init(true)
|
||||||
}
|
}
|
||||||
if raylib.IsKeyDown(raylib.KeyRight) && !g.Playing {
|
if raylib.IsKeyDown(raylib.KeyRight) && !g.Playing {
|
||||||
g.Update()
|
g.Update()
|
||||||
}
|
}
|
||||||
|
if raylib.IsMouseButtonPressed(raylib.MouseLeftButton) {
|
||||||
|
g.Click(raylib.GetMouseX(), raylib.GetMouseY())
|
||||||
|
}
|
||||||
if raylib.IsKeyPressed(raylib.KeySpace) {
|
if raylib.IsKeyPressed(raylib.KeySpace) {
|
||||||
g.Playing = !g.Playing
|
g.Playing = !g.Playing
|
||||||
}
|
}
|
||||||
|
@ -86,82 +101,76 @@ func (g *Game) Input() {
|
||||||
g.FramesCounter++
|
g.FramesCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Click - Toggle if a cell is alive or dead on click
|
||||||
|
func (g *Game) Click(x, y int32) {
|
||||||
|
for i := int32(0); i <= g.Cols; i++ {
|
||||||
|
for j := int32(0); j <= g.Rows; j++ {
|
||||||
|
cell := g.Cells[i][j].Position
|
||||||
|
if int32(cell.X) < x && int32(cell.X)+squareSize > x && int32(cell.Y) < y && int32(cell.Y)+squareSize > y {
|
||||||
|
g.Cells[i][j].Alive = !g.Cells[i][j].Alive
|
||||||
|
g.Cells[i][j].Next = g.Cells[i][j].Alive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update - Update game
|
// Update - Update game
|
||||||
func (g *Game) Update() {
|
func (g *Game) Update() {
|
||||||
for i := int32(0); i <= g.ScreenWidth/squareSize; i++ {
|
for i := int32(0); i <= g.Cols; i++ {
|
||||||
for j := int32(0); j <= g.ScreenHeight/squareSize; j++ {
|
for j := int32(0); j <= g.Rows; j++ {
|
||||||
NeighbourCount := 0
|
NeighborCount := g.CountNeighbors(i, j)
|
||||||
if j-1 >= 0 {
|
|
||||||
if g.Cells[i][j-1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if j+1 <= g.ScreenHeight/squareSize {
|
|
||||||
if g.Cells[i][j+1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i-1 >= 0 {
|
|
||||||
if g.Cells[i-1][j].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i+1 <= g.ScreenWidth/squareSize {
|
|
||||||
if g.Cells[i+1][j].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i-1 >= 0 && j-1 >= 0 {
|
|
||||||
if g.Cells[i-1][j-1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i-1 >= 0 && j+1 <= g.ScreenHeight/squareSize {
|
|
||||||
if g.Cells[i-1][j+1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i+1 <= g.ScreenWidth/squareSize && j-1 >= 0 {
|
|
||||||
if g.Cells[i+1][j-1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i+1 <= g.ScreenWidth/squareSize && j+1 <= g.ScreenHeight/squareSize {
|
|
||||||
if g.Cells[i+1][j+1].Alive {
|
|
||||||
NeighbourCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if g.Cells[i][j].Alive {
|
if g.Cells[i][j].Alive {
|
||||||
if NeighbourCount < 2 {
|
if NeighborCount < 2 {
|
||||||
g.Cells[i][j].Next = false
|
g.Cells[i][j].Next = false
|
||||||
} else if NeighbourCount > 3 {
|
} else if NeighborCount > 3 {
|
||||||
g.Cells[i][j].Next = false
|
g.Cells[i][j].Next = false
|
||||||
} else {
|
} else {
|
||||||
g.Cells[i][j].Next = true
|
g.Cells[i][j].Next = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if NeighbourCount == 3 {
|
if NeighborCount == 3 {
|
||||||
g.Cells[i][j].Next = true
|
g.Cells[i][j].Next = true
|
||||||
g.Cells[i][j].Visited = true
|
g.Cells[i][j].Visited = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := int32(0); i <= g.ScreenWidth/squareSize; i++ {
|
for i := int32(0); i <= g.Cols; i++ {
|
||||||
for j := int32(0); j < g.ScreenHeight/squareSize; j++ {
|
for j := int32(0); j < g.Rows; j++ {
|
||||||
g.Cells[i][j].Alive = g.Cells[i][j].Next
|
g.Cells[i][j].Alive = g.Cells[i][j].Next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountNeighbors - Counts how many neighbous a cell has
|
||||||
|
func (g *Game) CountNeighbors(x, y int32) int {
|
||||||
|
count := 0
|
||||||
|
|
||||||
|
for i := int32(-1); i < 2; i++ {
|
||||||
|
for j := int32(-1); j < 2; j++ {
|
||||||
|
col := (x + i + (g.Cols)) % (g.Cols)
|
||||||
|
row := (y + j + (g.Rows)) % (g.Rows)
|
||||||
|
if g.Cells[col][row].Alive {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.Cells[x][y].Alive {
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
// Draw - Draw game
|
// Draw - Draw game
|
||||||
func (g *Game) Draw() {
|
func (g *Game) Draw() {
|
||||||
raylib.BeginDrawing()
|
raylib.BeginDrawing()
|
||||||
raylib.ClearBackground(raylib.RayWhite)
|
raylib.ClearBackground(raylib.RayWhite)
|
||||||
|
|
||||||
// Draw cells
|
// Draw cells
|
||||||
for x := int32(0); x <= g.ScreenWidth/squareSize; x++ {
|
for x := int32(0); x <= g.Cols; x++ {
|
||||||
for y := int32(0); y <= g.ScreenHeight/squareSize; y++ {
|
for y := int32(0); y <= g.Rows; y++ {
|
||||||
if g.Cells[x][y].Alive {
|
if g.Cells[x][y].Alive {
|
||||||
raylib.DrawRectangleV(g.Cells[x][y].Position, g.Cells[x][y].Size, raylib.Blue)
|
raylib.DrawRectangleV(g.Cells[x][y].Position, g.Cells[x][y].Size, raylib.Blue)
|
||||||
} else if g.Cells[x][y].Visited {
|
} else if g.Cells[x][y].Visited {
|
||||||
|
@ -171,7 +180,7 @@ func (g *Game) Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw grid lines
|
// Draw grid lines
|
||||||
for i := int32(0); i < g.ScreenWidth/squareSize+1; i++ {
|
for i := int32(0); i < g.Cols+1; i++ {
|
||||||
raylib.DrawLineV(
|
raylib.DrawLineV(
|
||||||
raylib.NewVector2(float32(squareSize*i), 0),
|
raylib.NewVector2(float32(squareSize*i), 0),
|
||||||
raylib.NewVector2(float32(squareSize*i), float32(g.ScreenHeight)),
|
raylib.NewVector2(float32(squareSize*i), float32(g.ScreenHeight)),
|
||||||
|
@ -179,7 +188,7 @@ func (g *Game) Draw() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := int32(0); i < g.ScreenHeight/squareSize+1; i++ {
|
for i := int32(0); i < g.Rows+1; i++ {
|
||||||
raylib.DrawLineV(
|
raylib.DrawLineV(
|
||||||
raylib.NewVector2(0, float32(squareSize*i)),
|
raylib.NewVector2(0, float32(squareSize*i)),
|
||||||
raylib.NewVector2(float32(g.ScreenWidth), float32(squareSize*i)),
|
raylib.NewVector2(float32(g.ScreenWidth), float32(squareSize*i)),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue