/************************************* MICRODEV.GR Tic Tac Toe Triliza (in Greek) (C) PANOS PAPAZOGLOU 2023 License CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/ **************************************/ /****************************************** The code contains also additional sections and variables for debugging ******************************************/ #include #include #include #include LiquidCrystal_I2C lcd(0x27,20,4); #define LED_PIN 14 #define NUM_LEDS 30 CRGB leds[NUM_LEDS]; //General delay variable int d=100; int DIN = 12; int CS = 11; int CLK = 10; LedControl lc=LedControl(DIN, CLK, CS,9); LedControl lc9=LedControl(7, 5, 6,1); //up-down inputs left to right int ain[]={6,8,7,3,4,5,1,0,2}; int kin[]={12,11,9,10}; int laser[]={37,39}; int buttons[]={49,47,45,43,53,51}; int board[]={0,0,0,0,0,0,0,0,0}; //int matrix[]={6,7,9,5,4,3,0,1,2}; int matrix[]={6,7,9,3,4,5,0,1,2}; int player=1; int threshold=120; int thresholdstep=180; int choice=0; int played; int pos=0; int mode; int frame[8] ={ B11111111, B10000001, B10000001, B10000001, B10000001, B10000001, B10000001, B11111111 }; int empty[8]={ B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 }; int heart[8]= { B01100110, B11111111, B11111111, B11111111, B01111110, B00111100, B00011000, B00000000 }; int T[8]={ 0b00000000, 0b01111110, 0b01011010, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000 }; int I[8]={ 0b00000000, 0b00111100, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00011000, 0b00111100 }; int C[8]={ 0b00000000, 0b00111100, 0b01100110, 0b01100000, 0b01100000, 0b01100000, 0b01100110, 0b00111100 }; int A[8]= { 0b00000000, 0b00111100, 0b01100110, 0b01100110, 0b01111110, 0b01100110, 0b01100110, 0b01100110 }; int L[8]= { 0b00000000, 0b00111100, 0b01100110, 0b01100110, 0b01100110, 0b01100110, 0b01100110, 0b01100110 }; int P[8]= { 0b00000000, 0b01111100, 0b01100110, 0b01100110, 0b01100110, 0b01111100, 0b01100000, 0b01100000 }; int Z[8]= { 0b00000000, 0b01111110, 0b00000110, 0b00001100, 0b00011000, 0b00110000, 0b01100000, 0b01111110 }; int w[8]= { 0b00011000, 0b00111100, 0b00111100, 0b00011000, 0b00011000, 0b00000000, 0b00011000, 0b00000000 }; int O[8]= { 0b00000000, 0b00111100, 0b01100110, 0b01100110, 0b01100110, 0b01100110, 0b01100110, 0b00111100 }; int E[8]= { 0b00000000, 0b01111110, 0b01100000, 0b01100000, 0b01111100, 0b01100000, 0b01100000, 0b01111110 }; int cross[8] ={ B00011000, B00011000, B00011000, B11111111, B11111111, B00011000, B00011000, B00011000, }; int x[8]={ B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 }; int X[]= { 0b00000000, 0b01100011, 0b01100011, 0b00110110, 0b00011100, 0b00110110, 0b01100011, 0b01100011 }; /********************************* S E T U P **********************************/ void setup() { Serial.begin(9600); //debug_analog(); FastLED.addLeds(leds, NUM_LEDS); init_lcd(); init_buttons(); init_led8x8(); go_intro(1); //update_threshold(); mode=4; } /********************************* L O O P **********************************/ void loop() { if (mode==3) {init_lcd(); go_intro(1); mode=4;} if (mode==4) start_again(); if (mode==2) { int a,b,c; do { a=digitalRead(buttons[0]); b=digitalRead(buttons[1]); c=digitalRead(buttons[4]); } while ((a==HIGH) && (b==HIGH) && (c==HIGH)); if (a==LOW) { free_display(pos,2); pos-=1; if (pos<0) pos=9; if (pos==8) pos=7; free_display(pos,1); } if (b==LOW) { free_display(pos,2); pos+=1; if (pos==8) pos=9; if (pos==10) pos=0; free_display(pos,1); } if (c==LOW) mode=4; delay(100); } if (mode==1) { int a; played=0; for(int i=0;i<9;i++) { a=analogRead(ain[i]); if (a>threshold) //a box has been selected play_board(i); if (played) { int w=find_winner(); if (w>0) { //line_star(); lcd_msg(4,0,"Winner:",1); lcd_msg(4,2,String(w),0); press_key(); //line_star(); mode=4; } else { int isfull=check_full(); if (isfull) mode=4; else { if (player==1) player=2; else player=1; lcd_msg(0,0,"Next Player:",1); lcd_msg(12,0,String(player),0); played=0; } } } }//play with ldr } } void free_display(int box, int type) { if (type==1) { if ((box>=0) && (box<9)) for(int h=0;h<8;h++) lc.setRow(box,h,frame[h]); if (box==9) for(int h=0;h<8;h++) lc9.setRow(0,h,frame[h]); } else if (type==2) { if ((box>=0) && (box<9)) for(int h=0;h<8;h++) lc.setRow(box,h,empty[h]); if (box==9) for(int h=0;h<8;h++) lc9.setRow(0,h,empty[h]); } } void start_again() { init_board(); clear_matrix(); lcd.clear(); player=1;pos=0; lcd_msg(0,0,"1- Use LDR sensors",1); lcd_msg(0,1,"2- Use keypad",0); lcd_msg(0,2,"3- Play intro",0); int a,b,c,d; //clear(); int potval,pot; do { a=digitalRead(buttons[0]); b=digitalRead(buttons[1]); c=digitalRead(buttons[2]); pot=analogRead(13); potval=map(pot,0,1023,500,150); lcd_msg(0,3,String(potval),0); } while ((a==HIGH) && (b==HIGH) && (c==HIGH)); update_threshold(potval); if (c==LOW) mode=3; else { lcd_msg(0,0,"Next Player:",1); lcd_msg(12,0,String(player),0); if (a==LOW) mode=1; if (b==LOW) mode=2; } } void start_game() { lcd_msg(0,0,"Starting new game...",0); press_key(); if ((analogRead(12)>threshold) || (digitalRead(buttons[0]==LOW))) { init_board(); clear_matrix(); lcd.clear(); player=1; lcd_msg(0,0,"Next Player:",1); lcd_msg(12,0,String(player),0); } } void play_board(int i) { if (board[i]==0) //if box is free { display(matrix[i],player); played=1; if (player==1) board[i]=player; else board[i]=8; } else //box is not empty { lcd_msg(4,3,"Box not empty",0); } } void press_key() { lcd_msg(1,3,"OK to continue",0); while((analogRead(12)=0) && (box<9)) { if (player==1) for(int h=0;h<8;h++) lc.setRow(box,h,X[h]); else for(int h=0;h<8;h++) lc.setRow(box,h,O[h]); } if (box==9) { if (player==1) for(int h=0;h<8;h++) lc9.setRow(0,h,X[h]); else for(int h=0;h<8;h++) lc9.setRow(0,h,O[h]); } } void clear() { for(int i=0;i<10;i++) Serial.println(""); } void test_lcd() { lcd.init(); lcd.backlight(); lcd.setCursor(7,0); lcd.print("WELCOME"); lcd.setCursor(7,1); lcd.print("I2C LCD"); lcd.setCursor(7,2); lcd.print("20x4"); lcd.setCursor(7,3); lcd.print("TEST!!!"); } void lcd_msg(int col, int row, String text, int clr) { if (clr) lcd.clear(); lcd.setCursor(col,row); lcd.print(text); } void test_led(int r, int g, int b) { for (int i = 0; i <= 30; i++) { leds[i] = CRGB ( r, g, b); FastLED.show(); delay(d); leds[i] = CRGB ( 0, 0, 0); FastLED.show(); } } void print_tictactoe(int d1) { //TIC for(int h=0;h<8;h++) lc.setRow(6,h,T[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(7,h,I[h]); delay(d1); for(int h=0;h<8;h++) lc9.setRow(0,h,C[h]); delay(d1); //TAC for(int h=0;h<8;h++) lc.setRow(3,h,T[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(4,h,A[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(5,h,C[h]); //TOE delay(d1); for(int h=0;h<8;h++) lc.setRow(0,h,T[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(1,h,O[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(2,h,E[h]); } void print_hearts(int dh) { for(int i=0;i<8;i++) { for(int h=0;h<8;h++) lc.setRow(i,h,heart[h]); delay(dh); } for(int h=0;h<8;h++) lc9.setRow(0,h,heart[h]); delay(dh); } void print_triliza(int d1) { //TIC for(int h=0;h<8;h++) lc.setRow(6,h,T[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(7,h,P[h]); delay(d1); for(int h=0;h<8;h++) lc9.setRow(0,h,I[h]); delay(d1); //TAC for(int h=0;h<8;h++) lc.setRow(3,h,L[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(4,h,I[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(5,h,Z[h]); //TOE delay(d1); for(int h=0;h<8;h++) lc.setRow(0,h,A[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(1,h,w[h]); delay(d1); for(int h=0;h<8;h++) lc.setRow(2,h,w[h]); delay(d1); } void line_on(int start, int stop, int r, int g, int b, int d) { if (r>0) r-=128; if (g>0) g-=128; if (b>0) b-=128; for (int i = start; i <= stop; i++) { leds[i] = CRGB ( r, g, b); FastLED.show(); } delay(d); for (int i = start; i <= stop; i++) { leds[i] = CRGB ( 0, 0, 0); FastLED.show(); } FastLED.show(); } void go_intro(int n) { for(int i=1;i<=n;i++) { print_hearts(100); print_tictactoe(100); delay(2000); print_hearts(100); print_triliza(100); delay(2000); print_hearts(100); line_star(); } clear_matrix(); } void line_star() { line_on(0,5,255,0,0,200); line_on(6,11,0,255,0,200); line_on(12,17,0,0,255,200); line_on(18,23,255,0,0,200); line_on(24,29,0,255,0,200); } void clear_matrix() { for(int i=0;i<8;i++) lc.clearDisplay(i); lc9.clearDisplay(0); } void debug() { int a; while(1) { for(int i=0;i<13;i++) { a=analogRead(i); if (a<50) { Serial.print(i);Serial.print(":");Serial.println(a); } } //Serial.println(); } } void init_board() { for(int i=0;i<9;i++) board[i]=0; } void debug_analog() { int a; int pot; while(1) { for(int i=0;i<9;i++) { a=analogRead(ain[i]); Serial.print(a);Serial.print(" "); } pot=analogRead(13); Serial.print("--");Serial.print(pot); Serial.println("");delay(300); } }