First game complete!

Started by
10 comments, last by Alima 19 years, 6 months ago
Well everyone I posted a kind of half done version of my console checkers game a while back, but now I believe everything is working and its ready to post here! Well i know your all eagerly awaiting the unveiling so heres the source! main.cpp

#include "checkers.h"

int board[8][8];


int main()
{
	int menu_choice;
	
	do
	{
		cout<<"=======================================\n";
		cout<<"** Welcome to Alima's Checkers game! **\n";
		cout<<"=======================================\n\n";
		cout<<"1 -- New 1 Player Game\n";
		cout<<"2 -- New 2 Player Game\n";
		cout<<"3 -- Help\n";
		cout<<"0 -- Quit\n";
		cout<<endl<<"Enter your choice: ";
		cin>>menu_choice;

		switch(menu_choice)
		{
			case 1:
				New_Game(1);
				break;
			case 2:
				New_Game(2);
				break;
			case 3:
				Help();
				break;
			default:
				cout<<"Thanks for playing!\n";
				break;
		}
	}
	while(menu_choice != 0);

	return(0);
}

void Help()
{
	cout<<"Symbols Key\n";
	cout<<"-----------\n";
	cout<<"Player1 Piece = X\n";
	cout<<"Player1 King  = +\n";
	cout<<"Player2 Piece = O\n";
	cout<<"Player2 King  = *\n\n";
	
	cout<<"How to play:\n";
	cout<<"------------\n";
	cout<<"When it is your turn enter the X and Y coordinate for the piece you wish\n";
	cout<<"to move. You can Enter this as 'X Y' and hit the ENTER key, or you can \n";
	cout<<"enter X, hit ENTER, and then enter Y and hit ENTER.\n\n";
	cin.get();
}


void New_Game(int num_players)
{

	Player player1;
	Player player2;

	player1.setup(1);
	player2.setup(2);

	for (int y=0;y<8;y++)
	{
		for (int x=0;x<8;x++)
			board[x][y]=0;
	}

	if (num_players==1)
		Single_Player(player1,player2);
	else
		Multi_Player(player1,player2);
}

void Update_Board(Player player1,Player player2)
{

	for (int x=0;x<8;x++)
	{
		for (int y=0;y<8;y++)
		{
			board[x][y]=0;
		}
	}

	for (int z=0;z<12;z++)
	{
		if (player1.pieces[z].king)
			board[player1.pieces[z].x_pos][player1.pieces[z].y_pos]=3;
		else
			board[player1.pieces[z].x_pos][player1.pieces[z].y_pos]=1;

		if (player2.pieces[z].king)
			board[player2.pieces[z].x_pos][player2.pieces[z].y_pos]=4;
		else
			board[player2.pieces[z].x_pos][player2.pieces[z].y_pos]=2;
	}
}

void DisplayBoard()
{
	system("cls");

	cout<<"  1 2 3 4 5 6 7 8 X\n";

	for (int y=0;y<8;y++)
	{
		cout<<(y+1)<<"|";
		for (int x=0;x<8;x++)
		{
			if(board[x][y]==1)
				cout<<"X|";
			else if(board[x][y]==2)
				cout<<"O|";
			else if(board[x][y]==3)
				cout<<"+|";
			else if(board[x][y]==4)
				cout<<"*|";
			else
				cout<<" |";
		}
		cout<<"\n";
	}
	cout<<"Y\n";
}

