Friday, April 27, 2012

Four in a Row game using C

This game is similar to the Connect 4 game, Here we make use of signals and pipes to communicate between M children and a parent and play the game of connect 4.
The child is Intelligent to an extent and will not make just random moves, whereas the parent will make random moves.Here 1 or B stand for child and 2 or R stands for the parent.
The size of the board is N which is currently fixed to be 5 but can be changed.
I have made use of two c files, 1 is the header and the other is the c file. The header file contains all of the headers and non calculating functions. Also i made this program in Linux, if you are building it on windows you might wanna include conio.h as the header file as well and use getch().
I will be putting up the code and some of its outputs as well

this is the header file called as header.h


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#define M 3 //number of players
#define N 5 //board size

int count = 0;
int isDone[M];
pid_t array[M];

union BoardGame{
int board[N][N];
pid_t childpid;
int hasCompleted;
int boardNumber;
int signal;
};
typedef union BoardGame game;


void initializeBoard(game *board,int id){
board-> hasCompleted = 0;
board -> boardNumber = id;
board -> signal = 0;
int i,j;
for(i = 0; i<N;i++){
for(j = 0;j<N;j++){
board-> board[i][j] = 0;
}
}
}

int isBoardEmpty(game *board){
int column;
for(column = 0; column < N ; column++){
if(board->board[0][column] == 0)
return 0;
}

printf(" Board %d is full ", board->boardNumber);
return 1;
}

int isValidMove(game *board, int column) {
if (board->board[0][column] == 0) {
return 1;
}

else
return 0;
}

void print(game *board){
int i = 0 ;
int j;
int k;
int row = 0;
for(k =0; k<N;k++)
printf(" -------");
printf("\n");
for(i= 0 ; i<3*N; i++){
for(j = 0;j<=N;j++){

if (i% 3 == 1 && j!=N){
printf("|");
if( board->board[i/3][j] == 1){
printf("   B ");
}
else if( board->board[i/3][j] == 2){
printf("   R ");
}
else if( board->board[i/3][j] == 0){
printf("   %d ", board->board[i/3][j]);
}
}
else
printf("| ");
}

printf("\n");
if(i%3==2){
for(k =0; k<N;k++)
printf(" -------");
printf("\n");
}
}
}

The main file :


#include "four_header.h"


int randomNumber(){
int x1 = rand()%N;
return x1;
}

int calculateChild1(int column, game *board){        //(game *board){{
int i;
//int column = rand()%N;
for(i = N-1;i >= 0;i--){
//        printf("i = %d\n",i);
if(board->board[i][column] == 0){
board->board[i][column] = 1;
return i;
}
}  
}


int columnCalculate(game *board){
int column;
again:
column = randomNumber();
if(isValidMove(board, column) == 1)
return column;
else
goto again;
}

int calculateRow(int column, game *board){  
int i;
//int column = rand()%N;
for(i = N-1;i >= 0;i--){
//        printf("i = %d\n",i);
if(board->board[i][column] == 0){
return i;
}
}  
}

int calculateChild(game *board){
int column,row;
// srand(time(NULL));
for(column = 0; column < N; column++) {

if(board->board[0][column] != 0) {

continue;
}
row = calculateRow(column,board);

if((row - 1) >= 0){
if(board->board[row - 1][column] == 1) {
return column;
}
}
//check left
if((column - 1) >= 0){
if(board->board[row][column - 1] == 1) {
return column;
}
}

if((column + 1) <= N -1) {
if(board->board[row][column + 1] == 1){
return column;
}
}


if(((column + 1) <= (N - 1)) && ((row - 1) >= 0)){
if( board->board[row - 1][column + 1] == 1)
return column;
}

if(((column - 1) > -1) && ((row - 1) > -1)){
if(board->board[row - 1][column - 1] == 1)
return column;
}

if(((column + 1) < N) && ((row + 1) < N)){
if(board->board[row + 1][column + 1] == 1)
return column;
}
}
while(1) {
column = columnCalculate(board);
return column;
}

}


