172 lines
4.1 KiB
Plaintext
172 lines
4.1 KiB
Plaintext
/*
|
|
* A Gobstones implementation of Conwey's Game of Life
|
|
* that tries to use most of Gobstones syntax.
|
|
*
|
|
* Check out more about Gobstones at http://gobstones.org
|
|
*/
|
|
|
|
-----------------------------------------------------------
|
|
-- HELPERS TO MOVE AROUND ALL THE BOARD --
|
|
-----------------------------------------------------------
|
|
|
|
// This helpers allow the user to move around the board
|
|
// one cell at a time
|
|
procedure GoToStartOfBoard(firstDir, secondDir) {
|
|
IrAlBorde(opuesto(firstDir))
|
|
IrAlBorde(opuesto(secondDir))
|
|
}
|
|
|
|
function isEndOfBoard(firstDir, secondDir) {
|
|
return (not puedeMover(firstDir) && not puedeMover(secondDir))
|
|
}
|
|
|
|
procedure NextCellOfTheBoard(firstDir, secondDir) {
|
|
if (puedeMover(firstDir)) {
|
|
Mover(firstDir)
|
|
} else {
|
|
IrAlBorde(opuesto(firstDir))
|
|
Mover(secondDir)
|
|
}
|
|
}
|
|
|
|
-----------------------------------------------------------
|
|
-- TYPE DECLARATIONS --
|
|
-----------------------------------------------------------
|
|
// The cell type declarations
|
|
type CellStatus is variant {
|
|
case Alive {}
|
|
case Dead {}
|
|
}
|
|
|
|
type Cell is record {
|
|
field status # CellStatus
|
|
field color # Color
|
|
}
|
|
|
|
|
|
-----------------------------------------------------------
|
|
-- PROGRAM DEFINITION --
|
|
-----------------------------------------------------------
|
|
interactive program {
|
|
# Map key press to actions
|
|
K_UP -> { PrepareNextTick() }
|
|
K_RIGHT -> { CompleteNextTick() }
|
|
K_RETURN -> { SimulateNextTick() }
|
|
}
|
|
|
|
/*
|
|
program {
|
|
return ( numberOfNeighbors())
|
|
}
|
|
*/
|
|
-----------------------------------------------------------
|
|
-- FUNCTIONS --
|
|
-----------------------------------------------------------
|
|
function isCellAlive() {
|
|
return (hayBolitas(Verde))
|
|
}
|
|
|
|
function cellStatus() {
|
|
return (
|
|
choose
|
|
Alive when (isCellAlive())
|
|
Dead otherwise
|
|
)
|
|
}
|
|
|
|
function readCell() {
|
|
return (
|
|
Cell(color <- Verde, status <- cellStatus())
|
|
)
|
|
}
|
|
|
|
function numberOfNeighbors() {
|
|
amountOfNeighbors := 0
|
|
foreach dir in [minDir() .. maxDir()] {
|
|
amountOfNeighbors := amountOfNeighbors + aliveCellsAt(dir)
|
|
}
|
|
return (amountOfNeighbors)
|
|
}
|
|
|
|
function aliveCellsAt(dir) {
|
|
firstCompare := puedeMover(dir) && hasAliveCellAt(dir)
|
|
secondCompare := puedeMover(dir) && puedeMover(siguiente(dir)) && hasAliveCellAtD(dir)
|
|
value :=
|
|
matching (firstCompare) select
|
|
1 on True
|
|
0 otherwise
|
|
+
|
|
matching (secondCompare) select
|
|
1 on True
|
|
0 otherwise
|
|
return (value)
|
|
}
|
|
|
|
function hasAliveCellAt(dir) {
|
|
Mover(dir)
|
|
return (isCellAlive())
|
|
}
|
|
|
|
function hasAliveCellAtD(dir) {
|
|
Mover(dir)
|
|
Mover(siguiente(dir))
|
|
return (isCellAlive())
|
|
}
|
|
|
|
-----------------------------------------------------------
|
|
-- ROCEDURES DECLARATIONS --
|
|
-----------------------------------------------------------
|
|
procedure TagAsReanimated() {
|
|
Poner(Azul)
|
|
}
|
|
|
|
procedure TagAsDead() {
|
|
Poner(Rojo)
|
|
}
|
|
|
|
procedure ProcessAction() {
|
|
switch (hayBolitas(Rojo)) {
|
|
True -> { Sacar(Verde); Sacar(Rojo) }
|
|
_ -> {}
|
|
}
|
|
switch (hayBolitas(Azul)) {
|
|
True -> { Poner(Verde); Sacar(Azul) }
|
|
_ -> {}
|
|
}
|
|
}
|
|
|
|
procedure TagCell(numNeighbors) {
|
|
if ( isCellAlive() && numNeighbors < 2) { TagAsDead() }
|
|
elseif ( isCellAlive() && numNeighbors > 3) { TagAsDead() }
|
|
elseif ((not isCellAlive()) && numNeighbors == 3) { TagAsReanimated() }
|
|
}
|
|
|
|
procedure SimulateTicks(amount) {
|
|
repeat(amount) {
|
|
SimulateNextTick()
|
|
}
|
|
}
|
|
|
|
procedure SimulateNextTick() {
|
|
PrepareNextTick()
|
|
CompleteNextTick()
|
|
}
|
|
|
|
procedure PrepareNextTick() {
|
|
GoToStartOfBoard(Norte, Este)
|
|
while (not isEndOfBoard(Norte, Este)) {
|
|
TagCell(numberOfNeighbors())
|
|
NextCellOfTheBoard(Norte, Este)
|
|
}
|
|
TagCell(numberOfNeighbors())
|
|
}
|
|
|
|
procedure CompleteNextTick() {
|
|
GoToStartOfBoard(Norte, Este)
|
|
while (not isEndOfBoard(Norte, Este)) {
|
|
ProcessAction()
|
|
NextCellOfTheBoard(Norte, Este)
|
|
}
|
|
ProcessAction()
|
|
}
|