root/trunk/qd/snake.d

Revision 369, 2.1 kB (checked in by FeepingCreature, 4 years ago)
  • Added a Snakes impl
Line 
1 module snake;
2 import qd, tools.base, tools.mersenne;
3
4 struct pt { int x, y; }
5 struct Snake { pt[] fields; }
6
7 import tools.log;
8 class Field {
9   enum State { empty, apple, snake }
10   State[] board;
11   int width, height;
12   mixin This!("width, height; #board.length=width*height; #snake.fields ~= pt(width/2, height/2); ");
13   State getState(pt p) { return board[p.y*width+p.x]; }
14   void setState(pt p, State s) { board[p.y*width+p.x] = s; }
15   void updateState() {
16     foreach (ref entry; board) if (entry != State.apple) entry = State.empty;
17     foreach (part; snake.fields) setState(part, State.snake);
18   }
19   enum Direction { up, left, down, right }
20   Direction dir;
21   Snake snake;
22   bool outside(pt p) { return p.x < 0 || p.y < 0 || p.x !< width || p.y !< height; }
23   void spawnApple() {
24     pt rp;
25     do { rp = pt(rand % width, rand % height); } while (getState(rp) != State.empty);
26     setState(rp, State.apple);
27   }
28   void step() {
29     scope(exit) updateState;
30     pt next = snake.fields[$-1];
31     [{next.y --; }, {next.x --; }, {next.y ++; }, {next.x ++; }][dir]();
32     if (outside(next)) throw new Exception("You have left the board!");
33     if (getState(next) == State.snake) throw new Exception("You have lost!");
34     snake.fields ~= next;
35     if (getState(next) != State.apple) with (snake) fields = fields[1 .. $];
36     else spawnApple;
37   }
38   void draw() {
39     line(10, 10, 10+width*16, 10+height*16, Box=White);
40     for (int x = 0; x < width; ++x)
41       for (int y = 0; y < height; ++y)
42         switch (getState(pt(x, y))) {
43           case State.apple: circle(10+x*16+8, 10+y*16+8, 7.5, Fill=Red); break;
44           case State.snake: circle(10+x*16+8, 10+y*16+8, 7.5, Fill=Green); break;
45           default: break;
46         }
47   }
48 }
49
50 import tools.time;
51 void main() {
52   screen(640, 480);
53   auto field = new Field(39, 29);
54   for (int i = 0; i < 8; ++i) field.spawnApple;
55   while (true) {
56     cls;
57     events;
58     foreach (i, k; [SDLKey.Up, SDLKey.Left, SDLKey.Down, SDLKey.Right])
59       if (key.pressed(k)) field.dir = cast(Field.Direction) i;
60     field.step; field.draw;
61     flip;
62     sleep(0.3);
63   }
64 }
Note: See TracBrowser for help on using the browser.