void Single_Player(Player player1,Player player2)
{
		bool victory=false;

	int VictoryP2, VictoryP1;

	int current_player=1;
	int jump=12;

	do
	{
		VictoryP1=0;
		VictoryP2=0;
		
		if(current_player==1)
		{		
			Update_Board(player1,player2);
			DisplayBoard();
			jump=player1.Player_Turn(player2.pieces,1);
			if (jump<12){player2.pieces[jump].x_pos=8;player2.pieces[jump].y_pos=8;}
			current_player++;
			jump=12;
		}
		else
		{
			jump=player2.Comp_Turn(player1.pieces);
			if (jump<12){player1.pieces[jump].x_pos=8;player1.pieces[jump].y_pos=8;}
			current_player--;
			jump=12;
		}

		for (int c=0;c<12;c++)
		{
			if ((player1.pieces[c].x_pos==8) && (player1.pieces[c].x_pos==8))
				VictoryP2++;
			else if ((player2.pieces[c].x_pos==8) && (player2.pieces[c].x_pos==8))
				VictoryP1++;
		}
		
		victory=VictoryCheck(VictoryP1, VictoryP2);
			
	}
	while(!victory);
}

void Multi_Player(Player player1,Player player2)
{
	bool victory=false;

	int VictoryP2, VictoryP1;

	int current_player=1;
	int jump=12;

	do
	{
		VictoryP1=0;
		VictoryP2=0;
		
		Update_Board(player1,player2);
		DisplayBoard();
		
		if(current_player==1)
		{
			jump=player1.Player_Turn(player2.pieces,1);
			if (jump<12){player2.pieces[jump].x_pos=8;player2.pieces[jump].y_pos=8;}
			current_player++;
			jump=12;
		}
		else
		{
			jump=player2.Player_Turn(player1.pieces,2);
			if (jump<12){player1.pieces[jump].x_pos=8;player1.pieces[jump].y_pos=8;}
			current_player--;
			jump=12;
		}

		for (int c=0;c<12;c++)
		{
			if ((player1.pieces[c].x_pos==8) && (player1.pieces[c].x_pos==8))
				VictoryP2++;
			else if ((player2.pieces[c].x_pos==8) && (player2.pieces[c].x_pos==8))
				VictoryP1++;
		}
		
		victory=VictoryCheck(VictoryP1, VictoryP2);
			
	}
	while(!victory);
}

bool VictoryCheck(int VictoryP1, int VictoryP2)
{
	if (VictoryP1==12)
	{
		system("cls");
		cout<<"Player1 Wins!!!\n";
		cin.get();
		return (true);
	}
	else if (VictoryP2==12)
	{
		system("cls");
		cout<<"Player2 Wins!!!\n";
		cin.get();
		return (true);
	}

	return (false);
}

checkers.h

#include <iostream.h>
#include <stdlib.h>

extern int board[8][8];

struct piece
{
	int x_pos;
	int y_pos;
	bool king;
};

class Player
{
public:
	piece pieces[12];

	void setup(int player_num);
	int Player_Turn(piece sPlayer2[12], int player_num);
	int Comp_Turn(piece sPlayer1[12]);

	Player();
	~Player();

private:
	bool CheckPiece(int xOld, int yOld, int *CurrentPiece);
	bool CheckDest(int PlayerNum, int CurrentPiece, int xNew, int yNew, piece sPlayer2[12], int *DeadPiece);
	int JumpCheck(bool king, int CurrentPiece, int PlayerNum, int xNew, int yNew, piece sPlayer2[12]);
	bool KingCheck(int PlayerNum, int yNew);

	int CompCheckJumps(piece sPlayer1[12], int *CurrentPiece);
	int CompMovePiece(piece sPlayer1[12]);
};

void Help();
void New_Game(int num_players);
void Update_Board(Player player1,Player player2);
void DisplayBoard();
void Single_Player(Player player1,Player player2);
void Multi_Player(Player player1,Player player2);
bool VictoryCheck(int VictoryP1, int VictoryP2);

checkers.cpp

#include "checkers.h"

Player::Player()
{
}

Player::~Player()
{
}

