//Source code
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
#include<time.h>
#include<windows.h>
#define KEY_LEFT 75							/* Move left, left arrow */
#define KEY_UP 72							/* Move up, up arrow */ 
#define KEY_RIGHT 77						/* Move right, right arrow */
#define KEY_DOWN 80							/* Move down, down arrow */
#define KEY_ENTER 13						/*Enter key*/
#define BOARDSIZE 8							/*size of the board*/
#define BATTLESHIPSIZE 5					/*size of the biggest ship*/
#define CRUISERSIZE 4						/*size of the second biggest ship*/
#define FRIGATESIZE 3						/*size of the second smallest ship*/
#define MINESWEEPERSIZE 2					/*size of the smallest ship*/
#define SHIPNUMBER 4						/*number of all the ship*/
#define WATER 177							/*character for water*/
#define SHIP 219							/*character for ship(while selecting)*/
#define BOMB 1								/*character for ship that has been hit (smiley face)*/
#define NOTBOMB 248							/*character for water that is empty (tiny circle)*/
#define PLAYER 219							/*character when the player is selecting the position of the ships*/
#define BLANK -52							/*black character*/
#define PLAYERNO 2							/*number of player*/

struct board{
	char ship[SHIPNUMBER][BOARDSIZE][BOARDSIZE];
	int score;	//contain positions of the 2-block ship
	int mainboard[BOARDSIZE][BOARDSIZE];	/*8-by-8 board*/
	char openbomb[BOARDSIZE][BOARDSIZE];	/*the 8-by-8 board contains the position of the block that a bomb has been placed*/
	char openwater[BOARDSIZE][BOARDSIZE];	/*the 8-by-8 board contains the position of the block that has been opened*/
};
typedef struct board Board;	
struct info{				/*store the winner's information*/
	char name[100];
	int score;
	char date[80];

};
typedef struct info Info;
struct dt{					/*Information for the present date, year and month*/
	int date;
	int month;
	int year;
};
//Introduction to the game 
void intro(){
	int user;
	while (1){
		printf("=========================================================");
		printf("\n=		   Welcome to Battleship  		=");
		printf("\n=========================================================");
		printf("\n");
		printf("                    ()\n");
		printf("                    ||q',,'\n");
		printf("                    ||d,~\n");
		printf("         (,---------------------,)\n");
		printf("          ',       q888p       ,'\n");
		printf("            \\       986       /\n");
		printf("             \\  8p, d8b ,q8  /\n");
		printf("              ) 888a888a888 (\n");
		printf("             /  8b` q8p `d8  \\              O\n");
		printf("            /       689       \\             |','\n");
		printf("           /       d888b       \\      (,---------,)\n");
		printf("         ,'_____________________',     \\   ,8,   /\n");
		printf("         (`__________|__________`)      ) a888a (  \n");
		printf("         [___________|___________]     /___`8`___\\   }*{\n");
		printf("           }:::|:::::}::|::::::{      (,=========,)  -=-\n");
		printf("            '|::::}::|:::::{:|'  .,.    \\:::|:::/    ~`~\n");
		printf("--=~(@)~=-- ' |}:::::|::{:::|'           ~\"., .\"~`~\n");
		printf("               '|:}::|::::|'~`~\"., .\" \n");
		printf("         ~`~\"., .\"~`~\"., \"~`~\"., .\"~\n\n");
		printf("		Press enter to play\n");
		user = _getch();
		if (user == KEY_ENTER)	//will only go to the next window if the enter button is pressed
			break;
		system("cls");
	}
	system("cls");
}
//display the board that shows the position of the ships
void displayBoard(Board *ptrBoard){
	int option = WATER;
	printf("\nYour current board: \n\n");
	int i, j;
	for (i = 0; i < BOARDSIZE; i++){
		printf("\t    ");
		for (j = 0; j < BOARDSIZE; j++){
			printf(" %c ", ptrBoard->mainboard[i][j]);	//display the current character in main board 
		}
		printf("\n\n");
	}
}
//gameCore function is for assigning the position from all the ships to the mainboard or refresh the main board
void gameCore(Board *ptrBoard){
	int i, j,k;
	int option = WATER;
	for (i = 0; i < BOARDSIZE; i++){
		for (j = 0; j < BOARDSIZE; j++){
			for (k = 0; k < SHIPNUMBER; k++){
				if (ptrBoard->ship[k][i][j] != BLANK){
					ptrBoard->mainboard[i][j] = ptrBoard->ship[k][i][j];	//assign the position of the placed ship to the main board
				}
				if (ptrBoard->ship[0][i][j] == BLANK && ptrBoard->ship[1][i][j] == BLANK && ptrBoard->ship[2][i][j] == BLANK && ptrBoard->ship[3][i][j] == BLANK)
				ptrBoard->mainboard[i][j] = option;						//assign WATER character to the main board
			}
		}
	}
}
//Check if the ships are placed overlapped
int isOverlapped(Board *ptrBoard, int m, int n, int shipnum, int choice){ //m and n are the row and column respectively
	int k, l,i;
	for (i = 0; i < shipnum; i++){
		for (k = 0; k < SHIPNUMBER; k++){
			if (ptrBoard->ship[k][m][n] != BLANK)			//if the current position already exists in current ship array, return 1
				return 1;
		}
			if (choice == 1)		//the direction that the ship is facing to move forward the position in the loop
				n = n + 1;
			else if (choice == 2)	//1 for left and right and 2 for up and down
				m = m + 1;
	}
		return 0;	//no conditions above have been applied then the function returns 0
}
// Function fixPos is used to move the position of the ship  around while selectiing
void fixPos(Board *ptrBoard, int m, int n, int shipnum, int choice, int enter){ 
	// if the enter button is pressed, the value of enter is 1, otherwise it is 0;
	int option = SHIP, k, l, list[] = { BATTLESHIPSIZE, CRUISERSIZE, FRIGATESIZE, MINESWEEPERSIZE };

	for (l = 0; l < shipnum; l++){
		ptrBoard->mainboard[m][n] = option;
		for (k = 0; k < SHIPNUMBER; k++){
			if (enter == 1 && shipnum == list[k])							//enter is pressed and the selected ship is battleship
				ptrBoard->ship[k][m][n] = ptrBoard->mainboard[m][n];		//the selected position on the main board will be assigned to the ship array
		}
		if (choice == 1)		//the direction that the ship is facing to move forward the position in the loop
			n++;				//1 for left and right and 2 for up and down
		else if (choice == 2)
			m++;
		
	}
}
//selectionWindows is a window for the users(players) to place the ships.
Board selectionWindow(Board board, Board *ptrBoard){
	int i, ships[SHIPNUMBER] = {BATTLESHIPSIZE, CRUISERSIZE, FRIGATESIZE, MINESWEEPERSIZE}, j, user = 1, m = 0, n = 0;
	int count = 0, user2, enter = 0, player = 1, edge ;
	// i and j = used in a loop// user = the decision of the ship direction that the user made// m = // n = column
	// count = used to change the kind of ship to the next one //user2 = key that user entered// player = player's number
	char choice; //direction of the ship
	ptrBoard = &board;
	ptrBoard->score = 0;
	system("cls");
		for (i = 0; i < SHIPNUMBER; i++){
			m = n = 0;
			enter = 0;
			while (1){									//loop for selecting the direction that the ship will be faciing
				printf("What direction will the ship be facing?\n");
				printf("\n\t");
				for (j = 0; j < ships[i]; j++){			//Display ship facing right and left
					printf("%c ", SHIP);
				}
				printf("\t %c\n", SHIP);
				for (j = 0; j < ships[i] - 1; j++){		//Display ship facing up and down*/
					if (ships[i] < 4)
						printf("\n\t\t %c\n", SHIP);
					else
						printf("\n\t\t\t %c\n", SHIP);
				}
				//Number (1) and (2) to be picked
				if (ships[i] < 4)						//organize the format for the ship that is larger that 3 blocks
					printf("\n\t(1)\t(2)");				//display choices 
				else
					printf("\n\t(1)\t\t(2)\n");			//display choices  

				if (user == 1){
					printf("\n\t ^");					//display the position for the curser for the first choice
				}
				else if (user == 2){					//display the position for the curser for the second choice
					if (ships[i] < 4)					//organize the format for the ship that is smaller that 4 blocks
						printf("\n\t\t ^");				//display the position for the curser for the second choice
					else                                //organize the format for the ship that is larger that 3 blocks
						printf("\n\t\t\t ^");			//display the position for the curser for the second choice
				}

				choice = _getch();						//input from the user
				if (choice == KEY_LEFT){				//left button is pressed
					user = 1;							
				}
				else if (choice == KEY_RIGHT){			//right button is pressed
					user = 2;
				}
				else if (choice == KEY_ENTER){			//enter button is pressed
					if (user == 1 || user == 2){		//assign user value to the variable user
						break;
					}
				}
				system("cls");
			}
			gameCore(ptrBoard);							//call gameCore fuction to initialize the main board
			fixPos(ptrBoard, m, n, ships[count], user, enter);
			system("cls");
			while (1){									//loop for plaing the ship in the board
				printf("Row = %d Column = %d\n", m, n);
				displayBoard(ptrBoard);
				user2 = _getch();						//keyboard input from the user
				if (user2 == KEY_RIGHT){				//right button is pressed
					if (user == 1)
						edge = BOARDSIZE - ships[count];	//initialize the value of the edge 
					else if (user == 2)
						edge = BOARDSIZE - 1;			//initialize the value of the edge 
					if (n < edge){						//apply the following commands if the position is not beyond the edge
						n++;
						gameCore(ptrBoard);
						fixPos(ptrBoard, m, n, ships[count], user, enter);
					}
					else{								//the selected position is beyond the edge and display the message to the user
						printf("\nOut of the board!!!\n");
						Sleep(300);
					}
				}
				else if (user2 == KEY_LEFT){			//left button is pressed
					if (n > 0){							//apply the following commands if the position is not beyond the edge
						n--;	
						gameCore(ptrBoard);
						fixPos(ptrBoard, m, n, ships[count], user, enter);
					}
					else{								//the selected position is beyond the edge and display the message to the user
						printf("\nOut of the board!!!\n");
						Sleep(300);
					}
				}
				else if (user2 == KEY_UP){				//up button is pressed
					if (m > 0){							//apply the following commands if the position is not beyond the edge
						m--;
						gameCore(ptrBoard);
						fixPos(ptrBoard, m, n, ships[count], user, enter);
					}
					else{								//the selected position is beyond the edge and display the message to the user
						printf("\nOut of the board!!!\n");
						Sleep(300);
					}
				}
				else if (user2 == KEY_DOWN){			//down button is pressed
					if (user == 2)						//intialize the value of the edge
						edge = BOARDSIZE - ships[count];
					else if (user == 1)
						edge = BOARDSIZE - 1;
					if (m < edge){						//apply the following commands if the position is not beyond the edge
						m++;
						gameCore(ptrBoard);
						fixPos(ptrBoard, m, n, ships[count], user, enter);
					}
					else{								//the selected position is beyond the edge and display the message to the user
						printf("\nOut of the board!!!\n");
						Sleep(300);
					}
				}
				else if (user2 == KEY_ENTER){			//enter button is pressed
					if (isOverlapped(ptrBoard, m, n, ships[count], user) == 0){	//do the following commands if the ships are not overlapped
						fixPos(ptrBoard, m, n, ships[count], user, 1);
						gameCore(ptrBoard);
						system("cls");
						break;
					}
					else if (isOverlapped(ptrBoard, m, n, ships[count], user) == 1){ //'the ships are overlapped' is displayed to the user
						printf("\nThey're overlapped!!!\n");
						Sleep(750);
					}
				}
				system("cls");
			}
			count++;

		}
		displayBoard(ptrBoard);
		Sleep(1000);
		system("cls");
		return board;		//return structure board
}
//displayGame is used to display the openbomb board which is surface of the water and display the number of remaining ships
void displayGame(Board *ptrBoard){
	char shipname[SHIPNUMBER][15] = { "Battleship", "Cruiser", "Frigate", "Minesweeper" };
	int count = 0;
	printf("\nPick the spot\n\n");
	int i, j, k;
	for (i = 0; i < BOARDSIZE; i++){
		printf("\t    ");
		for (j = 0; j < BOARDSIZE; j++){
			printf(" %c ", ptrBoard->openbomb[i][j]);	//display the surface board
		}
		printf("\n\n");
	}
	for (k = 0; k < SHIPNUMBER; k++){					//display the remaining ships 
		for (i = 0; i < BOARDSIZE; i++){
			for (j = 0; j < BOARDSIZE; j++){
				if (ptrBoard->ship[k][i][j] != BLANK)
					count++;
			}
		}
		printf("%s : %d\n", shipname[k], count);
		count = 0;
	}
}
//refreshBoard function is for assigning the position from all the ships to the mainboard or refresh the main board( similar to gameCore function)
void refreshBoard(Board *ptrBoard){
	int i, j;
	for (i = 0; i < BOARDSIZE; i++){
		for (j = 0; j < BOARDSIZE; j++){
			if (ptrBoard->openwater[i][j] == BLANK){	//if the unerneath water position is empty, assign Water to the surface position
				ptrBoard->openbomb[i][j] = WATER;
			}
			if (ptrBoard->openwater[i][j] == BOMB){		//if the unerneath water position is bomb, assign bomb to the surface position
				ptrBoard->openbomb[i][j] = BOMB;
			}
			if (ptrBoard->openwater[i][j] != BOMB && ptrBoard->openwater[i][j] != BLANK){ //otherwise assign NOTBOMB to the surface position
				ptrBoard->openbomb[i][j] = NOTBOMB;
			}
		}
	}
}
//check if any user has found all the ships and become the winner
int checkWinner(Board *ptrBoard, int player){
	int i, j, check = 1;
	//following loop is checking whether all the position of all the 4 ships are empty
	for (i = 0; i < BOARDSIZE; i++){	
		for (j = 0; j < BOARDSIZE; j++){
			if (ptrBoard->ship[1][i][j] == BLANK && ptrBoard->ship[2][i][j] == BLANK && ptrBoard->ship[3][i][j] == BLANK &&ptrBoard->ship[0][i][j] == BLANK)
				check = 1;
			else{
				return 0;
			}
		}
	}
	if (check == 1){	//all the position of all the 4 ships are empty
		printf("Number of shots you've missed: %d",ptrBoard->score);
		return 1;
	}
}
//placeBomb is for placing the bomb to the board but yet assign the value to the board
int placeBomb(Board *ptrBoard, int m, int n, int enter){
	int k;
	if (enter == 1 && ptrBoard->openwater[m][n] != BLANK){	//check if the position has already been selected before
		printf("You've already selected the spot!");
		Sleep(500);
		return 0;
	}
	else{
		ptrBoard->openbomb[m][n] = PLAYER;						//assign PLAYER character to the surface board
		if (enter == 1 && ptrBoard->mainboard[m][n] != WATER){	//the position is not water, inform the user they've found a ship
			printf("Bomb!");
			ptrBoard->openbomb[m][n] = BOMB;
			ptrBoard->openwater[m][n] = BOMB;
			for (k = 0; k < SHIPNUMBER; k++){
				if (ptrBoard->ship[k][m][n] != BLANK)
					ptrBoard->ship[k][m][n] = BLANK;
			}
			Sleep(500);
			return 2;
		}
		else if (enter == 1 && ptrBoard->mainboard[m][n] == WATER){	//the selected position is WATER and inform it to the user
			printf("Missed!");
			ptrBoard->score += 1;
			ptrBoard->openbomb[m][n] = NOTBOMB;			//assign not bomb to both surface and underwater board
			ptrBoard->openwater[m][n] = NOTBOMB;
			Sleep(500);
		}
	}
	return 1;
}
//Main function of te game for hitting the ships and finding the winner
Board mainGame(Board board, Board *ptrBoard, int player){
	ptrBoard = &board;
	int m = 0, n = 0, user, enter, end;
	refreshBoard(ptrBoard);
	placeBomb(ptrBoard, m, n, 0);
	while (1){
		enter = 0;
		printf("Player %d's turn ", player+1);		//display each player's turn
		printf("\nRow = %d Column = %d", m, n);
		displayGame(ptrBoard);						//show the board
		user = _getch();							//recieve input from the user
		if (user == KEY_RIGHT){						//the user press left button, n(column) will be moved to the right 1 block
			if (n < BOARDSIZE - 1){					//check if n is not beyond the edge
				n++;
				refreshBoard(ptrBoard);
				placeBomb(ptrBoard, m, n, enter);
			}
			else{
				printf("Out of the board!");		//inform the user that the selected position is beyond the edge
				Sleep(500);
			}
		}
		else if (user == KEY_LEFT){					//the user press right button, n(column) will be moved to the left 1 block
			if (n > 0){								//check if n is not beyond the edge
				n--;
				refreshBoard(ptrBoard);
				placeBomb(ptrBoard, m, n, enter);
			}
			else{
				printf("Out of the board!");		//check if n is not beyond the edge
				Sleep(500);
			}
		}
		else if (user == KEY_UP){					//the user press up button, n(column) will be moved up 1 block
			if (m > 0){								//check if n is not beyond the edge
				m--;
				refreshBoard(ptrBoard);
				placeBomb(ptrBoard, m, n, enter);
			}
			else{
				printf("Out of the board!");		//check if n is not beyond the edge
				Sleep(500);
			}
		}
		else if (user == KEY_DOWN){					//the user press down button, n(column) will be moved down 1 block
			if (m < BOARDSIZE - 1){					//check if n is not beyond the edge
				m++;
				refreshBoard(ptrBoard);
				placeBomb(ptrBoard, m, n, enter);
			}
			else{
				printf("Out of the board!");		//check if n is not beyond the edge
				Sleep(500);
			}
		}
		else if (user == KEY_ENTER){				//the user press enter
			if (placeBomb(ptrBoard, m, n, 1) == 1){	//the selected position didn't hit the ship
				break;
			}
			if (checkWinner(ptrBoard, player) == 1){//check if any player has found all the ships
				system("cls");
				return board;
			}
		}
		system("cls");
	}
	system("cls");
	displayGame(ptrBoard);	//display the board before leaving
	system("cls");
	return board;
}
//record function is responsible for keeping up with the highest score
void record(Board *ptrBoard, Info *info){
	//Info *info;
	FILE *outFile;
	char name[100], name1[100];
	char *s;
	int score, score1=-1000;
	outFile = fopen("record.txt", "r");
	char date1[80];
	time_t rawDate;
	struct dt *date;
	char buffer[80];
	char a;

	time(&rawDate);
	date = localtime(&rawDate);
	strftime(buffer, 80, "%x", date);			//store the date into the string buffer

	printf("\n\nEnter your name: ");			//ask the user to type in a name
	gets(name);	
	//system("cls");
	//printf("\nDate: %s ", buffer);				//display the current date
	score = ptrBoard->score;
	if (outFile  == NULL){						//check if the record file exists, if not, the file will be created
		outFile = fopen("record.txt", "w");		
		fprintf(outFile, "name: %s score: %d Date: %s", name, score, buffer); //set the first winner
	}
	else{
		fscanf(outFile, "name: %s score: %d Date: %s", name1, &score1, date1);	//in case the file already exists
		if (score < score1){													//the score will be compared to find the smaller score
			fclose(outFile);
			outFile = fopen("record.txt", "w");								//if the new score is lower, the file will be overwritten 
			printf("\n\nCongraturation!\n\nYou've made a new top score");
			fprintf(outFile, "name: %s score: %d Date: %s", name, score, buffer);
		}
	}
	printf("\n\nThe winner of all time (has fewest missed shots):\n\n"); //final announcement of top player
	fclose(outFile);
	outFile = fopen("record.txt", "r");
	while (fscanf(outFile, "%c", &a) != EOF)							//display the winner
		printf("%c", a);
	fclose(outFile);
}
void main(){
	Info info;
	Info *ptrinfo;
	Board board[PLAYERNO];
	Board *ptrBoard[PLAYERNO];
	ptrinfo = &info;
	ptrBoard[0] = &board[0];
	ptrBoard[1] = &board[1];
	int player = 0, round, user, order =1;
	intro();

	for (round = 0; round < 2; round++){											
		while (1){
			printf("\n\n\n\n\tPlayer %d's turn...\n", round+1);				//display a message telling whose turn is starting
			printf("\n\n\tPress enter to go on...");						//user must press enter to go to the selection window
			if (user = _getch() == KEY_ENTER)
				break;
			system("cls");
		}
			board[order] = selectionWindow(board[order], ptrBoard[order]);	//selecting the positions for the ships
			displayBoard(ptrBoard[order]);									//display the complete board filled with ships
			system("cls");							 
			order--;
			/*because each player must place the ships for the others, so the fitst turn is for the second player*/
	}
	while (1){
		board[player % 2] = mainGame(board[player % 2], ptrBoard[player % 2], player % 2);	//main part of the game is running
		displayGame(ptrBoard[player % 2]);													//display  the board 
		system("cls");
		if (checkWinner(ptrBoard[player % 2], player % 2) == 1){							//check for the winner and announce it
			printf("\nPlayer %d wins!!\n", player % 2 + 1);
			break;
		}
		player++;
	}
	printf("\nHere where all the winner's ships are... ");
	displayBoard(ptrBoard[player % 2]);
	record(ptrBoard[player % 2 ], ptrinfo);							//call the record function to show the highest score
	
	getch();
}
 

C Language online compiler

Write, Run & Share C Language code online using OneCompiler's C online compiler for free. It's one of the robust, feature-rich online compilers for C language, running the latest C version which is C18. Getting started with the OneCompiler's C editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'C' and start coding!

Read inputs from stdin

OneCompiler's C online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample C program which takes name as input and print your name with hello.

#include <stdio.h>
int main()
{
    char name[50];
    printf("Enter name:");
    scanf("%s", name);
    printf("Hello %s \n" , name );
    return 0;
    
}

About C

C language is one of the most popular general-purpose programming language developed by Dennis Ritchie at Bell laboratories for UNIX operating system. The initial release of C Language was in the year 1972. Most of the desktop operating systems are written in C Language.

Key features:

  • Structured Programming
  • Popular system programming language
  • UNIX, MySQL and Oracle are completely written in C.
  • Supports variety of platforms
  • Efficient and also handle low-level activities.
  • As fast as assembly language and hence used as system development language.

Syntax help

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition if-else is used.

if(conditional-expression) {
   // code
} else {
   // code
}

You can also use if-else for nested Ifs and if-else-if ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to if-else-if ladder.

switch(conditional-expression) {    
case value1:    
 // code    
 break;  // optional  
case value2:    
 // code    
 break;  // optional  
...    
    
default:     
 // code to be executed when all the above cases are not matched;    
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for(Initialization; Condition; Increment/decrement){  
  // code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition) {  
 // code 
}  

5. Do-While:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

do {
  // code 
} while (condition); 

Arrays

Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.

Syntax

One dimentional Array:

data-type array-name[size];

Two dimensional array:

data-type array-name[size][size];

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

Two types of functions are present in C

  1. Library Functions:

Library functions are the in-built functions which are declared in header files like printf(),scanf(),puts(),gets() etc.,

  1. User defined functions:

User defined functions are the ones which are written by the programmer based on the requirement.

How to declare a Function

return_type function_name(parameters);

How to call a Function

function_name (parameters)

How to define a Function

return_type function_name(parameters) {  
  //code
}