You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
5.7 KiB
C#

using IntelOrca.Launchpad;
using System;
using System.Collections.Generic;
using System.Linq;
namespace IntelOrca.LaunchpadTests
{
struct Point
{
public Point(int x, int y)
: this()
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
}
class Snake
{
private LaunchpadDevice mLaunchpadDevice;
private Random mRandom = new Random();
private long mCurrentTicks = 0;
private Point[] mBody;
private Point mDirection;
private bool mFoodActive;
private Point mFood;
private bool snakeFrozen = false;
private bool gameEnd = false;
public Snake(LaunchpadDevice device)
{
mLaunchpadDevice = device;
mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
Restart();
}
private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
{
if (e.Type == ButtonType.Grid) {
mFood.X = e.X;
mFood.Y = e.Y;
mFoodActive = true;
}
if (e.Type == ButtonType.Side)
{
if(e.SidebarButton == SideButton.Solo)
{
if (snakeFrozen)
snakeFrozen = false;
else
snakeFrozen = true;
}
}
if (e.Type == ButtonType.Side)
{
if (e.SidebarButton == SideButton.Arm)
{
mLaunchpadDevice.Reset();
gameEnd = true;
}
}
}
public void Run()
{
// Kontrolle des internen Ticks (6*12 Frames werden pro "nächster" aktion verstreichen gelassen)
long last_tick = Environment.TickCount;
long delay = 12;
delay = 12 * 6;
// GameLoop
while (true && !gameEnd) {
if (Environment.TickCount - last_tick < delay)
continue;
mCurrentTicks += Environment.TickCount - last_tick;
last_tick = Environment.TickCount;
// Spielroutine (mit "Pause" Funktion [bei einem Snake Spiel natürlich quasi cheaten xD])
if(!snakeFrozen)
{
// Update aller Positionen
Update();
// Neu Zeichnen des Brettes
Draw();
}
}
}
private void Update()
{
SetSnakeDirection();
MoveSnake();
}
private void Draw()
{
ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
// Draw snake
foreach (Point p in mBody)
if (InBounds(p))
greengrid[p.X, p.Y] = ButtonBrightness.Full;
if (InBounds(mBody[0]))
redgrid[mBody[0].X, mBody[0].Y] = ButtonBrightness.Full;
// Draw food
if (mFoodActive)
redgrid[mFood.X, mFood.Y] = ButtonBrightness.Full;
// Invalidate (Neu Zeichnen aller Kacheln anhand was in red/greengrid drin steht
for (int y = 0; y < 8; y++)
for (int x = 0; x < 8; x++)
mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
// Refresh um neue Konstellation anzuzeigen
mLaunchpadDevice.Refresh();
}
private void Restart()
{
mBody = new Point[4];
for (int y = 8; y < 8 + 4; y++)
mBody[y - 8] = new Point(3, y);
mDirection = new Point(0, -1);
mFoodActive = false;
// PlaceFood();
}
private void MoveSnake()
{
// Nachrücken aller Steine nach vorne (Letzer wird entfernt)
for (int i = mBody.Length - 1; i > 0; i--)
mBody[i] = mBody[i - 1];
//Kopf wird in Richtung bewegt
mBody[0].X += mDirection.X;
mBody[0].Y += mDirection.Y;
// Wenn
for (int i = 1; i < mBody.Length; i++) {
if (mBody[0].X == mBody[i].X && mBody[0].Y == mBody[i].Y)
Restart();
}
if (mBody[0].X == mFood.X && mBody[0].Y == mFood.Y) {
mFoodActive = false;
ExtendSnake();
// PlaceFood();
}
}
public void SetSnakeDirection()
{
bool danger = false;
Point head = mBody[0];
if (head.X == 7 && mDirection.X > 0) {
if (head.Y < 7) mDirection = new Point(0, 1);
else mDirection = new Point(0, -1);
danger = true;
} else if (head.X == 0 && mDirection.X < 0) {
if (head.Y < 7) mDirection = new Point(0, 1);
else mDirection = new Point(0, -1);
danger = true;
}
if (head.Y == 7 && mDirection.Y > 0) {
if (head.X < 7) mDirection = new Point(1, 0);
else mDirection = new Point(-1, 0);
danger = true;
} else if (head.Y == 0 && mDirection.Y < 0) {
if (head.X < 7) mDirection = new Point(1, 0);
else mDirection = new Point(-1, 0);
danger = true;
}
if (!danger && mFoodActive) {
if (mDirection.X != 0) {
if (mBody[0].X == mFood.X) {
if (mBody[0].Y < mFood.Y) mDirection = new Point(0, 1);
else mDirection = new Point(0, -1);
}
} else {
if (mBody[0].Y == mFood.Y) {
if (mBody[0].X < mFood.X) mDirection = new Point(1, 0);
else mDirection = new Point(-1, 0);
}
}
}
}
private void ExtendSnake()
{
Point[] newBody = new Point[mBody.Length + 1];
newBody[0] = mBody[0];
Array.Copy(mBody, 0, newBody, 1, mBody.Length);
mBody = newBody;
}
private void PlaceFood()
{
List<Point> possiblePlaces = new List<Point>();
for (int y = 0; y < 8; y++)
for (int x = 0; x < 8; x++)
if (!mBody.Contains(new Point(x, y)))
possiblePlaces.Add(new Point(x, y));
int index = mRandom.Next(possiblePlaces.Count);
mFood = possiblePlaces[index];
}
private bool InBounds(Point p)
{
return (p.X >= 0 && p.Y >= 0 && p.X < 8 && p.Y < 8);
}
}
}