Examples Snake game

Snake game

Snake game in Prolog.

Run example

W A S D to play

Source code

<script id="snake.pl" type="text/prolog"> :- use_module(library(lists)). :- use_module(library(random)). :- use_module(library(dom)). :- use_module(library(js)). :- use_module(library(os)). :- dynamic(direction/1). direction(down). key_direction(w, up) :- direction(Direction), Direction \== down. key_direction(a, left) :- direction(Direction), Direction \== right. key_direction(d, right) :- direction(Direction), Direction \== left. key_direction(s, down) :- direction(Direction), Direction \== up. snake :- once(get_by_tag(body, Body)), bind(Body, keydown, Event, ( event_property(Event, key, Key), key_direction(Key, Direction), prevent_default(Event), retractall(direction(_)), asserta(direction(Direction)) )), get_by_id(snake, Canvas), apply(Canvas, getContext, ['2d'], Ctx), random_between(1, 20, X), random_between(1, 20, Y), snake(Ctx, [(1,1)], (X,Y)). snake(Ctx, Snake, Point) :- get_time(T0), draw(Ctx, Snake, Point), direction(Direction), update(Snake, Point, Direction, Snake1, Point1), get_time(T1), Timeout is max(0, 60-round(T1-T0)), set_timeout(Timeout, snake(Ctx, Snake1, Point1), _). next_position(left, (1,Y), (20,Y)). next_position(left, (X0,Y), (X1,Y)) :- succ(X1, X0). next_position(right, (20,Y), (1,Y)). next_position(right, (X0,Y), (X1,Y)) :- succ(X0, X1). next_position(up, (X,1), (X,20)). next_position(up, (X,Y0), (X,Y1)) :- succ(Y1, Y0). next_position(down, (X,20), (X,1)). next_position(down, (X,Y0), (X,Y1)) :- succ(Y0, Y1). inits([_], []). inits([X,Y|T], [X|S]) :- inits([Y|T], S). update(Snake0, Point0, Direction, [Head1|Snake1], Point1) :- Snake0 = [Head0|_], next_position(Direction, Head0, Head1), ( member(Head1, Snake0) -> Snake1 = [], Point1 = Point0 ; ( Head1 == Point0 -> Snake1 = Snake0, Point1 = (X,Y), random_between(1,20,X), random_between(1,20,Y) ; inits(Snake0, Snake1), Point1 = Point0 ) ). draw(Ctx, Snake, Point) :- apply(Ctx, clearRect, [0,0,200,200], _), draw_point(Ctx, Point, red), forall( member(Body, Snake), draw_point(Ctx, Body, black) ). draw_point(Ctx, (X,Y), Color) :- PointX is (X-1)*10, PointY is (Y-1)*10, set_prop(Ctx, fillStyle, Color), apply(Ctx, beginPath, [], _), apply(Ctx, rect, [PointX,PointY,10,10], _), apply(Ctx, fill, [], _). </script> <style type="text/css"> #snake { border: 2px solid black; } </style> <canvas id="snake" width="200" height="200"></canvas> <div><kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd> to play</div> <script type="text/javascript"> var session = pl.create(); session.consult("snake.pl", function() { session.query("snake.", function() { session.answer(); }); }); </script>