//this is a mental arithmetic trainer
//how to use:

//the goal of the game is to use Addition and subtraction operation
//to get the number on the lower bottom right from the starting number
//on the left hand side of the game, which represents user's current number.


//from left to right
//the first button allows the users to select which row to proceed(upper or lower)
//the second button allows the user to select what sign to use(+ or -)
//the third button is the confirmation button, will into the next column.

//each time user press the "confirmation" button, the user's number(far left on the lcd)
//will add/subtract the number on the closest column according to user's choice.
//the goal is to get the target number after proceeding the three column in each round.

//以下是自己设置的变量
const int btp = 6;
const int btf = 5;
const int btc = 7;
//bt:button detection pin
//bt (p:postion) (f:flip) (c:confirm)

int user = 0;//玩家目前的数字
int tgt = 10;//target,用户的数字
int sign[3];//预设的正确答案三次分别是加号还是减号
int signf;//用于计算diff
int diff;//目标与目前的总差,也可用于计算compensate
int comp;//compensate,修正除出非整数时的误差
int x; //差

int r_ct;//roll counter
int s_ct;//sign counter

int a;
int b;
int c;
int fx1;//flux #1, a+,b-
int fx2;//flux #2, b+,c-


//生成随机数(错误答案)
int r1;
int r2;
int r3;

//生成答案位置(答案摆放)
int p1;
int p2;
int p3;


//下面是用户状态的数字:
int gc=3;//game status counter, 为3时刷新答案数字,每次确认键(推进键)都会导致其加1
int urs=1;//user sign,用户选择的家好或者减号
int urp=1;//user selection,选择上行或者下行
int lv;//用户等级



int signf2;

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup()
{
  delay(100);
  lcd.begin();
  lcd.backlight();

pinMode(btp,INPUT);
pinMode(btf,INPUT);
pinMode(btc,INPUT);
pinMode(10,OUTPUT);

Serial.begin(9600);

randomSeed(analogRead(A4));
}


void logInfo(){
  Serial.println(gc);
  Serial.print("p1:");
  Serial.print(p1);
  Serial.print("p2:");
  Serial.print(p2);
  Serial.print("p3:");
  Serial.print(p3);
  Serial.print("     a:");
  Serial.print(a); 
  Serial.print(" b:");
  Serial.print(b);
  Serial.print(" c:");
  Serial.print(c);
  Serial.print("         user:");
  Serial.print(user);
  Serial.print(" tgt:");
  Serial.print(tgt);
  Serial.print("     x=");
  Serial.print(x);
  Serial.print(" fx1:");
  Serial.print(fx1);
  Serial.print(" fx2:");
  Serial.print(fx2);
  Serial.print(" comp:");
  Serial.print(comp);
  Serial.print(" signf:");
  Serial.print(signf2);
  Serial.print("   sign:");
  Serial.print(sign[0]);
  Serial.print(" ");
  Serial.print(sign[1]);
  Serial.print(" ");
  Serial.print(sign[2]);
  Serial.println("");
}