int calculateParent(int column,game *board){
int i;
for(i = N-1;i >= 0;i--){
//        printf("i = %d\n",i);
if(board->board[i][column] == 0){
board -> board[i][column] = 2;
return i;
}
}
}



int check1(game *board){
int row[N], column[N], diagonal1[N], diagonal2[N];
int i,j;
for(i = 0;i<N;i++){
row[i] = 0;
column[i] = 0;
diagonal1[i] = 0;
diagonal2[i] = 0;
}
for(i = 0;i<N;i++){
for(j = 0; j<N;j++){
if(board -> board[i][j] == 1){

row[i] = row[i]+1;
//                printf("row check of %d = %d\n",i,row[i]);
//                printf("----------------------------\n");
}
else row[i] = 0;
if(board-> board[j][i]==1){
column[i] = column[i]+1;
//                printf("column check of %d = %d\n",i,column[i]);
//                printf("----------------------------\n");
}
else column[i] = 0;
if(board -> board[i+j][j] == 1){
diagonal1[i] = diagonal1[i] + 1;
//                printf("diagonal1 check of player 1 = %d\n",diagonal1[i]);
//                printf("----------------------------\n");
}
else diagonal1[i] = 0;  
if(board->board[i+j][N-1-j] == 1){
//                printf("diag2 = %d\n i+j = %d \n n-1-j = %d\n",board[i+j][N-1-j][no],i+j,((N-1)-j));
diagonal2[i] = diagonal2[i] + 1;
//                printf("diagonal2 check of player 1 = %d\n",diagonal2[i]);
//                printf("----------------------------\n");
}
else diagonal2[i] = 0;
//if(row[i] == 4 || column[i] == 4|| diagonal1[i] == 4||diagonal2[i]==4)
//    return 1;
if(row[i] == 4){
printf ("\nChild won on row\n");
sleep(2);
return 1;
}
else if(column[i] == 4){
printf ("\nChild won on column\n");
sleep(2);
return 1;
}
else if(diagonal1[i] == 4){
printf ("\nChild won on diagonal\n");
sleep(2);
return 1;
}
else if(diagonal2[i] == 4){
printf ("\nChild won on anti-diagonal\n");
sleep(2);
return 1;
}
}
}  
return 0;
}

int check2(game *board){
int row[N], column[N], diagonal1[N], diagonal2[N];
int i,j;
for(i = 0;i<N;i++){
row[i] = 0;
column[i] = 0;
diagonal1[i] = 0;
diagonal2[i] = 0;
}
for(i = 0;i<N;i++){
for(j = 0; j<N;j++){
if(board -> board[i][j] == 2){

row[i] = row[i]+1;
//                printf("row check of %d = %d\n",i,row[i]);
//                printf("----------------------------\n");
}
else row[i] = 0;
if(board-> board[j][i] == 2){
column[i] = column[i]+1;
//                printf("column check of %d = %d\n",i,column[i]);
//                printf("----------------------------\n");
}
else column[i] = 0;
if(board -> board[i+j][j] == 2){
diagonal1[i] = diagonal1[i] + 1;
//                printf("diagonal1 check of player 1 = %d\n",diagonal1[i]);
//                printf("----------------------------\n");
}
else diagonal1[i] = 0;  
if(board->board[i+j][N-1-j] == 2){
//                printf("diag2 = %d\n i+j = %d \n n-1-j = %d\n",board[i+j][N-1-j][no],i+j,((N-1)-j));
diagonal2[i] = diagonal2[i] + 1;
//                printf("diagonal2 check of player 1 = %d\n",diagonal2[i]);
//                printf("----------------------------\n");
}
else diagonal2[i] = 0;
//if(row[i] == 4 || column[i] == 4|| diagonal1[i] == 4||diagonal2[i]==4)
//    return 1;
if(row[i] == 4){
printf ("\nParent won on row\n");
sleep(2);
return 1;
}
else if(column[i] == 4){
printf ("\nParent won on column\n");
sleep(2);
return 1;
}
else if(diagonal1[i] == 4){
printf ("\nParent won on diagonal\n");
sleep(2);
return 1;
}
else if(diagonal2[i] == 4){
printf ("\nParent won on anti-diagonal\n");
sleep(2);
return 1;
}
}
}  
return 0;
}


