mirror of
https://codeberg.org/scip/golsky.git
synced 2025-12-16 20:20:57 +01:00
added options -p and -n, using images not draw rects anymore
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
gameoflife
|
gameoflife
|
||||||
|
bak
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ You'll need the golang toolchain.
|
|||||||
The game has a couple of commandline options:
|
The game has a couple of commandline options:
|
||||||
|
|
||||||
```default
|
```default
|
||||||
|
|
||||||
Usage of ./gameoflife:
|
Usage of ./gameoflife:
|
||||||
-c, --cellsize int cell size in pixels (default 8)
|
-c, --cellsize int cell size in pixels (default 8)
|
||||||
-d, --debug show debug info
|
-d, --debug show debug info
|
||||||
@@ -23,6 +22,8 @@ Usage of ./gameoflife:
|
|||||||
-e, --empty start with an empty screen
|
-e, --empty start with an empty screen
|
||||||
-H, --height int grid height in cells (default 40)
|
-H, --height int grid height in cells (default 40)
|
||||||
-i, --invert invert colors (dead cell: black)
|
-i, --invert invert colors (dead cell: black)
|
||||||
|
-n, --nogrid do not draw grid lines
|
||||||
|
-p, --paused do not start simulation (use space to start)
|
||||||
-r, --rule string game rule (default "B3/S23")
|
-r, --rule string game rule (default "B3/S23")
|
||||||
-s, --show-evolution show evolution tracks
|
-s, --show-evolution show evolution tracks
|
||||||
-t, --tps int game speed in ticks per second (default 60)
|
-t, --tps int game speed in ticks per second (default 60)
|
||||||
@@ -35,6 +36,7 @@ While it runs, there are a couple of commands you can use:
|
|||||||
* left mouse click: set a cell to alife
|
* left mouse click: set a cell to alife
|
||||||
* right mouse click: set a cell to dead
|
* right mouse click: set a cell to dead
|
||||||
* space: pause or resume the game
|
* space: pause or resume the game
|
||||||
|
* while game is paused: press n to forward one step
|
||||||
* q: quit
|
* q: quit
|
||||||
* up arrow: speed up
|
* up arrow: speed up
|
||||||
* down arrow: slow down
|
* down arrow: slow down
|
||||||
|
|||||||
111
main.go
111
main.go
@@ -27,17 +27,23 @@ type Grid struct {
|
|||||||
Data [][]int
|
Data [][]int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Images struct {
|
||||||
|
Black, White, Beige *ebiten.Image
|
||||||
|
}
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
Grids []*Grid // 2 grids: one current, one next
|
Grids []*Grid // 2 grids: one current, one next
|
||||||
History *Grid
|
History *Grid
|
||||||
Index int // points to current grid
|
Index int // points to current grid
|
||||||
Width, Height, Cellsize, Density int
|
Width, Height, Cellsize, Density int
|
||||||
ScreenWidth, ScreenHeight int
|
ScreenWidth, ScreenHeight int
|
||||||
Generations int
|
Generations int
|
||||||
Black, White, Grey, Beige color.RGBA
|
Black, White, Grey, Beige color.RGBA
|
||||||
Speed int
|
Speed int
|
||||||
Debug, Paused, Empty, Invert, ShowEvolution bool
|
Debug, Paused, Empty, Invert bool
|
||||||
Rule *Rule
|
ShowEvolution, NoGrid, RunOneStep bool
|
||||||
|
Rule *Rule
|
||||||
|
Tiles Images
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
func (game *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||||
@@ -101,6 +107,10 @@ func (game *Game) UpdateCells() {
|
|||||||
|
|
||||||
// global counter
|
// global counter
|
||||||
game.Generations++
|
game.Generations++
|
||||||
|
|
||||||
|
if game.RunOneStep {
|
||||||
|
game.RunOneStep = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a GOL rule
|
// a GOL rule
|
||||||
@@ -198,30 +208,24 @@ func (game *Game) CheckInput() {
|
|||||||
ebiten.SetTPS(game.Speed)
|
ebiten.SetTPS(game.Speed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if game.Paused {
|
||||||
|
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
||||||
|
game.RunOneStep = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Update() error {
|
func (game *Game) Update() error {
|
||||||
game.CheckInput()
|
game.CheckInput()
|
||||||
|
|
||||||
if !game.Paused {
|
if !game.Paused || game.RunOneStep {
|
||||||
game.UpdateCells()
|
game.UpdateCells()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill a cell with the given color
|
|
||||||
func FillCell(screen *ebiten.Image, x, y, cellsize int, col color.RGBA) {
|
|
||||||
vector.DrawFilledRect(
|
|
||||||
screen,
|
|
||||||
float32(x*cellsize+1),
|
|
||||||
float32(y*cellsize+1),
|
|
||||||
float32(cellsize-1),
|
|
||||||
float32(cellsize-1),
|
|
||||||
col, false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set a cell to alive or dead
|
// set a cell to alive or dead
|
||||||
func ToggleCell(game *Game, alive int) {
|
func ToggleCell(game *Game, alive int) {
|
||||||
xPX, yPX := ebiten.CursorPosition()
|
xPX, yPX := ebiten.CursorPosition()
|
||||||
@@ -239,18 +243,27 @@ func (game *Game) Draw(screen *ebiten.Image) {
|
|||||||
// we fill the whole screen with a background color, the cells
|
// we fill the whole screen with a background color, the cells
|
||||||
// themselfes will be 1px smaller as their nominal size, producing
|
// themselfes will be 1px smaller as their nominal size, producing
|
||||||
// a nice grey grid with grid lines
|
// a nice grey grid with grid lines
|
||||||
screen.Fill(game.Grey)
|
op := &ebiten.DrawImageOptions{}
|
||||||
|
if game.NoGrid {
|
||||||
|
screen.Fill(game.White)
|
||||||
|
} else {
|
||||||
|
screen.Fill(game.Grey)
|
||||||
|
}
|
||||||
|
|
||||||
for y := 0; y < game.Height; y++ {
|
for y := 0; y < game.Height; y++ {
|
||||||
for x := 0; x < game.Width; x++ {
|
for x := 0; x < game.Width; x++ {
|
||||||
|
op.GeoM.Reset()
|
||||||
|
op.GeoM.Translate(float64(x*game.Cellsize), float64(y*game.Cellsize))
|
||||||
|
|
||||||
switch game.Grids[game.Index].Data[y][x] {
|
switch game.Grids[game.Index].Data[y][x] {
|
||||||
case 1:
|
case 1:
|
||||||
FillCell(screen, x, y, game.Cellsize, game.Black)
|
|
||||||
|
screen.DrawImage(game.Tiles.Black, op)
|
||||||
case 0:
|
case 0:
|
||||||
if game.History.Data[y][x] == 1 && game.ShowEvolution {
|
if game.History.Data[y][x] == 1 && game.ShowEvolution {
|
||||||
FillCell(screen, x, y, game.Cellsize, game.Beige)
|
screen.DrawImage(game.Tiles.Beige, op)
|
||||||
} else {
|
} else {
|
||||||
FillCell(screen, x, y, game.Cellsize, game.White)
|
screen.DrawImage(game.Tiles.White, op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,11 +283,7 @@ func (game *Game) Draw(screen *ebiten.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Init() {
|
func (game *Game) InitGrid() {
|
||||||
// setup the game
|
|
||||||
game.ScreenWidth = game.Cellsize * game.Width
|
|
||||||
game.ScreenHeight = game.Cellsize * game.Height
|
|
||||||
|
|
||||||
grid := &Grid{Data: make([][]int, game.Height)}
|
grid := &Grid{Data: make([][]int, game.Height)}
|
||||||
gridb := &Grid{Data: make([][]int, game.Height)}
|
gridb := &Grid{Data: make([][]int, game.Height)}
|
||||||
history := &Grid{Data: make([][]int, game.Height)}
|
history := &Grid{Data: make([][]int, game.Height)}
|
||||||
@@ -299,7 +308,22 @@ func (game *Game) Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game.History = history
|
game.History = history
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill a cell with the given color
|
||||||
|
func FillCell(tile *ebiten.Image, cellsize int, col color.RGBA) {
|
||||||
|
vector.DrawFilledRect(
|
||||||
|
tile,
|
||||||
|
float32(1),
|
||||||
|
float32(1),
|
||||||
|
float32(cellsize-1),
|
||||||
|
float32(cellsize-1),
|
||||||
|
col, false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare tile images
|
||||||
|
func (game *Game) InitTiles() {
|
||||||
game.Black = color.RGBA{0, 0, 0, 0xff}
|
game.Black = color.RGBA{0, 0, 0, 0xff}
|
||||||
game.White = color.RGBA{200, 200, 200, 0xff}
|
game.White = color.RGBA{200, 200, 200, 0xff}
|
||||||
game.Grey = color.RGBA{128, 128, 128, 0xff}
|
game.Grey = color.RGBA{128, 128, 128, 0xff}
|
||||||
@@ -308,9 +332,28 @@ func (game *Game) Init() {
|
|||||||
if game.Invert {
|
if game.Invert {
|
||||||
game.White = color.RGBA{0, 0, 0, 0xff}
|
game.White = color.RGBA{0, 0, 0, 0xff}
|
||||||
game.Black = color.RGBA{200, 200, 200, 0xff}
|
game.Black = color.RGBA{200, 200, 200, 0xff}
|
||||||
game.Beige = color.RGBA{0x8b, 0x1a, 0x1a, 0xff}
|
//game.Beige = color.RGBA{0x8b, 0x1a, 0x1a, 0xff}
|
||||||
|
game.Beige = color.RGBA{0x30, 0x1c, 0x11, 0xff}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game.Tiles.Beige = ebiten.NewImage(game.Cellsize, game.Cellsize)
|
||||||
|
game.Tiles.Black = ebiten.NewImage(game.Cellsize, game.Cellsize)
|
||||||
|
game.Tiles.White = ebiten.NewImage(game.Cellsize, game.Cellsize)
|
||||||
|
|
||||||
|
cellsize := game.ScreenWidth / game.Cellsize
|
||||||
|
FillCell(game.Tiles.Beige, cellsize, game.Beige)
|
||||||
|
FillCell(game.Tiles.Black, cellsize, game.Black)
|
||||||
|
FillCell(game.Tiles.White, cellsize, game.White)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (game *Game) Init() {
|
||||||
|
// setup the game
|
||||||
|
game.ScreenWidth = game.Cellsize * game.Width
|
||||||
|
game.ScreenHeight = game.Cellsize * game.Height
|
||||||
|
|
||||||
|
game.InitGrid()
|
||||||
|
game.InitTiles()
|
||||||
|
|
||||||
game.Index = 0
|
game.Index = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +390,9 @@ func main() {
|
|||||||
pflag.IntVarP(&game.Density, "density", "D", 10, "density of random cells")
|
pflag.IntVarP(&game.Density, "density", "D", 10, "density of random cells")
|
||||||
pflag.StringVarP(&rule, "rule", "r", "B3/S23", "game rule")
|
pflag.StringVarP(&rule, "rule", "r", "B3/S23", "game rule")
|
||||||
pflag.BoolVarP(&showversion, "version", "v", false, "show version")
|
pflag.BoolVarP(&showversion, "version", "v", false, "show version")
|
||||||
|
pflag.BoolVarP(&game.Paused, "paused", "p", false, "do not start simulation (use space to start)")
|
||||||
pflag.BoolVarP(&game.Debug, "debug", "d", false, "show debug info")
|
pflag.BoolVarP(&game.Debug, "debug", "d", false, "show debug info")
|
||||||
|
pflag.BoolVarP(&game.NoGrid, "nogrid", "n", false, "do not draw grid lines")
|
||||||
pflag.BoolVarP(&game.Empty, "empty", "e", false, "start with an empty screen")
|
pflag.BoolVarP(&game.Empty, "empty", "e", false, "start with an empty screen")
|
||||||
pflag.BoolVarP(&game.Invert, "invert", "i", false, "invert colors (dead cell: black)")
|
pflag.BoolVarP(&game.Invert, "invert", "i", false, "invert colors (dead cell: black)")
|
||||||
pflag.BoolVarP(&game.ShowEvolution, "show-evolution", "s", false, "show evolution tracks")
|
pflag.BoolVarP(&game.ShowEvolution, "show-evolution", "s", false, "show evolution tracks")
|
||||||
|
|||||||
Reference in New Issue
Block a user