#include <iostream>
#include <random>
#include <vector>
#include <ShiftRegister74HC595.h>
using namespace std;
bool p1Flags[9];
bool p2Flags[9];
ShiftRegister74HC595 < 1 > redLeds(23, 19, 21);
ShiftRegister74HC595 < 1 > greenLeds(5, 15, 22);
const int redLed8Pin = 4;
const int greenLed8Pin = 2;
bool xFields[9] = {false, false, false, false, false, false, false, false, false};
bool oFields[9] = {false, false, false, false, false, false, false, false, false};
char board[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
bool playerMove = true;
void lightLeds();
bool checkWinner(char board[][3], char player);
vector < pair < int, int >> checkWinningCoordinates();
bool isBoardFull(char board[][3]);
void flashLeds(pair < int, int > coordinates[]);
void lightLeds() {
for (int i = 0; i < 9; i++) {
xFields[i] = false;
oFields[i] = false;
int row = i / 3;
int col = i % 3;
if (board[row][col] == 'X') {
xFields[i] = true;
} else if (board[row][col] == 'O') {
oFields[i] = true;
} else if (board[row][col] == '!') {
xFields[i] = true;
oFields[i] = true;
}
if (i == 8) {
break;
}
if (xFields[i]) {
greenLeds.set(i, HIGH);
} else {
greenLeds.set(i, LOW);
}
if (oFields[i]) {
redLeds.set(i, HIGH);
} else {
redLeds.set(i, LOW);
}
}
if (xFields[8]) {
digitalWrite(greenLed8Pin, HIGH);
} else {
digitalWrite(greenLed8Pin, LOW);
}
if (oFields[8]) {
digitalWrite(redLed8Pin, HIGH);
} else {
digitalWrite(redLed8Pin, LOW);
}
}
bool checkWinner(char board[][3], char player) {
for (int row = 0; row < 3; row++) {
if (board[row][0] == board[row][1] && board[row][0] == board[row][2] && board[row][0] == player) {
return true;
}
}
for (int col = 0; col < 3; col++) {
if (board[0][col] == board[1][col] && board[0][col] == board[2][col] && board[0][col] == player) {
return true;
}
}
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == player) {
return true;
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == player) {
return true;
}
return false;
}
vector < pair < int, int >> checkWinningCoordinates() {
vector < pair < int, int >> coordinates;
for (int row = 0; row < 3; row++) {
if (board[row][0] == board[row][1] && board[row][0] == board[row][2] && board[row][0] != ' '){
for (int i = 0; i < 3; i++) {
coordinates.push_back(make_pair(row, i));
}
return coordinates;
}
}
for (int col = 0; col < 3; col++) {
if (board[0][col] == board[1][col] && board[0][col] == board[2][col] && board[0][col] != ' ') {
for (int i = 0; i < 3; i++) {
coordinates.push_back(make_pair(i, col));
}
return coordinates;
}
}
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ') {
for (int i = 0; i < 3; i++) {
coordinates.push_back(make_pair(i, i));
}
return coordinates;
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ') {
for (int i = 0; i < 3; i++) {
coordinates.push_back(make_pair(i, 2 - i));
}
return coordinates;
}
return coordinates;
}
bool isBoardFull(char board[][3]) {
for (int i = 0; i < 9; i++) {
int row = i / 3;
int col = i % 3;
if (board[row][col] == ' ') {
return false;
}
}
return true;
}
void flashLeds(vector < pair < int, int >> coordinates) {
char signs[3];
for (int i = 0; i < coordinates.size(); i++) {
signs[i] = board[coordinates[i].first][coordinates[i].second];
board[coordinates[i].first][coordinates[i].second] = '!';
}
lightLeds();
delay(250);
for (int i = 0; i < coordinates.size(); i++) {
board[coordinates[i].first][coordinates[i].second] = signs[i];
}
lightLeds();
delay(250);
}
void resetGame(bool *p1, bool *p2){
for (int i = 0; i<9;i++){
p2[i] = false;
p1[i] = false;
}
}
void setup() {
pinMode(27, INPUT);
pinMode(14,INPUT);
pinMode(12,INPUT);
pinMode(25, INPUT);
pinMode(26,INPUT);
pinMode(33,INPUT);
pinMode(redLed8Pin, OUTPUT);
pinMode(greenLed8Pin, OUTPUT);
}
void loop() {
int yValue = analogRead(27);
int xValue = analogRead(14);
if(xValue ==0 && yValue == 2048){
p1Flags[5]=1;
}
if(xValue ==4095 && yValue == 2048){
p1Flags[3]=1;
}
if(xValue ==2048 && yValue == 4095){
p1Flags[1]=1;
}
if(xValue ==2048 && yValue == 0){
p1Flags[7]=1;
}
if(xValue ==0 && yValue == 4095){
p1Flags[2]=1;
}
if(xValue ==0 && yValue == 0){
p1Flags[8]=1;
}
if(xValue ==4095 && yValue == 4095){
p1Flags[0]=1;
}
if(xValue ==4095 && yValue == 0){
p1Flags[6]=1;
}
if(digitalRead(12)){
p1Flags[4] = 1;
}
for (int i = 0; i < 9; i++) {
if (p1Flags[i] && playerMove) {
int row = i / 3;
int col = i % 3;
if (board[row][col] == ' ') {
playerMove = false;
board[row][col] = 'X';
}
}
}
lightLeds();
if (!playerMove && !isBoardFull(board)) {
int x2 = analogRead(26);
int y2 = analogRead(25);
if(x2 ==0 && y2 == 2048){
p2Flags[5]=1;
}
if(x2 ==4095 && y2 == 2048){
p2Flags[3]=1;
}
if(x2 ==2048 && y2 == 4095){
p2Flags[1]=1;
}
if(x2 ==2048 && y2 == 0){
p2Flags[7]=1;
}
if(x2 ==0 && y2 == 4095){
p2Flags[2]=1;
}
if(x2 ==0 && y2 == 0){
p2Flags[8]=1;
}
if(x2 ==4095 && y2 == 4095){
p2Flags[0]=1;
}
if(x2 ==4095 && y2 == 0){
p2Flags[6]=1;
}
if(digitalRead(33)){
p2Flags[4] = 1;
}
for (int i = 0; i < 9; i++) {
if (p2Flags[i] && !playerMove) {
int row = i / 3;
int col = i % 3;
if (board[row][col] == ' ') {
playerMove = true;
board[row][col] = 'O';
}
}
}
lightLeds();
}
if (checkWinner(board, 'X')) {
flashLeds(checkWinningCoordinates());
resetGame(p2Flags,p1Flags);
}
if (checkWinner(board, 'O')) {
flashLeds(checkWinningCoordinates());
resetGame(p2Flags,p1Flags);
}
delay(1);
}