Code:
#include <cstdio>
#include <windows.h>
#include <string>
class piece
{
private:
char type[2];
bool owner;
short x, y;
public:
piece(){;}
~piece(){;}
void SetOwner(bool o) {owner=o;}
bool GetOwner() {return owner; }
void SetX(short i) { x=i; }
short GetX() { return x; }
void SetY(short i) { y=i; }
short GetY() { return y; }
void SetXY(short a, short b) { x=a; y=b; }
char *GetName(char t);
void SetType(char t1, char t2) { type[0]=t1; type[1]=t2; }
char GetType(int i) {return type[i];}
bool CheckMove(int sx, int sy, int ex, int ey, char t);
bool RookMove(int sx, int sy, int ex, int ey);
bool KnightMove(int sx, int sy, int ex, int ey);
bool BishopMove(int sx, int sy, int ex, int ey);
bool QueenMove(int sx, int sy, int ex, int ey);
bool KingMove(int sx, int sy, int ex, int ey);
bool PawnMove(int sx, int sy, int ex, int ey);
};
class player
{
private:
char *name;
public:
player(){;}
~player(){;}
void SetName(char *s)
{
for(int i=0; i<20; i++)
{
name[i] = s[i];
if(s[i] == '\0') break;
}
}
char *GetName() {return name;}
};
class board
{
private:
piece *cell[8][8];
player *pl[2];
short go;//Which players go it is
short turn;//Turn number
public:
player *GetPlayer(int i) { return pl[i]; }
piece *GetCell(int x, int y) { return cell[x][y]; }
//Gets the first piece of a given kind that a player owns
piece *GetPiece(char type, bool player)
{
for(int y=0; y<8; y++)
for(int x=0; x<8; x++)
if(cell[x][y] != NULL)
if(cell[x][y]->GetType(1)==type)
return cell[x][y];
}
void NewPiece(int x, int y, bool i)
{
cell[x][y] = new piece;
cell[x][y]->SetOwner(1-i);
cell[x][y]->SetXY(x, y);
if(y==0 || y==7)
if(x==0 || x==7) cell[x][y]->SetType('R', 'k');
else if(x==1 || x==6) cell[x][y]->SetType('K', 't');
else if(x==2 || x==5) cell[x][y]->SetType('B', 's');
else if(x==4) cell[x][y]->SetType('K', 5);
else cell[x][y]->SetType('Q', 6);
else
cell[x][y]->SetType('P', 'n');
}
board()
{
int x, y;
go=0; turn=1;
for(y=0; y<2; y++) pl[y] = new player;
for(y=0; y<8; y++) for(x=0; x<8; x++) cell[x][y]=NULL;
for(y=0; y<2; y++) for(x=0; x<8; x++) NewPiece(x, y, false);
for(y=6; y<8; y++) for(x=0; x<8; x++) NewPiece(x, y, true);
}
~board(){;}
void DrawBoard();
void DrawCell(int x, int y);
bool GetOwner(int x, int y) { return cell[x][y]->GetOwner(); }
void PlayerSetup();
void TurnText()
{
printf("Turn: %i %s\n", turn, GetPlayer(go)->GetName());
}
bool MakeMove();
int ValidateLocation(char term_a, char term_b);
void EndGo() { if(go==0){go=1;} else{go=0; turn++;} }
short GetGo() { return go; }
};
HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE );
WORD wOldColorAttrs;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
board b;
int main()
{
//SetConsoleScreenBufferSize(h
GetConsoleScreenBufferInfo(h, &csbiInfo);
wOldColorAttrs = csbiInfo.wAttributes;
SetConsoleTextAttribute ( h, 8 );
bool quit=false;
bool check;
b.PlayerSetup();
//MAIN LOOP
while(quit == false)
{
check=true;
while(check == true)
{
b.DrawBoard();
b.TurnText();
check=b.MakeMove();
getchar();
system("CLS");
}
b.EndGo();
system("CLS");
}
return 0;
}
// Get name from second character of type tag
char* piece::GetName(char t)
{
int n=0;
if(t=='k') n=1;
else if(t=='t') n=2;
else if(t=='s') n=3;
else if(t==6) n=4;
else if(t==5) n=5;
else if(t=='n') n=6;
static char *name[] =
{
"Error", "Rook", "Knight", "Bishop", "Queen", "King", "Pawn"
};
return name[n];
}
void board::PlayerSetup()
{
char temp[20];
printf("Enter name for player 1: ");
gets(temp);
GetPlayer(0)->SetName(temp);
printf("Enter name for player 2: ");
gets(temp);
GetPlayer(1)->SetName(temp);
getchar();
system("CLS");
}
void board::DrawBoard()
{
for(int y=0; y<18; y++)
for(int x=0; x<26; x++)
if(y==0)
if(x==25) printf(" \n");
else if(x%3==2) putchar(65+(x/3));
else putchar(' ');
else if (y==1)
if(x==0) putchar(' ');
else if(x==1) putchar(218);
else if(x==25) printf("%c\n", 191);
else if(x%3==1) putchar(194);
else putchar(196);
else if(y==17)
if(x==0) putchar(' ');
else if(x==1) putchar(192);
else if(x==25) printf("%c\n", 217);
else if(x%3==1) putchar(193);
else putchar(196);
else if(y%2==1)
if(x==0) putchar(' ');
else if(x==1) putchar(195);
else if(x==25) printf("%c\n", 180);
else if(x%3==1) putchar(197);
else putchar(196);
else
if (x==0) putchar(48+(y/2));
else if(x==25) printf("%c\n", 179);
else if(x%3==1) putchar(179);
else if(x%3==2) DrawCell(x/3, (y/2)-1);
}
void board::DrawCell(int x, int y)
{
int i;
bool own;
if(cell[x][y]==NULL) //Empty Cell
{
if(x%2==0 && y%2==0 || x%2==1 && y%2==1) SetConsoleTextAttribute ( h, BACKGROUND_BLUE | 0 );
else SetConsoleTextAttribute ( h, BACKGROUND_RED | 0 );
printf(" ");
}
else //There is a piece in the Cell
{
own=GetOwner(x, y);
if(own == true)//Check owner colourv
if(x%2==0 && y%2==0 || x%2==1 && y%2==1)//Check tile colour
SetConsoleTextAttribute ( h, BACKGROUND_BLUE | 8 );
else
SetConsoleTextAttribute ( h, BACKGROUND_RED | 8 );
else
if(x%2==0 && y%2==0 || x%2==1 && y%2==1)
SetConsoleTextAttribute ( h, BACKGROUND_BLUE | 0 );
else
SetConsoleTextAttribute ( h, BACKGROUND_RED | 0 );
putchar(cell[x][y]->GetType(0));
putchar(cell[x][y]->GetType(1));
}
SetConsoleTextAttribute ( h, 8 );
}
bool board::MakeMove()
{
char temp[100];
int xa, ya, xb, yb, i;
char t, t2;
printf("Move Piece From: ");
gets(temp);
ya=ValidateLocation(temp[0], temp[1]);
if(ya==-1)
{
printf("Location Not On The Board.");
return 1;
}
xa=ya%8;
ya=ya/8;
if(cell[xa][ya]==NULL)
{
printf("There is no piece to move there.");
return 1;
}
else if(GetOwner(xa, ya) != go)
{
printf("That piece does not belong to you.");
return 1;
}
t=cell[xa][ya]->GetType(1);//Get The type
printf("Move %s to:", cell[xa][ya]->GetName(t));//Get The name
gets(temp);
yb=ValidateLocation(temp[0], temp[1]);
if(yb==-1)
{
printf("Location Not On The Board.");
return 1;
}
xb=yb%8;
yb=yb/8;
if(cell[xa][ya]->CheckMove(xa, ya, xb, yb, t) == true)
{
printf("Invalid Move");
return 1;
}
if(cell[xb][yb] != NULL)
{
if(GetOwner(xb, yb) == go)
{
printf("You Cant Take Your Own Piece.");
return 1;
} //If Piece belongs to opponent
t2=cell[xb][yb]->GetType(1);//Get The type
printf("You take your opponents %s", cell[xb][yb]->GetName(t2));
}
delete cell[xb][yb]; //Delete the taken piece
cell[xb][yb]=cell[xa][ya]; //Put Piece in Cell Moved To
cell[xa][ya]=NULL; //Clear cell moved from
cell[xb][yb]->SetXY(xb, yb); //Set new co-ords for piece
return 0;
}
//Returns Y*8 + X, or -1 for invlaid move location
int board::ValidateLocation(char term_a, char term_b)
{
if(term_a > 96 && term_a < 105) term_a-=32;
if(term_b > 96 && term_b < 105) term_b-=32;
if(term_a > 48 && term_a < 57)
if(term_b > 64 && term_b < 73)
return ((term_a-49)*8)+(term_b-65);
else
return -1;
else if(term_b > 48 && term_b < 57)
if(term_a > 64 && term_a < 73)
return ((term_b-49)*8)+(term_a-65);
else
return -1;
else
return -1;
}
bool piece::CheckMove(int sx, int sy, int ex, int ey, char tz)
{
if(tz=='k' && RookMove(sx, sy, ex, ey)==true)return true;
else if(tz=='t' && KnightMove(sx, sy, ex, ey)==true)return true;
else if(tz=='s' && BishopMove(sx, sy, ex, ey)==true)return true;
else if(tz==6 && QueenMove(sx, sy, ex, ey)==true)return true;
else if(tz==5 && KingMove(sx, sy, ex, ey)==true)return true;
else if(tz=='n' && PawnMove(sx, sy, ex, ey)==true)return true;
}
bool piece::RookMove(int sx, int sy, int ex, int ey)
{
if(sx==ex && sy!=ey)//Moves Y but not X
if(sy < ey) //Moving Down
for(int y=sy+1; y<ey; y++)//Check path for obstructions
if(b.GetCell(sx, y) != NULL) //If Obstruction on path
return 1;
if(sy > ey) //Moving Up
for(int y=ey+1; y<sy; y++)//Check path for obstructions
if(b.GetCell(sx, y) != NULL) //If Obstruction on path
return 1;
if(sy==ey && sx!=ex)//Moves X but not Y
if(sx < ex) //Moving Right
for(int x=sx+1; x<ex; x++)
if(b.GetCell(x, sy) != NULL)
return 1;
if(sx > ex) //Moving Left
for(int x=ex+1; x<sx; x++)
if(b.GetCell(x, sy) != NULL)
return 1;
if(sx!=ex && sy!=ey || sx==ex && sy==ey)//Moves Both X and Y or neither then Invalid
return 1;
return 0;
}
bool piece::KnightMove(int sx, int sy, int ex, int ey)
{
if(sx==ex-1 || sx==ex+1)
if(sy==ey-2 || sy==ey+2)
return false;
else
return true;
else if(sy==ey-1 || sy==ey+1)
if(sx==ex-2 || sx==ex+2)
return false;
else
return true;
else
return true;
}
bool piece::BishopMove(int sx, int sy, int ex, int ey)
{
int dx=sx-ex;
int dy=sy-ey;
if(dx < 0)dx=-dx;//Make the difference absolute
if(dy < 0)dy=-dy;
if(dx != dy) return 1; //If not diagonal then invalid
if(dx == 0) return 1; //If not moved then invalid
//Check for obstructions
if(sx < ex && ey < sy) //Up and Right
for(int m=1; m<dx; m++)
if(b.GetCell(sx+m, sy-m) != NULL)
//printf("X: %i Y: %i\n", sx+m, sy-m);
return 1;
if(sx < ex && ey > sy)//Down and Right
for(int m=1; m<dx; m++)
if(b.GetCell(sx+m, sy+m) != NULL)
return 1;
if(sx > ex && ey < sy)//Up and Left
for(int m=1; m<dx; m++)
if(b.GetCell(sx-m, sy-m) != NULL)
return 1;
if(sx > ex && ey > sy)//Down and Left
for(int m=1; m<dx; m++)
if(b.GetCell(sx-m, sy+m) != NULL)
return 1;
return 0;
}
bool piece::QueenMove(int sx, int sy, int ex, int ey)
{
if(RookMove(sx, sy, ex, ey)==true && BishopMove(sx, sy, ex, ey)==true)
return 1;
else
return 0;
}
bool piece::KingMove(int sx, int sy, int ex, int ey)
{
if(sx==ex-1 || sx==ex+1 || sx==ex)
if(sy==ey-1 || sy==ey+1 || sy==ey)
if(sx==ex && sy==ey)//If Not Moved
return 1;
else
return 0;
return 1;
}
bool piece::PawnMove(int sx, int sy, int ex, int ey)
{
int mod, jmp=0;
if(b.GetGo()==0) mod= 1;
else mod=-1;
if((sy==6 && ey==4) || (sy==1 && ey==3)) jmp=1;
if(sy==ey+mod || (sy=ey+mod+mod && jmp==1))
if(sx==ex)//Move Forward
if(b.GetCell(ex, ey) != NULL)//If Blocked
return 1;
else
return 0;
else if((sx==ex-1 || sx==ex+1) && jmp==0)
if(b.GetCell(ex, ey) != NULL)//If Piece to take
return 0;
else
return 1;
else
return 1;
return 1;
}