生命遊戲


 說明

生命遊戲(Game of life)為1970年由英國數學家J. H. Conway提出,某細胞的鄰居包括上、下、左、右、左上、左下、右上與右下相鄰之細胞,遊戲規則如下:
  1. 孤單死亡:如果細胞的鄰居小於一個,則該細胞在下次狀態將死亡。
  2. 擁擠死亡:如果細胞的鄰居在四個以上,則該細胞在下次狀態將死亡。
  3. 穩定:如果細胞的鄰居為二個或三個,則下一次狀態為穩定存活。
  4. 復活:如果某位置原無細胞存活,而該位置的鄰居為三個,則該位置將復活一細胞。

解法

生命遊戲的規則可簡化為某位置有無細胞:
  1. 某位置之細胞鄰居數為0、1、4、5、6、7、8時,則該位置下次狀態必無細胞存活。
  2. 某位置之細胞鄰居數為2時,則該位置下次狀態保持不變(有細胞就有細胞,無細胞就無細胞)。
  3. 某位置之細胞鄰居數為3時,則該位置下次狀態必有細胞存活。

實作:Toy    C    Java    Python    Scala    Ruby    JavaScript    Haskell    Prolog

ROW = 10
COLUMN = 10

(DIRS = [
    [-1, 0], [-1, 1], [0, 1],  [1, 1],
    [1, 0],  [1, -1], [0, -1], [-1, -1]
])

def produce(current, next) {
    (iterate(0, ROW).forEach(row -> 
        iterate(0, COLUMN).forEach(column -> produceRC(row, column, current, next))
    ))
}

def produceRC(row, column, current, next) {
    switch neighbors(current, row, column) {
        case 0, 1, 4
            next.get(row).set(column, 0) 
        case 2
            next.get(row).set(column, current.get(row).get(column)) 
        case 3
            next.get(row).set(column, 1) 
    }         
}

def neighbors(current, row, column) {
    count = 0
    i = 0
    while i < 8 and count < 4 {
        r = row + DIRS.get(i).get(0)
        c = column + DIRS.get(i).get(1)
        if r > -1 and r < ROW and c > -1 and c < COLUMN and current.get(r).get(c) {
            count += 1
        }
        i += 1
    }

    return count
} 

def copy(from, to) {
    (iterate(0, ROW).forEach(row -> 
        iterate(0, COLUMN).forEach(column -> 
            copyRC(from, to, row, column)
        )
    ))
}  

def copyRC(from, to, row, column) {
    to.get(row).set(column, from.get(row).get(column))
    from.get(row).set(column, 0)
}

def isDifferent(current, next) {
    (return range(0, ROW)
              .any(row -> isDiffByRow(current.get(row), next.get(row))))
}  

def isDiffByRow(currentRow, nextRow) {
    (return range(0, COLUMN)
              .any(column -> currentRow.get(column) != nextRow.get(column)))
}

def printCells(current) {
    println('Status...')
    current.forEach(printRow)
    println()
} 

def printRow(row) {
    row.forEach(column -> print('*' if column != 0 else '~'))
    println()
} 

(current = [
    [0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
    [0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
    [0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
    [0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
    [0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
    [0, 1, 0, 1, 1, 0, 0, 1, 1, 1],
    [0, 1, 0, 1, 0, 1, 0, 0, 1, 1],
    [0, 1, 0, 1, 0, 0, 1, 0, 1, 1],
    [0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
    [0, 1, 0, 1, 1, 0, 0, 0, 1, 1]
])

next = range(0, ROW).map(_ -> range(0, COLUMN).fill(0))

printCells(current)
produce(current, next)

while isDifferent(current, next) {
    copy(next, current)
    printCells(current)
    produce(current, next)
}

#include <stdio.h> 
#define ROW 10
#define COLUMN 10

void produce(int[][COLUMN], int[][COLUMN]);
void print(int[][COLUMN]);
void copy(int[][COLUMN], int[][COLUMN]);
int neighbors(int[][COLUMN], int, int);
int isDifferent(int[][COLUMN], int[][COLUMN]);

int main() {
int current[ROW][COLUMN] = {
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 1, 1, 0, 0, 1, 0, 1, 1},
{0, 1, 1, 1, 0, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 1, 0, 0, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 1, 1},
{0, 1, 0, 1, 1, 0, 0, 0, 1, 1}
};
int next[ROW][COLUMN] = {0};

print(current);
produce(current, next);
while(isDifferent(current, next)) {
copy(next, current);
print(current);
produce(current, next);
}

return 0;
}


void produce(int current[][COLUMN], int next[][COLUMN]) {
int row;
for(row = 0; row < ROW; row++) {
int column;
for(column = 0; column < COLUMN; column++) {
switch (neighbors(current, row, column)) {
case 0: case 1: case 4:
next[row][column] = 0; break;
case 2:
next[row][column] = current[row][column]; break;
case 3:
next[row][column] = 1;
}
}
}
}

int neighbors(int current[][COLUMN], int row, int column) {
int dirs[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1},
{1, 0}, {1, -1}, {0, -1}, {-1, -1}};
int count, i;
for(count = 0, i = 0; i < 8 && count < 4; i++) {
int r = row + dirs[i][0];
int c = column + dirs[i][1];
if(r > -1 && r < ROW && c > -1 && c < COLUMN && current[r][c]) {
count++;
}
}
return count;
}

void print(int current[][COLUMN]) {
printf("Status...\n");
int row;
for(row = 0; row < ROW; row++) {
int column;
for(column = 0; column < COLUMN; column++) {
putchar(current[row][column] ? '*' : '~');
}
puts("");
}
}

void copy(int from[][COLUMN], int to[][COLUMN]) {
int row;
for(row = 0; row < ROW; row++) {
int column;
for(column = 0; column < COLUMN; column++) {
to[row][column] = from[row][column];
from[row][column] = 0;
}
}
}

int isDifferent(int current[][COLUMN], int next[][COLUMN]) {
int row;
for(row = 0; row < ROW; row++) {
int column;
for(column = 0; column < COLUMN; column++) {
if(current[row][column] != next[row][column]) {
return 1;
}
}
}
return 0;
}

import java.util.*;
import static java.lang.System.out;

class Cell {
final int i, j;
public Cell(int i, int j) {
this.i = i;
this.j = j;
}

public Cell seekToSurvive(Cell[][] current) {
return isLivable(current) ? this : null;
}

public boolean isLivable(Cell[][] cells) {
switch(neighbors(cells)) {
case 0: case 1: case 4: return false;
case 2: return this == cells[i][j];
}
return true;
}

public int neighbors(Cell[][] cells) {
int dirs[][] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1},
{1, 0}, {1, -1}, {0, -1}, {-1, -1}};
int count = 0;
for(int i = 0; i < 8 && count < 4; i++) {
int r = this.i + dirs[i][0];
int c = this.j + dirs[i][1];
if(r > -1 && r < cells.length && c > -1 && c <
cells[0].length && cells[r][c] != null) {
count++;
}
}
return count;
}

public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final Cell that = (Cell) obj;
return this.i == that.i && this.j == that.j;
}

public int hashCode() {
int hash = 7;
hash = 59 * hash + this.i;
hash = 59 * hash + this.j;
return hash;
}

}

public class LifeGame {
public static Cell[][] asCells(int[][] rowData) {
Cell[][] cells = new Cell[rowData.length][rowData[0].length];
for(int i = 0; i < rowData.length; i++) {
for(int j = 0; j < rowData[i].length; j++) {
if(rowData[i][j] == 1) {
cells[i][j] = new Cell(i, j);
}
}
}
return cells;
}

public static Cell getOrNew(Cell[][] cells, int i, int j) {
return cells[i][j] == null ? new Cell(i, j) : cells[i][j];
}

public static Cell[][] produce(Cell[][] current) {
Cell[][] next = new Cell[current.length][current[0].length];
for(int i = 0; i < current.length; i++) {
for(int j = 0; j < current.length; j++) {
next[i][j] = getOrNew(current, i, j).seekToSurvive(current);
}
}
return next;
}

public static void print(Cell[][] cells) {
out.println("Status...");
for(Cell[] row : cells) {
for(Cell cell : row) {
out.print(cell == null ? '~' : '*');
}
out.println();
}
}

public static void main(String[] args) {
Cell[][] current = asCells(new int[][] {
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 1, 1, 0, 0, 1, 0, 1, 1},
{0, 1, 1, 1, 0, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 1, 0, 0, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 0, 0, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 1, 1},
{0, 1, 0, 1, 1, 0, 0, 0, 1, 1}});

print(current);
Cell[][] next = produce(current);
while(!Arrays.deepEquals(current, next)) {
current = next;
print(current);
next = produce(current);
}
}
}