void Player::setup(int player_num)
{
	if (player_num==1)
	{
		pieces[0].x_pos=0;
		pieces[0].y_pos=0;

		pieces[1].x_pos=2;
		pieces[1].y_pos=0;

		pieces[2].x_pos=4;
		pieces[2].y_pos=0;

		pieces[3].x_pos=6;
		pieces[3].y_pos=0;

		pieces[4].x_pos=1;
		pieces[4].y_pos=1;

		pieces[5].x_pos=3;
		pieces[5].y_pos=1;

		pieces[6].x_pos=5;
		pieces[6].y_pos=1;

		pieces[7].x_pos=7;
		pieces[7].y_pos=1;

		pieces[8].x_pos=0;
		pieces[8].y_pos=2;

		pieces[9].x_pos=2;
		pieces[9].y_pos=2;

		pieces[10].x_pos=4;
		pieces[10].y_pos=2;

		pieces[11].x_pos=6;
		pieces[11].y_pos=2;
	}
	else
	{
		pieces[0].x_pos=1;
		pieces[0].y_pos=5;

		pieces[1].x_pos=3;
		pieces[1].y_pos=5;

		pieces[2].x_pos=5;
		pieces[2].y_pos=5;

		pieces[3].x_pos=7;
		pieces[3].y_pos=5;

		pieces[4].x_pos=0;
		pieces[4].y_pos=6;

		pieces[5].x_pos=2;
		pieces[5].y_pos=6;

		pieces[6].x_pos=4;
		pieces[6].y_pos=6;

		pieces[7].x_pos=6;
		pieces[7].y_pos=6;

		pieces[8].x_pos=1;
		pieces[8].y_pos=7;

		pieces[9].x_pos=3;
		pieces[9].y_pos=7;

		pieces[10].x_pos=5;
		pieces[10].y_pos=7;

		pieces[11].x_pos=7;
		pieces[11].y_pos=7;
	}

	//set all pieces to non-king
	for (int z=0;z<12;z++)
		pieces[z].king=false;

}

int Player::Player_Turn(piece sPlayer2[12], int player_num)
{
	int xOld;
	int yOld;
	int xNew;
	int yNew;

	int CurrentPiece=0;
	int DeadPiece=12;

	bool valid=false;


	do
	{
		do
		{
			cout<<"Player"<<player_num<<", Enter the X and Y coord for the piece you wish to move: ";
			cin>>xOld>>yOld;
			
			xOld--;
			yOld--;
			valid=CheckPiece(xOld, yOld,&CurrentPiece);
		}
		while(!valid);
		
		valid=false;

		cout<<"Player"<<player_num<<", Enter the X and Y coord for where you want to move thie piece: ";
		cin>>xNew>>yNew;
		
		xNew--;
		yNew--;

		valid=CheckDest(player_num, CurrentPiece, xNew, yNew, sPlayer2, &DeadPiece);
		if (!valid)
			cout<<"You cannot move your piece there!\n";
	}
	while(!valid);

	//Check to King Piece
	if (!pieces[CurrentPiece].king)
		pieces[CurrentPiece].king=KingCheck(player_num, yNew);

	//if (DeadPiece<12)
		return (DeadPiece);

	//return 12;
}

int Player::Comp_Turn(piece sPlayer1[12])
{
	int CurrentPiece;

	int Jump;

	Jump=CompCheckJumps(sPlayer1, &CurrentPiece);

	if (Jump!=12)
	{
		if (pieces[CurrentPiece].x_pos < sPlayer1[Jump].x_pos)
			pieces[CurrentPiece].x_pos+=2;
		else if (pieces[CurrentPiece].x_pos > sPlayer1[Jump].x_pos)
			pieces[CurrentPiece].x_pos-=2;
		
		if (pieces[CurrentPiece].y_pos < sPlayer1[Jump].y_pos)
			pieces[CurrentPiece].y_pos+=2;
		else if (pieces[CurrentPiece].y_pos > sPlayer1[Jump].y_pos)
			pieces[CurrentPiece].y_pos-=2;

		//Check to King Piece
		if (!pieces[CurrentPiece].king)
			pieces[CurrentPiece].king=KingCheck(2, pieces[CurrentPiece].y_pos);

		return (Jump);
	}
	else
	{
		CurrentPiece=CompMovePiece(sPlayer1);
		
		//Check to King Piece
		if (!pieces[CurrentPiece].king)
			pieces[CurrentPiece].king=KingCheck(2, pieces[CurrentPiece].y_pos);
		
		return (Jump);
	}
}

