/*
Copyright (c) 2014-2015 NicoHood
See the readme for credit to other people.
IRL Receive
Receives IR signals from different protocols and prints them to the Serial monitor.
Choose your protocols that should be decoded. Remove the not used ones to save flash/ram/speed.
You can choose a custom debounce time to not trigger a button two times in a row too fast.
The following pins are usable for PinInterrupt or PinChangeInterrupt*:
Arduino Uno/Nano/Mini: All pins are usable
Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
HoodLoader2: All (broken out 1-7) pins are usable
Attiny 24/44/84: All pins are usable
Attiny 25/45/85: All pins are usable
Attiny 13: All pins are usable
Attiny 441/841: All pins are usable
ATmega644P/ATmega1284P: All pins are usable
PinChangeInterrupts* requires a special library which can be downloaded here:
https://github.com/NicoHood/PinChangeInterrupt
*/
#include <IRLremote.h>
// include PinChangeInterrupt library* BEFORE IRLremote to acces more pins if needed
//#include "PinChangeInterrupt.h"
#include <LedControl.h>
const int DIN = 12; //Led matrix
const int CS = 10; //Led matrix
const int CLK = 11; //Led matrix
// Choose a valid PinInterrupt or PinChangeInterrupt* pin of your Arduino board
#define pinIR 2 //IR sensor
// Choose the IR protocol of your remote. See the other example for this.
CNec IRLremote;
//CPanasonic IRLremote;
//CHashIR IRLremote;
//#define IRLremote Sony12
LedControl lc = LedControl(DIN, CLK, CS,1); //Led matrix
bool AppleDetected = false;
bool IsGamePlaying = false;
int x[64] ={1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int y[64] = {3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int appleX = 7;
int appleY = 3;
int deathX = 0;
int deathY = 0;
byte direction = 0;
byte currentDirection = 0;
byte stoploop = 0;
byte snakelength = 1;
// Invert x // Invert y // Switch x and y // Mode //
// - false = 0 // - false = 0 // - false = 0 // - arduino irl = 0 //
// - true = 1 // - true = 1 // - true = 1 // - arduino simulator = 1 //
int settings[4] = {0,0,0,1};
byte SettingStep = 0;
// Rotation :
// - 90° = 0,1,1
// 0,0,1 for simulator (simulator flips the binary bytes so 11110000 would equal 00001111)
//
// - 180° = 1,1,0
// 0,1,0 for simulator
//
// - 270° = 1,0,1
// 1,1,1 for simulator
//
//when settings[3] == 1 invert x values and invert y value when settings[2] == 1
byte clearmatrix[8]={
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B00000000}; //⬛⬛⬛⬛⬛⬛⬛⬛
byte start[8]={
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B01111010, //⬛🟥🟥🟥🟥⬛🟥⬛
B01000000, //⬛🟥⬛⬛⬛⬛⬛⬛
B01000000, //⬛🟥⬛⬛⬛⬛⬛⬛
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B00000010, //⬛⬛⬛⬛⬛⬛🟥⬛
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B00000000}; //⬛⬛⬛⬛⬛⬛⬛⬛
byte die[8]={
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B11111111, //🟥🟥🟥🟥🟥🟥🟥🟥
B10011001, //🟥⬛⬛🟥🟥⬛⬛🟥
B10011001, //🟥⬛⬛🟥🟥⬛⬛🟥
B11111111, //🟥🟥🟥🟥🟥🟥🟥🟥
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B01011010}; //
byte SettingsIcon[8]={
B10011001, //🟥⬛⬛🟥🟥⬛⬛🟥
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B11011011, //🟥🟥⬛🟥🟥⬛🟥🟥
B11011011, //🟥🟥⬛🟥🟥⬛🟥🟥
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01111110, //⬛🟥🟥🟥🟥🟥🟥⬛
B10011001}; //🟥⬛⬛🟥🟥⬛⬛🟥
byte Pause[8]={
B00000000, //⬛⬛⬛⬛⬛⬛⬛⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B01100110, //⬛🟥🟥⬛⬛🟥🟥⬛
B00000000}; //⬛⬛⬛⬛⬛⬛⬛⬛
void setup()
{
lc.shutdown(0,false); //Led matrix
lc.setIntensity(0,5);
lc.clearDisplay(0);
// Start serial debug output ir reciever
while (!Serial);
Serial.begin(9600);
Serial.println(F("Startup"));
// Start reading the remote. PinInterrupt or PinChangeInterrupt* will automatically be selected
if (!IRLremote.begin(pinIR))
Serial.println(F("You did not choose a valid pin."));
}
void clearm(){
lc.setColumn(0,7,clearmatrix[0]);
lc.setColumn(0,6,clearmatrix[1]);
lc.setColumn(0,5,clearmatrix[2]);
lc.setColumn(0,4,clearmatrix[3]);
lc.setColumn(0,3,clearmatrix[4]);
lc.setColumn(0,2,clearmatrix[5]);
lc.setColumn(0,1,clearmatrix[6]);
lc.setColumn(0,0,clearmatrix[7]);
}
void startw(){
if(settings[2] == 1)
{
lc.setRow(0,7 + (!settings[0] *-7),start[0]);
lc.setRow(0,6 + (!settings[0] *-5),start[1]);
lc.setRow(0,5 + (!settings[0] *-3),start[2]);
lc.setRow(0,4 + (!settings[0] *-1),start[3]);
lc.setRow(0,3 + (!settings[0] * 1),start[4]);
lc.setRow(0,2 + (!settings[0] * 3),start[5]);
lc.setRow(0,1 + (!settings[0] * 5),start[6]);
lc.setRow(0,0 + (!settings[0] * 7),start[7]);
}
else
{
lc.setColumn(0,7 + (settings[1] *-7),start[0]);
lc.setColumn(0,6 + (settings[1] *-5),start[1]);
lc.setColumn(0,5 + (settings[1] *-3),start[2]);
lc.setColumn(0,4 + (settings[1] *-1),start[3]);
lc.setColumn(0,3 + (settings[1] * 1),start[4]);
lc.setColumn(0,2 + (settings[1] * 3),start[5]);
lc.setColumn(0,1 + (settings[1] * 5),start[6]);
lc.setColumn(0,0 + (settings[1] * 7),start[7]);
}
}
void settingsiconw(){
if(settings[2] == 1)
{
lc.setRow(0,7 + (!settings[0] *-7),SettingsIcon[0]);
lc.setRow(0,6 + (!settings[0] *-5),SettingsIcon[1]);
lc.setRow(0,5 + (!settings[0] *-3),SettingsIcon[2]);
lc.setRow(0,4 + (!settings[0] *-1),SettingsIcon[3]);
lc.setRow(0,3 + (!settings[0] * 1),SettingsIcon[4]);
lc.setRow(0,2 + (!settings[0] * 3),SettingsIcon[5]);
lc.setRow(0,1 + (!settings[0] * 5),SettingsIcon[6]);
lc.setRow(0,0 + (!settings[0] * 7),SettingsIcon[7]);
}
else
{
lc.setColumn(0,7 + (settings[1] *-7),SettingsIcon[0]);
lc.setColumn(0,6 + (settings[1] *-5),SettingsIcon[1]);
lc.setColumn(0,5 + (settings[1] *-3),SettingsIcon[2]);
lc.setColumn(0,4 + (settings[1] *-1),SettingsIcon[3]);
lc.setColumn(0,3 + (settings[1] * 1),SettingsIcon[4]);
lc.setColumn(0,2 + (settings[1] * 3),SettingsIcon[5]);
lc.setColumn(0,1 + (settings[1] * 5),SettingsIcon[6]);
lc.setColumn(0,0 + (settings[1] * 7),SettingsIcon[7]);
}
}
void diew(){
if(settings[2] == 1)
{
lc.setRow(0,7 + (!settings[0]+-7),die[0]);
lc.setRow(0,6 + (!settings[0]+-5),die[1]);
lc.setRow(0,5 + (!settings[0]+-3),die[2]);
lc.setRow(0,4 + (!settings[0]+-1),die[3]);
lc.setRow(0,3 + (!settings[0]+ 1),die[4]);
lc.setRow(0,2 + (!settings[0]+ 3),die[5]);
lc.setRow(0,1 + (!settings[0]+ 5),die[6]);
lc.setRow(0,0 + (!settings[0]+ 7),die[7]);
}
else
{
lc.setColumn(0,7 + (settings[1] *-7),die[0]);
lc.setColumn(0,6 + (settings[1] *-5),die[1]);
lc.setColumn(0,5 + (settings[1] *-3),die[2]);
lc.setColumn(0,4 + (settings[1] *-1),die[3]);
lc.setColumn(0,3 + (settings[1] * 1),die[4]);
lc.setColumn(0,2 + (settings[1] * 3),die[5]);
lc.setColumn(0,1 + (settings[1] * 5),die[6]);
lc.setColumn(0,0 + (settings[1] * 7),die[7]);
}
}
void pausem(){
if(settings[2] == 1)
{
lc.setRow(0,7 + (!settings[0] *-7),Pause[0]);
lc.setRow(0,6 + (!settings[0] *-5),Pause[1]);
lc.setRow(0,5 + (!settings[0] *-3),Pause[2]);
lc.setRow(0,4 + (!settings[0] *-1),Pause[3]);
lc.setRow(0,3 + (!settings[0] * 1),Pause[4]);
lc.setRow(0,2 + (!settings[0] * 3),Pause[5]);
lc.setRow(0,1 + (!settings[0] * 5),Pause[6]);
lc.setRow(0,0 + (!settings[0] * 7),Pause[7]);
}
else
{
lc.setColumn(0,7 + (settings[1] *-7),Pause[0]);
lc.setColumn(0,6 + (settings[1] *-5),Pause[1]);
lc.setColumn(0,5 + (settings[1] *-3),Pause[2]);
lc.setColumn(0,4 + (settings[1] *-1),Pause[3]);
lc.setColumn(0,3 + (settings[1] * 1),Pause[4]);
lc.setColumn(0,2 + (settings[1] * 3),Pause[5]);
lc.setColumn(0,1 + (settings[1] * 5),Pause[6]);
lc.setColumn(0,0 + (settings[1] * 7),Pause[7]);
}
}
void loop()
{
if(IsGamePlaying == false)
{
if(settings[2] == 0 && settings[3] == 1)
{
for(int i = 0; i < 8; i++)
{
start[i] = (start[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
die[i] = (die[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
SettingsIcon[i] = (SettingsIcon[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
Pause[i] = (Pause[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
}
}
if(
(settings[0] == 1)||
(settings[1] == 1))
{
for(int i = 0; i < 8; i++)
{
start[i] = (start[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
die[i] = (die[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
SettingsIcon[i] = (SettingsIcon[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
Pause[i] = (Pause[i] * 0x0202020202ULL & 0x010884422010ULL) % 1023;
}
}
Serial.print(settings[0]);Serial.print(",");Serial.print(settings[1]);Serial.print(",");Serial.print(settings[2]);Serial.print(",");Serial.print(settings[3]);Serial.println();
Serial.println(start[1],BIN);
}
while (IsGamePlaying == false)
{
startw();
if (IRLremote.available())
{
//Serial.println(data.command, HEX);
auto data = IRLremote.read(); // Receive the next value
if((data.command == 64 && settings[3] == 0) ||
(data.command == 168 && settings[3] == 1) ||
(data.command == 82 && settings[3] == 1)) // key pause
{
IsGamePlaying=true;
};
};
delay(100);
};
stoploop = 0;
Serial.println(currentDirection);
while (stoploop < 15)
{
// Check if new IR protocol data is available
if (IRLremote.available())
{
// Get the new data from the remote
auto data = IRLremote.read();
//Serial.println(data.command);
//Serial.println();
if(((data.command == 8 && settings[3] == 0) || (data.command == 16 && settings[3] == 1)) && currentDirection != 0) // key 4 (Left)
{
//Serial.println("LEFT");
direction = 2;
}
else if ((data.command == 90 && (settings[3] == 0 || settings[3] == 1)) && currentDirection != 2) // key 6 (Right)
{
//Serial.println("RIGHT");
direction = 0;
}
else if ((data.command == 24 && (settings[3] == 0 || settings[3] == 1)) && currentDirection != 1) // key 2 (Up)
{
//Serial.println("UP");
direction = 3;
}
else if (((data.command == 82 && settings[3] == 0) || (data.command == 74 && settings[3] == 1)) && currentDirection != 3) // key 8 (Down)
{
//Serial.println("DOWN");
direction = 1;
} else if((data.command == 64 && settings[3] == 0) || (data.command == 168 && settings[3] == 1) || (data.command == 82 && settings[3] == 1)) // key pause
{
//Serial.println("PAUSE");
IsGamePlaying = false;
while (IsGamePlaying == 0)
{
pausem();
if (IRLremote.available())
{
//Serial.println(data.command);
auto data = IRLremote.read(); // Receive the next value
if((data.command == 64 && settings[3] == 0) || (data.command == 168 && settings[3] == 1) || (data.command == 82 && settings[3] == 1)) // key pause
{
//Serial.println("PLAY");
IsGamePlaying = true;
}
else if((data.command == 34 && settings[3] == 1))
{
SettingStep = 0;
while (IsGamePlaying == 0)
{
if (IRLremote.available())
{
auto data = IRLremote.read(); // Receive the next value
if((data.command == 34 && settings[3] == 1))
{
IsGamePlaying = true;
}
switch(data.command){
case 104: //0
settings[SettingStep]=0;
SettingStep = SettingStep + 1;
break; case 48: //1
settings[SettingStep]=1;
SettingStep = SettingStep + 1;
break; case 24: //2
settings[SettingStep]=2;
SettingStep = SettingStep + 1;
break; default : //no number
break;
}
}
}
IsGamePlaying = false;
}
}
delay(100);
}
}
}
//delay(8);
//delay(30);
/*good luck trying to figure how this works
btw it switchs the setting[0] for settings[1] and appleX for appleY when the x and y coordonates of the matrix are switched
then it will just do 7-(value x or y here) basically inverting them (Ex: 0 becomes 7, 2 becomes 5, etc...)*/
//(0,0,0) = nothing
//(1,0,0) = invert x values
//(0,1,0) = invert y values
//(0,0,1) = switch x and y
for(int loopn = 3;loopn > 0;loopn = loopn - 1)
{
delay(8);
if(settings[3] == 0)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * settings[0] + appleX + appleX * -2 * settings[0],
7 * settings[1] + appleY + appleY * -2 * settings[1] ,true);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * settings[0] + appleY + appleY * -2 * settings[0],
7 * settings[1] + appleX + appleX * -2 * settings[1] ,true);
}
}
else if(settings[3] == 1)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * not(settings[0]) + appleX + appleX * -2 * not(settings[0]),
7 * settings[1] + appleY + appleY * -2 * settings[1] ,true);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * not(settings[0]) + appleY + appleY * -2 * not(settings[0]),
7 * settings[1] + appleX + appleX * -2 * settings[1] ,true);
}
}
delay(2);
if(settings[3] == 0)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * settings[0] + appleX + appleX * -2 * settings[0],
7 * settings[1] + appleY + appleY * -2 * settings[1] ,false);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * settings[0] + appleY + appleY * -2 * settings[0],
7 * settings[1] + appleX + appleX * -2 * settings[1] ,false);
}
}
else if(settings[3] == 1)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * not(settings[0]) + appleX + appleX * -2 * not(settings[0]),
7 * settings[1] + appleY + appleY * -2 * settings[1] ,false);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * not(settings[0]) + appleY + appleY * -2 * not(settings[0]),
7 * settings[1] + appleX + appleX * -2 * settings[1] ,false);
}
}
}
stoploop++;
}
//clear the screen
clearm();
//new test for death is here
if (direction == 0)
{
currentDirection = 0;
//Serial.println("right");
if(x[0]>=7)
{
deathX = 0;
}else
{
deathX = x[0]+1;
}
}
if (direction == 1)
{
currentDirection = 1;
//Serial.println("down");
if(y[0]<=0)
{
deathY = 7;
}else
{
deathY = y[0] - 1;
}
}
if (direction == 2)
{
currentDirection = 2;
//Serial.println("left");
if(x[0]<=0)
{
deathX = 7;
}else
{
deathX = x[0] - 1;
}
}
if (direction == 3)
{
currentDirection = 3;
//Serial.println("up");
if(y[0]>=7)
{
deathY = 0;
}else
{
deathY = y[0]+1;
}
}
for (int i = 1; i < snakelength ; i++)
{
if(x[i] == deathX && y[i] == deathY)
{
IsGamePlaying = false;
}
}
if (IsGamePlaying == 0)
{
Serial.println("DEATH");
diew();
while(IsGamePlaying == 0)
{
// Check if new IR protocol data is available
if (IRLremote.available())
{
// Get the new data from the remote
auto data = IRLremote.read();
//Serial.println(data.command, HEX);
if((data.command == 64 && settings[3] == 0) || ((data.command == 82 || data.command == 168) && settings[3] == 1)) // key pause
{
AppleDetected = false;
IsGamePlaying = true;
x[0] = 1;
y[0] = 3;
appleX = 7;
appleY = 3;
deathX = 0;
deathY = 0;
direction = 0;
currentDirection = 0;
stoploop = 0;
snakelength = 1;
clearm();
}
}
delay(100);
}
}
IsGamePlaying = true;
//display new frame
if(AppleDetected == true)
{
for (byte i = snakelength; i > 0; i = i - 1)
{
x[i] = x[i-1];
y[i] = y[i-1];
}
//snakelength = snakelength + 1;
}
else if (AppleDetected = false)
{
for (byte i = snakelength - 1; i > 0; i = i - 1)
{
x[i] = x[i-1];
y[i] = y[i-1];
}
}
if (direction == 0)
{
//Serial.println("right");
if(x[0]>=7)
{
x[0] = 0;
}else
{
x[0] = x[0]+1;
}
}
if (direction == 1)
{
//Serial.println("down");
if(y[0]<=0)
{
y[0] = 7;
}else
{
y[0] = y[0] - 1;
}
}
if (direction == 2)
{
//Serial.println("left");
if(x[0]<=0)
{
x[0] = 7;
}else
{
x[0] = x[0] - 1;
}
}
if (direction == 3)
{
//Serial.println("up");
if(y[0]>=7)
{
y[0] = 0;
}else
{
y[0] = y[0]+1;
}
}
for(byte i = 0; i < snakelength; i++)
{
if(settings[3] == 0)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * settings[0] + x[i] + y[i] * -2 * settings[0],
7 * settings[1] + y[i] + y[i] * -2 * settings[1] ,true);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * settings[0] + y[i] + y[i] * -2 * settings[0],
7 * settings[1] + x[i] + x[i] * -2 * settings[1] ,true);
}
}
else if(settings[3] == 1)
{
if(settings[2] == 0)
{
lc.setLed(0,7 * not(settings[0]) + x[i] + x[i] * -2 * not(settings[0]),
7 * settings[1] + y[i] + y[i] * -2 * settings[1] ,true);
}
else if (settings[2] == 1)
{
lc.setLed(0,7 * not(settings[0]) + y[i] + y[i] * -2 * not(settings[0]),
7 * settings[1] + x[i] + x[i] * -2 * settings[1] ,true);
}
}
}
//put apple position here
if (appleX == x[0] && appleY == y[0])
{
appleX = random(0,7);
appleY = random(0,7);
for (int i = 0; i < snakelength; i++)
{
if(appleX == x[i] && appleY == y[i]) //is the apple on the snake's tail
{
appleX = random(0,7);
appleY = random(0,7);
i = 0;
}
}
snakelength = snakelength + 1;
AppleDetected = true;
}
//lc.setLed(0,7-appleX,appleY,true);
// Serial.println();
//
// for (int i = 0; snakelength-1 > i; i++)
// {
// Serial.print(x[i]);
// Serial.print(",");
// }
//
// Serial.println();
//
// for (int i = 0; snakelength-1 > i; i++)
// {
// Serial.print(y[i]);
// Serial.print(",");
// }
//
// Serial.println();
}