#include <FastLED.h>
//For Chess pieces
#define EMPTY 0
#define PAWN 1
#define KNIGHT 2
#define BISHOP 3
#define ROOK 4
#define QUEEN 5
#define KING 6
// Use negative values for black pieces
//Tracker variables for movement
int pickedUpRow = -1;
int pickedUpCol = -1;
bool isPiecePickedUp = false;
//switch tracker
byte prevSwitchStates[8][8] = {{0}}; // Initialize all to 0
#define NUM_LEDS 64 // Define the number of LEDs
#define LED_DATA_PIN 6 // The data pin for the LED strip
#define LED_TYPE WS2812B // Type of LED strip
#define LED_COLOR_ORDER GRB // Color order for the LED strip
// Pin definitions for the HC165 shift register
#define SHIFT_REGISTER_PIN_DATA 12 // Data pin
#define SHIFT_REGISTER_PIN_CLOCK 13 // Clock pin
#define SHIFT_REGISTER_PIN_LATCH 9 // Latch pin
CRGB leds[NUM_LEDS]; // Array to hold the LEDs
void setup() {
// Set the pin modes for the shift register pins
pinMode(SHIFT_REGISTER_PIN_DATA, INPUT);
pinMode(SHIFT_REGISTER_PIN_CLOCK, OUTPUT);
pinMode(SHIFT_REGISTER_PIN_LATCH, OUTPUT);
// Initialize the LED strip
FastLED.addLeds<LED_TYPE, LED_DATA_PIN, LED_COLOR_ORDER>(leds, NUM_LEDS);
// Initialize serial communication at 9600 bits per second
Serial.begin(9600);
}
// Define a new 8x8 matrix for LED control, initially filled with 1's
byte ledControlMatrix[8][8] = {0};
//Define a matrix for Chess board
byte chessBoard[8][8] = {
{ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK},
{PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN},
{EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},
{EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},
{EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},
{EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},
{-PAWN, -PAWN, -PAWN, -PAWN, -PAWN, -PAWN, -PAWN, -PAWN},
{-ROOK, -KNIGHT, -BISHOP, -QUEEN, -KING, -BISHOP, -KNIGHT, -ROOK}
};
//Logic for movements updating
void updateChessBoard(int oldRow, int oldCol, int newRow, int newCol) {
int piece = chessBoard[oldRow][oldCol];
chessBoard[newRow][newCol] = piece; // Move the piece to the new position
chessBoard[oldRow][oldCol] = EMPTY; // Set the old position to empty
updateLEDsFromMatrix(); // Optional: Update LED display to reflect new board state
}
//logic for updating lights
void updateLEDsFromMatrix() {
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
int ledIndex = (row % 2 == 0) ? (row * 8 + (7 - col)) : (row * 8 + col);
leds[ledIndex] = ledControlMatrix[row][col] ? CRGB::Green : CRGB::Black;
}
}
FastLED.show();
}
//Logic for pawn
void showPossibleMovesForPawn(int row, int col, int piece) {
//Clear last highlight
memset(ledControlMatrix, 0, sizeof(ledControlMatrix));
// Determine pawn direction based on its color
int direction = (piece > 0) ? -1 : 1; // White pawns move up (-1), Black pawns move down (+1)
// Standard move (one square forward)
int nextRow = row + direction;
if (nextRow >= 0 && nextRow < 8 && chessBoard[nextRow][col] == EMPTY) {
ledControlMatrix[nextRow][col] = 1; // Highlight this square
// Check for the initial two-square move
if ((piece > 0 && row == 6) || (piece < 0 && row == 1)) {
int twoSquaresForward = row + 2 * direction;
if (chessBoard[twoSquaresForward][col] == EMPTY) {
ledControlMatrix[twoSquaresForward][col] = 1; // Highlight this square
}
}
Serial.print("I am Working");
}
// This function assumes the existence of updateLEDsFromMatrix() which updates the actual LEDs from ledControlMatrix
updateLEDsFromMatrix();
}
void loop() {
digitalWrite(SHIFT_REGISTER_PIN_LATCH, LOW);
delayMicroseconds(5);
digitalWrite(SHIFT_REGISTER_PIN_LATCH, HIGH);
delayMicroseconds(5);
// Reading from the shift registers into an array
byte switchStates[8];
for (int i = 0; i < 8; ++i) {
switchStates[i] = shiftIn(SHIFT_REGISTER_PIN_DATA, SHIFT_REGISTER_PIN_CLOCK, MSBFIRST);
}
// Check for changes in the switch matrix and identify the chess piece
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
byte currentState = bitRead(switchStates[7-i], j);
if (currentState != prevSwitchStates[i][j]) { // Detect change
prevSwitchStates[i][j] = currentState; // Update previous state
Serial.print(currentState == 1 ? "Piece picked up at: " : "Piece placed down at: ");
Serial.print(i);
Serial.print(", ");
Serial.println(j);
if (currentState == 1) { // Piece picked up
pickedUpRow = i;
pickedUpCol = j;
isPiecePickedUp = true;
} else if (isPiecePickedUp && currentState == 0) { // Piece placed down
updateChessBoard(pickedUpRow, pickedUpCol, i, j);
isPiecePickedUp = false;
}
// Identifying the chess piece type
int piece = chessBoard[i][j]; // Identify the chess piece
Serial.print("Piece type: ");
if (piece > 0) {
Serial.print("White ");
} else if (piece < 0) {
Serial.print("Black ");
}
piece = abs(piece); // Make piece positive to check type
switch (piece) {
case PAWN: Serial.println("Pawn"); break;
case KNIGHT: Serial.println("Knight"); break;
case BISHOP: Serial.println("Bishop"); break;
case ROOK: Serial.println("Rook"); break;
case QUEEN: Serial.println("Queen"); break;
case KING: Serial.println("King"); break;
default: Serial.println("Empty");
}
if (piece == PAWN) {
showPossibleMovesForPawn(i, j, piece);
}
}
}
}
// Update and compare the matrix to detect changes and identify chess pieces
// The provided code goes here, replacing the example change detection and identification logic
// Create an 8x8 matrix and populate it with switch states
byte matrix[8][8];
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
matrix[i][j] = bitRead(switchStates[7-i], j); // Each row corresponds to a shift register
}
}
// Print the matrix to Serial Monitor
Serial.println("Switch Matrix:");
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
Serial.print(matrix[i][j]);
Serial.print(" ");
}
Serial.println();
}
Serial.println();
delay(500);
}
// Custom shiftIn function to read the state of the shift register
byte shiftIn(byte dataPin, byte clockPin, byte bitOrder){
byte value = 0;
for (int i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
delayMicroseconds(5); // Ensure a stable clock pulse
if (bitOrder == LSBFIRST) {
value |= digitalRead(dataPin) << i;
} else {
value |= digitalRead(dataPin) << (7 - i);
}
digitalWrite(clockPin, LOW);
delayMicroseconds(5); // Ensure a stable clock pulse
}
return value;
}