Arduino Esplora Pong Game - c

Over the last couple of days I've been working on a Pong game for Arduino Esplora with Arduino's TFT display. Everything in the game works except that, when the player scores the ball gets deleted from it's last location and reappears in the center (as it should), while when the computer scores the ball doesn't get deleted (or overwritten would be a better word) but reappears in the center. I have tried some changes on this area of the code with no success, particularly since I have no idea where it comes from. Goal detection goes from line 161 to 187.
#include <Esplora.h>
#include <TFT.h> // Arduino LCD library
#include <SPI.h>
float BPX;
float BPY;
int byx;
int bx;
int A;
int by = 1;
int playerScore;
int computerScore;
#define WINSCORE 5
int CPaddlePlus;
int CPaddleMinus;
int R, L, D, U;
int playerPaddle;
int computerPaddle;
int Random;
void setup() {
// initialize the screen
EsploraTFT.begin();
EsploraTFT.background(0, 0, 0);
EsploraTFT.setTextColor(ST7735_YELLOW, ST7735_BLACK);
EsploraTFT.setTextSize(5);
EsploraTFT.setCursor(22, 15);
EsploraTFT.print("PONG");
EsploraTFT.setTextSize(1);
EsploraTFT.println("");
EsploraTFT.println(" By: David Rutherford");
EsploraTFT.println("");
EsploraTFT.println(" Esplora port by:");
EsploraTFT.println(" -Mike Barela");
EsploraTFT.println(" -Bernardo Meurer");
EsploraTFT.setTextColor(ST7735_WHITE, ST7735_BLACK);
EsploraTFT.println(" ");
EsploraTFT.println(" Press Switch 4 To Start");
while (Esplora.readButton(SWITCH_RIGHT) == HIGH)
;
EsploraTFT.fillScreen(ST7735_BLACK);
EsploraTFT.setRotation(0);
DrawCourt(0);
playerScore = 0;
computerScore = 0;
DisplayScore(playerScore, computerScore);
BPX = 15;
BPY = 15;
byx = 15;
bx = 1;
A = 1;
playerPaddle = 48;
computerPaddle = 48;
long seed = Esplora.readLightSensor() * Esplora.readMicrophone() / Esplora.readTemperature(DEGREES_F);
randomSeed(seed);
}
void loop() {
if ((BPY == 80) || (BPY == 20)) {
Random = random(1, 10);
}
CPaddlePlus = computerPaddle + 16;
CPaddleMinus = computerPaddle - 16;
if (Random <= 8) {
if ((A == 1) || ((BPY > 100) && (A == -1))) {
if ((bx == -1) && (BPX < (CPaddlePlus))) {
U = 1;
D = 0;
}
if ((bx == 1) && (BPX > (CPaddlePlus))) {
D = 1;
U = 0;
}
}
else {
D = 0;
U = 0;
}
}
if ((Random > 8) && (Random <= 9)) {
if ((A == 1) || ((BPY > 100) && (A == -1))) {
if ((bx == -1) && (BPX < (CPaddlePlus))) {
U = 0;
D = 1;
}
if ((bx == 1) && (BPX > (CPaddlePlus))) {
D = 0;
U = 1;
}
}
else {
D = 0;
U = 0;
}
}
if (Random > 9) {
if ((A == 1) || ((BPY > 100) && (A == -1))) {
if ((bx == -1) && (BPX < (CPaddleMinus))) {
U = 1;
D = 0;
}
if ((bx == 1) && (BPX > (CPaddleMinus))) {
D = 1;
U = 0;
}
}
else {
D = 0;
U = 0;
}
}
DrawCourt(0);
R = Esplora.readButton(SWITCH_DOWN);
L = Esplora.readButton(SWITCH_UP);
playerPaddle = playerPaddle + R;
playerPaddle = playerPaddle - L;
computerPaddle = computerPaddle + D;
computerPaddle = computerPaddle - U;
EsploraTFT.fillRect(playerPaddle - 1, 3, 2, 3, ST7735_BLACK);
EsploraTFT.fillRect(playerPaddle + 33, 3, 2, 3, ST7735_BLACK);
EsploraTFT.fillRect(playerPaddle, 3, 32, 3, ST7735_GREEN);
if (playerPaddle == 1) {
playerPaddle = 2;
}
if (playerPaddle == 95) {
playerPaddle = 94;
}
EsploraTFT.fillRect(computerPaddle, 154, 32, 3, ST7735_GREEN);
EsploraTFT.fillRect(computerPaddle - 1, 154, 2, 3, ST7735_BLACK);
EsploraTFT.fillRect(computerPaddle + 33, 154, 2, 3, ST7735_BLACK);
if (computerPaddle == 1) {
computerPaddle = 2;
}
if (computerPaddle == 95) {
computerPaddle = 94;
}
byx += A;
BPY = byx;
BPX += bx ;
if ((BPX == 127) || (BPX == 2)) {
(bx = (-1 * bx));
}
else {
};
if ((BPX <= (computerPaddle + 38)) && (BPX >= (computerPaddle - 6)) && (BPY == 149)) {
(A = (-1 * A));
}
else {
};
if ((BPX <= (playerPaddle + 38) && (BPX >= (playerPaddle - 6)) && (BPY == 11))) {
(A = (-1 * A));
}
else {
};
if (BPY >= 160 || BPY <= 0) {//Goal Detection
if (BPY >= 160) {
playerScore = playerScore + 1;
DisplayScore(playerScore, computerScore);
DrawCourt(0);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
BPX = 64;
BPY = 80;
EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
delay(3000);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
byx = 80;
}
else {
computerScore = computerScore + 1;
DisplayScore(playerScore, computerScore);
DrawCourt(0);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
BPX = 64;
BPY = 80;
EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
delay(3000);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
byx = 80;
}
}
DisplayScore(playerScore, computerScore);
if (playerScore == WINSCORE || computerScore == WINSCORE) {
EsploraTFT.setRotation(1);
EsploraTFT.setTextColor(ST7735_WHITE, ST7735_BLACK);
EsploraTFT.setCursor(8, 50);
EsploraTFT.setTextSize(2);
if (playerScore == WINSCORE) {
EsploraTFT.print("YOU WIN");
}
else {
EsploraTFT.print("ESPLORA WINS");
}
EsploraTFT.setTextSize(1);
EsploraTFT.setTextColor(ST7735_YELLOW, ST7735_BLACK);
EsploraTFT.setCursor(8, 90);
EsploraTFT.print("Press Switch 4 To Restart");
while (Esplora.readButton(SWITCH_RIGHT) == HIGH)
;
EsploraTFT.setRotation(0);
EsploraTFT.fillScreen(ST7735_BLACK);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
BPX = 15;
BPY = 15;
byx = 15;
bx = 1;
A = 1;
EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
//EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
//EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
computerScore = 0;
playerScore = 0;
DrawCourt(0);
DisplayScore(playerScore, computerScore);
delay(2000);
}
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
}
void DrawCourt(boolean onlycenter) {
if (!onlycenter) {
EsploraTFT.drawFastVLine(0, 0, 160, ST7735_GREEN);
EsploraTFT.drawFastVLine(127, 0, 160, ST7735_GREEN);
}
EsploraTFT.drawFastHLine(0, 80, 127, ST7735_GREEN);
}
void DisplayScore(int playerScore, int computerScore) {
EsploraTFT.setRotation(1);
EsploraTFT.setTextColor(ST7735_GREEN, ST7735_BLACK);
EsploraTFT.setCursor(65, 5);
EsploraTFT.setTextSize(2);
EsploraTFT.print(playerScore);
EsploraTFT.setCursor(85, 5);
EsploraTFT.print(computerScore);
EsploraTFT.setRotation(0);
}
A visualization of what's happening:

So following #PaulOgilvie's idea I fixed the problem with the following code:
if (BPY >= 160 || BPY <= 0) {//Goal Detection
if (BPY >= 160) {
playerScore = playerScore + 1;
}
else {
computerScore = computerScore + 1;
}
DrawCourt(0);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
EsploraTFT.fillRect(computerPaddle, 154, 32, 3, ST7735_GREEN);
EsploraTFT.fillRect(1,0,126,15,ST7735_BLACK);
EsploraTFT.fillRect(playerPaddle, 3, 32, 3, ST7735_GREEN);
DisplayScore(playerScore, computerScore);
BPX = 64;
BPY = 80;
EsploraTFT.fillCircle(BPX, BPY, 4, ST7735_GREEN);
delay(3000);
EsploraTFT.fillCircle(BPX, BPY, 7, ST7735_BLACK);
byx = 80;
}
Basically I just made a workaround drawing a big black rectangle on top of the whole thing.

Related

finding path to all 3 corners on a chess board starting from 0,0 isn't working

#include <stdio.h>
#define SIDE 8
#define VISITED 1
#define NOT_VISITED 0
#define FALSE 0
#define TRUE !FALSE
void printBoard(int board[][SIDE]);
int goHorsie(int board[][SIDE], int x, int y, int step);
int main(void)
{
int board[SIDE][SIDE] = { NOT_VISITED };
goHorsie(board, 0, 0, 1);
printBoard(board);
getchar();
return 0;
}
int goHorsie(int board[][SIDE], int x, int y, int step)
{
int res = FALSE;
int cor1 = 0, cor2 = 0, cor3 = 0;
if (x == 7 && y == 7)
{
cor1 = 1;
}
if (x == 7 && y == 0)
{
cor2 = 1;
}
if (x == 0 && y == 7)
{
cor3 = 1;
}
if (cor1 == 1 && cor2 == 1 && cor3 == 1)
{
printf("FOUND ALL!\n");
res = TRUE;
}
else if (board[x][y] != NOT_VISITED //We were here already!
|| x >= SIDE || y >= SIDE || x < 0 || y < 0)
{
res = FALSE;
}
else
{
board[x][y] = step;
step++;
res =
goHorsie(board, x + 1, y - 2, step) ||
goHorsie(board, x + 2, y + 1, step) ||
goHorsie(board, x + 2, y - 1, step) ||
goHorsie(board, x + 1, y + 2, step) ||
goHorsie(board, x - 2, y + 1, step) ||
goHorsie(board, x - 2, y - 1, step) ||
goHorsie(board, x - 1, y + 2, step) ||
goHorsie(board, x + 1, y - 2, step);
if (!res)
{
board[x][y] = NOT_VISITED;
}
}
return res;
}
/*
Prints the chess board
*/
void printBoard(int board[][SIDE])
{
int i = 0, j = 0;
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
printf("%3d", board[i][j]);
}
printf("\n");
}
}
im using recursion to find the path to all 3 corners.
i ran the program for about 20min now and it's still didn't get to the solution.
ik why its taking too long but not sure if it will even get me to the answer.
so my question is did i make the function right and will it eventually give me the right answer (the path to all 3 corners).

cell overlap removal in vlsi placement

Below code is to remove overlap among cells residing inside grids.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
//coordinate representation
struct Point
{
double x;
double y;
};
//block representation with 4 coordinates
struct Block
{
unsigned int id;
struct Point bottomLeft, topLeft, bottomRight, topRight;
double width, height;
double whitespace;
};
struct Overlap
{
double overlapLength;
struct Block *b1, *b2;
} OL[1000];
struct Block *b;
struct Block ROW1, ROW2, ROW3;
int comparator(const void *p, const void *q)
{
return (((struct Overlap *)p)->overlapLength -
(((struct Overlap *)q)->overlapLength));
}
//intialise Blocks using bottom left x,y coordinate
void intialiseBlock(struct Block *B)
{
B->topLeft.x = B->bottomLeft.x;
B->topLeft.y = B->height + B->bottomLeft.y;
B->bottomRight.x = B->width + B->bottomLeft.x;
B->bottomRight.y = B->bottomLeft.y;
B->topRight.x = B->width + B->bottomLeft.x;
B->topRight.y = B->height + B->bottomLeft.y;
}
//update coordinate
void move(double xDelta, double yDelta, struct Point *p)
{
// Parameter values are increments to the current coordinates
p->x += xDelta;
p->y += yDelta;
}
//calculate and return distance between 2 points
double distance(const struct Point aPoint, const struct Point bPoint)
{
return sqrt((aPoint.x - bPoint.x) * (aPoint.x - bPoint.x) +
(aPoint.y - bPoint.y) * (aPoint.y - bPoint.y));
}
//generate width of cell using number of cells
double computeCellWidth(int ncell)
{
double width = (0.8 * 400) / ncell;
return width;
}
//create a
unsigned int rand_interval(unsigned int min, unsigned int max)
{
int r;
const unsigned int range = 1 + max - min;
const unsigned int buckets = RAND_MAX / range;
const unsigned int limit = buckets * range;
/* Create equal size buckets all in a row, then fire randomly towards
* the buckets until you land in one of them. All buckets are equally
* likely. If you land off the end of the line of buckets, try again. */
do
{
r = rand();
} while (r >= limit);
return min + (r / buckets);
}
//place blocks in appropriate rows
void placeVertical(struct Block *b, int n, struct Block ROW1, struct Block ROW2,
struct Block ROW3)
{
for (int i = 0; i < n; i++)
{
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
// check if Inside Row1 and Row2
if ((b[i].bottomLeft.y < ROW1.topLeft.y) && (b[i].topLeft.y > ROW1.topLeft.y))
{
//printf("ROW1 and ROW2 Executed\n");
distanceFromBottom = ROW1.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
// check if Inside Row2 and Row3
else if ((b[i].bottomLeft.y < ROW2.topLeft.y) && (b[i].topLeft.y > ROW2.topLeft.y))
{
//System.out.println("ROW2 and ROW3 Executed");
distanceFromBottom = ROW2.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
else if ((b[i].bottomLeft.y >= ROW1.bottomLeft.y) && (b[i].topLeft.y <= ROW1.topLeft.y))
{
// do nothing in ROW1
}
else if ((b[i].bottomLeft.y >= ROW2.bottomLeft.y) && (b[i].topLeft.y <= ROW2.topLeft.y))
{
// do nothing in ROW2
}
else // ((b[i].bottomLeft.y >=
// ROW2.bottomLeft.y)&&(b[i].topLeft.y <=
// ROW2.topLeft.y))
{
// do nothing in ROW3
}
}
}
//use when floating point operations create run time problems
void linkfloat()
{
float a = 0.0, *x;
x = &a;
a = *x;
}
int findOverlaps(struct Block *b, int n)
{
int k, j, p = 0;
//struct Overlap OL[200];
//short flag = FALSE;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//for ROW1
if (b[k].bottomLeft.y >= 0 && b[k].topLeft.y <= 100 && b[j].bottomLeft.y >= 0 && b[j].topLeft.y <= 100)
{
//if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row2
else if (b[k].bottomLeft.y >= 100 && b[k].topLeft.y <= 200 && b[j].bottomLeft.y >= 100 && b[j].topLeft.y <= 200)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row3
else if (b[k].bottomLeft.y >= 200 && b[k].topLeft.y <= 300 && b[j].bottomLeft.y >= 200 && b[j].topLeft.y <= 300)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
else
{
//do nothing
}
}
}
return p;
}
struct Block *
getBlock(struct Block *b, int n, int id)
{
int i;
for (i = 0; i < n; i++)
{
if (id == b[i].id)
return (b + i);
}
return NULL;
}
void placeHorizontalGreedy(struct Block *b, int n)
{
struct Block *t = NULL;
int p = 0, k = 0;
p = findOverlaps(b, n);
qsort(OL, p, sizeof(struct Overlap), comparator);
while (TRUE)
{
t = getBlock(b, 12, OL[k].b2->id);
if (t != NULL)
{
//t->bottomLeft.x = t->bottomLeft.x+OL[0].overlapLength;
if ((t->bottomLeft.x + OL[0].overlapLength + t->width) <= ROW1.bottomRight.x)
{
move(OL[0].overlapLength, 0, &t->bottomLeft);
intialiseBlock(t);
}
}
p = findOverlaps(b, n);
if (p == 0)
break;
else
qsort(OL, p, sizeof(struct Overlap), comparator);
}
}
void placeHorizontalNonGreedy(struct Block *b, int n, struct Block ROW1,
struct Block ROW2, struct Block ROW3)
{
int k, j, p = 0;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//check if in Row1
if (b[k].bottomLeft.y >= ROW1.bottomLeft.y && b[k].topLeft.y <= ROW1.topLeft.y && b[j].bottomLeft.y >= ROW1.bottomLeft.y && b[j].topLeft.y <= ROW1.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
ROW1.bottomRight.x)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
else
{
b[j].bottomLeft.x =
b[j].bottomLeft.x + (ROW1.bottomRight.x -
b[j].bottomRight.x);
}
}
}
}
//check if in Row2
else if (b[k].bottomLeft.y >= ROW2.bottomLeft.y && b[k].topLeft.y <= ROW2.topLeft.y && b[j].bottomLeft.y >= ROW2.bottomLeft.y && b[j].topLeft.y <= ROW2.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
//check if in Row3
else if (b[k].bottomLeft.y >= ROW3.bottomLeft.y && b[k].topLeft.y <= ROW3.topLeft.y && b[j].bottomLeft.y >= ROW3.bottomLeft.y && b[j].topLeft.y <= ROW3.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
else
{
//printf("Invalid input\n");
continue;
}
}
}
}
int main()
{
//struct Block b[16];
//struct Block b[4];
//struct Block *b;
//struct Block ROW1, ROW2, ROW3;
//FILE *fp = fopen("/home/jeetu/experimentprograms/recordcoord.txt", "w+");
//FILE *fp = fopen("/home/jeetu/experimentprograms/blockcoordinates.txt", "r");
int ncell = 0, width = 0, i = 0, totalncells = 0, id = 0;
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
int x = 0, y = 0, temp = 0, d = 0;
printf("Enter number of cells: ");
scanf("%d", &ncell);
width = computeCellWidth(ncell);
//width = 40;
b = (struct Block *)malloc(3 * ncell * sizeof(struct Block));
//b = (struct Block *)malloc(12 * sizeof(struct Block));
srand(time(0));
ROW1.bottomLeft.x = 0;
ROW1.bottomLeft.y = 0;
ROW1.height = 100;
ROW1.width = 400;
ROW1.whitespace = 40000;
intialiseBlock(&ROW1);
ROW2.bottomLeft.x = 0;
ROW2.bottomLeft.y = 100;
ROW2.height = 100;
ROW2.width = 400;
ROW2.whitespace = 40000;
intialiseBlock(&ROW2);
ROW3.bottomLeft.x = 0;
ROW3.bottomLeft.y = 200;
ROW3.height = 100;
ROW3.width = 400;
ROW3.whitespace = 40000;
intialiseBlock(&ROW3);
for (i = 0; i < ncell; i++)
{
if (i == 0)
{
// x = rand_interval(0, width / 2);
x = rand() % (width / 2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
//m = rand();
else
{
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW1
if (b[totalncells].bottomLeft.y >= ROW1.bottomLeft.y && b[totalncells].topLeft.y <= ROW1.topLeft.y)
{
ROW1.whitespace =
ROW1.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row2
for (i = 0; i < ncell; i++)
{
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(100, 170); */
//x = rand() % (width / 2);
x = rand() % (width / 2);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(100, 170); */
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
x = rand_interval((temp + (int)width / 2), temp + width);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW2
if (b[totalncells].bottomLeft.y >= ROW2.bottomLeft.y && b[totalncells].topLeft.y <= ROW2.topLeft.y)
{
ROW2.whitespace =
ROW2.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row3
for (i = 0; i < ncell; i++)
{
//int x = rand_interval(0, 100 - (int)width);
//int y = rand_interval(20, 25); //cell height is 5 so max will reach 30
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(200, 250); */
x = rand() % (width / 2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(200, 250); */
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW3
if (b[totalncells].bottomLeft.y >= ROW3.bottomLeft.y && b[totalncells].topLeft.y <= ROW3.topLeft.y)
{
ROW3.whitespace =
ROW3.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
for (i = 0; i < totalncells; i++)
{
//printf("%f %f %f %f\n", b[i].bottomLeft.x, b[i].bottomLeft.y, b[i].width, b[i].height);
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
placeVertical(b, totalncells, ROW1, ROW2, ROW3);
//placeVerticalWithDensityConstraints(b,totalncells,ROW1,ROW2,ROW3);
printf("\nAfter vertical Updation\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
/*placeHorizontalNonGreedy(b, 12, ROW1, ROW2, ROW3);
printf("\nAfter Horizontal Updation(Non greedy)\n");
for (i = 0; i < 12; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x, (int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
} */
placeHorizontalGreedy(b, totalncells);
printf("\nAfter Horizontal Updation(Greedy)\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
return 0;
}
Explanation about the code
in this program I have defined three structures
one to represent a Point,one to represent rectangular block with 4 coordinates,one to represent overlap between pair of cells.
There is function(computeCellWidth) to dynamically compute width of cells according to a formula.
There are three rows ROW1,ROW2,ROW3 in which cells will reside.
This program will first ask for number of cells and this is numbers of cells per row.At first x,y coordinates for each cell is randomly generated.Then placeVertical() function will move cells to different rows which are spanning across two rows.Then there is a placeHorizontalGreedy() function which will remove overlap among cells by first finding overlaplength and then sorting them and removing the overlap between cells which has least overlap and this process will continue till either there will be no overlaps or overlap removal is not possible anymore.Here I would like to bring to the notice of everybody that cells will be moved towards the right of the grid to remove overlaps.In placeHorizontalGreedy() function I have used a variable p which will indicate number of overlaps after each iteration.for small number of cells testing for p to be zero works fine but not as I increase the numbers.Plus how can I make sure that overlaps exists but overlap removal is not possible anymore,so that I can stop the loop. Please help me out.

C language isMagicsquare function: What logic error is in my function code?

Although the output with the my current examples is correct, my code seems to have a logic error that doesn't give the right output for other cases.
I have previously addressed this issue:
"What would happen in your code if there are no repeated numbers, all numbers are used, your last column sum is correct, but your second-last column sum is incorrect?"
Any help would be very much appreciated.
My current code:
/* Magic Square */
#include <stdio.h>
#define MAX_N 100
#define TRUE 1
#define FALSE 0
int isMagicSquare(int square[MAX_N][MAX_N], int n);
int main(void) {
int square1[MAX_N][MAX_N] = {
{4, 9, 2},
{3, 5, 7},
{8, 1, 6}};
// should print TRUE
int check1 = isMagicSquare(square1, 3);
if (check1 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
int square2[MAX_N][MAX_N] = {
{20, 6, 7, 17},
{ 9, 15, 14, 12},
{13, 11, 10, 16},
{ 8, 18, 19, 5} };
/*{ 1 , 2 , 3 , 4 , },
{ 5 , 6 , 7 , 8 , },
{ 9 , 10, 11, 12, },
{ 13, 14, 15, 16,} };*/
/*{16, 2, 3, 13,},
{5, 11, 10, 8 ,},
{9, 7, 6, 12 ,},
{4, 14, 15, 1, } };*/
// should print FALSE
int check2 = isMagicSquare(square2, 4);
if (check2 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
int square3[MAX_N][MAX_N] = {
{17, 24, 1, 15, 8},
{23, 5, 7, 16, 14},
{ 4, 6, 13, 22, 20},
{10, 12, 19, 3, 21},
{11, 18, 25, 9, 2}};
// should print FALSE
int check3 = isMagicSquare(square3, 5);
if (check3 == TRUE) {
printf("TRUE\n");
} else {
printf("FALSE\n");
}
return 0;
}
int isMagicSquare(int square[MAX_N][MAX_N], int n) {
int row, col;
int drow, dcol;
int sum, sum1, sum2, sum3;
int boolean = 0;
//For Diagonals
sum = 0;
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if (row == col)
sum += square[row][col];
}
}
for (row = 0; row < n; row++) {
sum3 = 0;
for (col = 0; col < n; col++) {
sum3 += square[n-row-1][col];
}
if (sum == sum3)
boolean = 1;
else {
return FALSE;
}
}
//For Rows
for (row = 0; row < n; row++) {
sum1 = 0;
for (col = 0; col < n; col++) {
sum1 = sum1 + square[row][col];
}
if (sum == sum1)
boolean = 1;
else {
return FALSE;
}
}
//For Columns
for (row = 0; row < n; row++) {
sum2 = 0;
for (col = 0; col < n; col++) {
sum2 = sum2 + square[col][row];
}
if (sum == sum2)
boolean = 1;
else {
return FALSE;
}
}
if (boolean == 1) {
//Check if All Numbers is used
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if(square[row][col] > n*n || square[row][col] < 0) {
boolean = 0;
break;
}
}
}
//Check for Repeating Numbers
for (row = 0; row < n; row++) {
for(col = 0; col < n; col++) {
for(drow = row + 1; drow < n; drow++){
for(dcol = col + 1; dcol < n; dcol++) {
if(square[row][col] == square[drow][dcol]) {
boolean = 0;
break;
}
}
}
}
}
// if Statement End
}
else {
boolean = 0;
}
if (boolean == 1)
return TRUE;
else
return FALSE;
}
it seems the sum3 var is reinitialized to 0 inside the computation loop, plus the diagonal sum equality check should be outside of the loop.
I would rework it this way:
//For Diagonals
sum = 0;
sum3 = 0;
for (row = 0; row < n; row++) {
sum += square[row][row];
sum3 += square[row][n - 1 - row];
}
if (sum == sum3)
boolean = 1;
else {
return FALSE;
}
BTW I simplified a bit the diagonal calculation since it is linear, there is no need for 2 nested loops.
I found some other bugs in the final checks:
-0 should not be a valid value
-return instead of just breaking (break only exists the inner loop, the outer loop continues)
for (row = 0; row < n; row++) {
for (col = 0; col < n; col++) {
if(square[row][col] > n*n || square[row][col] <= 0) {
return FALSE;
}
}
}
//Check for Repeating Numbers
int storedNumbers[n * n];
for (row = 0; row < n; row++) {
for(col = 0; col < n; col++) {
storedNumbers[row + n * col] = square[row][col];
}
}
Then scan storedNumbers for duplicates.
Searching for duplicate values in an array
cheers
You can use a more compact scheme to check that all numbers 1 .. (n*n) are used with no duplicates using code such as:
int counts[n * n]; // Can't use an initializer with a VLA
memset(counts, '\0', sizeof(counts));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (square[i][j] <= 0 || square[i][j] > n * n)
return FALSE;
counts[square[i][j] - 1]++; // Map 1..n*n to 0..n*n-1
// if (++counts[square[i][j] - 1] > 1)
// return FALSE;
}
}
for (int i = 0; i < n * n; i++)
{
if (counts[i] != 1)
return FALSE;
}
Since there are n*n elements to check, this code uses space and time that is linear with respect to the number of elements in the magic square, which is within a constant factor of optimal.

Segmentation Fault in C ,Breadth First Search

I'm trying to access directly into memory in c. I need that because my array size needed to be dynamic. There's the code block that includes Breadth-First Search Algorithm, where am i wrong?
int visited[h][w];
int parent[h][w][2]; // Width, Height, {x,y}
int d[] = {0, -1, 0, 1, 1, 0, -1, 0};
int p[2];
int cell[2];
int *q = (int*)malloc(10000*sizeof(int));
int front = 0, rear = 0;
q[front++]=sPoint[0];
q[front++]=sPoint[1];
visited[sPoint[1]][sPoint[0]] = 1;
while ((front - rear) > 0) {
p[0] = q[rear++]; // [0,1,5,6,7,8]
p[1] = q[rear++];
for (int i = 0; i < 4; i++) {
cell[0] = d[i * 2] + p[0];
cell[1] = d[i * 2 + 1] + p[1];
if (cell[0] >= 0 && cell[0] < w && cell[1] >= 0 && cell[1] < h
&& visited[cell[1]][cell[0]] == 0 && isBlack(cell[0], cell[1]) != 1) {
if(!(front <= sizeof(front)/sizeof(int) - 5))
{
q = (int*)realloc(q,1.75*front);
}
q[front++] = cell[0];
q[front++] = cell[1];
visited[cell[1]][cell[0]] = visited[p[1]][p[0]] + 1;
parent[cell[1]][cell[0]][0] = p[0];
parent[cell[1]][cell[0]][1] = p[1];
if (cell[0] == ePoint[0] && cell[1] == ePoint[1]) {
found = 1;
break;
}
}
}
}

Processing ArrayIndexOutOfBoundsException

I'm writing some code for an interactive graphic I'm making which has three states. I used a switch statement to move between the states which showcase an array of images. I uploaded all the images and yet when I call the one state which has an array of 8 images that I uploaded get an error message: ArrayIndexOutOfBoundsException 8
I can't seem to get rid of it even though I have the correct number of images loaded into my sketch.
Below is my code and I am working on a Macbook Pro OSX using Processing 2.0b7
PImage[] teams;
int n = 24;
PImage[] teams2;
int m = 16;
PImage [] quarterFinalWinners;
int o = 7;
PImage bg;
float damping = 0.1;
PFont font;
String[] positions, prevPositions;
float x;
float y;
int afconState = 3;
/**----------------------------------------------------------------------------------------------------------------------------**/
public void setup() {
size(600, 1600);
bg = loadImage("football-pitch-hi.png");
positions = new String[]{"18", "26", "32", "45", "58", "56", "59", "61", "66", "69", "71", "85", "98", "100", "116", "133"};
prevPositions = new String[]{"14", "19", "25", "30", "34", "45", "52", "69", "71", "72", "87", "84", "89", "105", "107", "110"};
int a = 16;
font = loadFont("Calibri-Bold-48.vlw");
textFont(font);
frame.setResizable(true);
teams = new PImage[n];
for (int i = 0; i < teams.length; i++) {
teams[i] = loadImage(i + ".png");
}
teams2 = new PImage[m];
for (int i = 0; i < teams2.length; i++) {
teams2[i] = loadImage(i + ".gif");
}
quarterFinalWinners = new PImage[o];
for (int o = 0; o < quarterFinalWinners.length; o++); {
quarterFinalWinners[o] = loadImage(o + "_.png");
}
}
/**----------------------------------------------------------------------------------------------------------------------------**/
void draw() {
background(#000000);
if ((x < width) && (y < height)) {
for (int i = 0; i < 16; i++);
}
}
/**----------------------------------------------------------------------------------------------------------------------------**/
public void keyPressed() {
noLoop();
switch(afconState) {
case 1:
afconState = 1;
background(#000000);
for (int i = 0; i < 16; i++) {
image(teams[i], 150, 60*i);
}
}
if ((key == 's') || (key == 'S')) {
afconState = 2;
background(#000000);
for (int i = 0; i < 16; i++) {
image(teams2[i], 150, 60*i);
}
}
else if ((key == 'q') || (key == 'Q')) {
afconState = 3;
background(#000000);
for (int i = 0; i < 16; i++) {
image(quarterFinalWinners[i], 150, 60*i);
}
}
break;
/**----------------------------------------------------------------------------------------------------------------------------**/
case 2:
if((key == 's') || (key == 'S')) {
afconState = 2;
background(#000000);
for (int i = 0; i < 16; i++) {
image(teams2[i], 150, 60*i);
}
}
else if ((key == 'q') || (key == 'Q')) {
afconState = 3;
for (int i = 0; i < 16; i++) {
image(quarterFinalWinners[i], 150, 60*i);
}
}
break;
case 3:
background(#000000);
if ((key == 'q') || (key == 'Q')) {
afconState = 3;
for (int i = 0; i < 16; i++) {
image(quarterFinalWinners[i], 150, 60*i);
}
}
else if((key == 's') || (key == 'S')) {
afconState = 2;
background(#000000);
for (int i = 0; i < 16; i++) {
image(teams2[i], 150, 60*i);
}
}
break;
default:
afconState = 1;
background(#000000);
for (int i = 0; i < 16; i++) {
image(teams[i], 150, 60*i);
}
if ((key == 's') || (key == 'S')) {
afconState = 2;
// modify the positions list
for (int i = 0; i < 16; i++) {
image(teams2[i], 150, 60*i);
}
}
else if ((key == 'q') || (key == 'Q')) {
afconState = 3;
for (int i = 0; i < 16; i++) {
image(quarterFinalWinners[i], 150, 60*i);
}
}
}
redraw();
}
void mousePressed () {
// revert to previous array. We can only do this once.
// if someone pressed the key seven times, we can't revert
// seven times, because the code only has one history state
// that is updated every time a key is pressed
// redraw now that our state has changed
redraw();
}
Most languages index from 0 (ie. 8 items will be indexed 0 through 7) - It looks like you are trying to reference an array item with index 8 which probably doesn't exist.

Resources