Displaying Source Code(s)
|
|
Computer Chess
--------------------------------------------------------------------------------
Description : it is a primary work of Artificial
Intelligence,And provides a good framework for the person
interested in A.I. I dont claim that entire work is mine Rather
it is an improved version of TSCP a engine developed by
Kerringhan. But it has excellent graphics,mouse interaction and
single file.And much more... so just go.
/* This project of chess deserve thanks to many person.This all
has
been possible due to their kind efforts.This is a primary level
work based
on Artificial Intelligence and might be that computer does not
made the
best move.But still it deserves the attention of many C
programmers who may
benefit from it. At last thank to all who has helped me in
direct or
indirect way.So enjoy */
//-------------------------------------------------------------------------//
#include <stdio.h>
#include <string.h>
#include<graphics.h>
#include<dos.h>
char pattern[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
#define PAWN 0
#define KNIGHT 1
#define BISHOP 2
#define ROOK 3
#define QUEEN 4
#define KING 5
#define EMPTY 6
#define WHITE 15
#define BLACK 0
#define VALUE_PAWN 100
#define VALUE_KNIGHT 300
#define VALUE_BISHOP 300
#define VALUE_ROOK 500
#define VALUE_QUEEN 900
#define VALUE_KING 10000
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$$$
$$$$ MOVE TYPES $$$$$
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$*/
#define MOVE_TYPE_NONE 0
#define MOVE_TYPE_NORMAL 1
#define MOVE_TYPE_CASTLE 2
#define MOVE_TYPE_ENPASANT 3
#define MOVE_TYPE_PROMOTION_TO_QUEEN 4
#define MOVE_TYPE_PROMOTION_TO_ROOK 5
#define MOVE_TYPE_PROMOTION_TO_BISHOP 6
#define MOVE_TYPE_PROMOTION_TO_KNIGHT 7
#define MATE 10000 /* losing King==mate */
#define column(pos) pos%8
#define row(pos) pos/8
//========================================================================
union REGS i,o; //for hardware interaction
//============================pieces
representation===========================
/* Board representation */
int piece[64] = {
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
};
int color[64] = {
BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK,
BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK,
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,
WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE,
WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
};
//========================================================================
int player; /* whose turn? BLACK or WHITE */
char check,rookwm='f',kingwm='f',castlew='f';
typedef struct move { //move information
int from,
dest,
type;
} MOVE;
/* For storing all moves of game */
typedef struct history { //history.
MOVE m;
int cap;
} HIST;
HIST hist[3000]; /* length of game < 3000 */
int moveorder; /* Current move order */
/* For searching */
int nodes; /* Count all visited nodes when searching*/
int ply; /* ply of search */
/***************************************************************************
* Utilities And Various Drawing Routines For Pieces. *
****************************************************************************/
void pawndraw(int px,int py,int c1) //Drawing A Pawn
{
int pos[8][2];
pos[0][0]=px+18; pos[0][1]=py+6;
pos[1][0]=px+18; pos[1][1]=py+31;
pos[2][0]=px+6; pos[2][1]=py+31;
pos[3][0]=px+6; pos[3][1]=py+43;
pos[4][0]=px+43; pos[4][1]=py+43;
pos[5][0]=px+43; pos[5][1]=py+31;
pos[6][0]=px+31; pos[6][1]=py+31;
pos[7][0]=px+31; pos[7][1]=py+6;
if(c1==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(c1==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(8, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
void rookdraw(int rx,int ry,int c1) //Drawing A Rook
{
int pos[20][2];
pos[0][0]=rx+6; pos[0][1]=ry+6;
pos[1][0]=rx+6; pos[1][1]=ry+18;
pos[2][0]=rx+18; pos[2][1]=ry+18;
pos[3][0]=rx+18; pos[3][1]=ry+31;
pos[4][0]=rx+6; pos[4][1]=ry+31;
pos[5][0]=rx+6; pos[5][1]=ry+43;
pos[6][0]=rx+43; pos[6][1]=ry+43;
pos[7][0]=rx+43; pos[7][1]=ry+31;
pos[8][0]=rx+31; pos[8][1]=ry+31;
pos[9][0]=rx+31; pos[9][1]=ry+18;
pos[10][0]=rx+43; pos[10][1]=ry+18;
pos[11][0]=rx+43; pos[11][1]=ry+6;
pos[12][0]=rx+37; pos[12][1]=ry+6;
pos[13][0]=rx+37; pos[13][1]=ry+12;
pos[14][0]=rx+31; pos[14][1]=ry+12;
pos[15][0]=rx+31; pos[15][1]=ry+6;
pos[16][0]=rx+18; pos[16][1]=ry+6;
pos[17][0]=rx+18; pos[17][1]=ry+12;
pos[18][0]=rx+12; pos[18][1]=ry+12;
pos[19][0]=rx+12; pos[19][1]=ry+6;
if(c1==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(c1==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(20, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void drawknite(int kx,int ky,int c1) //Drawing A Knight
{
int pos[14][2];
pos[0][0]=kx+9; pos[0][1]=ky+21;
pos[1][0]=kx+15; pos[1][1]=ky+15;
pos[2][0]=kx+13; pos[2][1]=ky+13;
pos[3][0]=kx+21; pos[3][1]=ky+6;
pos[4][0]=kx+30; pos[4][1]=ky+15;
pos[5][0]=kx+25; pos[5][1]=ky+37;
pos[6][0]=kx+31; pos[6][1]=ky+37;
pos[7][0]=kx+31; pos[7][1]=ky+43;
pos[8][0]=kx+6; pos[8][1]=ky+43;
pos[9][0]=kx+6; pos[9][1]=ky+37;
pos[10][0]=kx+12; pos[10][1]=ky+37;
pos[11][0]=kx+21; pos[11][1]=ky+24;
pos[12][0]=kx+18; pos[12][1]=ky+18;
pos[13][0]=kx+11; pos[13][1]=ky+26;
if(c1==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(c1==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(14, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void drawbishop(int bx,int by,int c1) //Drawing A Bishop
{
int pos[11][2];
pos[0][0]=bx+6; pos[0][1]=by+31;
pos[1][0]=bx+21; pos[1][1]=by+31;
pos[2][0]=bx+21; pos[2][1]=by+12;
pos[3][0]=bx+18; pos[3][1]=by+9;
pos[4][0]=bx+25; pos[4][1]=by+2;
pos[5][0]=bx+31; pos[5][1]=by+9;
pos[6][0]=bx+28; pos[6][1]=by+12;
pos[7][0]=bx+28; pos[7][1]=by+31;
pos[8][0]=bx+43; pos[8][1]=by+31;
pos[9][0]=bx+43; pos[9][1]=by+43;
pos[10][0]=bx+6; pos[10][1]=by+43;
if(c1==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(c1==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(11, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void drawqueen(int qx,int qy,int c1) //Drawing The Most Strong
{ //Piece A Queen
int pos[10][2];
pos[0][0]=qx+6; pos[0][1]=qy+37;
pos[1][0]=qx+15; pos[1][1]=qy+37;
pos[2][0]=qx+21; pos[2][1]=qy+15;
pos[3][0]=qx+18; pos[3][1]=qy+9;
pos[4][0]=qx+31; pos[4][1]=qy+9;
pos[5][0]=qx+28; pos[5][1]=qy+15;
pos[6][0]=qx+34; pos[6][1]=qy+37;
pos[7][0]=qx+43; pos[7][1]=qy+37;
pos[8][0]=qx+43; pos[8][1]=qy+43;
pos[9][0]=qx+6; pos[9][1]=qy+43;
if(c1==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(c1==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(10, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void drawking(int kx,int ky,int kc) //Drawing A King.
{
int pos[10][2];
pos[0][0]=kx+6; pos[0][1]=ky+37;
pos[1][0]=kx+18; pos[1][1]=ky+37;
pos[2][0]=kx+6; pos[2][1]=ky+18;
pos[3][0]=kx+25; pos[3][1]=ky+6;
pos[4][0]=kx+43; pos[4][1]=ky+18;
pos[5][0]=kx+31; pos[5][1]=ky+37;
pos[6][0]=kx+43; pos[6][1]=ky+37;
pos[7][0]=kx+43; pos[7][1]=ky+43;
pos[8][0]=kx+6; pos[8][1]=ky+43;
if(kc==0)
{
setcolor(WHITE);
setfillstyle(SOLID_FILL, WHITE);
}
else if(kc==1)
{
setcolor(BLACK);
setfillstyle(SOLID_FILL, BLACK);
}
/* draw a filled polygon */
fillpoly(9, (int *)pos);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
int relposx(int x2)
{ //gives the click x pos in terms of standard coord.
int x3,var;
for(var=0;var<=350;var=var+50)
{
if(x2>=var && x2<var+50)
x3=var;
}
return(x3);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
int relposy(int y2)
{ //gives the click pos in terms of standard coordinates.
int y3,var;
for(var=0;var<=350;var=var+50)
{
if(y2>=var && y2<var+50)
y3=var;
}
return(y3);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void bottom()
{
setfillpattern(pattern,3);//draw display at bottom
bar(10,420,400,460);
setcolor(WHITE);
rectangle(10,420,400,460);
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void sidelogo() //For SideLogo
{
int side[4][2]={ {410,10},{629,10},{629,469},{410,469}};
setfillstyle(8,5);//SOLID_FILL, 5);
fillpoly(4,(int *)side);
settextstyle(4,HORIZ_DIR,8);
outtextxy(430,50,"Chess");
settextstyle(5,HORIZ_DIR,4);
outtextxy(470,150,"based on");
settextstyle(7,HORIZ_DIR,4);
outtextxy(420,250,"Artificial");
settextstyle(7,HORIZ_DIR,4);
outtextxy(440,300,"Intelligence");
settextstyle(5,HORIZ_DIR,2);
outtextxy(490,400,"Developed By:");
setcolor(2);
settextstyle(4,HORIZ_DIR,4);
outtextxy(450,420,"Akhil Mittal");
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
void printboard() //Prints The Updated board.
{
int i,x,y;
hidemouseptr();
for(i=0;i<=63;i++)
{
y=i/8; x=i%8;
draw(x,y,piece[i],color[i]);
}
showmouseptr();
return;
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
draw(int x3,int y3,int piece,int color) //Draws Pieces At
{ //Their Correct Position
int nx3,ny3,ncx,ncy;
char newclr;
nx3=x3*50; ny3=y3*50;
hidemouseptr();
if( (x3+y3)%2==0)
setfillpattern(pattern,7);
else
setfillpattern(pattern,8);
bar(nx3,ny3,nx3+50,ny3+50);
setcolor(WHITE);
rectangle(nx3,ny3,nx3+50,ny3+50);
showmouseptr();
if(piece==EMPTY)
{
return;
}
else if(piece==PAWN) //if pawn was selected then draw the pawn
at new position.
{ if(color==WHITE)
pawndraw(nx3,ny3,0); // 0 for white.
else if(color==BLACK)
pawndraw(nx3,ny3,1);
}
else if(piece==ROOK) //if rook was selected
{ if(color==WHITE)
rookdraw(nx3,ny3,0); // 0 for white.
else if( color==BLACK )
rookdraw(nx3,ny3,1);
}
else if(piece==KNIGHT) //if knight was selected
{ if(color==WHITE)
drawknite(nx3,ny3,0); // 0 for white.
else if(color==BLACK)
drawknite(nx3,ny3,1);
}
else if(piece==BISHOP) //if bishop was selected
{ if(color==WHITE)
drawbishop(nx3,ny3,0); // 0 for white.
else if(color==BLACK)
drawbishop(nx3,ny3,1);
}
else if(piece==KING)
{ if(color==WHITE)
drawking(nx3,ny3,0); // 0 for white.
else if(color==BLACK)
drawking(nx3,ny3,1);
}
else if(piece==QUEEN)
{ if(color==WHITE)
drawqueen(nx3,ny3,0); // 0 for white.
else if(color==BLACK)
drawqueen(nx3,ny3,1);
}
return;
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
-_-_-
void castling(int clr) //Gives The Option For CASTLING.
{
outtextxy(100,430,"CASTLING");
delay(200);
if(clr==WHITE)
{
castlew='t';
piece[60]=EMPTY;
color[60]=EMPTY;
piece[62]=KING;
color[62]=WHITE;
piece[63]=EMPTY;
color[63]=EMPTY;
piece[61]=ROOK;
color[61]=WHITE;
check=IsInCheck(WHITE);
if(check)//that is king not safe even now
{
piece[60]=KING; //undo the changes
color[60]=WHITE;
piece[62]=EMPTY;
color[62]=EMPTY;
piece[63]=ROOK; //undo the changes
color[63]=WHITE;
piece[61]=EMPTY;
color[61]=EMPTY;
return;
}
bottom();
hidemouseptr();
setfillpattern(pattern,7);
bar(350,350,400,400);
bar(250,350,300,400);
setcolor(WHITE);
rectangle(350,350,400,400);
rectangle(250,350,300,400);
setfillpattern(pattern,8);
bar(300,350,350,400);
bar(200,350,250,400);
setcolor(WHITE);
rectangle(300,350,350,400);
rectangle(200,350,250,400);
drawking(300,350,0); // 0 for white.
rookdraw(250,350,0); // 0 for white.
player=BLACK;
showmouseptr();
}
bottom();
}
/*
****************************************************************************
* Generate all possible moves *
*
*****************************************************************************/
void Pushmove(int from, int dest, int type, MOVE * Buffer, int *moveno)
{
MOVE move;
move.from = from;
move.dest = dest;
move.type = type;
Buffer[*moveno] = move; //put in buffer move number *pmcount
*moveno = *moveno + 1;//in effect inc movecount.
}
void PushNormalmov(int from, int dest, MOVE * Buffer, int *moveno)//In
case move is normal.
{
Pushmove(from, dest, MOVE_TYPE_NORMAL, Buffer, moveno);
}
/* Pawn can promote? */
void PushPawn(int from, int dest, MOVE * Buffer, int *moveno)
{
if (dest > 7 && dest < 56) //simply means at the row no 1 or row
no 6
Pushmove(from, dest, MOVE_TYPE_NORMAL, Buffer, moveno);
else {
Pushmove(from, dest, MOVE_TYPE_PROMOTION_TO_QUEEN, Buffer,
moveno);
Pushmove(from, dest, MOVE_TYPE_PROMOTION_TO_ROOK, Buffer, moveno);
Pushmove(from, dest, MOVE_TYPE_PROMOTION_TO_BISHOP, Buffer,
moveno);
Pushmove(from, dest, MOVE_TYPE_PROMOTION_TO_KNIGHT, Buffer,
moveno);
}
}
/*#############################################################################
##### Gen all moves of current_side , push them in Buffer
################# and return total number of moves############
#################################################################################*/
int Generate(int current_side, MOVE * Buffer)
{
int i, k, y, row, col, movecount;
movecount = 0;//initialised to zero means initially no move in
total.
for (i = 0; i < 64; i++) /* Scan all board */
if (color[i] == current_side) { //means current person's turn
switch (piece[i]) { //check its type.
case PAWN:
col = column(i); //find out its current position.
row = row(i);
if (current_side == BLACK) { //its black turn?
if (color[i + 8] == EMPTY)//see whether we can promote?and allow
single step.
PushPawn(i, i + 8, Buffer, &movecount);//generate all moves.
if (row == 1 && color[i + 8] == EMPTY && color[i + 16]
==EMPTY)//check whether we can allow two step.
PushNormalmov(i, i + 16, Buffer, &movecount);
if (col && color[i + 7] == WHITE) //colunn> 0 and nothing at
diagonal.
PushNormalmov(i, i + 7, Buffer, &movecount);
if (col < 7 && color[i + 9] == WHITE)//nothing at other
diagonal.
PushNormalmov(i, i + 9, Buffer, &movecount);
} else {
if (color[i - 8] == EMPTY)//see for single step.For white.
PushPawn(i, i - 8, Buffer, &movecount);
if (row == 6 && color[i - 8] == EMPTY && color[i - 16] == EMPTY)
PushNormalmov(i, i - 16, Buffer, &movecount);//see for double
step.
if (col && color[i - 9] == BLACK)
PushNormalmov(i, i - 9, Buffer, &movecount);//check diag.
if (col < 7 && color[i - 7] == BLACK)
PushNormalmov(i, i - 7, Buffer, &movecount);
}
break;
case QUEEN: /* == BISHOP+ROOK */
case BISHOP:
for (y = i - 9; y >= 0 && column(y) != 7; y -= 9) { /* go left
up*/
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
for (y = i - 7; y >= 0 && column(y) != 0; y -= 7) { /* go right
up */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
for (y = i + 9; y < 64 && column(y) != 0; y += 9) { /* go right
down */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
for (y = i + 7; y < 64 && column(y) != 7; y += 7) { /* go right
down */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
if (piece[i] == BISHOP)
break;
/* FALL THROUGH FOR QUEEN {I dont mean to do that} ;-) */
case ROOK:
col = column(i);
for (k = i - col, y = i - 1; y >= k; y--) { /* go left */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)//something in between.
break;
}
for (k = i - col + 7, y = i + 1; y <= k; y++) { /* go right */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
for (y = i - 8; y >= 0; y -= 8) { /* go up */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
for (y = i + 8; y < 64; y += 8) { /* go down */
if (color[y] != current_side)
PushNormalmov(i, y, Buffer, &movecount);
if (color[y] != EMPTY)
break;
}
break; //this is for great queen.
case KNIGHT:
col = column(i);
y = i - 6;//check all eight moves.
if (y >= 0 && col < 6 && color[y] != current_side)//1
PushNormalmov(i, y, Buffer, &movecount);
y = i - 10;
if (y >= 0 && col > 1 && color[y] != current_side)//2
PushNormalmov(i, y, Buffer, &movecount);
y = i - 15;
if (y >= 0 && col < 7 && color[y] != current_side)//3
PushNormalmov(i, y, Buffer, &movecount);
y = i - 17;
if (y >= 0 && col > 0 && color[y] != current_side)//4
PushNormalmov(i, y, Buffer, &movecount);
y = i + 6;
if (y < 64 && col > 1 && color[y] != current_side)//5
PushNormalmov(i, y, Buffer, &movecount);
y = i + 10;
if (y < 64 && col < 6 && color[y] != current_side)//6
PushNormalmov(i, y, Buffer, &movecount);
y = i + 15;
if (y < 64 && col > 0 && color[y] != current_side)//7
PushNormalmov(i, y, Buffer, &movecount);
y = i + 17;
if (y < 64 && col < 7 && color[y] != current_side)//8
PushNormalmov(i, y, Buffer, &movecount);
break;
case KING:
col = column(i);
if (col && color[i - 1] != current_side)
PushNormalmov(i, i - 1, Buffer, &movecount); /* left */
if (col < 7 && color[i + 1] != current_side)
PushNormalmov(i, i + 1, Buffer, &movecount); /* right */
if (i > 7 && color[i - 8] != current_side)
PushNormalmov(i, i - 8, Buffer, &movecount); /* up */
if (i < 56 && color[i + 8] != current_side)
PushNormalmov(i, i + 8, Buffer, &movecount); /* down */
if (col && i > 7 && color[i - 9] != current_side)
PushNormalmov(i, i - 9, Buffer, &movecount); /* left up */
if (col < 7 && i > 7 && color[i - 7] != current_side)
PushNormalmov(i, i - 7, Buffer, &movecount); /* right up */
if (col && i < 56 && color[i + 7] != current_side)
PushNormalmov(i, i + 7, Buffer, &movecount); /* left down */
if (col < 7 && i < 56 && color[i + 9] != current_side)
PushNormalmov(i, i + 9, Buffer, &movecount); /* right down */
break;
default:
outtextxy(50,430,"wrong piece selection");
}
}
return movecount;
}
/*
****************************************************************************
* Evaluation for current position - main "brain" function
*
* just a rough idea, almost no knowlegde
*
*****************************************************************************/
int Evaluate()
{
int value_piece[6] = {VALUE_PAWN, VALUE_KNIGHT,VALUE_BISHOP,
VALUE_ROOK, VALUE_QUEEN, VALUE_KING};
int i,
score = 0;
for (i = 0; i < 64; i++) {
if (color[i] == WHITE)
score += value_piece[piece[i]];
else if (color[i] == BLACK)
score -= value_piece[piece[i]];
}
if (player == WHITE)
return score;
return -score;
}
/*
****************************************************************************
* Make and Take back a move if king is in Check
* this will check and return 1 if side is in Check
*****************************************************************************/
int IsInCheck(int current_side)
{
int k,
h,
y,
row,
col,
xside;
xside = (WHITE + BLACK) - current_side; /* opposite
current_side,who may be checking */
/* Find King */
for (k = 0; k < 64; k++)
if (piece[k] == KING && color[k] == current_side)
break;
row = row(k), col = column(k);
/* Check attacking of Knight and also check all eight
positions*/
if (col > 0 && row > 1 && color[k - 17] == xside && piece[k -
17] == KNIGHT)//1
return 1;
if (col < 7 && row > 1 && color[k - 15] == xside && piece[k -
15] == KNIGHT)//2
return 1;
if (col > 1 && row > 0 && color[k - 10] == xside && piece[k -
10] == KNIGHT)//3
return 1;
if (col < 6 && row > 0 && color[k - 6] == xside && piece[k - 6]
== KNIGHT)//4
return 1;
if (col > 1 && row < 7 && color[k + 6] == xside && piece[k + 6]
== KNIGHT)//5
return 1;
if (col < 6 && row < 7 && color[k + 10] == xside && piece[k +
10] == KNIGHT)//6
return 1;
if (col > 0 && row < 6 && color[k + 15] == xside && piece[k +
15] == KNIGHT)//7
return 1;
if (col < 7 && row < 6 && color[k + 17] == xside && piece[k +
17] == KNIGHT)//8
return 1;
/* Check horizontal and vertical lines for attacking of Queen,
Rook,King */
/* go down */
y = k + 8;//at the square just down
if (y < 64) {
if (color[y] == xside && (piece[y] == KING || piece[y] == QUEEN
|| piece[y] == ROOK))
return 1;
if (piece[y] == EMPTY)//means no body just down to serve you
matar paneer.
for (y += 8; y < 64; y += 8) { //move downward.
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
ROOK))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go left */
y = k - 1;
h = k - col;
if (y >= h) {
if (color[y] == xside && (piece[y] == KING || piece[y] == QUEEN
||piece[y] == ROOK))
return 1;
if (piece[y] == EMPTY)//means no body just left.
for (y--; y >= h; y--) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
ROOK))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go right */
y = k + 1;
h = k - col + 7;
if (y <= h) {
if (color[y] == xside && (piece[y] == KING || piece[y] == QUEEN
|| piece[y] == ROOK))
return 1;
if (piece[y] == EMPTY)
for (y++; y <= h; y++) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
ROOK))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go up */
y = k - 8;
if (y >= 0) {
if (color[y] == xside && (piece[y] == KING || piece[y] == QUEEN
|| piece[y] == ROOK))
return 1;
if (piece[y] == EMPTY)
for (y -= 8; y >= 0; y -= 8) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
ROOK))
return 1;
if (piece[y] != EMPTY)
break;
}
}//means only bishop and queen can serve you well...what? u know
well.
/* Check diagonal lines for attacking of Queen, Bishop, King,
Pawn */
/* go right down - _ */
y = k + 9;
if (y < 64 && column(y) != 0) {
if (color[y] == xside) {
if (piece[y] == KING || piece[y] == QUEEN || piece[y] == BISHOP)
return 1; //check just right down
if (current_side == BLACK && piece[y] == PAWN)
return 1;
}
if (piece[y] == EMPTY)
for (y += 9; y < 64 && column(y) != 0; y += 9) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
BISHOP))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go left down */
y = k + 7;
if (y < 64 && column(y) != 7) {
if (color[y] == xside) {
if (piece[y] == KING || piece[y] == QUEEN || piece[y] == BISHOP)
return 1;
if (current_side == BLACK && piece[y] == PAWN)
return 1;
}
if (piece[y] == EMPTY)
for (y += 7; y < 64 && column(y) != 7; y += 7) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
BISHOP))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go left up */
y = k - 9;
if (y >= 0 && column(y) != 7) {
if (color[y] == xside) {
if (piece[y] == KING || piece[y] == QUEEN || piece[y] == BISHOP)
return 1;
if (current_side == WHITE && piece[y] == PAWN)
return 1;
}
if (piece[y] == EMPTY)
for (y -= 9; y >= 0 && column(y) != 7; y -= 9) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
BISHOP))
return 1;
if (piece[y] != EMPTY)
break;
}
}
/* go right up */
y = k - 7;
if (y >= 0 && column(y) != 0) {
if (color[y] == xside) {
if (piece[y] == KING || piece[y] == QUEEN || piece[y] == BISHOP)
return 1;
if (current_side == WHITE && piece[y] == PAWN)
return 1;
}
if (piece[y] == EMPTY)
for (y -= 7; y >= 0 && column(y) != 0; y -= 7) {
if (color[y] == xside && (piece[y] == QUEEN || piece[y] ==
BISHOP))
return 1;
if (piece[y] != EMPTY)
break;
}
}
return 0;
}
//thank GOD u r safe.
/*########################################################################
#####
##### Makes The Move And Also Updates The Arrays
############
##### and Also Take care Whether There Is a Promotion.
############
##########################################################################
#######*/
int MakeMove(MOVE m)
{
int r;
hist[moveorder].m = m;
hist[moveorder].cap = piece[m.dest];//entity lying at the
destination of the move.
piece[m.dest] = piece[m.from];//update values.if rook moves from
3 to 5 say thenwe will have rook at 5.
piece[m.from] = EMPTY; //that is piece[5]=piece[3] initial
pos
become empty.final bcom
// piece[m.from]=piece[m.dest];
color[m.dest] = color[m.from];//new initial.Also update color.
color[m.from] = EMPTY;
if (m.type >= MOVE_TYPE_PROMOTION_TO_QUEEN) {/*Means need of
Promotion
*/
switch (m.type) {
case MOVE_TYPE_PROMOTION_TO_QUEEN:
piece[m.dest] = QUEEN;//place queen at that pos.
break;
case MOVE_TYPE_PROMOTION_TO_ROOK:
piece[m.dest] = ROOK;
break;
case MOVE_TYPE_PROMOTION_TO_BISHOP:
piece[m.dest] = BISHOP;
break;
case MOVE_TYPE_PROMOTION_TO_KNIGHT:
piece[m.dest] = KNIGHT;
break;
default:
puts("impossible to get here...");
// assert(false);
}
}
ply++;
moveorder++;
r = !IsInCheck(player);//if in check r return zero.
player= (WHITE + BLACK) - player; /* After making move, give
turnto opponent */
return r;
}
/*########################################################################
#####
##### Takes Back A Piece If It puts A King In Check or It Doesnt
############
##### Deserve To Be Made.
############
##########################################################################
#######*/
void TakeBack() /* undo what MakeMove did */
{
player = (WHITE + BLACK) - player;
moveorder--;
ply--;
piece[hist[moveorder].m.from] = piece[hist[moveorder].m.dest];
piece[hist[moveorder].m.dest] = hist[moveorder].cap;
color[hist[moveorder].m.from] = player;
if (hist[moveorder].cap != EMPTY)
color[hist[moveorder].m.dest] = (WHITE + BLACK) - player;
else
color[hist[moveorder].m.dest] = EMPTY;
if (hist[moveorder].m.type >=
MOVE_TYPE_PROMOTION_TO_QUEEN)/*Means ove was done by pawn for
Promotion */
piece[hist[moveorder].m.from] = PAWN;
}
/*
**************************************************************************
**
* Search function - a typical alphabeta, main search function
*
* No Way To Order The Moves
*
**************************************************************************
**
*/
int Search(int alpha, int beta, int depth, MOVE *
pBestMove)
{
int i,
value,
havemove,
movecnt;
MOVE moveBuf[200],
tmpMove;
nodes++; /* visiting a node, count it */
havemove = 0;
pBestMove->type = MOVE_TYPE_NONE;
movecnt = Generate(player, moveBuf); /* generate all moves for
current position */
/* loop through the moves */
for (i = 0; i < movecnt; ++i) {
if (!MakeMove(moveBuf[i])) {
TakeBack();
continue;
}
havemove = 1;
if (depth - 1 > 0) /* If depth is still, continue to search
deeper */
value = -Search(-beta, -alpha, depth - 1, &tmpMove);
else /* If no depth left (leaf node), go to evalute that
position */
value = Evaluate();
TakeBack();
if (value > alpha) {
/* This move is so good and caused a cutoff */
if (value >= beta)
return beta;
alpha = value;
*pBestMove = moveBuf[i]; /* so far, current move is the best
reaction for current position */
}
}
if (!havemove) { /* If no legal moves, that is checkmate or
stalemate */
if (IsInCheck(player))
return -MATE + ply; /* add ply to find the longest path to lose
or shortest path to win */
else
return 0;
}
return alpha;
}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@
@@@@ Computer also has the right to think.Isnt it? @@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@*/
MOVE ComputerThink(int max_depth)
{
MOVE m;
int score;
/* reset some values before searching */
ply = 0;
nodes = 0;
/* search now */
/*score =*/ Search(-MATE, MATE, max_depth, &m);
/* after searching, print results */
return m;
}
/*************************************************************************
***
********************** Mouse Handling Routines
*********************
**************************************************************************
**/
getmousepos(int *button,int* x,int* y) //gets mouse position.
{
i.x.ax=3;
int86(0x33,&i,&o);
*button=o.x.bx;
*x=o.x.cx;
*y=o.x.dx;
return;
}
//========================================================================
showmouseptr() //shows pointer in graphics mode.
{
i.x.ax=1;
int86(0x33,&i,&o);
return;
}
//========================================================================
hidemouseptr() //hides pointer
{
i.x.ax=2;
int86(0x33,&i,&o);
return;
}
//========================================================================
restrictmouseptr(int x1,int y1,int x2,int y2) //restrict pointer
{
i.x.ax=7;
i.x.cx=x1;
i.x.dx=x2;
int86(0x33,&i,&o);
i.x.ax=8;
i.x.cx=y1;
i.x.dx=y2;
int86(0x33,&i,&o);
return;
}
//========================================================================
/****************************************************************************
* Main program
*
****************************************************************************/
void main()
{
char choice,ch;
int from,
dest,
i1=0;
int button,x,y,x1,y1,x2,y2,x3,y3,j=0,k=0;
int computer_side;
int max_depth; /* max depth to search */
int bkground[6][2]={
{400,0},{639,0},{639,479},{0,479},{0,400},{400,400} };
MOVE moveBuf[200];
int movecnt;
int gd=DETECT,gm;
player = WHITE;
computer_side = BLACK; /* Human is white side */
max_depth =6;
moveorder = 0;
restrictmouseptr(0,0,400,400); //restricts pointer of mouse in
the area specified there.
initgraph(&gd,&gm,"");
setfillstyle(SOLID_FILL, 6); //prepares user interaction
environment
fillpoly(6,(int *)bkground);
bottom();
sidelogo();
for (;;)
{
printboard();
showmouseptr();
if (player == computer_side) //if else
{ /* computer's turn */
/* Find out the best move */
MOVE bestMove = ComputerThink(max_depth);
MakeMove(bestMove);
continue;
}
else
{
k=k+1;
outtextxy(100,415,"Your Turn..");
check=IsInCheck(player); //finds whether king in check.
if( check )
{
bottom();
outtextxy(100,415,"check your king");
}
while(k) //while1
{
if(kbhit())
{
ch=getch();
if(ch=='
') //escape at pressing enter.
exit(0);
}
getmousepos(&button,&x,&y); //gets click position of mouse
if((button== 001))
{
sound(1000);
k=k-1;
delay(50);
nosound();
delay(500);
}
} //while 1
x1=relposx(x)/50;
y1=relposy(y)/50;
j=j+1;
setcolor(5);
rectangle(x1*50,y1*50,x1*50+50,y1*50+50);
bottom();//clear bottom display
while(j) //while 2
{
if(kbhit())
{
ch=getch();
if(ch=='
') //escape at pressing enter.
exit(0);
}
getmousepos(&button,&x2,&y2); //gets click position of mouse
if((button== 001))
{
sound(500);
j=j-1;
delay(100);
nosound();
delay(500);
}
} //while 2
x3=relposx(x2)/50; //gives standard x coordinate
y3=relposy(y2)/50; //gives standard y coordinate
setcolor(WHITE); //undo the changes
rectangle(x1*50,y1*50,x1*50+50,y1*50+50);
setfillpattern(pattern,5);//blink effect
bar(x3*50,y3*50,x3*50+50,y3*50+50);
delay(200);
setcolor(WHITE); //undo the changes
rectangle(x3*50,y3*50,x3*50+50,y3*50+50);
from=8*y1+x1; //get from and destination acc to
dest=8*y3+x3; //program's conventions.
} //if else
//############################################################################
//-------------------------------------CASTLING--------------------------------
//############################################################################
if( x1==4 && y1==7 && piece[60]==KING && x3==6 && y3==7 &&
piece[61]==EMPTY
&& piece[62]==EMPTY && piece[63]==ROOK && color[60]==WHITE &&
color[63]==WHITE && rookwm=='f' && kingwm=='f'&& check==0 &&
castlew=='f')
{
//we need not to check whether king will be in check at new
position
// bcoz if it will be in check the changes will be undone
automatically
//for the king not for the rook and turn will move only when
move saves king.
castling(WHITE);
continue;
}
//______________________________User's
Turn___________________________________
/* get user input */
/* maybe the user entered a move? */
movecnt = Generate(player, moveBuf);
/* loop through the moves to see if it's legal */
for (i1 = 0; i1 < movecnt; i1++) //for
if (moveBuf[i1].from == from && moveBuf[i1].dest == dest)//if 1
{
if (piece[from] == PAWN && (dest < 8 || dest > 55)) //if 2
{ /* Promotion move? */
outtextxy(50,415,"enter initial of the piece");
getch(choice);
switch (choice)
{//at promopte you must enter one more char. //switch
case 'q':
moveBuf[i1].type = MOVE_TYPE_PROMOTION_TO_QUEEN;
break;
case 'r':
moveBuf[i1].type = MOVE_TYPE_PROMOTION_TO_ROOK;
break;
case 'b':
moveBuf[i1].type = MOVE_TYPE_PROMOTION_TO_BISHOP;
break;
case 'n':
moveBuf[i1].type = MOVE_TYPE_PROMOTION_TO_KNIGHT;
break;
default:
outtextxy(50,430,"promoting to obvious choice queen");
moveBuf[i1].type = MOVE_TYPE_PROMOTION_TO_QUEEN;
} //switch
} //if 2
else if(piece[from] == ROOK && player==WHITE)
rookwm='t'; //rook moved?
else if(piece[from] == ROOK && player==WHITE)
kingwm='t'; //king moved?
if (!MakeMove(moveBuf[i1]))
{ //that move cant be made.King can be in check
TakeBack();//this portion gives updated board.
outtextxy(50,430,"Illegal move.<BR>);
}
break;
} //if 1
} //for loop
}
//if you find any discrepancy or if it helped you in any way
then please mail us bcoz your feedback is my motivation.Thanks
for downloading it.//
--------------------------------------------------------------------------------
|
|
|