Skip to content

Instantly share code, notes, and snippets.

@Tapped
Created May 19, 2012 03:37
Show Gist options
  • Save Tapped/2728897 to your computer and use it in GitHub Desktop.
Save Tapped/2728897 to your computer and use it in GitHub Desktop.
Snake on novation launchpad
#include <iostream>
#include <conio.h>
#include <cstdio>
#include <windows.h>
#include <mmsystem.h>
#include <cmath>
#include <ctime>
//Snake directions
enum {UP, DOWN, LEFT, RIGHT};
//Easy way to convert between binary and int
union Message{ unsigned long word; char data[4];};
Message message;
//Switch buffer of launchpad
void SwitchBuffer();
//Set the led specified by cell green
void SetLedOn(int cell);
//Set the led specified by cell, with a color
void SetLedOn(int color, int cell);
//Set the led specified by cell off
void SetLedOff(int cell);
//Find empty space in the grid
int FindEmptySpace(int cell);
//Move a cell, and prevent it from going out of grid
int Move(int cell, int dirCode);
//Move the snake
void MoveSnake();
int points = 0;
int snakeLength = 2;
int snakeDir;
int snakeCells[64];
int foodCell;
int snakeOldCell[64];
bool gameover = false;
int flag;
HMIDIOUT device;
using namespace std;
int main()
{
srand((unsigned)time(0));
flag = midiOutOpen(&device, 1, 0, 0, CALLBACK_NULL);
if (flag != MMSYSERR_NOERROR) {
cout << "Error opening MIDI Output.\n";
return 1;
}
cout << "Snake, how long can you become? Use WASD to move, and press q to quit.\nPlease press enter to start.\n";
cin.get();
snakeCells[0] = 4;
snakeDir = DOWN;
foodCell = FindEmptySpace(rand() % 64);
bool shiftDir = false;
int pos = -1;
SwitchBuffer();
while(1)
{
if(_kbhit())
{
char key = _getch();
if(key == 'q')
break;
else if(key == 's')
snakeDir = DOWN;
else if(key == 'w')
snakeDir = UP;
else if(key == 'a')
snakeDir = LEFT;
else if(key == 'd')
snakeDir = RIGHT;
}
if(!gameover)
{
MoveSnake();
SetLedOn(63, foodCell);
SwitchBuffer();
Sleep(150);
}
else
{
if(!shiftDir)
++pos;
else
--pos;
SetLedOn(62, pos);
if(!shiftDir && pos % 8 == 7)
{
pos += 9;
shiftDir = true;
}
else if(shiftDir && pos % 8 == 0)
{
pos += 7;
shiftDir = false;
}
SwitchBuffer();
Sleep(20);
}
}
message.data[0] = (char)0xB0;
message.data[1] = (char)0x00;
message.data[2] = (char)0x00;
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
midiOutReset(device);
midiOutClose(device);
return 0;
}
void SwitchBuffer()
{
static bool switchBuffer;
message.data[0] = (char)0xB0;
message.data[1] = (char)0x00;
if(!switchBuffer)
{
message.data[2] = 0x31;
switchBuffer = true;
}
else
{
message.data[2] = 0x34;
switchBuffer = false;
}
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
}
void SetLedOn(int cell)
{
message.data[0] = (char)0x90;
message.data[1] = (int)(cell % 8) + (((int)cell / 8) * 16);
message.data[2] = (char)48;
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
}
void SetLedOn(int color, int cell)
{
message.data[0] = (char)0x90;
message.data[1] = (int)(cell % 8) + (((int)cell / 8) * 16);
message.data[2] = (char)color & (char)0x73;
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
}
void SetLedOff(int cell)
{
message.data[0] = (char)0x90;
message.data[1] = (int)(cell % 8) + (((int)cell / 8) * 16);
message.data[2] = 0;
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
}
int FindEmptySpace(int cell)
{
for(int i = 0;i < snakeLength;++i)
{
if(snakeCells[i] == cell)
{
return FindEmptySpace(rand() % 64);
}
}
return cell;
}
void MoveSnake()
{
int oldCell = snakeCells[0];
snakeCells[0] = Move(snakeCells[0], snakeDir);
snakeOldCell[0] = oldCell;
SetLedOn(15, snakeCells[0]);
//Hide old cells
if(oldCell != snakeCells[0])
{
SetLedOff(oldCell);
}
for(int i = 1;i < snakeLength;++i)
{
oldCell = snakeCells[i];
snakeCells[i] = snakeOldCell[i - 1];
snakeOldCell[i] = oldCell;
//Check for collision with head
if(snakeCells[0] == snakeCells[i])
{
message.data[0] = (char)0xB0;
message.data[1] = (char)0x00;
message.data[2] = (char)0x00;
flag = midiOutShortMsg(device, message.word);
if(flag != MMSYSERR_NOERROR)
{
cout << "Warning: MIDI Output is not open.\n";
}
gameover = true;
return;
}
SetLedOn(snakeCells[i]);
if(oldCell != snakeCells[i])
{
SetLedOff(oldCell);
}
}
//Check for collision with food
if(snakeCells[0] == foodCell)
{
snakeCells[snakeLength] = snakeOldCell[snakeLength - 1];
snakeOldCell[snakeLength] = snakeOldCell[snakeLength - 1];
foodCell = FindEmptySpace(rand() % 64);
++snakeLength;
points += 10;
system("cls");
cout << "You have " << points << " points." << "\n";
}
}
int Move(int cell, int dirCode)
{
int column = cell % 8;
int row = cell / 8;
if(dirCode == DOWN)
{
if(row + 1 > 7)
return cell;
else
return cell + 8;
}
else if(dirCode == UP)
{
if(row - 1 < 0)
return cell;
else
return cell - 8;
}
else if(dirCode == LEFT)
{
if(column - 1 < 0)
return cell;
else
return cell - 1;
}
else if(dirCode == RIGHT)
{
if(column + 1 > 7)
return cell;
else
return cell + 1;
}
return cell;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment