//befor setup_ Working Memory
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <pitches.h>
const int rs = 7, en = 6, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {A7,A6,A5,A4};
byte colPins[COLS] = {A3,A2,A1,A0};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
int point = 0;
int mainmode =0;
int gamemode = 1;
int difficulty =1;
int saved_num[20];
int given_num[20];
int buzzer_num[20];
int rand_num[20];
int buzzer_i =0;
int buzzer =0;
int rand_ =0;
int number = 0;
int number_row=0;
int n = 0;
int n_holder=0;
int n_timer=0;
int i = 0;
int judge = 1;
int mistakes= 0;
long int mistakes_pattern= 2;
long int the_number = 2;
long int the_4_5_number = 2;
long int data[10];
/*
hello guys im benyamin :)
im here to say that the data collecting systen have a bug that i couldent fix...
heres the list:
if the number gets too big then it dosent fit in the variables...
thts because of the type of the variable...
as you can see i have already make the mistakes_pattern and the_number a long int variables...
i tried to make them long long int but that dosent work :|
so...
for now stick to the easy and medium mode and not hard mode...
*/
int choose_difficulty(int gamemode){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("choose difficulty:");
lcd.setCursor(4,1);
lcd.print("easy with[1]");
lcd.setCursor(3,2);
lcd.print("normal with[2]");
lcd.setCursor(4,3);
lcd.print("hard with[3]");
while(true) {
char key = keypad.getKey();
if(key) {
if(key == '1') {
data[2]=1;
return 4;
}
else if(key == '2'){
data[2]=2;
return 8;
}
else if(key == '3'){
data[2]=3;
return 12;
}
}
}
}
void giving_data(){
data[3]=point+1;
data[4]=n;
data[5]=the_number;
data[6]=mistakes_pattern;
data[7]=mistakes;
for(int i=0;i<8;i++){
Serial.print(data[i]);
Serial.print("\n");
}
if(gamemode==4 || gamemode==5){
data[8]=the_4_5_number;
Serial.print(data[8]);
Serial.print("\n");
}
}
//--------------------------------------------------------
//befor setup_ LED Matrix
#define CLK 16
#define DIN 14
#define CS 15
#define X_SEGMENTS 4
#define Y_SEGMENTS 4
#define NUM_SEGMENTS (X_SEGMENTS * Y_SEGMENTS)
// a framebuffer to hold the state of the entire matrix of LEDs
// laid out in raster order, with (0, 0) at the top-left
byte fb[8 * NUM_SEGMENTS];
void shiftAll(byte send_to_address, byte send_this_data)
{
digitalWrite(CS, LOW);
for (int i = 0; i < NUM_SEGMENTS; i++) {
shiftOut(DIN, CLK, MSBFIRST, send_to_address);
shiftOut(DIN, CLK, MSBFIRST, send_this_data);
}
digitalWrite(CS, HIGH);
}
//--------------------------------------------------------
void setup() {
//setup_LCD Matrix
Serial.begin(115200);
pinMode(CLK, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CS, OUTPUT);
shiftAll(0x0f, 0x00); //display test register - test mode off
shiftAll(0x0b, 0x07); //scan limit register - display digits 0 thru 7
shiftAll(0x0c, 0x01); //shutdown register - normal operation
shiftAll(0x0a, 0x0f); //intensity register - max brightness
shiftAll(0x09, 0x00); //decode mode register - No decode
//--------------------------------------------------------
//setup_Working Memory
pinMode(13, OUTPUT);
unsigned long seed = 0;
for(int i = A0; i <= A5; i++) {
seed += analogRead(i);
}
randomSeed(seed);
Serial.begin(9600);
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("choose the main mode");
lcd.setCursor(2,2);
lcd.print("LCD mode with[1]");
lcd.setCursor(1,3);
lcd.print("MATRIX mode with[2]");
while(true) {
char key = keypad.getKey();
if(key) {
if(key == '1') {
data[0]=1;
mainmode=1;
break;
}
else if(key == '2'){
data[0]=2;
mainmode=2;
break;
}
}
}
if(mainmode==1){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("WORKING MEMORY TEST!");
lcd.setCursor(1,2);
lcd.print("by: Benyamin,Roham");
lcd.setCursor(2,3);
lcd.print("and Amirhossien!");
delay(3000);
lcd.clear();
lcd.setCursor(1,0);
lcd.print("choose a gamemode:");
lcd.setCursor(0, 1);
lcd.print(" mode [1] mod [2] ");
lcd.setCursor(0, 2);
lcd.print(" mode [3] mod [4] ");
lcd.setCursor(0, 3);
lcd.print(" mode [5] mod [6] ");
while(true) {
char key = keypad.getKey();
if(key) {
if(key == '1') {
gamemode = 1;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 1");
lcd.setCursor(0, 1);
lcd.print("try to memorize");
lcd.setCursor(2, 2);
lcd.print("THE WHOLE NUMBERS!");
delay(3000);
break;
}
else if(key == '2') {
gamemode = 2;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 2");
lcd.setCursor(0, 1);
lcd.print("try to memorize the");
lcd.setCursor(0, 2);
lcd.print("number but BACKWARD!");
delay(3000);
break;
}
else if(key == '3') {
gamemode = 3;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 3");
lcd.setCursor(0, 1);
lcd.print("try to memorize");
lcd.setCursor(0, 2);
lcd.print("as much as you can!");
delay(3000);
break;
}
else if(key == '4') {
gamemode = 4;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 4");
lcd.setCursor(0, 1);
lcd.print("memorise the number");
lcd.setCursor(2, 2);
lcd.print("then tell us the ");
lcd.setCursor(2, 3);
lcd.print("specified digits");
delay(3000);
break;
}
else if(key == '5') {
gamemode = 5;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 5");
lcd.setCursor(0, 1);
lcd.print("listen to the buzzer");
lcd.setCursor(1, 2);
lcd.print("then memorise the ");
lcd.setCursor(7, 3);
lcd.print("digit!");
delay(3000);
break;
}
else if(key == '6') {
gamemode = 6;
n=choose_difficulty(gamemode);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("you choose mode 6");
lcd.setCursor(0, 1);
lcd.print("memorize the random");
lcd.setCursor(1, 2);
lcd.print("appering digits!");
lcd.setCursor(2, 3);
lcd.print("in reverse order!");
delay(3000);
break;
}
}
}
data[1]=gamemode;
number=(20-n)/2;
n_holder=n;
}
else if(mainmode==2){
lcd.clear();
lcd.setCursor(2,1);
lcd.print("CUMming soon! :)");
delay(3000);
setup();
//--------------------------------------------------------
}
}
void loop() {
//loop_LED Matrix
static int16_t sx1 = 15 << 8, sx2 = sx1, sy1, sy2;
sx1 = sx1 - (sy1 >> 6);
sy1 = sy1 + (sx1 >> 6);
sx2 = sx2 - (sy2 >> 5);
sy2 = sy2 + (sx2 >> 5);
static byte travel = 0;
travel--;
byte *dst = fb;
byte output = 0;
int8_t x_offset = (sx1 >> 8) - X_SEGMENTS * 4;
int8_t y_offset = (sx2 >> 8) - Y_SEGMENTS * 4;
uint8_t screenx, screeny, xroot, yroot;
uint16_t xsumsquares, ysumsquares, xnextsquare, ynextsquare;
int8_t x, y;
// offset the origin in screen space
x = x_offset;
y = y_offset;
ysumsquares = x_offset * x_offset + y * y;
yroot = int(sqrtf(ysumsquares));
ynextsquare = yroot*yroot;
// Quadrant II (top-left)
screeny = Y_SEGMENTS * 8;
while (y < 0 && screeny) {
x = x_offset;
screenx = X_SEGMENTS * 8;
xsumsquares = ysumsquares;
xroot = yroot;
if (x < 0) {
xnextsquare = xroot * xroot;
while (x < 0 && screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares < xnextsquare)
xnextsquare -= 2 * xroot-- - 1;
}
}
// Quadrant I (top right)
if (screenx) {
xnextsquare = (xroot + 1) * (xroot + 1);
while (screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares >= xnextsquare)
xnextsquare += 2 * ++xroot + 1;
}
}
ysumsquares += 2 * y++ + 1;
if (ysumsquares < ynextsquare)
ynextsquare -= 2 * yroot-- - 1;
screeny--;
}
// Quadrant III (bottom left)
ynextsquare = (yroot + 1) * (yroot + 1);
while (screeny) {
x = x_offset;
screenx = X_SEGMENTS * 8;
xsumsquares = ysumsquares;
xroot = yroot;
if (x < 0) {
xnextsquare = xroot * xroot;
while (x < 0 && screenx) {
screenx--;
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares < xnextsquare)
xnextsquare -= 2 * xroot-- - 1;
}
}
// Quadrant IV (bottom right)
if (screenx) {
xnextsquare = (xroot + 1) * (xroot + 1);
while (screenx--) {
output <<= 1;
output |= ((xroot + travel) & 8) >> 3;
if (!(screenx & 7))
*dst++ = output;
xsumsquares += 2 * x++ + 1;
if (xsumsquares >= xnextsquare)
xnextsquare += 2 * ++xroot + 1;
}
}
ysumsquares += 2 * y++ + 1;
if (ysumsquares >= ynextsquare)
ynextsquare += 2 * ++yroot + 1;
screeny--;
}
show();
//--------------------------------------------------------
//loop_WOrking Memory
if(mainmode==1){
lcd.clear();
for(i; i < n && i < 15; i++) {
if(gamemode==6){
lcd.clear();
number = random(0,20);
number_row = random(0,4);
}
lcd.setCursor(number++,number_row);
saved_num[i] = random(0,10);
the_number=((the_number)*10)+saved_num[i];
lcd.print(saved_num[i]);
if(gamemode==5){
buzzer = random(0,10);
if(buzzer%2==0){
buzzer_num[buzzer_i++]=saved_num[i];
tone(13,NOTE_G4);
delay(500);
noTone(13);
}
}
delay(750);
if (i == n-1)
delay(3000);
}
if(gamemode==4){
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Please enter the");
lcd.setCursor(0,1);
lcd.print("memorized number:");
delay(2000);
lcd.clear();
i = 0;
number -= n;
if(gamemode==5){
n=buzzer_i;
number=(20-n)/2;
}
if(gamemode==6)
number=(20-n)/2;
if(gamemode==4){
lcd.setCursor(0,1);
lcd.print("[");
for(int y=0;y<5;y++){
rand_=random(1,n+1);
rand_num[y]=saved_num[int(rand_-1)];
lcd.print(int(rand_));
if(y!=4)
lcd.print("] [");
}
lcd.print("]");
n=5;
number=(20-n)/2;
}
while(true) {
char key = keypad.getKey();
if(key) {
if(key=='#'){
if(i>0)
i--;
if(number>(20-n)/2)
number--;
lcd.setCursor(number,0);
lcd.print(" ");
}
else if(key=='*'){
setup();
while(true)
loop();
//this part of code is a bit sus...
}
else{
lcd.setCursor(number++,0);
lcd.print(key);
given_num[i++] = key;
}
}
if(i == n) {
number -= n;
lcd.clear();
if(gamemode == 1){
for(int j = 0; j < n; j++) {
if(int(given_num[j]) - 48 == saved_num[j]) {
judge *= 1;
mistakes_pattern=((mistakes_pattern)*10)+1;
}
else{
judge *= 0;
mistakes_pattern=((mistakes_pattern)*10);
}
}
}
else if(gamemode == 2){
the_number=2;
for(int j = 0; j < n; j++) {
the_number=((the_number)*10)+saved_num[n - j - 1];
if(int(given_num[j]) - 48 == saved_num[n - j - 1]) {
judge *= 1;
mistakes_pattern=((mistakes_pattern)*10)+1;
mistakes++;
}
else{
judge *= 0;
mistakes_pattern=((mistakes_pattern)*10);
mistakes++;
}
}
}
else if(gamemode == 3){
for(int j = 0; j < n; j++) {
if(int(given_num[j]) - 48 == saved_num[j]) {
judge++;
mistakes_pattern=((mistakes_pattern)*10)+1;
}
else{
mistakes_pattern=((mistakes_pattern)*10);
mistakes++;
}
}
point += judge;
}
else if(gamemode == 4){
for(int j = 0; j < n; j++) {
the_4_5_number=((the_4_5_number)*10)+rand_num[j];
if(int(given_num[j]) - 48 == rand_num[j]) {
judge = 1;
mistakes_pattern=((mistakes_pattern)*10)+1;
}
else{
judge = 0;
mistakes_pattern=((mistakes_pattern)*10);
mistakes++;
}
}
}
else if(gamemode == 5){
for(int j = 0; j < n; j++) {
if(int(given_num[j]) - 48 == buzzer_num[j]) {
the_4_5_number=((the_4_5_number)*10)+buzzer_num[j];
judge = 1;
mistakes_pattern=((mistakes_pattern)*10)+1;
}
else{
judge = 0;
mistakes_pattern=((mistakes_pattern)*10);
mistakes++;
}
}
}
else if(gamemode == 6){
for(int j = 0; j < n; j++) {
if(int(given_num[j]) - 48 == saved_num[n - j - 1]) {
judge *= 1;
mistakes_pattern=((mistakes_pattern)*10)+1;
}
else{
judge *= 0;
mistakes_pattern=((mistakes_pattern)*10);
}
}
}
if(gamemode == 3) {
giving_data();
lcd.setCursor(0,0);
lcd.print("you got ");
lcd.print(judge);
judge = 0;
lcd.print(" of digits");
lcd.setCursor(0,1);
lcd.print("correct! score:");
lcd.print(point);
lcd.setCursor(2,2);
lcd.print("lets continue...");
delay(3000);
}
else {
if(judge == 1) {
point++;
if(gamemode==4 || gamemode==5){
n = n_holder;
number=(20-n)/2;
}
else{
n += 2;
if(number > 0)
number--;
}
giving_data();
lcd.setCursor(6,0);
lcd.print("CORRECT!");
lcd.setCursor(5,1);
lcd.print("NEXT LEVEL");
delay(2000);
}
else if(judge == 0) {
giving_data();
lcd.setCursor(7,0);
lcd.print("WRONG!");
lcd.setCursor(0,1);
lcd.print("your point: ");
lcd.print(point);
lcd.setCursor(2,2);
lcd.print("lets start over.");
point = 0;
n = n_holder;
number=(20-n)/2;
delay(2000);
}
}
buzzer_i=0;
i = 0;
judge=1;
mistakes_pattern=2;
the_number=2;
mistakes=0;
break;
}
}
}
/*else if(mainmode==2){
}*/
//----------------------------------------------------------------
}
//after loop_LED Matrix
void set_pixel(uint8_t x, uint8_t y, uint8_t mode) {
byte *addr = &fb[x / 8 + y * X_SEGMENTS];
byte mask = 128 >> (x % 8);
switch (mode) {
case 0: // clear pixel
*addr &= ~mask;
break;
case 1: // plot pixel
*addr |= mask;
break;
case 2: // XOR pixel
*addr ^= mask;
break;
}
}
void safe_pixel(uint8_t x, uint8_t y, uint8_t mode) {
if ((x >= X_SEGMENTS * 8) || (y >= Y_SEGMENTS * 8))
return;
set_pixel(x, y, mode);
}
// turn off every LED in the framebuffer
void clear() {
byte *addr = fb;
for (byte i = 0; i < 8 * NUM_SEGMENTS; i++)
*addr++ = 0;
}
// send the raster order framebuffer in the correct order
// for the boustrophedon layout of daisy-chained MAX7219s
void show() {
for (byte row = 0; row < 8; row++) {
digitalWrite(CS, LOW);
byte segment = NUM_SEGMENTS;
while (segment--) {
byte x = segment % X_SEGMENTS;
byte y = segment / X_SEGMENTS * 8;
byte addr = (row + y) * X_SEGMENTS;
if (segment & X_SEGMENTS) { // odd rows of segments
shiftOut(DIN, CLK, MSBFIRST, 8 - row);
shiftOut(DIN, CLK, LSBFIRST, fb[addr + x]);
} else { // even rows of segments
shiftOut(DIN, CLK, MSBFIRST, 1 + row);
shiftOut(DIN, CLK, MSBFIRST, fb[addr - x + X_SEGMENTS - 1]);
}
}
digitalWrite(CS, HIGH);
}
}
//----------------------------------------------------------------