public unsafe bool Update() { // Workout where new head of snake will go var newHeadX = HeadX; var newHeadY = HeadY; switch (_direction) { case Direction.Left: newHeadX--; break; case Direction.Right: newHeadX++; break; case Direction.Up: newHeadY--; break; case Direction.Down: newHeadY++; break; } newHeadX = GraphicHelper.WrapAround(newHeadX, Graphics.ScreenWidth / 2); newHeadY = GraphicHelper.WrapAround(newHeadY, Graphics.ScreenHeight); // Does new head hit body of snake? if (GetBoardItem(newHeadX, newHeadY)) { return(false); } // Add new head _snakeHead++; _snakeHead %= _maxLength; _snakeXs[_snakeHead] = newHeadX; _snakeYs[_snakeHead] = newHeadY; // Move tail of snake if (_actualLength == _desiredLength) { _snakeTail++; _snakeTail %= _maxLength; } else { _actualLength++; } return(true); }
private unsafe Result Run(/* ref FrameBuffer fb */) { const int MAX_LENGTH = 80; var snakeXs = stackalloc int[MAX_LENGTH]; var snakeYs = stackalloc int[MAX_LENGTH]; // Initialise Xs & Ys to -1 for (int i = 0; i < MAX_LENGTH; i++) { snakeXs[i] = -1; snakeYs[i] = -1; } const int bits = 128 * 48; const int boardSize = (bits) / 32; var board = stackalloc int[boardSize]; for (int i = 0; i < 192; i++) { board[i] = 0; } var startX = GraphicHelper.WrapAround((byte)_random.Next(), Graphics.ScreenWidth / 2); var startY = GraphicHelper.WrapAround((byte)_random.Next(), Graphics.ScreenHeight); var s = new Snake(startX, startY, snakeXs, snakeYs, board, MAX_LENGTH, (Direction)(_random.Next() % 4)); MakeFood(s, out int foodX, out int foodY); SetPixel(foodX, foodY, Color.White); SetPixel(s.HeadX, s.HeadY, Color.White); SetBoardItem(board, s.HeadX, s.HeadY, true); while (true) { if (Console.KeyAvailable) { ConsoleKeyInfo ki = Console.ReadKey(true); int kc = ki.KeyChar; switch (kc) { case 10: s.SetCourse(Direction.Down); break; case 91: s.SetCourse(Direction.Up); break; case 8: s.SetCourse(Direction.Left); break; case 9: s.SetCourse(Direction.Right); break; } } var oldTailX = s.TailX; var oldTailY = s.TailY; if (!s.Update()) { return(Result.Loss); } SetPixel(oldTailX, oldTailY, Color.Black); SetPixel(s.HeadX, s.HeadY, Color.White); SetBoardItem(board, oldTailX, oldTailY, false); SetBoardItem(board, s.HeadX, s.HeadY, true); if (s.HitTest(foodX, foodY)) { if (s.Extend()) { MakeFood(s, out foodX, out foodY); SetPixel(foodX, foodY, Color.White); } else { return(Result.Win); } } Thread.Sleep(30); } }