We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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 load a game when it's very close to a check
Hm, 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!