bool Player::CheckPiece(int xOld, int yOld, int *CurrentPiece)
{
	for (int z=0;z<12;z++)
	{
		if ((pieces[z].x_pos==xOld)&&(pieces[z].y_pos==yOld))
		{
			*CurrentPiece=z;
			return (true);
		}
	}
	return (false);
} 

bool Player::CheckDest(int PlayerNum, int CurrentPiece, int xNew, int yNew, piece sPlayer2[12], int *DeadPiece)
{
	int Jump=12;

	for (int z=0;z<12;z++)
	{
		if ((xNew==sPlayer2[z].x_pos) && (yNew==sPlayer2[z].y_pos))
			return (false);
		else if ((xNew==pieces[z].x_pos) && (yNew==pieces[z].y_pos))
			return (false);
	}

	switch(PlayerNum)
	{
	case 1:
		if (pieces[CurrentPiece].king)
		{
			if (((pieces[CurrentPiece].x_pos+1==xNew)||(pieces[CurrentPiece].x_pos-1==xNew))&&((pieces[CurrentPiece].y_pos+1==yNew)||(pieces[CurrentPiece].y_pos-1==yNew)))
			{
				pieces[CurrentPiece].x_pos=xNew;
				pieces[CurrentPiece].y_pos=yNew;
				return (true);
			}
			else if ((pieces[CurrentPiece].x_pos+2==xNew)||(pieces[CurrentPiece].x_pos-2==xNew)&&(pieces[CurrentPiece].y_pos+2==yNew)||(pieces[CurrentPiece].y_pos-2==yNew))
			{
				Jump=JumpCheck(pieces[CurrentPiece].king, CurrentPiece, PlayerNum, xNew, yNew, sPlayer2);
				if (Jump==12)
					return (false);
				else
				{
					pieces[CurrentPiece].x_pos=xNew;
					pieces[CurrentPiece].y_pos=yNew;
					*DeadPiece=Jump;
					return (true);
				}
			}
		}
		else
		{
			if (((pieces[CurrentPiece].x_pos+1==xNew)||(pieces[CurrentPiece].x_pos-1==xNew))&&(pieces[CurrentPiece].y_pos+1==yNew))
			{
				pieces[CurrentPiece].x_pos=xNew;
				pieces[CurrentPiece].y_pos=yNew;
				return (true);
			}
			else if ((pieces[CurrentPiece].x_pos+2==xNew)||(pieces[CurrentPiece].x_pos-2==xNew)&&(pieces[CurrentPiece].y_pos+2==yNew))
			{
				Jump=JumpCheck(pieces[CurrentPiece].king, CurrentPiece, PlayerNum, xNew, yNew, sPlayer2);
				if (Jump==12)
					return (false);
				else
				{
					pieces[CurrentPiece].x_pos=xNew;
					pieces[CurrentPiece].y_pos=yNew;
					*DeadPiece=Jump;
					return (true);
				}
			}
		}
		break;
	case 2:
		if (pieces[CurrentPiece].king)
		{
			if (((pieces[CurrentPiece].x_pos+1==xNew)||(pieces[CurrentPiece].x_pos-1==xNew))&&((pieces[CurrentPiece].y_pos+1==yNew)||(pieces[CurrentPiece].y_pos-1==yNew)))
			{
				pieces[CurrentPiece].x_pos=xNew;
				pieces[CurrentPiece].y_pos=yNew;
				return (true);
			}
			else if (((pieces[CurrentPiece].x_pos+2==xNew)||(pieces[CurrentPiece].x_pos-2==xNew))&&((pieces[CurrentPiece].y_pos+2==yNew)||(pieces[CurrentPiece].y_pos-2==yNew)))
			{
				Jump=JumpCheck(pieces[CurrentPiece].king, CurrentPiece, PlayerNum, xNew, yNew, sPlayer2);
				if (Jump==12)
				{
					return (false);
				}
				else
				{
					pieces[CurrentPiece].x_pos=xNew;
					pieces[CurrentPiece].y_pos=yNew;
					*DeadPiece=Jump;
					return (true);
				}
			}
		}
		else
		{
			if (((pieces[CurrentPiece].x_pos+1==xNew)||(pieces[CurrentPiece].x_pos-1==xNew))&&(pieces[CurrentPiece].y_pos-1==yNew))
			{
				pieces[CurrentPiece].x_pos=xNew;
				pieces[CurrentPiece].y_pos=yNew;
				return (true);
			}
			else if ((pieces[CurrentPiece].x_pos+2==xNew)||(pieces[CurrentPiece].x_pos-2==xNew)&&(pieces[CurrentPiece].y_pos-2==yNew))
			{
				Jump=JumpCheck(pieces[CurrentPiece].king, CurrentPiece, PlayerNum, xNew, yNew, sPlayer2);
				if (Jump==12)
				{
					return (false);
				}
				else
				{
					pieces[CurrentPiece].x_pos=xNew;
					pieces[CurrentPiece].y_pos=yNew;
					*DeadPiece=Jump;
					return (true);
				}
			}
		}
		break;
	default:
		break;
	}
	return (false);
}

