Advertisement
Guest User

arduinoLightsOut

a guest
Mar 9th, 2023
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.11 KB | Source Code | 0 0
  1. // button press pins. Buttons are pressed by connecting signal in to signal out.
  2. // 28 possible combinations. 25 buttons used for main board,
  3. // 1 used for "start" button (0,0)
  4.  
  5. // button press signal in pins
  6. int bin[] = { A7, A6, A5, A4 }; // 0, 1, 2, 3
  7.  
  8. // button press signal out pins
  9. int bout[] = { 2, 3, 4, 5, 6, 7, 8 }; // 0, 1, 2, 3, 4, 5, 6
  10.  
  11. // current board state pins. Each pin gives a timed signal of 4 bits
  12. int bread[] = { A15, A14, A13, A12, A11, A10, A9 };
  13.  
  14. // map of buttons to signal out pins
  15. int butin[] = {
  16.   1, 1, 1, 1, 1,
  17.   1, 1, 2, 2, 2,
  18.   2, 2, 2, 2, 3,
  19.   3, 3, 3, 3, 3,
  20.   3, 0, 0, 0, 0
  21. };
  22.  
  23. // map of buttons to signal out pins
  24. int butout[] = {
  25.   1, 2, 3, 4, 0,
  26.   5, 6, 1, 2, 3,
  27.   4, 0, 5, 6, 1,
  28.   2, 3, 4, 0, 5,
  29.   6, 1, 2, 3, 4
  30. };
  31.  
  32. // global variables used in matrix solving
  33. int solution[25];
  34. int solverMatrix[25][25];
  35. int iMatrix[25][25];
  36. int gameArray[25];
  37. int loopAgain = 0;
  38. int temp[25];
  39. int temp2[25];
  40.  
  41. // simulate button signal connections by copying analog LOWs
  42. void copyLows(int in, int out) {
  43.   int f = 1;
  44.   for (int i = 0; i < 8; i++) {
  45.     // prevent bad timing by waiting for signal to go high first
  46.     while (analogRead(bin[in]) < 500) {
  47.       delay(1);
  48.     }
  49.     // wait for signal to return to low
  50.     while (analogRead(bin[in]) > 500) {
  51.       delay(1);
  52.     }
  53.     if (f==1) {
  54.       // on first run, set output pin to output (automatically sets to low)
  55.       pinMode(bout[out], OUTPUT);
  56.       f=0; // I added this. Surprised it worked without it. Will it work with it?
  57.     } else {
  58.       digitalWrite(bout[out], LOW);
  59.     }
  60.     // approx low time of 5ms
  61.     delay(5);
  62.     digitalWrite(bout[out], HIGH);
  63.     delay(3);
  64.   }
  65.   // return output pin to input to end button press
  66.   pinMode(bout[out], INPUT);
  67. }
  68.  
  69. // XOR to solverMatrix
  70. void binaryRowOperation(int ii, int jj) {
  71.   for(int bi=0; bi<25; bi++) {
  72.     solverMatrix[ii][bi] = solverMatrix[ii][bi]^solverMatrix[jj][bi];
  73.   }
  74. }
  75.  
  76. // XOR to iMatrix
  77. void binaryRowOperationM(int ii, int jj) {
  78.   for(int bi=0; bi<25; bi++) {
  79.     iMatrix[ii][bi] = iMatrix[ii][bi]^iMatrix[jj][bi];
  80.   }
  81. }
  82.  
  83. // gaussian elimination subroutine
  84. void pivotRotate(int pRcol) {
  85.   if(solverMatrix[pRcol][pRcol] != 0) {
  86.     loopAgain = 0;
  87.     return;
  88.   }
  89.   for(int y=0;y<25;y++) {
  90.     temp[y] = solverMatrix[pRcol][y];
  91.   }
  92.   int nflag = 1;
  93.   for(int x=0;x<25;x++) {
  94.     for(int tj=0;tj<25;tj++) {
  95.       if(iMatrix[x][tj] == 1) { nflag = 0; break; }
  96.     }
  97.     if(nflag==0) { break; }
  98.   }
  99.   if(nflag == 0) {
  100.     for(int w=0;w<25;w++) {
  101.       temp2[w] = iMatrix[pRcol][w];
  102.     }
  103.   }
  104.   for(int v=pRcol+1; v<25; v++) {
  105.     if(solverMatrix[v][pRcol] != 0) {
  106.       for(int tj=0;tj<25;tj++) {
  107.         solverMatrix[pRcol][tj] = solverMatrix[v][tj];
  108.       }
  109.       for(int tj=0;tj<25;tj++) {
  110.         solverMatrix[v][tj] = temp[tj];
  111.       }
  112.       int nflag = 1;
  113.       for(int z=0;z<25;z++) {
  114.         for(int tj=0;tj<25;tj++) {
  115.           if(iMatrix[z][tj] == 1) { nflag = 0; break; }
  116.         }
  117.         if(nflag==0) { break; }
  118.       }
  119.       if(nflag == 0) {
  120.         for(int tj=0;tj<25;tj++) {
  121.           iMatrix[pRcol][tj] = iMatrix[v][tj];
  122.         }
  123.         for(int tj=0;tj<25;tj++) {
  124.           iMatrix[v][tj] = temp2[tj];
  125.         }
  126.       }
  127.       loopAgain = 1;
  128.       return;
  129.     }
  130.   }
  131.   loopAgain = 0;
  132. }
  133.  
  134. // gaussian elimination
  135. void binaryMatrixInverse() {
  136.   generateIdentity();
  137.   for(int i=0; i<25; i++) {
  138.     pivotRotate(i);
  139.     loopAgain = 1;
  140.     do {
  141.       for(int j=0;j<i;j++) {
  142.         if(solverMatrix[i][j] == 1) {
  143.           binaryRowOperation(i, j);
  144.           binaryRowOperationM(i, j);
  145.         }
  146.       }
  147.       pivotRotate(i);
  148.       //delay(1000);
  149.     } while(loopAgain==1);
  150.   }
  151.   for(int i=0;i<25-1;i++) {
  152.     for(int j=i+1;j<25;j++) {
  153.       if(solverMatrix[i][j] == 1) {
  154.         binaryRowOperation(i,j);
  155.         binaryRowOperationM(i,j);
  156.       }
  157.     }
  158.   }
  159. }
  160.  
  161. // generate solver matrix pre-gaussian elimination
  162. void generateNPattern(int gnp) {
  163.   int N = pow(gnp,2);
  164.   for(int k=0; k<N; k++) {
  165.     int kElem = k%gnp;
  166.     int kLine = k/gnp;
  167.     int Ni = 0;
  168.     for(int gi=0; gi<gnp; gi++) {
  169.       for(int j=0; j<gnp; j++) {
  170.         solverMatrix[k][Ni] = (((gi == kLine && j == kElem) || (gi - 1 == kLine && j == kElem) || (gi + 1 == kLine && j == kElem) || (gi == kLine && j - 1 == kElem) || (gi == kLine && j + 1 == kElem)) ? 1 : 0);
  171.         Ni++;
  172.       }
  173.     }
  174.   }
  175. }
  176.  
  177. /* generate identity matrix
  178. 1,0,0,0,0
  179. 0,1,0,0,0
  180. 0,0,1,0,0
  181. 0,0,0,1,0
  182. 0,0,0,0,1
  183. */
  184. void generateIdentity() {
  185.   for(int u=0;u<25;u++) {
  186.     for(int j=0;j<25;j++) {
  187.       iMatrix[u][j] = 0;
  188.     }
  189.   }
  190.   for(int u=0; u<25; u++) {
  191.     iMatrix[u][u] = 1;
  192.   }
  193. }
  194.  
  195.  
  196. // run identity matrix on game array
  197. void binaryMultiplyMatrix() {
  198.   for(int m=0;m<25;m++) {
  199.     solution[m] = 0;
  200.   }
  201.   int lin = 1;
  202.   for(int j=0;j<25;j++) {
  203.     for(int k=0;k<25;k++) {
  204.       solution[j] = solution[j]^(iMatrix[j][k]*gameArray[k]);
  205.       lin++;
  206.     }
  207.   }
  208. }
  209.  
  210. // signal mappings
  211. int ijl[7][4] = { { 0, 21, 14, 7 }, { 1, 22, 15, 8 }, { 2, 23, 16, 9 }, { 3, 24, 17, 10 }, { 4, 25, 18, 11 }, { 5, 25, 19, 12 }, { 6, 25, 20, 13 } };
  212.  
  213. // global variables used for reading current state of buttons
  214. int reads[7][4];
  215. int onoff[25];
  216.  
  217. void readButtons() {
  218.   int c = 0;
  219.   int nine = analogRead(bin[0]); // sync lows with lows of solderpoint 9 (button input pin 0)
  220.  
  221.   // allow a full low cycle to pass
  222.   while (nine > 400) {
  223.     nine = analogRead(bin[0]);
  224.     delay(1);
  225.   }
  226.   while (nine < 400) {
  227.     c++;
  228.     nine = analogRead(bin[0]);
  229.     delay(1);
  230.   }
  231.   while (nine > 400) { nine = analogRead(bin[0]); }
  232.   long timer = millis();
  233.   // read all 4 bits of each of the 7 button signal pins
  234.   for (int j = 0; j < 4; j++) {
  235.     for (int i = 0; i < 7; i++) {
  236.       reads[i][j] = analogRead(bread[i]);
  237.     }
  238.     // leftover from when I was trying to sync the button reads to pin 0
  239.     if (j % 2 == 0) {
  240.       delay(4);
  241.     } else {
  242.       delay(4);
  243.     }
  244.   }
  245.  
  246.   // copy the 4 bit readings to global onoff[25]
  247.   for (int j = 0; j < 4; j++) {
  248.     for (int i = 0; i < 7; i++) {
  249.       int bn = ijl[i][j];
  250.       // ignore unused mappings (designated by 25)
  251.       if (bn == 25) { continue; }
  252.       if (reads[i][j] < 400) {
  253.         onoff[bn] = 1;
  254.       } else {
  255.         onoff[bn] = 0;
  256.       }
  257.     }
  258.   }
  259. }
  260.  
  261. // set permanent input pins
  262. // wait 10 seconds for game to start
  263. // press "start" by connecting input pin 0 to output pin 0
  264. // generate solving matrices
  265. void setup() {
  266.   for (int p = 0; p < 4; p++) {
  267.     pinMode(bin[p], INPUT);
  268.   }
  269.   for (int p = 0; p < 7; p++) {
  270.     pinMode(bread[p], INPUT);
  271.   }
  272.   delay(10000);
  273.   copyLows(0, 0);
  274.   delay(500);
  275.   generateNPattern(5);
  276.   binaryMatrixInverse();
  277. }
  278.  
  279. // read buttons, solve, and output
  280. void readAndSolve() {
  281.     readButtons();
  282.     for(int i=0;i<25;i++){
  283.       gameArray[i] = onoff[i];
  284.     }
  285.     binaryMultiplyMatrix();
  286.     for(int i=0;i<25;i++){
  287.       if(solution[i] == 1){
  288.         copyLows(butin[i], butout[i]);
  289.         delay(500);
  290.       }
  291.     }
  292. }
  293.  
  294. // wait 9 seconds between solves to allow level to change
  295. void loop() {
  296.   readAndSolve();
  297.   delay(9000);
  298. }
  299.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement