Go Down

Topic: 8x8 LED Matrix Tic Tac Toe Game  (Read 904 times) previous topic - next topic

farous97

Dec 05, 2017, 03:28 am Last Edit: Dec 05, 2017, 03:35 am by farous97
Hello! So this project uses the Arduino UNO/RedBoard from Sparksfun, 8x8 Bicolor LED Matrix from Adafruit, and a 2-Axis Thumb Joystick.

I'm almost done making the game but the issue I am facing right is whenever I hover over a taken spot on the matrix with the joystick, the LED turns off. So I want add a condition that will make the LED skip over already taken spots. I have an idea of maybe using an array but I have no clue how to actually do it. Adding the win condition of the game after figuring that out should be the same idea.

Shown below is the program, libraries, and the parts that I used. I also have some comments that will help.

http://www.kr4.us/sparkfun-redboard-programmed-with-arduino.html
https://learn.adafruit.com/adafruit-led-backpack/bi-color-8x8-matrix
http://www.learningaboutelectronics.com/Articles/Arduino-2-axis-thumb-joystick.php


https://github.com/adafruit/Adafruit-GFX-Library
https://github.com/adafruit/Adafruit_LED_Backpack

Code: [Select]


#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

#define ROWS 8
#define COLS 8
#define PLAYER_1 LED_GREEN
#define PLAYER_2 LED_RED

Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();

/************* Variables ************/
//Binary map for board
static const uint8_t PROGMEM
  board_bmp[] = {
    B00100100,
    B00100100,
    B11111111,
    B00100100,
    B00100100,
    B11111111,
    B00100100,
    B00100100 };
    
int buttonState = HIGH;
int X=6;
int Y=6;
bool player1 = true;
bool victory = false;
bool filled[8][8] = {false};

//Joystick Pins
const int SW_pin = 2;
const int X_pin = 0;
const int Y_pin = 1;


/********* Setup **********/
void setup()
{
  Serial.begin(9600);
  matrix.begin(0x70);

  pinMode(SW_pin, INPUT);
  digitalWrite(SW_pin, HIGH);
 

  //Make Game board
  matrix.setBrightness(5);
  matrix.drawBitmap(0, 0, board_bmp, ROWS, COLS, LED_YELLOW);
  matrix.writeDisplay();
}

/******** Loop *******/
void loop() {
  
matrix.setRotation(0); //Set rotation to normal

while(!victory) {

/********* Player 1's turn ********/
    while(player1) {
      Serial.print("X Axis:");
      Serial.print(X);
      Serial.print("\n");
      Serial.print("Y Axis:");
      Serial.print(Y);
      Serial.print("\n\n");
      matrix.drawRect(X,Y, 2,2, PLAYER_1);
      matrix.writeDisplay();
      delay(300);
      
      //Go Left
      if((analogRead(X_pin) < 500) && (X < 6))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        X=X+3;
        delay(300);
      }
      
      //Go Right
      else if((analogRead(X_pin) > 600) && (X > 0))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        X=X-3;
        delay(300);
      }
      //Go Up
      else if((analogRead(Y_pin) < 500) && (Y < 6))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        Y=Y+3;
        delay(300);
      }
      //Go Down
      else if((analogRead(Y_pin) > 600) && (Y > 0))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        Y=Y-3;
        delay(300);
      }
      
      //Click button for player 1
      buttonState = digitalRead(SW_pin);
      if(buttonState==LOW)
      {
        Serial.print("Button Click \n");
        Serial.print("X Axis:");
        Serial.print(X);
        Serial.print("\n");
        Serial.print("Y Axis:");
        Serial.print(Y);
        Serial.print("\n\n");
        matrix.drawRect(X,Y, 2,2, PLAYER_1);
        matrix.writeDisplay();
        delay(300);
        X=6;
        Y=6;
        player1 = false;
      }
    }
  

