Logic game - Arduino Uno code
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
#define I2C_ADDRESS 0x3C
// class and instance
SSD1306AsciiAvrI2c oled;
int g[3]; // 3 gates assigned 1 type: AND OR XOR NAND
char n[4]={0,1,2,3}; // 4 types of gates
int r; // random #
volatile int next=0;
void randomize() {
// output example g[0]= 3, g[1] = 2, g[2] = 0
n[0]=0;n[1]=1;n[2]=2;n[3]=3;
for (int i = 0; i <3; i++) {
r=random(0,4);
while (n[r] == 4) {// invalid #
r=random(0,4);
}
g[i]=n[r];
n[r]=4; // already used
}
}
//------------------------------------------
void reveal() {
int i = 2;
oled.setFont(font8x8);
oled.clear();
oled.setCursor(25,1);
oled.set1X();
do {
oled.print(i+1);
if (g[i] == 0) {
oled.print(":AND ");
} else if (g[i] == 1) {
oled.print(":OR ");
} else if (g[i] == 2) {
oled.print(":XOR ");
} else if (g[i] == 3) {
oled.print(":NAND ");
}
if (i==2) { // 3:AND
i = 0; // 1:XOR 2:NAND
oled.setCursor(0,3);
} else {
i++;
}
} while (i < 2);
}
//------------------------------------------
void proceed() {
next++;
if (next > 5) {
next = 5;
}
}
void setup() {
while (((r = analogRead(0)) == 0) or ((r = analogRead(0)) == 1023)) {}; // exclude 0 and 1023
randomSeed(r);
// randomSeed(millis());
// Serial.begin(9600);
// use pulldown resistors on PINB[0,1,2,3]
DDRB = 0x00; // all inputs PB0-PB5
PORTB = 0x00; // no pullups
DDRD |= 0xE0; // 1110 0000
PORTD = 0x00; // no pullups
attachInterrupt(digitalPinToInterrupt(2), proceed, RISING); // PD2, pin 4
oled.begin(&Adafruit128x32, I2C_ADDRESS);
// oled.setI2cClock(frequency) to change from the default frequency.
oled.setFont(Adafruit5x7);
oled.clear();
oled.set1X();
oled.setCursor(0,0);
oled.println("Which gates are used?");
oled.println("AND, OR, XOR, NAND. ");
oled.println("Use red switches to ");
oled.println("work out the gates. ");
while (next == 0) { delay(50); }
oled.clear();
oled.home();
oled.println("3 gates, no doubles! ");
oled.println("Press Next to begin ");
oled.println("and again to see what");
oled.println("logic gates were used");
while (next == 1) { delay(50); }
randomize();
oled.clear();
oled.setCursor(5,2);
oled.set2X();
oled.println("GAME ON");
}
void logic_gates(int gate, int pin1, int pin2, int sbit) {
if (gate == 0) { //AND
if (((PINB & bit(pin1)) == bit(pin1)) && ((PINB & bit(pin2)) == bit(pin2))) {
PORTD |= sbit;
} else {
PORTD &= ~(sbit);
}
} else if (gate == 1) { //OR
if (((PINB & bit(pin1)) == bit(pin1)) || ((PINB & bit(pin2)) == bit(pin2))) {
PORTD |= sbit;
} else {
PORTD &= ~(sbit);
}
} else if (gate == 2) { //XOR
if ((((PINB & bit(pin1)) == bit(pin1)) && ((PINB & bit(pin2)) == 0)) || (((PINB & bit(pin1)) == 0) && ((PINB & bit(pin2)) == bit(pin2)))) { // 0000 1100 AND
PORTD |= sbit;
} else {
PORTD &= ~(sbit);
}
} else if (gate == 3) { //NAND
if (((PINB & bit(pin1)) == bit(pin1)) && ((PINB & bit(pin2)) == bit(pin2))) { // 0000 1100 AND
PORTD &= ~(sbit);
} else {
PORTD |= sbit;
}
}
}
void loop() {
if (next == 2) {
logic_gates(g[0],0,1,0x20); // input from PB0 PB1, pin 14,15, output goes to PD5, pin 11, sbit 0010 0000
logic_gates(g[1],2,3,0x40); // input from PB2, PB3, pin 16,17, output goes to PD6, pin 12, sbit 0100 0000
logic_gates(g[2],4,5,0x80); // input from PB4(PD5), PB5(PD6), pin 18,19 output goes to PD7, pin 13, sbit 1000 0000
} else if (next == 3) {
reveal(); // next updated to 4
next = 4;
} else if (next == 5) {
randomize();
oled.clear();
oled.setCursor(5,2);
oled.set2X();
oled.println("GAME ON");
next = 2;
}
}