class Cell:
def __init__(self, i, j):
self.position = (i, j)

def seekToSurvive(self, cells):
return self if self.isLivable(cells) else None

def isLivable(self, cells):
n = self.neighbors(cells)
return False if n in [0, 1, 4] else (True if n == 3 else
id(self) == id(cells[self.position[0]][self.position[1]]))

def neighbors(self, cells):
dirs = [[-1, 0], [-1, 1], [0, 1], [1, 1],
[1, 0], [1, -1], [0, -1], [-1, -1]]
count = 0;
for i in range(8):
if count == 4:
break
r = self.position[0] + dirs[i][0]
c = self.position[1] + dirs[i][1]
if r > -1 and r < len(cells) and c > -1 and c < len(cells[0]) \
and cells[r][c] != None:
count += 1
return count

def __eq__(self, that):
return False if that == None else self.position == that.position

def __hash__(self):
return hash(self.position)

def asCells(rowData):
return [[Cell(i, j) if rowData[i][j] == 1 else None
for j in range(len(rowData[i]))] for i in range(len(rowData))]

def getOrNew(cells, i, j):
return Cell(i, j) if cells[i][j] == None else cells[i][j]

def produce(current):
return [[getOrNew(current, i, j).seekToSurvive(current)
for j in range(len(current[i]))] for i in range(len(current))]

def draw(cells):
print('Status...')
for row in cells:
for cell in row:
print('~' if cell == None else '*', end='')
print()

current = asCells([[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 1, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 0, 1, 1]])

draw(current)
next = produce(current)
while(current != next):
current = next
draw(current);
next = produce(current)

case class Cell(i: Int, j: Int) {
private val dirs = List(
List(-1, 0), List(-1, 1), List(0, 1), List(1, 1),
List(1, 0), List(1, -1), List(0, -1), List(-1, -1)
)

private val deathCounts = List(0, 1, 4)

def seekToSurvive(cells: List[List[Cell]]) = if(isLivable(cells)) this
else null

def isLivable(cells: List[List[Cell]]) = {
val n = neighbors(cells)
if(deathCounts.contains(n)) false
else if(n == 3) true
else this eq cells(i)(j)
}

def increment(index: Int, count: Int, cells: List[List[Cell]]): Int = {
if(index == 8 || count == 4) count
else {
val r = i + dirs(index)(0)
val c = j + dirs(index)(1)
if(r > -1 && r < cells.length &&
c > -1 && c < cells(0).length &&
cells(r)(c) != null) increment(index + 1, count + 1, cells)
else increment(index + 1, count, cells)
}
}

def neighbors(cells: List[List[Cell]]) = increment(0, 0, cells)
}

def asCells(rowData: List[List[Int]]) = {
(for(i <- 0 until rowData.length) yield
(for(j <- 0 until rowData(i).length) yield
if(rowData(i)(j) == 1) Cell(i, j) else null).toList).toList
}

def getOrNew(cells: List[List[Cell]], i: Int, j: Int) = {
if(cells(i)(j) == null) Cell(i, j) else cells(i)(j)
}

def produce(current: List[List[Cell]]) = {
(for(i <- 0 until current.length) yield
(for(j <- 0 until current(i).length) yield
getOrNew(current, i, j).seekToSurvive(current)).toList).toList
}

def showUntilSteady(cells: List[List[Cell]]) {
println("Status...")
for(row <- cells) {
for(cell <- row) {
print(if(cell == null) '~' else '*')
}
println
}
val next = produce(cells)
if(next != cells) showUntilSteady(next)
}

showUntilSteady(asCells(
List(
List(0, 1, 0, 1, 0, 0, 0, 0, 1, 1),
List(0, 1, 0, 1, 0, 0, 0, 0, 1, 1),
List(0, 1, 0, 1, 0, 0, 0, 0, 1, 1),
List(0, 1, 1, 1, 0, 0, 1, 0, 1, 1),
List(0, 1, 1, 1, 0, 1, 0, 0, 1, 1),
List(0, 1, 0, 1, 1, 0, 0, 1, 1, 1),
List(0, 1, 0, 1, 0, 1, 0, 0, 1, 1),
List(0, 1, 0, 1, 0, 0, 1, 0, 1, 1),
List(0, 1, 0, 1, 0, 1, 0, 1, 1, 1),
List(0, 1, 0, 1, 1, 0, 0, 0, 1, 1)
)
)
}

