gophertype/pvt-www/_builtin/js/ace-1.4.8/demo/kitchen-sink/docs/gobstones.gbs

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()
}