# Code in C Programming Language, C99 Program, The Bark

In this assignment the students are required to write a program in C Programming language. This is a C99 Program, it is also referred to as the bark. This program would allow the users to play a game. The program has to be written in such a way that it accepts input and gives ouput using both user and pre-stored files. In this game, there is a provision to use both deck of cards and a rectangular board . Board is a grid with spaces to place cards. After a particular turn, the game ends if there are fewer than 11 cards on the deck or if there is no space to place cards on the board.

#### SOLUTION : –

#ifndef _QUEUE_

#define _QUEUE_

#include

#include

#include

#include

// A linked list (LL) node to store a queue entry

struct Node

{

int row, col;

};

struct QNode {

struct Node node;

struct QNode* next;

};

// The queue, front stores the front node of LL and rear stores the

// last node of LL

struct Queue {

struct QNode *front, *rear;

int size;

};

// A utility function to create a new linked list node.

struct QNode* newNode(int row , int col)

{

struct QNode* temp = (struct QNode*)malloc(sizeof(struct QNode));

temp->node.row = row;

temp->node.col = col;

temp->next = NULL;

return temp;

}

// A utility function to create an empty queue

struct Queue* createQueue()

{

struct Queue* q = (struct Queue*)malloc(sizeof(struct Queue));

q->front = q->rear = NULL;

q->size = 0;

return q;

}

// The function to add a key k to q

void enQueue(struct Queue* q, int row , int col)

{

// Create a new LL node

struct QNode* temp = newNode(row , col);

q->size++;

// If queue is empty, then new node is front and rear both

if (q->rear == NULL) {

q->front = q->rear = temp;

return;

}

// Add the new node at the end of queue and change rear

q->rear->next = temp;

q->rear = temp;

}

// Function to remove a key from given queue q

void deQueue(struct Queue* q, int *row, int *col)

{

// If queue is empty, return NULL.

if (q->front == NULL)

{

*row = *col = -1;

return;

}

q->size–;

// Store previous front and move front one node ahead

struct QNode* temp = q->front;

q->front = q->front->next;

// If front becomes NULL, then change rear also as NULL

if (q->front == NULL)

q->rear = NULL;

*row = temp->node.row;

*col = temp->node.col;

}

#endif

#define _CRT_SECURE_NO_WARNINGS

#include “functions.h”

int main(int argc, char * argv[]) {

#include

#include

#include

#include

#include “Queue.h”

char deck1, deck2, gridArr, player1Type, player2Type;

char cardsInDeck;

int width, height, playedCardsP1, playedCards2, deckIndex,

CardsInHand1, cardsInHand2, lengthOfTheDeck;

int numberOfDrawnCards, whoToPlay,

furthestDistanceForEachLetter,

distanceFromNodeToOther, player1Score, player2Score;

bool gameOverValidator = 0;

int max(int a , int b)

{

return a > b ? a : b;

}

bool is_empty_cell(int row, int col);

/*

* check if the the node is not free and I can visit

*/

bool is_neighbour(char my_number, int row, int col)

{

row = row == height ? 0 : row;

row = row == -1 ? height – 1 : row;

col = col == width ? 0 : col;

col = col == -1 ? width – 1 : col;

if(!is_empty_cell(row, col))

return my_number < gridArr[row][col];

return 0;

}

void calculate_distances_to_node(int row , int col) {

memset(distanceFromNodeToOther, -1, sizeof distanceFromNodeToOther);

distanceFromNodeToOther[row][col] = 0;
struct Queue * q = createQueue();

enQueue( q,row, col);

while (q->size) {

char myNumber = gridArr[row][col];

deQueue(q, &row, &col);

//visiting neighboring nodes

for (int i = -1; i < 2; ++i)

{

for (int j = -1; j < 2; ++j)

{

if (is_neighbour(myNumber, row + i, col + j))

{

if(distanceFromNodeToOther[row+i][col+j] == -1)

{

distanceFromNodeToOther[row + i][col + j] = distanceFromNodeToOther[row][col] + 1; enQueue(q, row + i, col + j);

}

}

}

}

}

}

bool is_empty_cell(int row, int col);

void find_furthest_to_me(int row_, int col_)

{

int max_dis = -1;

for (int row = 0; row < height; ++row)

{

for (int col = 0; col < width; ++col)

{

if(is_empty_cell(row , col) == 0)

{

if (gridArr[row_][col_] == gridArr[row][col])

max_dis = max(max_dis, distanceFromNodeToOther[row][col]);

}

}

}

furthestDistanceForEachLetter[gridArr[row_][col_] – ‘A’]= max(furthestDistanceForEachLetter[gridArr[row_][col_] – ‘A’], max_dis + 1);

}

void scoring()

{

memset(furthestDistanceForEachLetter, -1,sizeof furthestDistanceForEachLetter);

for (int row = 0; row < height; ++row)

{

for (int col = 0; col < width; ++col)

{

if(gridArr[row][col] != ‘*’)

{

calculate_distances_to_node(row, col);

find_furthest_to_me(row, col);

}

}

}

player1Score = player2Score = -1;

for (char i = ‘A’; i <= ‘Z’; ++i)

{

if (i % 2 == 0)

{

player2Score = max(player2Score, furthestDistanceForEachLetter[i – ‘A’]);

}

else

{

player1Score = max(player1Score, furthestDistanceForEachLetter[i – ‘A’]);

}

}

printf(“Player 1=%d Player 2=%d\n”, player1Score, player2Score);

}

void remove_played_card(int player , int idx)

{

if(player== 1)

{

for (int i = idx; i < 5; ++i)

{

strcpy(deck1[i], deck1[i + 1]);

}

CardsInHand1–;

}

else

{

for (int i = idx; i < 5; ++i)

{

strcpy(deck2[i], deck2[i + 1]);

}

CardsInHand1–;

}

}

/*check if the player type if correct*/

bool player_type_validator(char playerType)

{

return playerType == ‘a’ || playerType == ‘h’;

}

{

FILE* deckFile = fopen(fileNameDeck, “r”);

if (deckFile == NULL)

{

exit(3);

}

fscanf(deckFile, “%d”, &lengthOfTheDeck);

for (int i = 0; i < lengthOfTheDeck; ++i)

{

if (fscanf(deckFile, “%s”, cardsInDeck[i]) == EOF)

exit(3);

}

}

void player_deck_line_to_arr(char playerD, int playerNumber)

{

int len = strlen(playerD);

for (int i = 0; i < len; i += 2)

{

if (playerNumber == 1)

{

deck1[i] = playerD[i];

deck1[i] = playerD[i + 1];

CardsInHand1 = len / 2;

}

else

{

deck2[i] = playerD[i];

deck2[i] = playerD[i + 1];

cardsInHand2 = len / 2;

}

}

}

int deck_pointer()

{

return numberOfDrawnCards – 1;

}

/*convert 2d gridArr into 3d gridArr for ease of use*/

void convert_lines_grid_to_3d_arr(char temp_map)

{

for (int i = 0; i < height; ++i)

{

int tempIdx = 0;

int rowLen = strlen(temp_map[i]);

for (int j = 0; j < rowLen; ++j)

{

if (temp_map[i][j] != ‘*’)

{

gridArr[i][tempIdx] = temp_map[i][j];

gridArr[i][tempIdx] = temp_map[i][j + 1];

tempIdx++;

j++;

}

else

{

gridArr[i][tempIdx] = temp_map[i][j];

tempIdx++;

}

}

}

}

{

for (int i = 0; i < 5 + (whoToPlay == 1); ++i)

{

fscanf(save_file, “%c%c”, &deck1[i], &deck1[i]);

}

char valll;

fscanf(save_file, “%c”, &valll); // remova triling endline

for (int i = 0; i < 5 + (whoToPlay ==2); ++i)

{

fscanf(save_file, “%c%c”, &deck2[i], &deck2[i]);

}

fscanf(save_file, “%c”, &valll);// remova triling endline

}

{

FILE * saveFile;

saveFile = fopen(saveFileName, “r”);

if (saveFile == NULL)

{

exit(4);

}

fscanf(saveFile, “%d%d%d%d”, &width, &height, &numberOfDrawnCards, &whoToPlay);

char deckFileName;

fscanf(saveFile, “%s”, deckFileName);

char tempMap;

CardsInHand1 = 5 + (whoToPlay == 1);

cardsInHand2 = 5 + (whoToPlay == 2);

deckIndex = deck_pointer();

for (int i = 0; i < height; ++i)

{

fgets(tempMap[i], 300, saveFile);

strtok(tempMap[i] , “\n”);

}

convert_lines_grid_to_3d_arr(tempMap);

}

void give_players_cards()

{

if (lengthOfTheDeck < 11)

exit(4);

for (int i = 0; i < 5; ++i)

{

strcpy(deck1[i], cardsInDeck[deckIndex]);

deckIndex++;

}

for (int i = 0; i < 5; ++i)

{

strcpy(deck2[i], cardsInDeck[deckIndex]);

deckIndex++;

}

CardsInHand1 = cardsInHand2 = 5;

}

void generate_grid()

{

for (int i = 0; i < height; ++i)

{

for (int j = 0; j < width; ++j)

{

strcpy(gridArr[i][j], “*”);

}

}

}

int arguments_input(int argc, char* argv[])

{

if (argc != 4 && argc != 6)

{

exit(1);

}

if (argc == 6) {

sscanf(argv, “%d”, &width);

sscanf(argv, “%d”, &height);

if (player_type_validator(argv) == 0 || player_type_validator(argv)==0 )

{

exit(2);

}

player1Type = argv;

player2Type = argv;

deckIndex = 0;

whoToPlay = 1;

give_players_cards();

generate_grid();

}

else {

if (player_type_validator(argv) == 0 || player_type_validator(argv) == 0)

{

exit(2);

}

player1Type = argv;

player2Type = argv;

}

return 0;

}

void print_grid()

{

for (int i = 0; i < height; ++i)

{

for (int j = 0; j < width; ++j)

{

printf(“%s”, gridArr[i][j]);

}

puts(“”);

}

}

bool game_over()

{

return gameOverValidator;

}

void draw_card_for_turn(int player)

{

if (player==1)

{

strcpy(deck1[CardsInHand1], cardsInDeck[deckIndex]);

deckIndex++;

CardsInHand1++;

gameOverValidator = deckIndex == lengthOfTheDeck;

}

else

{

strcpy(deck2, cardsInDeck[deckIndex]);

cardsInHand2++;

deckIndex++;

gameOverValidator = deckIndex == lengthOfTheDeck;

}

}

bool is_empty_cell(int row, int col)

{

return gridArr[row][col] == ‘*’;

}

bool human_input_validation(int row, int col, int card)

{

return (card >= 0 && card < 6) && col< width && row< height && is_empty_cell(row, col);

}

bool is_grid_empty()

{

for (int i = 0; i < height; ++i)

{

for (int j = 0; j < width; ++j)

{

if (gridArr[i][j] != ‘*’)

return false;

}

}

return true;

}

void insert_card_into_grid(int player, int row, int col, int cardIdx)

{

printf(“Player %d playes %s in column %d row %d\n”, player, deck1[cardIdx], col+1, row+1);

strcpy(gridArr[row][col], deck1[cardIdx]);

remove_played_card(player, cardIdx);

print_grid();

}

void player_one_turn()

{

int row, col, card;

if (CardsInHand1 == 0)

{

gameOverValidator = 1;

return;

}

draw_card_for_turn(1);

if (player1Type == ‘h’)

{

do

{

printf(“Hand(1): “);

for (int i = 0; i < 6; ++i)

{

printf(“%s “, deck1[i]);

}

printf(“\nMove?”);

scanf(“%d%d%d”, &row, &col, &card);

row–, col–, card–;

}

while (human_input_validation(row, col, card) == 0);

insert_card_into_grid(1, row, col, card);

}

else

{

printf(“Hand: “);

for (int i = 0; i < 6; ++i)

{

printf(“%s “, deck1[i]);

}

puts(“”);

if(is_grid_empty())

{

insert_card_into_grid(1, height / 2-1, width / 2-1, 0);

}

else

{

int stillLooking = 1;

for (int i = 0; i < height && stillLooking; ++i)

{

for (int j = 0; j < width && stillLooking; ++j)

{

if(is_empty_cell(i, j))

{

stillLooking = 0; insert_card_into_grid(1, i, j, 0);

}

}

}

}

}

}

void player_two_turn()

{

if(cardsInHand2 ==0)

{

gameOverValidator = 1;

return;

}

int row, col, card;

draw_card_for_turn(2);

if (player2Type == ‘h’)

{

do

{

printf(“Hand(1): “);

for (int i = 0; i < 6; ++i)

{

printf(“%s “, deck2[i]);

}

printf(“\nMove?”);

scanf(“%d%d%d”, &row, &col, &card);

row–, col–, card–;

}

while (human_input_validation(row, col, card) == 0);

insert_card_into_grid(2, row, col, card);

}

else

{

printf(“Hand: “);

for (int i = 0; i < 6; ++i)

{

printf(“%s “, deck2[i]);

}

puts(“”);

int stillLooking = 1;

for (int i =height-1;i>=0 && stillLooking; i–)

{

for (int j = width-1;j >=0 && stillLooking; j–)

{

if (is_empty_cell(i, j))

{

stillLooking = 0;

insert_card_into_grid(2, i, j, 0);

}

}

}

}

}

void is_map_full()

{

if(game_over())

return;

gameOverValidator = 1;

for (int i = 0; i < height; ++i)

{

for (int j = 0; j < width; ++j)

{

if(gridArr[i][j] == ‘*’)

{

gameOverValidator = 0;

return;

}

}

}

}

void run_game()

{

while (!game_over())

{

if (whoToPlay == 1)

{

player_one_turn();

whoToPlay = 2;

}else

{

player_two_turn();

whoToPlay = 1;

}

is_map_full();

}

}

arguments_input(argc, argv);

print_grid();

run_game();

scoring();

getchar();

}