class Cell
def initialize(r, c)
@position = {i: r, j: c}
end

def seekToSurvive(cells)
if isLivable(cells); self else nil end
end

def isLivable(cells)
n = neighbors(cells)
if [0, 1, 4].include? n; false
elsif n == 3; true
else self.object_id == cells[@position[:i]][@position[:j]].object_id
end
end

def neighbors(cells)
dirs = [[-1, 0], [-1, 1], [0, 1], [1, 1],
[1, 0], [1, -1], [0, -1], [-1, -1]]
count = 0;
(0...8).each do |i|
if count == 4
break
end
r = @position[:i] + dirs[i][0]
c = @position[:j] + dirs[i][1]
if r > -1 && r < cells.size &&
c > -1 && c < cells[0].size && cells[r][c] != nil
count += 1
end
end
count
end

def eq?(that)
@positon == that.position
end

def hash
@position.hash
end
end

def asCells(rowData)
(0...rowData.size).map { |i|
(0...rowData[i].size).map { |j|
if rowData[i][j] == 1; Cell.new(i, j) else nil end
}
}
end

def getOrNew(cells, i, j)
if cells[i][j] == nil; Cell.new(i, j) else cells[i][j] end
end

def produce(current)
(0...current.size).map { |i|
(0...current[i].size).map { |j|
getOrNew(current, i, j).seekToSurvive(current)
}
}
end

def draw(cells)
puts('Status...')
cells.each do |row|
row.each do |cell|
print(if cell == nil; '~' else '*' end)
end
puts
end
end

current = asCells([[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 1, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 0, 1, 1]])

draw(current)
newGen = produce(current)
while(current != newGen)
current = newGen
draw(current);
newGen = produce(current)
end

var produce = function() {
function range(start, end) {
var r = [];
for(var i = start; i < end; i++) {
r.push(i);
}
return r;
}

function liveOrDie(current, row, column) {
switch(neighbors(current, row, column)) {
case 0: case 1: case 4: return 0;
case 2: return current[row][column];
}
return 1;
}

function neighbors(current, row, column) {
var dirs = [[-1, 0], [-1, 1], [0, 1], [1, 1],
[1, 0], [1, -1], [0, -1], [-1, -1]];
var count = 0;
for(var i = 0; i < 8 && count < 4; i++) {
var r = row + dirs[i][0];
var c = column + dirs[i][1];
if(r > -1 && r < current.length &&
c > -1 && c < current[0].length && current[r][c]) {
count++;
}
}
return count;
}

return function(current) {
return range(0, current.length).map(function(row) {
return range(0, current[0].length).map(function(column) {
return liveOrDie(current, row, column);
});
});
};
}();

var draw = function(cells) {
print('Status...\n');
for(var row = 0; row < cells.length; row++) {
for(var column = 0; column < cells[0].length; column++) {
print(cells[row][column] ? '*' : '~');
}
print('\n');
}
};

var isDifferent = function(current, next) {
for(var row = 0; row < current.length; row++) {
for(var column = 0; column < current[0].length; column++) {
if(current[row][column] !== next[row][column]) {
return true;
}
}
}
return false;
};

var current = [[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 1, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 0, 1, 1]];

draw(current);
var next = produce(current)
while(isDifferent(current, next)) {
current = next;
draw(current);
next = produce(next);
}

import Control.Monad

produce current = [[liveOrDie current row column |
column <- [0..columnLength - 1]] | row <- [0..rowLength - 1]]
where rowLength = length current
columnLength = length \$ current !! 0

liveOrDie current row column =
if n `elem` [0, 1, 4] then 0
else if n == 2 then current !! row !! column
else 1
where n = neighbors current row column

neighbors cells row column = increment cells 0 0
where increment cells index count =
if index == 8 || count == 4 then count
else if r > -1 && r < rowLength &&
c > -1 && c < columnLength && cells !! r !! c /= 0
then increment cells (index + 1) (count + 1)
else increment cells (index + 1) count
where rowLength = length cells
columnLength = length \$ cells !! 0
dirs = [[-1, 0], [-1, 1], [0, 1], [1, 1],
[1, 0], [1, -1], [0, -1], [-1, -1]]
r = row + dirs !! index !! 0
c = column + dirs !! index !! 1