int Player::JumpCheck(bool king, int CurrentPiece, int PlayerNum, int xNew, int yNew, piece sPlayer2[12])
{
	int xCheck=8;
	int yCheck=8;

	if (pieces[CurrentPiece].x_pos == xNew-2)
		xCheck=xNew-1;
	else if (pieces[CurrentPiece].x_pos == xNew+2)
		xCheck=xNew+1;

	if (pieces[CurrentPiece].y_pos == yNew-2)
	{
		if ((PlayerNum!=1)&&(!king))
			return (12);
		else
			yCheck=yNew-1;
	}
	else if (pieces[CurrentPiece].y_pos == yNew+2)
	{
		if ((PlayerNum!=2)&&(!king))
			return (12);
		else
			yCheck=yNew+1;
	}

	for (int z=0;z<12;z++)
	{
		if ((sPlayer2[z].x_pos==xCheck) && (sPlayer2[z].y_pos==yCheck))
			return (z);
	}
	return (12);
}

bool Player::KingCheck(int PlayerNum, int yNew)
{
	if ((PlayerNum==1)&&(yNew==7))
		return (true);
	else if ((PlayerNum==2)&&(yNew==0))
		return (true);

	return (false);

}

int Player::CompCheckJumps(piece sPlayer1[12], int *CurrentPiece)
{
	for (int z=0;z<12;z++)
	{
		for (int q=0;q<12;q++)
		{
			if (pieces[z].king)
			{
				if ((pieces[z].x_pos+1==sPlayer1[q].x_pos)&&(pieces[z].y_pos+1==sPlayer1[q].y_pos)&&(board[pieces[z].x_pos+2][pieces[z].y_pos+2]==0))
				{
					*CurrentPiece=z;
					return (q);
				}
				else if ((pieces[z].x_pos-1==sPlayer1[q].x_pos)&&(pieces[z].y_pos+1==sPlayer1[q].y_pos)&&(board[pieces[z].x_pos-2][pieces[z].y_pos+2]==0))
				{
					*CurrentPiece=z;
					return (q);
				}
			}

			if ((pieces[z].x_pos+1==sPlayer1[q].x_pos)&&(pieces[z].y_pos-1==sPlayer1[q].y_pos)&&(board[pieces[z].x_pos+2][pieces[z].y_pos-2]==0))
			{
				*CurrentPiece=z;
				return (q);
			}
			else if ((pieces[z].x_pos-1==sPlayer1[q].x_pos)&&(pieces[z].y_pos-1==sPlayer1[q].y_pos)&&(board[pieces[z].x_pos-2][pieces[z].y_pos-2]==0))
			{
				*CurrentPiece=z;
				return (q);
			}
		}

	}

	return (12);
}

