Skip to content

Instantly share code, notes, and snippets.

@Glorp
Created April 8, 2014 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Glorp/10154283 to your computer and use it in GitHub Desktop.
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.
-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).
#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