Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // button press pins. Buttons are pressed by connecting signal in to signal out.
- // 28 possible combinations. 25 buttons used for main board,
- // 1 used for "start" button (0,0)
- // button press signal in pins
- int bin[] = { A7, A6, A5, A4 }; // 0, 1, 2, 3
- // button press signal out pins
- int bout[] = { 2, 3, 4, 5, 6, 7, 8 }; // 0, 1, 2, 3, 4, 5, 6
- // current board state pins. Each pin gives a timed signal of 4 bits
- int bread[] = { A15, A14, A13, A12, A11, A10, A9 };
- // map of buttons to signal out pins
- int butin[] = {
- 1, 1, 1, 1, 1,
- 1, 1, 2, 2, 2,
- 2, 2, 2, 2, 3,
- 3, 3, 3, 3, 3,
- 3, 0, 0, 0, 0
- };
- // map of buttons to signal out pins
- int butout[] = {
- 1, 2, 3, 4, 0,
- 5, 6, 1, 2, 3,
- 4, 0, 5, 6, 1,
- 2, 3, 4, 0, 5,
- 6, 1, 2, 3, 4
- };
- // global variables used in matrix solving
- int solution[25];
- int solverMatrix[25][25];
- int iMatrix[25][25];
- int gameArray[25];
- int loopAgain = 0;
- int temp[25];
- int temp2[25];
- // simulate button signal connections by copying analog LOWs
- void copyLows(int in, int out) {
- int f = 1;
- for (int i = 0; i < 8; i++) {
- // prevent bad timing by waiting for signal to go high first
- while (analogRead(bin[in]) < 500) {
- delay(1);
- }
- // wait for signal to return to low
- while (analogRead(bin[in]) > 500) {
- delay(1);
- }
- if (f==1) {
- // on first run, set output pin to output (automatically sets to low)
- pinMode(bout[out], OUTPUT);
- f=0; // I added this. Surprised it worked without it. Will it work with it?
- } else {
- digitalWrite(bout[out], LOW);
- }
- // approx low time of 5ms
- delay(5);
- digitalWrite(bout[out], HIGH);
- delay(3);
- }
- // return output pin to input to end button press
- pinMode(bout[out], INPUT);
- }
- // XOR to solverMatrix
- void binaryRowOperation(int ii, int jj) {
- for(int bi=0; bi<25; bi++) {
- solverMatrix[ii][bi] = solverMatrix[ii][bi]^solverMatrix[jj][bi];
- }
- }
- // XOR to iMatrix
- void binaryRowOperationM(int ii, int jj) {
- for(int bi=0; bi<25; bi++) {
- iMatrix[ii][bi] = iMatrix[ii][bi]^iMatrix[jj][bi];
- }
- }
- // gaussian elimination subroutine
- void pivotRotate(int pRcol) {
- if(solverMatrix[pRcol][pRcol] != 0) {
- loopAgain = 0;
- return;
- }
- for(int y=0;y<25;y++) {
- temp[y] = solverMatrix[pRcol][y];
- }
- int nflag = 1;
- for(int x=0;x<25;x++) {
- for(int tj=0;tj<25;tj++) {
- if(iMatrix[x][tj] == 1) { nflag = 0; break; }
- }
- if(nflag==0) { break; }
- }
- if(nflag == 0) {
- for(int w=0;w<25;w++) {
- temp2[w] = iMatrix[pRcol][w];
- }
- }
- for(int v=pRcol+1; v<25; v++) {
- if(solverMatrix[v][pRcol] != 0) {
- for(int tj=0;tj<25;tj++) {
- solverMatrix[pRcol][tj] = solverMatrix[v][tj];
- }
- for(int tj=0;tj<25;tj++) {
- solverMatrix[v][tj] = temp[tj];
- }
- int nflag = 1;
- for(int z=0;z<25;z++) {
- for(int tj=0;tj<25;tj++) {
- if(iMatrix[z][tj] == 1) { nflag = 0; break; }
- }
- if(nflag==0) { break; }
- }
- if(nflag == 0) {
- for(int tj=0;tj<25;tj++) {
- iMatrix[pRcol][tj] = iMatrix[v][tj];
- }
- for(int tj=0;tj<25;tj++) {
- iMatrix[v][tj] = temp2[tj];
- }
- }
- loopAgain = 1;
- return;
- }
- }
- loopAgain = 0;
- }
- // gaussian elimination
- void binaryMatrixInverse() {
- generateIdentity();
- for(int i=0; i<25; i++) {
- pivotRotate(i);
- loopAgain = 1;
- do {
- for(int j=0;j<i;j++) {
- if(solverMatrix[i][j] == 1) {
- binaryRowOperation(i, j);
- binaryRowOperationM(i, j);
- }
- }
- pivotRotate(i);
- //delay(1000);
- } while(loopAgain==1);
- }
- for(int i=0;i<25-1;i++) {
- for(int j=i+1;j<25;j++) {
- if(solverMatrix[i][j] == 1) {
- binaryRowOperation(i,j);
- binaryRowOperationM(i,j);
- }
- }
- }
- }
- // generate solver matrix pre-gaussian elimination
- void generateNPattern(int gnp) {
- int N = pow(gnp,2);
- for(int k=0; k<N; k++) {
- int kElem = k%gnp;
- int kLine = k/gnp;
- int Ni = 0;
- for(int gi=0; gi<gnp; gi++) {
- for(int j=0; j<gnp; j++) {
- 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);
- Ni++;
- }
- }
- }
- }
- /* generate identity matrix
- 1,0,0,0,0
- 0,1,0,0,0
- 0,0,1,0,0
- 0,0,0,1,0
- 0,0,0,0,1
- */
- void generateIdentity() {
- for(int u=0;u<25;u++) {
- for(int j=0;j<25;j++) {
- iMatrix[u][j] = 0;
- }
- }
- for(int u=0; u<25; u++) {
- iMatrix[u][u] = 1;
- }
- }
- // run identity matrix on game array
- void binaryMultiplyMatrix() {
- for(int m=0;m<25;m++) {
- solution[m] = 0;
- }
- int lin = 1;
- for(int j=0;j<25;j++) {
- for(int k=0;k<25;k++) {
- solution[j] = solution[j]^(iMatrix[j][k]*gameArray[k]);
- lin++;
- }
- }
- }
- // signal mappings
- 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 } };
- // global variables used for reading current state of buttons
- int reads[7][4];
- int onoff[25];
- void readButtons() {
- int c = 0;
- int nine = analogRead(bin[0]); // sync lows with lows of solderpoint 9 (button input pin 0)
- // allow a full low cycle to pass
- while (nine > 400) {
- nine = analogRead(bin[0]);
- delay(1);
- }
- while (nine < 400) {
- c++;
- nine = analogRead(bin[0]);
- delay(1);
- }
- while (nine > 400) { nine = analogRead(bin[0]); }
- long timer = millis();
- // read all 4 bits of each of the 7 button signal pins
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 7; i++) {
- reads[i][j] = analogRead(bread[i]);
- }
- // leftover from when I was trying to sync the button reads to pin 0
- if (j % 2 == 0) {
- delay(4);
- } else {
- delay(4);
- }
- }
- // copy the 4 bit readings to global onoff[25]
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 7; i++) {
- int bn = ijl[i][j];
- // ignore unused mappings (designated by 25)
- if (bn == 25) { continue; }
- if (reads[i][j] < 400) {
- onoff[bn] = 1;
- } else {
- onoff[bn] = 0;
- }
- }
- }
- }
- // set permanent input pins
- // wait 10 seconds for game to start
- // press "start" by connecting input pin 0 to output pin 0
- // generate solving matrices
- void setup() {
- for (int p = 0; p < 4; p++) {
- pinMode(bin[p], INPUT);
- }
- for (int p = 0; p < 7; p++) {
- pinMode(bread[p], INPUT);
- }
- delay(10000);
- copyLows(0, 0);
- delay(500);
- generateNPattern(5);
- binaryMatrixInverse();
- }
- // read buttons, solve, and output
- void readAndSolve() {
- readButtons();
- for(int i=0;i<25;i++){
- gameArray[i] = onoff[i];
- }
- binaryMultiplyMatrix();
- for(int i=0;i<25;i++){
- if(solution[i] == 1){
- copyLows(butin[i], butout[i]);
- delay(500);
- }
- }
- }
- // wait 9 seconds between solves to allow level to change
- void loop() {
- readAndSolve();
- delay(9000);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement