We are about to switch to a new forum software. Until then we have removed the registration on this forum.

- All Categories 25.7K
- Announcements & Guidelines 13
- Common Questions 30
- Using Processing 22.1K
- Programming Questions 12.2K
- Questions about Code 6.4K
- How To... 4.2K
- Hello Processing 72
- GLSL / Shaders 292
- Library Questions 4K
- Hardware, Integration & Other Languages 2.7K
- Kinect 668
- Arduino 1K
- Raspberry PI 188
- Questions about Modes 2K
- Android Mode 1.3K
- JavaScript Mode 413
- Python Mode 205
- Questions about Tools 100
- Espanol 5
- Developing Processing 548
- Create & Announce Libraries 211
- Create & Announce Modes 19
- Create & Announce Tools 29
- Summer of Code 2018 93
- Rails Girls Summer of Code 2017 3
- Summer of Code 2017 49
- Summer of Code 2016 4
- Summer of Code 2015 40
- Summer of Code 2014 22
- p5.js 1.6K
- p5.js Programming Questions 947
- p5.js Library Questions 315
- p5.js Development Questions 31
- General 1.4K
- Events & Opportunities 289
- General Discussion 365

I am trying to build a simple chess engine, but the check function isn't working. I have checked everything and the code makes sense, but it just doesn't work sometimes. It usually works, but there are a few exceptions. I have been trying to fix this bug, but no luck. Help is greatly appreciated!

```
void img() {
wpawn = loadImage("whitepawn.png");
bpawn = loadImage("blackpawn.png");
bqueen = loadImage("blackqueen.png");
wknight = loadImage("whiteknight.png");
wbishop = loadImage("whitebishop.png");
bknight = loadImage("blackknight.png");
wrook = loadImage("whiterook.png");
brook = loadImage("blackrook.png");
wking = loadImage("whiteking.png");
bking = loadImage("blackking.png");
bbishop = loadImage("blackbishop.png");
wqueen = loadImage("whitequeen.png");
bpawn.resize(100, 100);
wknight.resize(100, 100);
bknight.resize(100, 100);
wbishop.resize(100, 100);
bbishop.resize(100, 100);
wrook.resize(100, 100);
brook.resize(100, 100);
wking.resize(100, 100);
bking.resize(100, 100);
wqueen.resize(100, 100);
bqueen.resize(100, 100);
wpawn.resize(100, 100);
locationsglobal[0][0] = wrook;
locationsglobal[0][1] = wknight;
locationsglobal[0][2] = wbishop;
locationsglobal[0][4] = wqueen;
locationsglobal[0][3] = wking;
locationsglobal[0][5] = wbishop;
locationsglobal[0][6] = wknight;
locationsglobal[0][7] = wrook;
locationsglobal[1][0] = wpawn;
locationsglobal[1][1] = wpawn;
locationsglobal[1][2] = wpawn;
locationsglobal[1][3] = wpawn;
locationsglobal[1][4] = wpawn;
locationsglobal[1][5] = wpawn;
locationsglobal[1][6] = wpawn;
locationsglobal[1][7] = wpawn;
locationsglobal[7][0] = brook;
locationsglobal[7][1] = bknight;
locationsglobal[7][2] = bbishop;
locationsglobal[7][4] = bqueen;
locationsglobal[7][3] = bking;
locationsglobal[7][5] = bbishop;
locationsglobal[7][6] = bknight;
locationsglobal[7][7] = brook;
locationsglobal[6][0] = bpawn;
locationsglobal[6][1] = bpawn;
locationsglobal[6][2] = bpawn;
locationsglobal[6][3] = bpawn;
locationsglobal[6][4] = bpawn;
locationsglobal[6][5] = bpawn;
locationsglobal[6][6] = bpawn;
locationsglobal[6][7] = bpawn;
}
PImage[][] movepiece(int y, int x, int y1, int x1, boolean side, PImage[][] locations) {
if (side==white) {
if (locations[y][x] == wqueen) {
locations[y][x] = null;
locations[y1][x1] = wqueen;
} else if (locations[y][x] == wbishop) {
locations[y][x] = null;
locations[y1][x1] = wbishop;
} else if (locations[y][x] == wknight) {
locations[y][x] = null;
locations[y1][x1] = wknight;
} else if (locations[y][x] == wrook) {
locations[y][x] = null;
locations[y1][x1] = wrook;
} else if (locations[y][x] == wpawn) {
locations[y][x] = null;
locations[y1][x1] = wpawn;
} else if (locations[y][x] == wking) {
locations[y][x] = null;
locations[y1][x1] = wking;
}
} else {
if (locations[y][x] == bqueen) {
locations[y][x] = null;
locations[y1][x1] = bqueen;
} else if (locations[y][x] == bbishop) {
locations[y][x] = null;
locations[y1][x1] = bbishop;
} else if (locations[y][x] == bknight) {
locations[y][x] = null;
locations[y1][x1] = bknight;
} else if (locations[y][x] == brook) {
locations[y][x] = null;
locations[y1][x1] = brook;
} else if (locations[y][x] == bpawn) {
locations[y][x] = null;
locations[y1][x1] = bpawn;
} else if (locations[y][x] == bking) {
locations[y][x] = null;
locations[y1][x1] = bking;
}
}
return locations;
}
PImage[][] locationsglobal = new PImage [8][8];
PImage wpawn, bpawn, wknight, bknight, wbishop, bbishop, wrook, brook, wqueen, bqueen, wking, bking;
boolean white = true, turn = white, black = false, click = false;
int clickx, clicky, clickx1, clicky1;
player john = new player(0, true);//0 is black, 1 is white
player ai = new player(1, false);
void setup() {
size(800, 800);
img();
textSize(100);
}
void draw() {//------------------------------------------------------------------
john.move();
ai.move();
showboard();
noStroke();
}
void mousePressed() {
if (click) {
clickx1 = round(mouseX / (width/8)-0.5);
clicky1 = round(mouseY / (height/8)-0.5);
if (legal(clicky,clickx,clicky1,clickx1,black)) {
locationsglobal=movepiece(clicky, clickx, clicky1, clickx1, black, locationsglobal);
turn=white;
}
click= false;
} else {
clickx = round(mouseX / (width/8)-0.5);
clicky = round(mouseY / (height/8)-0.5);
click = true;
}
}
void showboard() {
for (int i = 0; i<=7; i++)
for (int j = 0; j<=7; j++) {
if ((i+j)%2 == 0) fill(180, 180, 255);
else fill(200, 115, 115);
rect(j*width/8, i*height/8, width/8, height/8);//chessboard
if (locationsglobal[i][j] != null) image(locationsglobal[i][j], j*width/8, i*height/8);//board
if (click) {
if (legal(clicky,clickx,i,j,black)) {
fill(50, 175, 50, 150);
ellipse(j*width/8+50, i*height/8+50, 20, 20);
}
if (legal(clicky,clickx,i,j,white)) {
fill(50, 175, 50, 150);
ellipse(j*width/8+50, i*height/8+50, 20, 20);
}
if (j == clickx && i == clicky && locationsglobal[i][j] != null) {
fill(0, 0, 255, 100);
rect(j*width/8, i*height/8, width/8, height/8);
}
}
if (check(white, locationsglobal)) {
fill(0, 255, 0);
text("CHECK", width/2, height/2, width, height);
} else if (check(black, locationsglobal)) {
fill(0, 255, 0);
text("CHECK", width/2, height/2, width, height);
}
}
}
boolean legal(int y,int x, int y1, int x1,boolean side){
return (!incheck(y,x,y1,x1,side)&&validmove(y,x,y1,x1,side,locationsglobal));
}
boolean check(boolean side, PImage[][] locations) {
int i, j = 0;
boolean detected = false;
for (i = 0; i<7; i++) {
for (j = 0; j<7; j++) {
if (side == white) {
if (locations[i][j] == wking) {
detected = true;
break;
}
} else {
if (locations[i][j] == bking) {
detected = true;
break;
}
}
}
if (detected == true) break;
}
for (int i2 = 0; i2<7; i2++) {
for (int j2 = 0; j2<7; j2++) {
if (side == white) {
if (black(i2, j2, locations)) {
if (validmove(i2, j2, i, j, black, locations)) {
return true;
}
}
} else {
if (white(i2, j2, locations)) {
if (validmove(i2, j2, i, j, white, locations)) {
return true;
}
}
}
}
}
return false;
}
boolean incheck(int y, int x, int y1, int x1, boolean side) {
PImage[][] locations2= new PImage[8][8];
for (int i = 0; i<7; i++) {
for (int j = 0; j<7; j++) {
locations2[i][j] = locationsglobal[i][j];
locations2 = movepiece(y, x, y1, x1, side, locations2);
}
}
if (check(side, locations2))return true;
return false;
}
//boolean mate(
boolean validmove(int y, int x, int y1, int x1, boolean side, PImage[][] locations) {
if (side==white) {
if (notwhite(y1, x1, locations)) {
if (locations[y][x] == wpawn) {
if (y!=7) {
if ((x-x1==1||x-x1==-1)&&y-y1==-1&&black(y1, x1, locations)) return true;//take
if (locations[y1][x1] == null&&x==x1) {//no block
if (y == 1 &&(y-y1 ==-1||y-y1==-2) ) {
return true;
} else return (y-y1 == -1&&x==x1);
} else return false;//no block
} else {
locations[y][x]=wqueen;
return false;
}
} else if (locations[y][x] == wbishop) {
if (notblocked(x, y, x1, y1, 1, 1, true, locations)) return true;//bottom right
if (notblocked(x, y, x1, y1, -1, 1, true, locations)) return true;//top right
if (notblocked(x, y, x1, y1, 1, -1, true, locations)) return true;//bottom left
if (notblocked(x, y, x1, y1, -1, -1, true, locations)) return true;//top left
return false;
} else if (locations[y][x] == wrook) {
if (notblocked(x, y, x1, y1, 0, 1, true, locations)) return true;//right
if (notblocked(x, y, x1, y1, 0, -1, true, locations)) return true;//left
if (notblocked(x, y, x1, y1, 1, 0, true, locations)) return true;//down
if (notblocked(x, y, x1, y1, -1, 0, true, locations)) return true;//up
return false;
} else if (locations[y][x]==wqueen) {
if (notblocked(x, y, x1, y1, 1, 1, true, locations)) return true;//bottom right
if (notblocked(x, y, x1, y1, -1, 1, true, locations)) return true;//top right
if (notblocked(x, y, x1, y1, 1, -1, true, locations)) return true;//bottom left
if (notblocked(x, y, x1, y1, -1, -1, true, locations)) return true;//top left
if (notblocked(x, y, x1, y1, 0, 1, true, locations)) return true;//right
if (notblocked(x, y, x1, y1, 0, -1, true, locations)) return true;//left
if (notblocked(x, y, x1, y1, 1, 0, true, locations)) return true;//down
if (notblocked(x, y, x1, y1, -1, 0, true, locations)) return true;//up
return false;
} else if (locations[y][x]==wknight) {
return((abs(y-y1)==2&&abs(x-x1)==1)||(abs(y-y1)==1&&abs(x-x1)==2));
} else if (locations[y][x]==wking) {
if (dist(x, y, x1, y1)<2) {
return true;
} else return false;
} else return false;
} else return false;
} else {
if (notblack(y1, x1, locations)) {
if (locations[y][x] == bpawn) {
if (y!=0) {
if ((x-x1==1||x-x1==-1)&&y-y1==1&&white(y1, x1, locations)) return true;//take
if (locations[y1][x1] == null&&x==x1) {//no block
if (y == 6 &&(y-y1 ==1||y-y1==2) ) {
return true;
} else return (y-y1 == 1&&x==x1);
} else return false;//no block
} else {
locations[y][x]=bqueen;
return false;
}
} else if (locations[y][x] == bbishop) {
if (notblocked(x, y, x1, y1, 1, 1, false, locations)) return true;//bottom right
if (notblocked(x, y, x1, y1, -1, 1, false, locations)) return true;//top right
if (notblocked(x, y, x1, y1, 1, -1, false, locations)) return true;//bottom left
if (notblocked(x, y, x1, y1, -1, -1, false, locations)) return true;//top left
return false;
} else if (locations[y][x] == brook) {
if (notblocked(x, y, x1, y1, 0, 1, false, locations)) return true;//right
if (notblocked(x, y, x1, y1, 0, -1, false, locations)) return true;//left
if (notblocked(x, y, x1, y1, 1, 0, false, locations)) return true;//down
if (notblocked(x, y, x1, y1, -1, 0, false, locations)) return true;//up
return false;
} else if (locations[y][x]==bqueen) {
if (notblocked(x, y, x1, y1, 1, 1, false, locations)) return true;//bottom right
if (notblocked(x, y, x1, y1, -1, 1, false, locations)) return true;//top right
if (notblocked(x, y, x1, y1, 1, -1, false, locations)) return true;//bottom left
if (notblocked(x, y, x1, y1, -1, -1, false, locations)) return true;//top left
if (notblocked(x, y, x1, y1, 0, 1, false, locations)) return true;//right
if (notblocked(x, y, x1, y1, 0, -1, false, locations)) return true;//left
if (notblocked(x, y, x1, y1, 1, 0, false, locations)) return true;//down
if (notblocked(x, y, x1, y1, -1, 0, false, locations)) return true;//up
return false;
} else if (locations[y][x]==bknight) {
return((abs(y-y1)==2&&abs(x-x1)==1)||(abs(y-y1)==1&&abs(x-x1)==2));
} else if (locations[y][x]==bking) {
if (dist(x, y, x1, y1)<2) {
return true;
} else return false;
} else return false;
} else return false;
// if
}
}
boolean notblocked(int x, int y, int x1, int y1, int horizontal, int vertical, boolean side, PImage[][]locations) {
for (int i = y + vertical, j = x + horizontal; i <= 7 && j <= 7 && i >= 0 && j >= 0; i+= vertical, j+= horizontal) {
if (side==white) {
if (white(i, j, locations)) break;
if (black(i, j, locations)) {
if (i == y1 && j == x1)return true;
break;
}
} else {
if (black(i, j, locations)) break;
if (white(i, j, locations)) {
if (i == y1 && j == x1)return true;
break;
}
}
if (i == y1 && j == x1)return true;//no piece
}
return false;
}
class player {
boolean ai, Break=false;
int colour, y, x, x1, y1, val, valx, valy;
player(int team, boolean computer) {
colour = team;
ai = computer;
}
void move() {
if (ai&&frameCount%10==0) {
if (turn==white) {
while (turn==white) {
Break=false;
y = int(random(8));
y1 = int(random(8));
x = int(random(8));
x1 = int(random(8));
if (legal(y,x,y1,x1,white)) {
locationsglobal=movepiece(y,x,y1,x1, white, locationsglobal);
turn = black;
print("yay");
break;
}
}
}
//if (frameCount%20==0&&turn==black) {
// while (turn==black) {
// Break=false;
// y = int(random(8));
// y1 = int(random(8));
// x = int(random(8));
// x1 = int(random(8));
// if (legal(y,x,y1,x1,black)) {
// locationsglobal=movepiece(x, y, x1, y1, black, locationsglobal);
// turn = white;
// print("yay");
// break;
// }
// }
//}
}
}
}
boolean black (int y, int x, PImage[][] locations) {
return (locations[y][x] == bqueen || locations[y][x] == bknight || locations[y][x] == bpawn || locations[y][x] == brook || locations[y][x] == bbishop || locations[y][x] == bking);
}
boolean white (int y, int x, PImage[][] locations) {
return (locations[y][x] == wqueen || locations[y][x] == wknight || locations[y][x] == wpawn || locations[y][x] == wrook || locations[y][x] == wbishop || locations[y][x] == wking);
}
boolean notblack (int y, int x, PImage[][] locations) {
return (white(y, x, locations) || locations[y][x] ==null);
}
boolean notwhite (int y, int x, PImage[][] locations) {
return (black(y, x, locations) || locations[y][x] ==null);
}
```

## Answers

Provide details about your bug and how to trigger it. This is important specially in those cases when "it doesn't work sometimes".

Kf

the program occasionally works, and occasionally doesn't work, I do not know how to trigger the bug, but if you play against the random moving ai, you will see that the bug occurs sometimes

You haven't told us what the bug is!

which line numbers are involved?

when it's a bug, is it a false positive or a false negative?

which other figure is involved, pawn?

we can't run your code since we don't have the images.

maybe you use several tabs instead of only one and upload to github?

https://github.com

Chrisir

The other thing that really bothers me is that your functions are passing arround 2D arrays of PImages! Can't you just enumerate the pieces and store a chessboard state in a 2D array of ints?

The bug is that the check function isn't working.

I don't really get what you mean, tfguy44

The images are here: https://drive.google.com/open?id=1ehgxRtZ1DuyKbEE4_2xXg2miDbmD91z5 in a zip file.

I only used one tab.

the figure that is involved is the king, it is the one that is being checked. also, any other piece that checks it is also involved.

That's not enough.

Does it say chess when there is none (false positive) OR does it say no check when there is a check (false negative)

And if possible to say:

In which circumstances does it occur, when the chess is given by a pawn or rook or... ?

I like your game!

It's fun.

But to control the check function you need to play an entire game

But you should be able to

loada game when it's very close to a checkHm, it's check (and he recognized it correctly) but the white king on E1 is not shown anymore

Hm, it's check (and he recognized it correctly) but the white king on E1 is not shown anymore

it's even check mate but he didn't say that

here he didnt'say check - false negative

he has issue if white king is on the 8 line

technically when it's check and he moves the king out of it, the message check appears only briefly

instead you could have a String variable that is shown 30 secs with a timer and says it was check

but nothing to do with the issue, I think

this looks suspicious but could work anyway

these are better colors for the board

it both says check when there is none and sometimes doesn't say check. I don't know how to trigger the bug, but it appears several times in each game, you just need to observe.

if you don't want to constantly play the ai, you can uncomment the lines between 354 and 370, and change the speed with the framecounts. I find that the bug occurs a lot more when there are two ais playing.

nothing to do with your problem

I think here

you want

instead

i got a lot not detected

using this:

Ah all 4 for loops must have <= not only < !!!!!

no, that gives me a out of bound exeption for some reason

I think

and for your first solution, I have tried it before, it did not work. and the incheck function is not the only one that doesn't work, occassionally the check function also doesn't work.

??

you got <= in your others for loops - then the out of bound error is caused elsewhere in black or validmove?

Also my other advice is valid: movepiece outside the nested for loop: otherwise you make the same error again and again

I have tried, I will try again, but so far nothing. and yes, the out of bounds error occurs in the black() and white() functions.

I have decided not to use openprocessing

actually chrisir I think your <= is the solution. I will message you again if it doesn't work, but at the moment it appears to be working, thanks

nevermind, there are still some bugs

nevermind, there are no more bugs hahah

THAT‘s a great achievement

thanks!