int Player::CompMovePiece(piece sPlayer1[12])
{
	for (int z=0;z<12;z++)
	{
		if (pieces[z].king)
		{
			if ((board[pieces[z].x_pos+1][pieces[z].y_pos+1]==0)&&(pieces[z].x_pos+1<8)&&(pieces[z].y_pos+1<8))
			{
				pieces[z].x_pos+=1;
				pieces[z].y_pos+=1;
				return (z);
			}
			else if ((board[pieces[z].x_pos-1][pieces[z].y_pos+1]==0)&&(pieces[z].x_pos-1>0)&&(pieces[z].y_pos+1<8))
			{		
				pieces[z].x_pos-=1;
				pieces[z].y_pos+=1;
				return (z);
			}
		}
		if ((board[pieces[z].x_pos+1][pieces[z].y_pos-1]==0)&&(pieces[z].x_pos+1<8)&&(pieces[z].y_pos-1>0))
		{
			pieces[z].x_pos+=1;
			pieces[z].y_pos-=1;
			return (z);
		}
		else if ((board[pieces[z].x_pos-1][pieces[z].y_pos-1]==0)&&(pieces[z].x_pos-1>0)&&(pieces[z].y_pos-1>0))
		{		
			pieces[z].x_pos-=1;
			pieces[z].y_pos-=1;
			return (z);
		}

	}
}

well there you have it folks! let me know what you think! criticism welcome, but be gentle, its my first completed program :P Alima
Advertisement
Just a note. Constructors and Desctructors does not need to be explicity declared/defined.. c++ adds it if it's not defined/declared. :)
This is really cool! Everything lines up nicely, the ai works good, and the menu system is very clean. Congrats Alima! I'm looking forward to seeing where you go from here.
very very cool [grin]
-im'm a n00b
I cant compile it, it gives me a ton of link error's, colud you e-mail me the compiled version? (in a zip)
Yea actually I already have a compiled version on the web to show to my friends who dont have compilers :P

you can get it HERE

Thanks for the good reviews guys, very encouraging to complete something even so simple as this and have people give good, encouraging advice and comments. And thanks for that tip about the constructors and deconstructors, save me a few keystrokes next time :P

[Edit]
Oh and dan, im curious to know what some of those errors are. Just a little curious as i didnt get any of these errors and no one else so far seems to be getting them either.

Alima
Excellent, it works fine 'n dandy for me, everything seems well done. (Note: I just compiled and tested, didn't actually look at the source). Good luck with whatever your next project is. [smile]

- Jason Astle-Adams

Good work!

Minor nitpick:

Quote:
void setup(int player_num);
int Player_Turn(piece sPlayer2[12], int player_num);
bool CheckPiece(int xOld, int yOld, int *CurrentPiece);


3 different function notations are used here: all lowercase, capitialised with underscores, and capitialised with no underscores. Pick a notation and stick with it, don't jump all over the map. Consistancy is the key to good source. Same thing with your variables.

Really good work other then that, your logic will improve through practice, so keep at it!
Yea GroZZleR, the reason behind that was as i was writting this program, when I wasnt at the computer I was reading a bunch of stuff id printed out, and looking at different styles of notation. Toward the end there i found a notation style that i liked and plan on sticking with. That one you listed last is what ive found i like the best and plan on using that from hear on out. Thanks for the advice!

Alima

[EDIT]
typos...
it gave me a link error to every call to a variable in a class (game.variable)

This topic is closed to new replies.

Advertisement