void loop()
{
  logInfo();

  //pin10 is the VCC of lcd
  digitalWrite(10,HIGH);//按钮供电电压
  delay(100);
  lcd.clear();


  //下面正式开始生成新一轮的答案
  if(gc == 3){
    tgt = random(1,21);
    //设置目标
    sign[0] = random(2);
    sign[1] = random(2);
    sign[2] = random(2);
    //设置每次计数的加减号

    for (int i = 0; i<=2; i++){//1代表该答案为正,0为负
      if(sign[i]==1){
        signf += 1;
      }
      else{
        signf -= 1;
      }
    }//设置signf,最终加减计数器

    diff = tgt - user;//求出tgt和user的差
    x = diff/signf;//x

    comp = signf*x - diff;//comp是假diff-真diff,假比真大多少
    //这个compensate加入到最后一个正确答案所在路径的数

      if(sign[0]==1){
        a = x;
      }
      else{
        a = 0-x;
      }

      if(sign[2]==1){
        b = x;
      }
      else{
        b = 0-x;
      }

      if(sign[2]==1){
        c = x;
      }
      else{
        c = 0-x;
      }


    fx1 = random(1,9);

    a = a + fx1;
    b = b - fx1;

    fx2 = random(1,9);

    b = b + fx2;
    c = c - fx2;


    c = c - comp;





    //致此,正确答案生成完

    //下面生成错误答案

    r1 = random(0,19);
    r2 = random(0,19);
    r3 = random(0,19);

    gc = 0;//game status counter清零,用户返回一号位置

    //生成答案摆放位置
    p1 = random(2);
    delay(5);
    p2 = random(2);
    delay(5);
    p3 = random(2);

    signf2=signf;
    signf=0;//重置加减号计数器 
  }//【答案的六个数字及位置生成完毕】

  //以下两个分别是选择符号以及位置
  if (digitalRead(btp)==HIGH){
    urs = urs*(0-1);
    delay(100);
  }
  if (digitalRead(btf)==HIGH){
    urp = urp*(0-1);
    delay(100);
  }

  //用户还在第一阶段的情况:
  if(gc == 0){
    //已经有:用户数字,用户加减号选择,答案以及位置
    //打印用户位置(上或下)1上,-1下
    if(urp == 1){
      lcd.setCursor(0,0);
    }
    else{
      lcd.setCursor(0,1);
    }
      lcd.print(user);//打印用户数字(最多两位)
      
    //打印用户符号(加或减)1+,-1-
    if(urs == 1){
      lcd.print("+");
    }
    else{
      lcd.print("-");
    }

    ////////放置数字
    if(p1==1){//放置一号答案
      lcd.setCursor(3,0);
      lcd.print(a);
      lcd.setCursor(3,1);
      lcd.print(r1); 
    }
    else{
      lcd.setCursor(3,0);
      lcd.print(r1);
      lcd.setCursor(3,1);
      lcd.print(a);
    }

    if(p2==1){//放置二号答案
      lcd.setCursor(6,0);
      lcd.print(b);
      lcd.setCursor(6,1);
      lcd.print(r2);
    }
    else{
      lcd.setCursor(6,0);
      lcd.print(r2);
      lcd.setCursor(6,1);
      lcd.print(b);
    }

    if(p3==1){//放置三号答案
      lcd.setCursor(9,0);
      lcd.print(c);
      lcd.setCursor(9,1);
      lcd.print(r3);
    }
    else{
      lcd.setCursor(9,0);
      lcd.print(r3);
      lcd.setCursor(9,1);
      lcd.print(c);
    }

    lcd.setCursor(12,0);
    lcd.print("LV");

    if(lv>99){
      lcd.print("!!");
    }
    else{
      lcd.print(lv);
    }

    lcd.setCursor(12,1);
    lcd.print("=");
    lcd.print(">");
    lcd.print(tgt);

    //confirmation,用户决定从第一层进入第二层
    if (digitalRead(btc)==HIGH){
      gc+=1;
      delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
      int adder;
      if(urp==1){
        if(p1 == 1){
          adder = a;
        }
        else{
          adder = r1;
        }
      }
      else{
        if(p1 == 1){
          adder = r1;
        }
        else{
          adder = a;
        }
      }
      //决定加还是减
      if(urs==1){
        user = user+adder;
      }
      else{
        user = user-adder;
      }
    }

  }//用户位置阶段一结束


  //////
  //用户在第二阶段的情况:
  if(gc == 1){
    //已经有:用户数字,用户加减号选择,答案以及位置
    //打印用户位置(上或下)1上,-1下
    if(urp == 1){
        lcd.setCursor(0,0);
      }
    else{
        lcd.setCursor(0,1);
    }
      lcd.print(user);//打印用户数字(最多两位)//记得测试一下如果是负数占多少个显示格子
      
    //打印用户符号(加或减)1+,-1-
    if(urs == 1){
      lcd.print("+");
    }
    else{
      lcd.print("-");
    }

    ////////放置数字
    if(p2==1){//放置二号答案
      lcd.setCursor(6,0);
        lcd.print(b);
      lcd.setCursor(6,1);
        lcd.print(r2);
    }
    else{
        lcd.setCursor(6,0);
        lcd.print(r2);
      lcd.setCursor(6,1);
        lcd.print(b);
    }

    if(p3==1){//放置三号答案
      lcd.setCursor(9,0);
        lcd.print(c);
      lcd.setCursor(9,1);
        lcd.print(r3);
    }
    else{
        lcd.setCursor(9,0);
        lcd.print(r3);
      lcd.setCursor(9,1);
        lcd.print(c);
    }

    lcd.setCursor(12,0);
    lcd.print("LV");
    if(lv>99){
    lcd.print("!!");
    }
    else{
      lcd.print(lv);
    }
    lcd.setCursor(12,1);
    lcd.print("=");
    lcd.print(">");
    lcd.print(tgt);

    //confirmation,用户决定从第二层进入第三层
    if (digitalRead(btc)==HIGH){
      gc+=1;
      delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
      int adder;
      if(urp==1){
        if(p2 == 1){
          adder = b;
        }
        else{
          adder = r2;
        }
      }
    else{
        if(p2 == 1){
          adder = r2;
        }
        else{
          adder = b;
        }
    }
    //决定加还是减
    if(urs==1){
      user = user+adder;
    }
    else{
      user = user-adder;
    }
  }

  }//用户位置阶段二结束

  //////
  //用户在第三阶段的情况:
  if(gc == 2){
    //已经有:用户数字,用户加减号选择,答案以及位置
    //打印用户位置(上或下)1上,-1下
    if(urp == 1){
        lcd.setCursor(0,0);
      }
    else{
        lcd.setCursor(0,1);
    }
      lcd.print(user);//打印用户数字(最多两位)//记得测试一下如果是负数占多少个显示格子
      
    //打印用户符号(加或减)1+,-1-
    if(urs == 1){
      lcd.print("+");
    }
    else{
      lcd.print("-");
    }

    ////////放置数字
    if(p3==1){//放置三号答案
      lcd.setCursor(9,0);
      lcd.print(c);
      lcd.setCursor(9,1);
      lcd.print(r3);
    }
    else{
      lcd.setCursor(9,0);
      lcd.print(r3);
      lcd.setCursor(9,1);
      lcd.print(c); 
    }

    lcd.setCursor(12,0);
    lcd.print("LV");
    if(lv>99){
      lcd.print("!!");
    }
    else{
      lcd.print(lv);
    }

    lcd.setCursor(12,1);
    lcd.print("=");
    lcd.print(">");
    lcd.print(tgt);

    //confirmation,用户决定从第三层进入第四层
    if (digitalRead(btc)==HIGH){
      gc+=1;
      delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
      int adder;
      if(urp==1){
        if(p3 == 1){
          adder = c;
        }
        else{
          adder = r3;
        }
      }
      else{
        if(p3 == 1){
          adder = r3;
        }
        else{
          adder = c;
        }
      }

      //决定加还是减
      if(urs==1){
        user = user+adder;
      }
      else{
        user = user-adder;
      }
    }

  }//用户位置阶段三结束


  if(gc == 3){
      lcd.clear();
    //阶段四判断是否为答案
    if(user==tgt){
      lv+=1;
      lcd.setCursor(5,0);
      lcd.print("congrat!");
      lcd.setCursor(7,1);
      lcd.print("LV+1");
      delay(1000);
    }
    else{
      lv=0;
      lcd.print("sorry, u've lost");
      lcd.setCursor(7,1);
      delay(500);
    lcd.clear();
    delay(1000);
      lcd.home();
      lcd.print("sorry, u've lost");
      delay(1000);
    lcd.clear();
    delay(500);
      lcd.home();
      lcd.setCursor(1,0);
      lcd.print("restarting...");
        delay(1000);
      user=0;
    }
  }

}



//记得在使用按钮的时候设置一个延迟,以防快速循环重复
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r