#!/usr/local/bin/pl -q -s % -*- prolog -*- % prologLife.txt - Conway's Game of Life % Copyright (C) YAMAMIYA Takasi % Rererence: http://www-2.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/prolog/code/fun/life/0.html clear :- write('\33c'). % traverse a map lifeMapScan(ColumnAct, RowAct) :- boardWidth(Width), boardHeight(Height), lifeMapScan(ColumnAct, RowAct, Width, Height). lifeMapScan(_, _, _, 0) :- !. lifeMapScan(ColumnAct, RowAct, 0, Y) :- RowAct, Y1 is Y - 1, boardWidth(Width), lifeMapScan(ColumnAct, RowAct, Width, Y1), !. lifeMapScan(ColumnAct, RowAct, X, Y) :- call(ColumnAct, X, Y), X1 is X - 1, lifeMapScan(ColumnAct, RowAct, X1, Y). % Make a new random map. % The map is assigned at board/2, boardWidth/1 and boardHeight/1 lifeMapNew(Width, Height) :- retractall(board(_, _)), retractall(boardWidth(_)), retractall(boardHeight(_)), assert(boardWidth(Width)), assert(boardHeight(Height)), lifeMapScan(lifeMapSetCell, true). lifeMapSetCell(X, Y) :- (0 =:= random(2)), assert(board(X, Y)), !. lifeMapSetCell(_, _). % Show a map lifeMapShow :- clear, lifeMapScan(lifeMapShowCell, nl). lifeMapShowCell(X, Y) :- board(X, Y), write('O '), !. lifeMapShowCell(_, _) :- write(' '). % next generation lifeMapStep :- retractall(newBoard(_, _)), lifeMapScan(lifeMapStep, true), retractall(board(_, _)), lifeMapCopy. lifeMapStep(X, Y) :- numAt(Sum, X, Y), nextWhen(Sum, X, Y), assert(newBoard(X, Y)), !. lifeMapStep(_, _). nextWhen(2, X, Y) :- board(X, Y), !. nextWhen(3, _, _). lifeMapCopy :- newBoard(X, Y), assert(board(X, Y)), fail. lifeMapCopy. % count number of neighbours numAt(Result, X, Y) :- numAt(Result, 0, X, Y, [ [X-1|Y-1],[X-1|Y],[X-1|Y+1], [X |Y-1], [X |Y+1], [X+1|Y-1],[X+1|Y],[X+1|Y+1] ]). numAt(Sum, Sum, _, _, []) :- !. numAt(Result, Sum, X, Y, [[X1|Y1] | Pairs]) :- X2 is X1, Y2 is Y1, (board(X2, Y2) -> Num1 is (Sum + 1) ; Num1 is Sum), numAt(Result, Num1, X, Y, Pairs). % main main :- lifeMapNew(20, 20), loop(50), main. loop(0). loop(X) :- X1 is X - 1, lifeMapStep, lifeMapShow, sleep(0.2), loop(X1). ?- main.