/examples/Snake/game.d

http://github.com/wilkie/djehuty · D · 133 lines · 103 code · 30 blank · 0 comment · 32 complexity · 215ffc2eb9e7676ccb661b08915a7850 MD5 · raw file

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