/examples/Snake/game.d
D | 133 lines | 103 code | 30 blank | 0 comment | 32 complexity | 215ffc2eb9e7676ccb661b08915a7850 MD5 | raw file
1import djehuty; 2 3import io.console; 4import math.random; 5 6import constants; 7import posn; 8import snake; 9import win; 10 11enum DeathBy { 12 NotDead, 13 CollisionSelf, 14 CollisionPortal, 15 CollisionReverse, 16 Quit, 17} 18 19class SnakeGame { 20 this(SnakeWindow win_n) { 21 _win = win_n; 22 23 _max_x = _win.width - 1; 24 _max_y = _win.height - 1; 25 26 _rand = new Random(); 27 28 Dir d = cast(Dir)_rand.choose([Dir.Up, Dir.Down, Dir.Left, Dir.Right]); 29 _snake = new Snake(_max_x, _max_y, d); 30 } 31 32 void turn(Dir d) { 33 if (_snake.direction == -d) { 34 _snake.reverse(); 35 _rev = true; 36 } 37 _snake.direction = d; 38 } 39 40 Snake snake() { 41 return _snake.dup; 42 } 43 44 void frame() { 45 if (_snake is null || _win is null) 46 return; 47 48 Posn oldTail = _snake.tail.dup; 49 50 MoveResult move = _snake.slither(); 51 52 if (_snake.length > 1) { 53 drawTile(_snake.neck, Tile.Block, TileColor.Block); 54 } 55 56 if (_snake.length <= 1 || _snake.tail != oldTail) { 57 drawTile(oldTail, Tile.Void); 58 } 59 60 drawTile(_snake.head, Tile.Head, TileColor.Head); 61 62 if (move == MoveResult.CollisionSelf) { 63 if (_rev) { 64 _win.gameOver(DeathBy.CollisionReverse); 65 } else { 66 _win.gameOver(DeathBy.CollisionSelf); 67 } 68 return; 69 } else if (_portal !is null && _portal == _snake.head) { 70 _win.gameOver(DeathBy.CollisionPortal); 71 return; 72 } else if (_food !is null && _food == _snake.head) { 73 _snake.head.moveTo(_portal); 74 75 drawTile(_food, Tile.Void); 76 77 _food = null; 78 _portal = null; 79 80 _snake.elongate(cast(uint)_rand.next(Growth.Min, Growth.Max)); 81 } 82 83 if (_food is null) { 84 _food = positionItem(); 85 drawTile(_food, Tile.Food, TileColor.Food); 86 } 87 if (_portal is null) { 88 _portal = positionItem(); 89 drawTile(_portal, Tile.Portal, TileColor.Portal); 90 } 91 92 _rev = false; 93 94 _win.setSpeed(); 95 } 96 97private: 98 void drawTile(Posn p, Tile t) { 99 Console.position(p.x, p.y); 100 Console.putChar(t); 101 } 102 103 void drawTile(Posn p, Tile t, TileColor c) { 104 Console.setColor(c); 105 drawTile(p, t); 106 } 107 108 Posn positionItem() { 109 Posn ret; 110 while (ret is null) { 111 auto r = new Posn(cast(uint)_rand.next(_max_x + 1), cast(uint)_rand.next(_max_y + 1)); 112 if (_snake !is null && _snake == r) 113 continue; 114 if (_food !is null && _food == r) 115 continue; 116 if (_portal !is null && _portal == r) 117 continue; 118 ret = r; 119 } 120 return ret; 121 } 122 123 uint _max_x, _max_y; 124 125 bool _rev; 126 127 SnakeWindow _win; 128 Random _rand; 129 130 Snake _snake; 131 Posn _food, _portal; 132} 133