void boardCheck(int ){
count += 1;
if(count == M){
printf("Game over\n");
exit(0);
}
}
void quit(int parentPipe[2],int childPipe[2],game *board, int player){

if(player == 1){
kill(getppid(), SIGUSR1);
close(parentPipe[0]);
close(childPipe[1]);
close(parentPipe[1]);
close(childPipe[0]);
}
else if(player == 2){
close(parentPipe[1]);
close(childPipe[0]);
close(parentPipe[0]);
close(childPipe[1]);      
}
}
void playChildGame(int parentPipe[2],int childPipe[2],game *board, int boardNum){
int i,j;
int parentMove = 0;
int childMove = 0;
int childMove1 = 0;
int check = 0;
int columnChild;
initializeBoard(board, boardNum);
for(i = 0; i< N*N;i++){
if(isBoardEmpty(board) == 1){
check = getpid();
write(childPipe[1], &check,sizeof(int));
goto quit;

}

do{
read(parentPipe[0],&parentMove,sizeof(int));
check = -1;
write(childPipe[1],&check,sizeof(int));
}while(isValidMove(board,parentMove) == 0);
calculateParent(parentMove, board);
printf("--------------------------------------------------------------------------\n");
printf("Parent is making the move on %d on board # %d \n",parentMove, boardNum);
printf("--------------------------------------------------------------------------\n");
print(board);
sleep(2);

if(check2(board) == 1 || isBoardEmpty(board) == 1){
check = getpid();
write(childPipe[1], &check, sizeof(int));
goto quit;

}
else{
check = -1;
write(childPipe[1], &check, sizeof(int));
}

check = 0;
do{
check++;
columnChild = randomNumber();
}while(isValidMove(board, columnChild) == 0 );

childMove = calculateChild(board);
childMove1 = calculateChild1(childMove,board);
printf("--------------------------------------------------------------------------\n");
printf("Child is making the move on %d on board # %d \n",columnChild, boardNum);
printf("--------------------------------------------------------------------------\n");
print(board);
sleep(2);
if(check1(board) == 1 || isBoardEmpty(board) == 1){
check = getpid();
write(childPipe[1], &check, sizeof(int));
goto quit;

}
else{
check = -1;
write(childPipe[1], &check, sizeof(int));
}
}
goto quit;
quit:  
kill(getppid(), SIGUSR1);
close(parentPipe[0]);
close(childPipe[1]);
close(parentPipe[1]);
close(childPipe[0]);

}

int playParentGame(int parentPipe[2],int childPipe[2], int boardNum){
int childMove = 0;
int random = 0;
int parentMove;
while(1){
random = randomNumber();
srand(time(NULL) - random*6);
random = randomNumber();
write(parentPipe[1], &random , sizeof(int));
read(childPipe[0], &childMove, sizeof(int));
if( childMove != -1){
if(array[boardNum] == childMove){
goto quit;

}
}
}
quit:
close(parentPipe[1]);
close(childPipe[0]);
close(parentPipe[0]);
close(childPipe[1]);
return 1;
}

int main(int argc, char **argv){
game boardGame[M];
int i, j, boardNum, k;
int pipe1[M][2];
int pipe2[M][2];
int flag = 0;
int index = 0;
pid_t pid;
srand(time(0));
signal(SIGUSR1, boardCheck);
for (i  = 0; i < M; i++) {
initializeBoard(&boardGame[i],i);
isDone[i] = 0;
}

for(i = 0; i < M; i++) {
pipe(pipe1[i]);
pipe(pipe2[i]);
pid = fork();

if (pid == 0) { //CHILD

if (!flag) {
boardNum = i;
flag = 1;
}
i += M;

playChildGame(pipe1[boardNum],pipe2[boardNum], &boardGame[boardNum], boardNum);

}

else {  //PARENT

array[index] = pid;
index++;
if(index == M) {
for(j = 0; j < M; j++)  
playParentGame(pipe1[j],pipe2[j], j);
}        
}
}
return 0;
}  

some sample out put:








No comments:

Post a Comment