#include #include #define LED_PIN 6 #define LED_COUNT 64 #define LEDS_ON_LINE 8 #define LEDS_ON_COL 8 #define LINES 3 #define COLS 3 #define CRT_PLAYER_FACT_MAX 30 #define CRT_PLAYER_FACT_MIN 0 #define BUTTON_LEFT 9 #define BUTTON_OK 8 #define BUTTON_RIGHT 7 #define BUTTON_COOLDOWN 200 int button_cooldown; #define P1 0 #define P2 1 #define EMPTY 2 int crt_player; int crt_player_fact; int crt_player_dir; int crt_line; int crt_col; int col_players[2]; int grid[LINES][COLS] = {EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY}; int score[2]; char col[6][8] = {"red ", "green ", "blue ", "yellow ", "magenta", "cyan "}; int rgb[6][3] = { 1, 0, 0, // red 0, 1, 0, // green 0, 0, 1, // blue 1, 1, 0, // yellow 1, 0, 1, // magenta 0, 1, 1}; // cyan Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); void game_start(); void restart(); void pick_color(); void setup() { // led matrix setup // Initialize all pixels to 'off' strip.begin(); strip.show(); // game setup crt_player = P1; crt_player_fact = 0; crt_player_dir = 1; crt_line = 0; crt_col = 0; // lcd display setup lcd.begin(16, 2); lcd.clear(); lcd.print("Hello!"); // buttons setup pinMode(BUTTON_LEFT, INPUT_PULLUP); pinMode(BUTTON_OK, INPUT_PULLUP); pinMode(BUTTON_RIGHT, INPUT_PULLUP); button_cooldown = 0; pick_color(); game_start(); } void color_border(); void update_crt_player_factor(); void color_grid(); void blink_crt(); void right_push(); void left_push(); void ok_push(); void switch_crt_player(); void celebrate(int winner); void draw(); void check_for_winner(); void loop() { if (button_cooldown <= 0 && digitalRead(BUTTON_LEFT) == 0) { left_push(); button_cooldown = BUTTON_COOLDOWN; } if (button_cooldown <= 0 && digitalRead(BUTTON_OK) == 0) { ok_push(); button_cooldown = BUTTON_COOLDOWN; } if (button_cooldown <= 0 && digitalRead(BUTTON_RIGHT) == 0) { right_push(); button_cooldown = BUTTON_COOLDOWN; } color_border(); update_crt_player_factor(); color_grid(); blink_crt(); strip.show(); delay(50); if (button_cooldown > 0) { button_cooldown -= 50; } check_for_winner(); } ////////////////////////////////////////////////////////////////////////////////// void game_start() { lcd.clear(); lcd.print("Game starts!"); lcd.setCursor(0, 1); lcd.print("Good luck!"); delay(3000); } void restart() { // led matrix setup // Initialize all pixels to 'off' for (int j = 0; j < LED_COUNT; j++) strip.setPixelColor(j, 0, 0, 0); strip.show(); // game setup crt_player = P1; crt_player_fact = 0; crt_player_dir = 1; crt_line = 0; crt_col = 0; for (int i = 0; i < LINES; i++) for (int j = 0; j < COLS; j++) grid[i][j] = EMPTY; button_cooldown = 0; pick_color(); game_start(); } void pick_color() { for (int i = 0; i < 2; i++) { col_players[i] = 0; lcd.clear(); lcd.print(String("Player ") + String(i + 1) + String(" color:")); int crt_col = 0; if (i == 1 && crt_col == col_players[0]) { crt_col = (crt_col - 1 + 6) % 6; } while (1) { lcd.setCursor(0, 1); lcd.print(col[crt_col]); if (digitalRead(BUTTON_OK) == 0) { col_players[i] = crt_col; delay(BUTTON_COOLDOWN); break; } if (digitalRead(BUTTON_LEFT) == 0) { crt_col = (crt_col - 1 + 6) % 6; if (i == 1 && crt_col == col_players[0]) { crt_col = (crt_col - 1 + 6) % 6; } } if (digitalRead(BUTTON_RIGHT) == 0) { crt_col = (crt_col + 1) % 6; if (i == 1 && crt_col == col_players[0]) { crt_col = (crt_col + 1) % 6; } } delay(BUTTON_COOLDOWN); } } } ////////////////////////////////////////////////////////////////////////////////// void color_border() { int r, g, b; r = rgb[col_players[crt_player]][0]; g = rgb[col_players[crt_player]][1]; b = rgb[col_players[crt_player]][2]; // upper border for (int i = 0; i < LEDS_ON_COL; i++) { strip.setPixelColor(i, r * crt_player_fact, g * crt_player_fact, b * crt_player_fact); } // lower border for (int i = 0; i < LEDS_ON_COL; i++) { strip.setPixelColor((LEDS_ON_COL - 1) * LEDS_ON_LINE + i, r * crt_player_fact, g * crt_player_fact, b * crt_player_fact); } // left border for (int i = 1; i < LEDS_ON_LINE; i++) { strip.setPixelColor(i * LEDS_ON_LINE, r * crt_player_fact, g * crt_player_fact, b * crt_player_fact); } // right border for (int i = 1; i < LEDS_ON_LINE; i++) { strip.setPixelColor(i * LEDS_ON_LINE + LEDS_ON_LINE - 1, r * crt_player_fact, g * crt_player_fact, b * crt_player_fact); } } void update_crt_player_factor() { if (crt_player_fact + crt_player_dir <= CRT_PLAYER_FACT_MAX && crt_player_fact + crt_player_dir >= CRT_PLAYER_FACT_MIN) { crt_player_fact += crt_player_dir; } else { crt_player_dir *= -1; } } void color_grid() { int r, g, b; for (int line = 0; line < LINES; line++) { for (int col = 0; col < COLS; col++) { int line_index = line * 2 + 1; int col_index = col * 2 + 1; int elem1 = line_index * LEDS_ON_LINE + col_index; int elem2 = elem1 + 1; int elem3 = elem1 + LEDS_ON_LINE; int elem4 = elem3 + 1; if (grid[line][col] == P1) { r = 20 * rgb[col_players[P1]][0]; g = 20 * rgb[col_players[P1]][1]; b = 20 * rgb[col_players[P1]][2]; } else if (grid[line][col] == P2){ r = 20 * rgb[col_players[P2]][0]; g = 20 * rgb[col_players[P2]][1]; b = 20 * rgb[col_players[P2]][2]; } else { r = g = b = 0; } strip.setPixelColor(elem1, r, g, b); strip.setPixelColor(elem2, r, g, b); strip.setPixelColor(elem3, r, g, b); strip.setPixelColor(elem4, r, g, b); } } } void blink_crt() { int line_index = crt_line * 2 + 1; int col_index = crt_col * 2 + 1; int elem1 = line_index * LEDS_ON_LINE + col_index; int elem2 = elem1 + 1; int elem3 = elem1 + LEDS_ON_LINE; int elem4 = elem3 + 1; if (crt_player_fact % 10) { strip.setPixelColor(elem1, crt_player_fact, crt_player_fact, crt_player_fact); strip.setPixelColor(elem2, crt_player_fact, crt_player_fact, crt_player_fact); strip.setPixelColor(elem3, crt_player_fact, crt_player_fact, crt_player_fact); strip.setPixelColor(elem4, crt_player_fact, crt_player_fact, crt_player_fact); } else { strip.setPixelColor(elem1, 0, 0, 0); strip.setPixelColor(elem2, 0, 0, 0); strip.setPixelColor(elem3, 0, 0, 0); strip.setPixelColor(elem4, 0, 0, 0); } } void right_push() { crt_col++; if (crt_col == COLS) { crt_col = 0; crt_line++; } if (crt_line == LINES) { crt_line = 0; } } void left_push() { crt_col--; if (crt_col == -1) { crt_col = COLS - 1; crt_line--; } if (crt_line == -1) { crt_line = LINES - 1; } } void ok_push() { if (grid[crt_line][crt_col] == EMPTY) { grid[crt_line][crt_col] = crt_player; switch_crt_player(); crt_line = 0; crt_col = 0; } } void switch_crt_player() { if (crt_player == P1) { crt_player = P2; } else { crt_player = P1; } } void celebrate(int winner) { lcd.clear(); lcd.print(String("Player ") + String(winner + 1) + String(" wins!")); for (int i = 0; i < LED_COUNT; i++) strip.setPixelColor(i, 0, 0, 0); int r = rgb[col_players[winner]][0] * 20; int g = rgb[col_players[winner]][1] * 20; int b = rgb[col_players[winner]][2] * 20; score[winner]++; // drawing strip.setPixelColor(2, r, g, b); strip.setPixelColor(3, r, g, b); strip.setPixelColor(4, r, g, b); strip.setPixelColor(5, r, g, b); strip.setPixelColor(9, r, g, b); strip.setPixelColor(14, r, g, b); strip.setPixelColor(16, r, g, b); strip.setPixelColor(18, r, g, b); strip.setPixelColor(21, r, g, b); strip.setPixelColor(23, r, g, b); strip.setPixelColor(24, r, g, b); strip.setPixelColor(31, r, g, b); strip.setPixelColor(32, r, g, b); strip.setPixelColor(34, r, g, b); strip.setPixelColor(37, r, g, b); strip.setPixelColor(39, r, g, b); strip.setPixelColor(40, r, g, b); strip.setPixelColor(43, r, g, b); strip.setPixelColor(44, r, g, b); strip.setPixelColor(47, r, g, b); strip.setPixelColor(49, r, g, b); strip.setPixelColor(54, r, g, b); strip.setPixelColor(58, r, g, b); strip.setPixelColor(59, r, g, b); strip.setPixelColor(60, r, g, b); strip.setPixelColor(61, r, g, b); strip.show(); delay(3000); lcd.clear(); lcd.print(String("Player 1: ") + String(score[P1])); lcd.setCursor(0, 1); lcd.print(String("Player 2: ") + String(score[P2])); delay(10000); } void draw() { lcd.clear(); lcd.print("Game over!"); lcd.setCursor(0, 1); lcd.print("Draw"); // drawing int r1 = rgb[col_players[0]][0] * 30; int r2 = rgb[col_players[1]][0] * 30; int g1 = rgb[col_players[0]][1] * 30; int g2 = rgb[col_players[1]][1] * 30; int b1 = rgb[col_players[0]][2] * 30; int b2 = rgb[col_players[1]][2] * 30; for (int i = 0; i < LED_COUNT; i++) strip.setPixelColor(i, 0, 0, 0); // X strip.setPixelColor(0, r1, g1, b1); strip.setPixelColor(3, r1, g1, b1); strip.setPixelColor(9, r1, g1, b1); strip.setPixelColor(10, r1, g1, b1); strip.setPixelColor(17, r1, g1, b1); strip.setPixelColor(18, r1, g1, b1); strip.setPixelColor(24, r1, g1, b1); strip.setPixelColor(27, r1, g1, b1); // 0 strip.setPixelColor(37, r2, g2, b2); strip.setPixelColor(38, r2, g2, b2); strip.setPixelColor(44, r2, g2, b2); strip.setPixelColor(47, r2, g2, b2); strip.setPixelColor(52, r2, g2, b2); strip.setPixelColor(55, r2, g2, b2); strip.setPixelColor(61, r2, g2, b2); strip.setPixelColor(62, r2, g2, b2); // diag for (int i = 0; i < LEDS_ON_COL; i++) strip.setPixelColor((i + 1) * LEDS_ON_LINE - i - 1, 10, 10, 10); strip.show(); delay(3000); lcd.clear(); lcd.print(String("Player 1: ") + String(score[P1])); lcd.setCursor(0, 1); lcd.print(String("Player 2: ") + String(score[P2])); delay(10000); } void check_for_winner() { int found = -1; int done = 1; // check lines for (int i = 0; i < LINES && found == -1; i++) { if (grid[i][0] != EMPTY && grid[i][0] == grid[i][1] && grid[i][0] == grid[i][2]) found = grid[i][0]; } // check cols for (int i = 0; i < COLS && found == -1; i++) { if (grid[0][i] != EMPTY && grid[0][i] == grid[1][i] && grid[0][i] == grid[2][i]) found = grid[0][i]; } // check diags if (found == -1 && grid[0][0] != EMPTY && grid[0][0] == grid[1][1] && grid[0][0] == grid[2][2]) found = grid[0][0]; if (found == -1 && grid[0][2] != EMPTY && grid[0][2] == grid[1][1] && grid[0][2] == grid[2][0]) found = grid[0][2]; if (found != -1) { celebrate(found); restart(); } else { for (int i = 0; i < LINES; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] == EMPTY) { done = 0; } } } if (done) { draw(); restart(); } } }