/*********** Player 2's turn *********/
  while(!player1) {
      matrix.drawRect(X,Y, 2,2, PLAYER_2);
      matrix.writeDisplay();
      delay(300);
      
      //Go Left
      if((analogRead(X_pin) < 500) && (X < 6))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        X=X+3;
        delay(300);
      }
      //Go Right
      else if((analogRead(X_pin) > 600) && (X > 0))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        X=X-3;
        delay(300);
      }
      //Go Up
      else if((analogRead(Y_pin) < 500) && (Y < 6))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        Y=Y+3;
        delay(300);
      }
      //Go Down
      else if((analogRead(Y_pin) > 600) && (Y > 0))
      {
        matrix.drawRect(X,Y, 2,2, LED_OFF);
        matrix.writeDisplay();
        Y=Y-3;
        delay(300);
      }
      
      //Click button for player 2
      buttonState = digitalRead(SW_pin);
      if(buttonState==LOW)
      {
        matrix.drawRect(X,Y, 2,2, PLAYER_2);
        matrix.writeDisplay();
        delay(300);
        X=6;
        Y=6;
        player1 = true;
      }
  }
  }
}

Grumpy_Mike

Quote
I have an idea of maybe using an array but I have no clue how to actually do it.
You already have an array that represents the display board, it is called "board_bmp". This gets updated as you play, so simply look at the appropriate bits in the appropriate array element to see if it is occupied.   

farous97

#2
Dec 05, 2017, 07:48 pm Last Edit: Dec 05, 2017, 09:12 pm by farous97
You already have an array that represents the display board, it is called "board_bmp". This gets updated as you play, so simply look at the appropriate bits in the appropriate array element to see if it is occupied.   
How would you go about that? Sorry I'm still new to programming but I tried printing what's inside the array to see if it was actually updating but I keep getting the same number. And this is when I have the middle location occupied.

I had this code right after while(player1) {}
Code: [Select]

for(int i=0; i<8; i++){
   Serial.print(board_bmp[i]);
}


Output:
Code: [Select]

Button Click
X Axis:3
Y Axis:3

5115924625525110345200

TonyWilk

#3
Dec 09, 2017, 07:15 am Last Edit: Dec 09, 2017, 07:21 am by TonyWilk
You already have an array that represents the display board, it is called "board_bmp". This gets updated as you play, so simply look at the appropriate bits in the appropriate array element to see if it is occupied.   
Sorry, but that's rubbish...

Code: [Select]
//Binary map for board
static const uint8_t PROGMEM
  board_bmp[] = {
    B00100100,
    B00100100,
    B11111111,
    B00100100,
    B00100100,
    B11111111,
    B00100100,
    B00100100 };


board_bmp is a fixed, read-only 'bitmap' image of the empty board.

For every step of your controller you are doing:

Code: [Select]
matrix.drawRect(X,Y, 2,2, LED_OFF);

and when player 1 clicks, you do:

Code: [Select]
matrix.drawRect(X,Y, 2,2, PLAYER_1); which sets the led green.

Usually in games like this you don't directly draw the 'screen' on each game move, you keep an internal 'map' of the game board and use that to update the display. What you want is something like:

Code: [Select]
byte gamegrid[3][3]= {
  { LED_OFF, LED_OFF, LED_OFF },
  { LED_OFF, LED_OFF, LED_OFF },
  { LED_OFF, LED_OFF, LED_OFF }
};

// function to update the main display
// using the game positions in gamegrid
//
void updateDisplayWithGamegrid(){

    //  in here write loops for each column (X) and row (Y) in gamegrid
    //  and output to the matrix display like this:
    //
    //      matrix.drawRect(X*3,Y*3, 2,2, gamegrid[X][Y]);

}


When your player clicks to mark a position, you can check gamegrid[][] to see if it's already marked, set that player's move and at the end you then call updateDisplayWithGamegrid()

While a player is moving you can do whatever you like to the display to show them moving because that will get replaced when updateDisplayWithGamegrid() is called

Yours,
   TonyWilk


Go Up