Created
April 8, 2014 16:46
-
-
Save Glorp/10154283 to your computer and use it in GitHub Desktop.
Game of lifey. Like way concurrent and broken. Don't remember exactly how to anything with this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(goats). | |
-compile(export_all). | |
cell(Pos, Vis) -> | |
receive | |
{neighbours, Cells} -> setupDeadCell(Pos, Cells, 0, Vis); | |
Stuff -> io:format("cell, ~p~n", [Stuff]), false = true | |
end. | |
setupDeadCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
receive | |
live -> | |
Vis ! {alive, Pos}, | |
sendToAll(Neighbours, iLive), | |
setupLiveCell(Pos, Neighbours, AliveNeighbours, Vis); | |
iLive -> setupDeadCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> setupDeadCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
readySet -> readyDeadCell(Pos, Neighbours, AliveNeighbours, Vis); | |
Stuff -> io:format("setupDeadCell, ~p~n", [Stuff]), false = true | |
end. | |
setupLiveCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
receive | |
die -> | |
Vis ! {dead, Pos}, | |
sendToAll(Neighbours, imDead), | |
setupDeadCell(Pos, Neighbours, AliveNeighbours, Vis); | |
iLive -> setupLiveCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> setupLiveCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
readySet -> readyLiveCell(Pos, Neighbours, AliveNeighbours, Vis); | |
Stuff -> io:format("setupLiveCell, ~p~n", [Stuff]), false = true | |
end. | |
readyDeadCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
receive | |
go -> deadCell(Pos, Neighbours, AliveNeighbours, Vis); | |
iLive -> deadCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> deadCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
Stuff -> io:format("readyDeadCell, ~p~n", [Stuff]), false = true | |
end. | |
readyLiveCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
receive | |
go -> liveCell(Pos, Neighbours, AliveNeighbours, Vis); | |
iLive -> liveCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> liveCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
Stuff -> io:format("readyLiveCell, ~p~n", [Stuff]), false = true | |
end. | |
liveCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
if | |
(AliveNeighbours < 2) or (AliveNeighbours > 3) -> | |
Vis ! {dead, Pos}, | |
sendToAll(Neighbours, imDead), | |
deadCell(Pos, Neighbours, AliveNeighbours, Vis); | |
true -> | |
receive | |
iLive -> liveCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> liveCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
go -> liveCell(Pos, Neighbours, AliveNeighbours, Vis); | |
Stuff -> io:format("liveCell, ~p~n", [Stuff]), false = true | |
end | |
end. | |
deadCell(Pos, Neighbours, AliveNeighbours, Vis) -> | |
if | |
(AliveNeighbours =:= 3) -> | |
Vis ! {alive, Pos}, | |
sendToAll(Neighbours, iLive), | |
liveCell(Pos, Neighbours, AliveNeighbours, Vis); | |
true -> | |
receive | |
iLive -> deadCell(Pos, Neighbours, AliveNeighbours + 1, Vis); | |
imDead -> deadCell(Pos, Neighbours, AliveNeighbours - 1, Vis); | |
go -> deadCell(Pos, Neighbours, AliveNeighbours, Vis); | |
Stuff -> io:format("deadCell, ~p~n", [Stuff]), false = true | |
end | |
end. | |
sendToAll(Cells, Message) -> | |
lists:foreach(fun(C) -> C ! Message end, Cells). | |
createCells(Width, Height, Vis) -> | |
lists:map (fun(Y) -> | |
lists:map (fun(X) -> | |
spawn(fun() -> cell({X, Y}, Vis) end) end, (lists:seq(1, Width))) end, | |
(lists:seq(1, Height))). | |
potentialNeighbours({X, Y}) -> | |
lists:flatmap (fun(Yy) -> | |
lists:map (fun(Xx) -> | |
{Xx, Yy} end, lists:seq(X - 1, X + 1)) end, | |
lists:seq(Y - 1, Y + 1)). | |
valid({X, Y}, Width, Height) -> | |
fun({Xx, Yy}) -> | |
if | |
{Xx, Yy} =:= {X, Y} -> false; | |
Xx < 1 -> false; | |
Xx > Width -> false; | |
Yy < 1 -> false; | |
Yy > Height -> false; | |
true -> true | |
end | |
end. | |
findNeighbours(Pos, Width, Height, Cells) -> | |
lists:map(fun(P) -> findCell(Cells, P) end, | |
lists:filter(valid(Pos, Width, Height), potentialNeighbours(Pos))). | |
registerNeighbours(Cells, Width, Height) -> | |
lists:foreach (fun(Y) -> | |
lists:foreach (fun(X) -> | |
findCell(Cells, {X, Y}) ! {neighbours, findNeighbours({X, Y}, Width, Height, Cells)} end, lists:seq(1, Width)) end, | |
lists:seq(1, Height)). | |
findCell(Cells, {X, Y}) -> | |
lists:nth(X, lists:nth(Y, Cells)). | |
initGame(Width, Height, Vis) -> | |
Vis ! {Width, Height}, | |
Cells = createCells(Width, Height, Vis), | |
registerNeighbours(Cells, Width, Height), | |
Cells. | |
startGame(Cells) -> | |
Cs = lists:flatten(Cells), | |
sendToAll(Cs, readySet), | |
sendToAll(Cs, go), | |
Cells. | |
blinker(Vis) -> | |
Cells = initGame(20, 20, Vis), | |
findCell(Cells, {8, 9}) ! live, | |
findCell(Cells, {9, 9}) ! live, | |
findCell(Cells, {10, 9}) ! live, | |
startGame(Cells), | |
Cells. | |
blinker() -> | |
blinker(connect()). | |
connect(Host, Port) -> | |
{ok, Socket} = gen_tcp:connect(Host, Port, []), | |
spawn(fun() -> vis(Socket) end). | |
connect() -> connect({127,0,0,1}, 56789). | |
vis(Socket) -> | |
receive | |
{State, {X, Y}} -> | |
sendStuff(Socket, io_lib:format("(~p (~p . ~p))", [State, X, Y])), | |
vis(Socket); | |
{X, Y} -> | |
sendStuff(Socket, io_lib:format("(~p . ~p)", [X, Y])), | |
vis(Socket); | |
Stuff -> io:format("vis, ~p~n", [Stuff]), false = true | |
end. | |
sendStuff(Socket, Message) -> | |
timer:sleep(200), | |
gen_tcp:send(Socket, Message). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
(require racket/gui/base) | |
(define size 32) | |
(define (live in w h) | |
(define cells (set)) | |
(define frame (new frame% | |
(label "Life") | |
(width (* (+ w 1) size)) | |
(height (* (+ h 1) size)))) | |
(define brush (new brush% (style 'opaque))) | |
(define canvas (new canvas% (parent frame) | |
(paint-callback | |
(lambda (canvas dc) | |
(send dc set-brush brush) | |
(draw-life dc cells))))) | |
(send frame show #t) | |
(define (run) | |
(define m (read in)) | |
(set! cells | |
(match m | |
(`(alive ,x) (set-add cells x)) | |
(`(dead ,x) (set-remove cells x)))) | |
(send canvas refresh-now) | |
(run)) | |
(thread run)) | |
(define (draw-life dc cells) | |
(for ((c cells)) | |
(match c | |
(`(,x . ,y) (send dc draw-rectangle (* x size) (* y size) size size))))) | |
(require racket/tcp) | |
(define listener (tcp-listen 56789)) | |
(define (run) | |
(define-values (in out) (tcp-accept listener)) | |
(thread (λ () (match (read in) | |
(`(,w . ,h) (live in w h))))) | |
(thread run)) | |
(run) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment