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[101][3], deck2[101][3], gridArr[301][301][3], player1Type, player2Type;
char cardsInDeck[10055][3];
int width, height, playedCardsP1[100], playedCards2[100], deckIndex,
CardsInHand1, cardsInHand2, lengthOfTheDeck;
int numberOfDrawnCards, whoToPlay,
furthestDistanceForEachLetter[30],
distanceFromNodeToOther[301][301], 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][1];
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][1];
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_][0] == gridArr[row][col][0])
max_dis = max(max_dis, distanceFromNodeToOther[row][col]);
}
}
}
furthestDistanceForEachLetter[gridArr[row_][col_][0] – ‘A’]= max(furthestDistanceForEachLetter[gridArr[row_][col_][0] – ‘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][0] != ‘*’)
{
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’;
}
void load_deck(char *fileNameDeck)
{
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[1000], int playerNumber)
{
int len = strlen(playerD);
for (int i = 0; i < len; i += 2)
{
if (playerNumber == 1)
{
deck1[i][0] = playerD[i];
deck1[i][1] = playerD[i + 1];
CardsInHand1 = len / 2;
}
else
{
deck2[i][0] = playerD[i];
deck2[i][1] = 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[100][100])
{
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][0] = temp_map[i][j];
gridArr[i][tempIdx][1] = temp_map[i][j + 1];
tempIdx++;
j++;
}
else
{
gridArr[i][tempIdx][0] = temp_map[i][j];
tempIdx++;
}
}
}
}
void read_player_hand_decks(FILE* save_file)
{
for (int i = 0; i < 5 + (whoToPlay == 1); ++i)
{
fscanf(save_file, “%c%c”, &deck1[i][0], &deck1[i][1]);
}
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][0], &deck2[i][1]);
}
fscanf(save_file, “%c”, &valll);// remova triling endline
}
void save_mode_load(char* saveFileName)
{
FILE * saveFile;
saveFile = fopen(saveFileName, “r”);
if (saveFile == NULL)
{
exit(4);
}
fscanf(saveFile, “%d%d%d%d”, &width, &height, &numberOfDrawnCards, &whoToPlay);
char deckFileName[100];
fscanf(saveFile, “%s”, deckFileName);
load_deck(deckFileName);
char tempMap[300][100];
read_player_hand_decks(saveFile);
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[2], “%d”, &width);
sscanf(argv[3], “%d”, &height);
if (player_type_validator(argv[4][0]) == 0 || player_type_validator(argv[5][0])==0 )
{
exit(2);
}
player1Type = argv[4][0];
player2Type = argv[5][0];
load_deck(argv[1]);
deckIndex = 0;
whoToPlay = 1;
give_players_cards();
generate_grid();
}
else {
if (player_type_validator(argv[4][0]) == 0 || player_type_validator(argv[5][0]) == 0)
{
exit(2);
}
save_mode_load(argv[1]);
player1Type = argv[2][0];
player2Type = argv[3][0];
}
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[5], cardsInDeck[deckIndex]);
cardsInHand2++;
deckIndex++;
gameOverValidator = deckIndex == lengthOfTheDeck;
}
}
bool is_empty_cell(int row, int col)
{
return gridArr[row][col][0] == ‘*’;
}
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][0] != ‘*’)
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][0] == ‘*’)
{
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();
}