showUntilSteady cells = do
putStrLn "Status..."
forM [0..rowLength - 1] (\row -> do
forM [0..columnLength - 1] (\column -> do
putChar (if cells !! row !! column == 0 then '~' else '*'))
putStrLn "")
when (next /= cells) \$ do
showUntilSteady next
where next = produce cells
rowLength = length cells
columnLength = length \$ cells !! 0

main = showUntilSteady [[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 1, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[0, 1, 0, 1, 1, 0, 0, 0, 1, 1]]

state(Neighbors, _, 0) :- between(0, 1, Neighbors), !.
state(Neighbors, _, 0) :- between(4, 8, Neighbors), !.
state(2, Value, Value).
state(3, _, 1).

block(Blocks, Row, Column, Value) :-
    nth0(Row, Blocks, Values), nth0(Column, Values, Value).
    
upper_neighbor(Blocks, Row, Column) :-
    Row > 0, R is Row - 1,
    block(Blocks, R, Column, 1).
    
down_neighbor(Blocks, Row, Column) :-
    length(Blocks, ROWS), R is Row + 1, R < ROWS,
    block(Blocks, R, Column, 1).
    
left_neighbor(Blocks, Row, Column) :-
    Column > 0, C is Column - 1,
    block(Blocks, Row, C, 1).
    
right_neighbor(Blocks, Row, Column) :-
    nth0(0, Blocks, Values), 
    length(Values, Columns), C is Column + 1, C < Columns,
    block(Blocks, Row, C, 1).
    
left_upper_neighbor(Blocks, Row, Column) :-
    Row > 0, R is Row - 1,
    Column > 0, C is Column - 1,
    block(Blocks, R, C, 1).
    
left_down_neighbor(Blocks, Row, Column) :-
    length(Blocks, ROWS), R is Row + 1, R < ROWS,
    Column > 0, C is Column - 1,
    block(Blocks, R, C, 1).
    
right_upper_neighbor(Blocks, Row, Column) :-
    Row > 0, R is Row - 1,
    nth0(0, Blocks, Values), 
    length(Values, Columns), C is Column + 1, C < Columns,
    block(Blocks, R, C, 1).
    
right_down_neighbor(Blocks, Row, Column) :-
    length(Blocks, ROWS), R is Row + 1, R < ROWS,
    nth0(0, Blocks, Values), 
    length(Values, Columns), C is Column + 1, C < Columns,
    block(Blocks, R, C, 1).
    
truthes([P|T], N) :- P, !, truthes(T, Acc), N is Acc + 1.
truthes([_|T], Acc) :- truthes(T, Acc).
truthes([], 0).

neighbors(Blocks, Row, Column, N) :-
    truthes([
        upper_neighbor(Blocks, Row, Column),
        down_neighbor(Blocks, Row, Column),
        left_neighbor(Blocks, Row, Column),
        right_neighbor(Blocks, Row, Column),
        left_upper_neighbor(Blocks, Row, Column),
        left_down_neighbor(Blocks, Row, Column),
        right_upper_neighbor(Blocks, Row, Column),
        right_down_neighbor(Blocks, Row, Column)
    ], N).

forRow(Row, Blocks) :-
    length(Blocks, Rows), Row < Rows, !,
    forElem(Row, 0, Blocks), NR is Row + 1,
    forRow(NR, Blocks).
forRow(_, _) :- nl.    

forElem(Row, Column, Blocks) :-
    nth0(0, Blocks, Values), length(Values, Columns),
    Column < Columns, !, 
    block(Blocks, Row, Column, Value),    
    neighbors(Blocks, Row, Column, N),
    state(N, Value, ToValue),
    write(ToValue),
    NC is Column + 1,
    forElem(Row, NC, Blocks).
forElem(_, _, _) :- nl. main(_) :- Blocks = [ [0, 1, 0, 1, 0, 0, 0, 0, 1, 1], [0, 1, 0, 1, 0, 0, 0, 0, 1, 1], [0, 1, 0, 1, 0, 0, 0, 0, 1, 1], [0, 1, 1, 1, 0, 0, 1, 0, 1, 1], [0, 1, 1, 1, 0, 1, 0, 0, 1, 1], [0, 1, 0, 1, 1, 0, 0, 1, 1, 1], [0, 1, 0, 1, 0, 1, 0, 0, 1, 1], [0, 1, 0, 1, 0, 0, 1, 0, 1, 1], [0, 1, 0, 1, 0, 1, 0, 1, 1, 1], [0, 1, 0, 1, 1, 0, 0, 0, 1, 1] ], forRow(0, Blocks).