int LEDshift = 0x0001; // przechowywanie wzoru LED
boolean RightLeft = false; // true dla kierunku w prawo
boolean Win = false; // wartość true oznacza stan wygranej
boolean button = false; // flaga oznaczająca naciśnięcie przycisku
byte level = 0; // przechowywanie bieżącego poziomu
byte HIout , LOWout; // przechowywanie stanu diody do wysłania

void setup() {
DDRD = DDRD | B11111000; // piny 3-7 
DDRB = DDRB | B00111111; // piny 8 - 13
digitalWrite(2,HIGH);  
}
void loop() {
detachInterrupt(0);

if (button == true){
 checkWin();
}
moveLED();
attachInterrupt(0, Button, LOW);
delay  ( 100 - (level*6)); 
}

void moveLED(){
if ( LEDshift & 0x0002){
RightLeft = false;
}
if (LEDshift & 0x0800){
RightLeft = true;
}
if (!RightLeft ){
LEDshift = LEDshift  << 1;
}
if (RightLeft){
LEDshift = LEDshift   >> 1;
}
dispayLED();    
}

void dispayLED(){
LOWout = (LEDshift & 0x003E) << 2 ;
HIout =  (LEDshift & 0x0FC0) >> 6 ;
PORTD = ~LOWout;
PORTB = ~HIout;
}

void Button(){
while ( digitalRead(2)== LOW){
button = true; 
if ((LEDshift & 0x0040)){
Win = true;
} 
else {
Win = false;
}
}
}

void checkWin(){
if (Win){
if (level < 10) {
flashWin();
}
if (level >= 10){
BigWin();
}
IncreaseLevel();
}
if (!Win){
notWin(); 
}
resetPlay ();
}


void flashWin(){
delay (100);
LEDshift = 0xFAAA;
for ( int i = 0 ; i < 10; i++){
LEDshift = ~LEDshift;
dispayLED();
delay (100);
} 
}

void BigWin (){
flashWin();
for (int i = 0 ; i < 4 ; i++){
LEDshift = 0x0040;
dispayLED();
delay (100);
for (int i = 0 ; i < 6 ; i++){
LEDshift = LEDshift  | (1<< 5 - i); 
LEDshift = LEDshift  | (1<< 7 + i); 
dispayLED();
delay (25);
}
}
flashWin();  
}

void notWin(){
level = 0;
delay (100);
LEDshift = 0x0001;
for ( int i = 0 ; i < 11; i++){ 
LEDshift = LEDshift << 1;
LEDshift++;
dispayLED();
delay (100);
} 
}

void DspLevel(){
LEDshift = 0x0000;
for (int i = 0 ; i <= level ; i++){
LEDshift = LEDshift | 0x1000;
LEDshift = LEDshift >> 1 ; 
dispayLED();
delay (50); 
} 
delay (500);
}

void resetPlay (){
DspLevel();
Win = false;
button = false;
LEDshift = 0x0001;
RightLeft = false;
}

void IncreaseLevel(){
level++;
level = level & 0x0F; // reset poziomu, jeżeli jest większy niż 15
} 
