“囚徒困境”抢答器 的教程


/*
 趴会儿Project项目集 http://steinslab.xyz/archives/752
 No.002 
 详见http://steinslab.xyz/archives/1008
  囚徒困境抢答器-《命运女神的抉择》
 SPtuan@steinslab.xyz
*/


int A[4]={10,11,12,13};
int B[4]={6,7,8,9};
int info = 5;
int Ain = 4;
int Bin = 3;
int Cin = 2;
volatile int flag=0;
int Aflag=0,Bflag=0,ix=0,jx=0;
    int Atemp=Aflag;
    int Btemp=Bflag;


void setup() {
  Serial.begin(9600);
  for(ix=0;ix<4;ix++)
  {
      pinMode(A[ix],OUTPUT);
      digitalWrite(A[ix],LOW);
      pinMode(B[ix],OUTPUT);
      digitalWrite(B[ix],LOW);
    }
  pinMode(Ain,INPUT_PULLUP);
  pinMode(Bin,INPUT_PULLUP);
  pinMode(Cin,INPUT_PULLUP);
  pinMode(info,OUTPUT);
  digitalWrite(info,LOW);
  attachInterrupt(0,signal0,RISING);
}

void signal0()
{
  if(flag==0) flag = 1;
 }

void wait()
{
    digitalWrite(info,HIGH);
    delay(3000);
    digitalWrite(info,LOW);
  }

void display0()
{
    digitalWrite(B[Bflag-1],HIGH);

    digitalWrite(A[Aflag-1],HIGH);
 

    }

void display1()
{
    if(Aflag==4)
    {
      for(ix=0;ix<3;ix++)
      {
        for(jx=0;jx<4;jx++)
        {
            digitalWrite(A[jx],HIGH);
             digitalWrite(B[jx],LOW);           
          } 
         delay(500); 
         for(jx=0;jx<4;jx++)
        {
            digitalWrite(A[jx],LOW);
          } 
         delay(500); 
        }   
       }

    else if(Bflag==4)
    {
      for(ix=0;ix<3;ix++)
      {
        for(jx=0;jx<4;jx++)
        {
            digitalWrite(B[jx],HIGH);
           digitalWrite(A[jx],LOW); 
          } 
         delay(500); 
         for(jx=0;jx<4;jx++)
        {
            digitalWrite(B[jx],LOW);
          } 
         delay(500); 
        }   
       }
  }
void loop() {
    Atemp=Aflag=Btemp=Bflag=0;
  do
  { for(ix=0;ix<4;ix++)
     {
        digitalWrite(A[ix],HIGH);
        digitalWrite(B[ix],HIGH);
        delay(300);
        if(flag==1) break;
       }
    for(ix=0;ix<4;ix++)
     {
        digitalWrite(A[ix],LOW);
        digitalWrite(B[ix],LOW);
        delay(300);
        if(flag==1) break;

   
       }
  }while(flag==0);
   for(ix=0;ix<4;ix++)
     {
        digitalWrite(A[ix],LOW);
        digitalWrite(B[ix],LOW);
   
       }
    delay(1000);
  do
  {
 

   
    
      do{
          wait();
          Atemp=Aflag;
          Btemp=Bflag;
          do{
              if(digitalRead(Ain)==LOW)
              {
                  delay(20);
                  if(digitalRead(Ain)==LOW) Aflag++;
                  Serial.print("Aflag");
                  while(digitalRead(Ain)==LOW);          
                }
              else if(digitalRead(Bin)==LOW)
                {
                    delay(20);
                    if(digitalRead(Bin)==LOW) Bflag++;  
                    Serial.print("Bflag");
                    while(digitalRead(Bin)==LOW);          
                } 
          }while((Atemp==Aflag)&&(Btemp==Bflag));
           display0();
       if(Bflag<4)    digitalWrite(B[3],LOW);
       if(Aflag<4)    digitalWrite(A[3],LOW);
   
      }while((Aflag!=4)&&(Bflag!=4));

      
    

     display1();
     flag = 0;
    }while(flag==1);

  

}

注:后来我也思考了一下。这个代码还是有相当的改进余地的。

对于抢答按钮的输入,使用了循环扫描的方法,势必会有一个优先级的问题,一旦一个持续按下,就会触发bug必赢。

可以改用中断,套用几个flag变量,综合判断真正在抢答器结束后按击的人。或者提前按下的人直接判负。


> “囚徒困境”抢答器