battleship源码 编译

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

//
// structs
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

//
// structs
//

typedef struct {
	int health;
	int x[5];
	int y[5];
} ship;

ship* INIT_SHIP(int healthPts){
	ship *newShip = malloc(sizeof(ship));
	newShip->health = healthPts;

	int i;
	for (i = 0; i < 5; i++) {
		newShip->x[i] = -1;
		newShip->y[i] = -1;
	}

	return newShip;
}

//
// global variables and constants
//

int sockfd;			// client socket
char buffer[256];	// buffer

int map[20][20];
int enemyMap[20][20];
int mapExtent;

int totalHealth = 0;
int gameOver = 1;

ship *listAircraftCarrier[2];
int numAircraftCarrier;

ship *listBattleship[3];
int numBattleship;

ship *listSubmarine[3];
int numSubmarine;

ship *listCruiser[3];
int numCruiser;

ship *listDestroyer[4];
int numDestroyer;

//
// method signatures
//

void connectToServer(char *IPAddress, char* portNum);
void closeCliSockets();

void setupFromServer();
int checkValidPos(int startNumPos, int startCharPos, int length, char *direction);
void setShipPos(ship *currentShip, int startNumPos, int startCharPos, char *direction);
void chooseShipPositions(int type);

void printBoard();
void clearBoard();
void printEnemyBoard();
void clearEnemyBoard();

void cliturn();
void cliattackTurn();
void clidefendTurn();

char *hitShip();
char *hitAircraftCarrier();
char *hitBattleship();
char *hitSubmarine();
char *hitCruiser();
char *hitDestroyer();

char *isGameOver();

//
// method definitions
//

// main method
int StartClient() {

	char szIpBuf[32] = {'\0'};
	char szSerPortBuf[32] = {'\0'};
	printf("input server ip port,for exp:127.0.0.1 10000\n");
	scanf("%s %s", szIpBuf, szSerPortBuf);
	
	connectToServer(szIpBuf, szSerPortBuf);
	setupFromServer();
	
	int i;

	printf("Waiting for opponent to position their ships...\n");
	fflush(stdout);
	int n = read(sockfd, buffer, sizeof(buffer));
	if (n < 0) {
		fprintf(stderr, "ERROR: could not read from socket\n");
		exit(2);
	}
	for (i = 0; i < 5; i++)
		chooseShipPositions(i);

	printBoard();
	cliturn();
	
	closeCliSockets();

	return 0;
}

// create and set up client socket
void connectToServer(char *IPAddress, char* portNum) {
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		fprintf(stderr, "ERROR: could not open client socket to the server\n");
		exit(2);
	}

	struct hostent *server;
	server = gethostbyname(IPAddress);
	struct sockaddr_in serv_addr;
  	bzero((char *) &serv_addr, sizeof(serv_addr));

	int portno = atoi(portNum);
	serv_addr.sin_family = AF_INET;
  	bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
  	serv_addr.sin_port = htons(portno);

  	if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
    		fprintf(stderr, "ERROR: could not bind client socket\n");
		exit(2);
	}
}

// close all sockets
void closeCliSockets() {
	close(sockfd);
}

// set up board based on information from server
void setupFromServer() {
	printf("Waiting for opponent to configure the game...\n");
	fflush(stdout);
	
	int setupState = 0;
	while (setupState < 6){
		bzero(buffer, sizeof(buffer));
		
		int n = read(sockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not read from socket\n");
			exit(2);
		}
		else {
			switch(setupState){
				case 0:
					mapExtent = atoi(buffer);
					break;
				case 1:
					numAircraftCarrier = atoi(buffer);
					totalHealth += (numAircraftCarrier * 5);
					break;
				case 2:
					numBattleship = atoi(buffer);
					totalHealth += (numBattleship * 4);
					break;
				case 3:
					numSubmarine = atoi(buffer);
					totalHealth += (numSubmarine * 3);
					break;
				case 4:
					numCruiser = atoi(buffer);
					totalHealth += (numCruiser * 3);
					break;
				case 5:
					numDestroyer = atoi(buffer);
					totalHealth += (numDestroyer * 2);
					break;
			}
			
			setupState++;
			if (setupState == 6 && numAircraftCarrier + numBattleship + numSubmarine + numCruiser + numDestroyer == 0)
				setupState = 1;
		}
	}
}

// Checks to see whether or not ship can be placed at this position
int checkValidPos(int startNumPos, int startCharPos, int length, char *direction) {
	int numPosOffset = 0;
	int charPosOffset = 0;
	int currNumPos = startNumPos;
	int currCharPos = startCharPos;

	if (strcmp(direction, "North") == 0 || strcmp(direction, "NORTH") == 0 || strcmp(direction, "north") == 0)
		numPosOffset = -1;
	else if (strcmp(direction, "East") == 0 || strcmp(direction, "EAST") == 0 || strcmp(direction, "east") == 0)
		charPosOffset = 1;
	else if (strcmp(direction, "South") == 0 || strcmp(direction, "SOUTH") == 0 || strcmp(direction, "south") == 0)
		numPosOffset = 1;
	else if (strcmp(direction, "West") == 0 || strcmp(direction, "WEST") == 0 || strcmp(direction, "west") == 0)
		charPosOffset = -1;

	int i;
	for (i = 0; i < length; i++){
		if (currNumPos < 1 || currNumPos > mapExtent || currCharPos < 1 || currCharPos > mapExtent)
			return 0;
		else if (map[currNumPos - 1][currCharPos - 1] != 0)
			return 0;

		currNumPos += numPosOffset;
		currCharPos += charPosOffset;
	}
	return 1;
}

// Configures the map using the placement of the ship
void setShipPos(ship *currentShip, int startNumPos, int startCharPos, char *direction) {
	int numPosOffset = 0;
	int charPosOffset = 0;
	int currNumPos = startNumPos;
	int currCharPos = startCharPos;
	int length = currentShip->health;

	if (strcmp(direction, "North") == 0 || strcmp(direction, "NORTH") == 0 || strcmp(direction, "north") == 0)
		numPosOffset = -1;
	else if (strcmp(direction, "East") == 0 || strcmp(direction, "EAST") == 0 || strcmp(direction, "east") == 0)
		charPosOffset = 1;
	else if (strcmp(direction, "South") == 0 || strcmp(direction, "SOUTH") == 0 || strcmp(direction, "south") == 0)
		numPosOffset = 1;
	else if (strcmp(direction, "West") == 0 || strcmp(direction, "WEST") == 0 || strcmp(direction, "west") == 0)
		charPosOffset = -1;

	int i;
	for (i = 0; i < length; i++){
		currentShip->x[i] = currNumPos;
		currentShip->y[i] = currCharPos;
		map[currNumPos - 1][currCharPos - 1] = 1;

		currNumPos += numPosOffset;
		currCharPos += charPosOffset;
	}
}

// Takes in user input to determine where to put the ships on the board.
void chooseShipPositions(int type) {
	int numShips;
	char *shipType;
	int healthPts;
	switch (type) {
		case 0:
			shipType = "Aircraft Carrier";
			numShips = numAircraftCarrier;
			healthPts = 5;
			break;
		case 1:
			shipType = "Battleship";
			numShips = numBattleship;
			healthPts = 4;
			break;
		case 2:
			shipType = "Submarine";
			numShips = numSubmarine;
			healthPts = 3;
			break;
		case 3:
			shipType = "Cruiser";
			numShips = numCruiser;
			healthPts = 3;
			break;
		case 4:
			shipType = "Destroyer";
			numShips = numDestroyer;
			healthPts = 2;
			break;
	}
	
	int i = 0;
	while (i < numShips) {
		ship *currentShip = INIT_SHIP(healthPts);
		
		int numPos = 0;
		char charPos = 'A';
		int charPosToNum = 0;
		char direction[5] = "";

		printBoard();
		printf("Where do you want to put %s %d? \nFormat: Num Char Direction (North, East, South, West) \nExample: 4 A South \n", shipType, i);
		scanf("%d %c %s", &numPos, &charPos, &direction);

		charPosToNum = charPos - 'A' + 1;

		if (checkValidPos(numPos, charPosToNum, currentShip->health, direction) == 1) {
			setShipPos(currentShip, numPos, charPosToNum, direction);
			
			switch (type) {
				case 0:
					listAircraftCarrier[i] = currentShip;
					break;
				case 1:
					listBattleship[i] = currentShip;
					break;
				case 2:
					listSubmarine[i] = currentShip;
					break;
				case 3:
					listCruiser[i] = currentShip;
					break;
				case 4:
					listDestroyer[i] = currentShip;
					break;
			}
			
			i++;
		} else
			fprintf(stderr, "ERROR: position is not valid\n");
	}
}

// Prints out the current status of the board
void printBoard() {
	printf("Your Board: \n");

	int i, j, c, n;
	printf("   ");
	for (c = 65; c < 65 + mapExtent; c++) {
		printf("%c ", c);
	}
	printf("\n");
	for (i = 0; i < mapExtent; i++) {
		if (i < 9)
			printf("%d  ", (i + 1));
		else
			printf("%d ", (i + 1));
		for (j = 0; j < mapExtent; j++) {
			switch(map[i][j]) {
				case 0:
					printf("_ ");
					break;
				case 1:
					printf("B ");
					break;
				case 2:
					printf("X ");
					break;
				case 3:
					printf("  ");
					break;
			}
		}
		printf("\n");
	}
}

// Sets all spots on the board to 0
void clearBoard() {
	int i, j;
	for (i = 0; i < mapExtent; i++) {
		for (j = 0; j < mapExtent; j++) {
			map[i][j] = 0;
		}
	}
}

char *hitAircraftCarrier(int xPos, int yPos) {
	int i;
	for (i = 0; i < numAircraftCarrier; i++) {
		if (listAircraftCarrier[i]->health > 0) {
			int j;
			for (j = 0; j < 5; j++) {
				if (listAircraftCarrier[i]->x[j] == xPos && listAircraftCarrier[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listAircraftCarrier[i]->health = listAircraftCarrier[i]->health - 1;
					totalHealth -= 1;
					printf("Aircraft carrier number %d got hit!\n", i);
					fflush(stdout);			
					if (listAircraftCarrier[i]->health <= 0) {
						printf("Aircraft carrier number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's aircraft carrier!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}

char *hitBattleship(int xPos, int yPos) {
	int i;
	for (i = 0; i < numBattleship; i++) {
		if (listBattleship[i]->health > 0) {
			int j;
			for (j = 0; j < 4; j++) {
				if (listBattleship[i]->x[j] == xPos && listBattleship[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listBattleship[i]->health = listBattleship[i]->health - 1;
					totalHealth -= 1;
					printf("Battleship number %d got hit!\n", i);
					fflush(stdout);
					if (listBattleship[i]->health <= 0) {
						printf("Battleship number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's battleship!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}

//char *hitSubmarine(int xPos, int yPos) {
//	int i;
//	for (i = 0; i < numSubmarine; i++) {
//		if (listSubmarine[i]->health > 0) {
//			int j;
//			for (j = 0; j < 3; j++) {
//				if (listSubmarine[i]->x[j] == xPos && listSubmarine[i]->y[j] == yPos) {
//					map[xPos - 1][yPos - 1] = 2;
//					listSubmarine[i]->health = listSubmarine[i]->health - 1;
//					totalHealth -= 1;
//					printf("Submarine number %d got hit!\n", i);
//					fflush(stdout);
//					if (listSubmarine[i]->health <= 0) {
//						printf("Submarine number %d was sunk!\n", i);
//						fflush(stdout);
//						return "1 You sunk your opponent's submarine!";
//					} else {
//						return "1 You hit one of your opponent's ships!";
//					}
//				}
//			}
//		}
//	}
//	return "0 You missed!";
//}

char *hitCruiser(int xPos, int yPos) {
	int i;
	for (i = 0; i < numCruiser; i++) {
		if (listCruiser[i]->health > 0) {
			int j;
			for (j = 0; j < 3; j++) {
				if (listCruiser[i]->x[j] == xPos && listCruiser[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listCruiser[i]->health = listCruiser[i]->health - 1;
					totalHealth -= 1;
					printf("Cruiser number %d got hit!\n", i);
					fflush(stdout);
					if (listCruiser[i]->health <= 0) {
						printf("Cruiser number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's cruiser!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}

char *hitDestroyer(int xPos, int yPos) {
	int i;
	for (i = 0; i < numDestroyer; i++) {
		if (listDestroyer[i]->health > 0) {
			int j;
			for (j = 0; j < 2; j++) {
				if (listDestroyer[i]->x[j] == xPos && listDestroyer[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listDestroyer[i]->health = listDestroyer[i]->health - 1;
					totalHealth -= 1;
					printf("Destroyer number %d got hit!\n", i);
					fflush(stdout);
					if (listDestroyer[i]->health <= 0) {
						printf("Destroyer number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's destroyer!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}

// Checks to see if a ship has been 
char *hitShip(int x, int y) {
	char *message;
	message = hitAircraftCarrier(x, y);
	if (strcmp(message, "0 You missed!") != 0) {
		return message;
	}
	message = hitBattleship(x, y);
	if (strcmp(message, "0 You missed!") != 0) {
		return message;
	}
	message = hitSubmarine(x, y);
	if (strcmp(message, "0 You missed!") != 0) {
		return message;
	}
	message = hitCruiser(x, y);
	if (strcmp(message, "0 You missed!") != 0) {
		return message;
	}
	message = hitDestroyer(x, y);
	if (strcmp(message, "0 You missed!") != 0) {
		return message;
	}
	return message;
}

// Checks to see if the game is over
char *isGameOver() {
	if (totalHealth <= 0) {
		gameOver = 0;
		return "2 You sunk all of your opponent's ships! You Win!";
	} else {
		return "Not over";
	}
}

// Prints out the current status of the enemy board
void printEnemyBoard() {
	printf("Enemy Board: \n");
	
	int i, j, c, n;
	printf("   ");
	for (c = 65; c < 65 + mapExtent; c++) {
		printf("%c ", c);
	}
	printf("\n");
	for (i = 0; i < mapExtent; i++) {
		if (i < 9)
			printf("%d  ", (i + 1));
		else
			printf("%d ", (i + 1));
		for (j = 0; j < mapExtent; j++) {
			switch(enemyMap[i][j]) {
				case 0:
					printf("_ ");
					break;
				case 1:
					printf("B ");
					break;
				case 2:
					printf("X ");
					break;
				case 3:
					printf("  ");
					break;
			}
		}
		printf("\n");
	}
	
	fflush(stdout);
}

// Sets all spots on the enemy board to 0
void clearEnemyBoard() {
	int i, j;
	for (i = 0; i < mapExtent; i++) {
		for (j = 0; j < mapExtent; j++) {
			enemyMap[i][j] = 0;
		}
	}
}

void cliturn(){
	bzero(buffer, sizeof(buffer));
	sprintf(buffer, "Done configuring ships\n");

	int n = write(sockfd, buffer, sizeof(buffer));
	if (n < 0) {
		fprintf(stderr, "ERROR: could not write to socket\n");
		exit(2);
	}

	while(gameOver == 1){
		clidefendTurn();
		cliattackTurn();
	}
}

void cliattackTurn(){
	if (gameOver == 1){
		printEnemyBoard();
		
		int numPos;
		char charPos;
		int charPosToNum;
		
		// ask user for input
		int validAttack = 0;
		while (validAttack == 0){
			printf("What position do you want to hit? \nFormat: Num Char \nExample: 4 A \n");
			scanf("%d %c", &numPos, &charPos);

			charPosToNum = charPos - 'A' + 1;

			if (enemyMap[numPos - 1][charPosToNum - 1] == 0){
				validAttack = 1;
			} else {
				printf("You already attacked this position. Try again.\n");
				fflush(stdout);
			}
		}
		
		// send user input through socket to opponent to check
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d %d\n", numPos, charPosToNum);
		
		int n = write(sockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);
		
		// read response from opponent
		bzero(buffer, sizeof(buffer));
		n = read(sockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not read from socket\n");
			exit(2);
		}
		else {
			int code;
			char* token;
			
			token = strtok(buffer, " ");
			code = atoi(token);
			while (token != NULL){
				token = strtok(NULL, ".");
				if (token != NULL) 
					printf("%s ", token);
			}
			printf("\n");
			
			if (code == 0) {			// miss
				enemyMap[numPos - 1][charPosToNum - 1] = 3;
			} else if (code == 1) {		// hit
				enemyMap[numPos - 1][charPosToNum - 1] = 2;
			} else if (code == 2) {		// game over
				enemyMap[numPos - 1][charPosToNum - 1] = 2;
				gameOver = 0;
			}
			
			printEnemyBoard();
		}
	}
}

void clidefendTurn(){
	if (gameOver == 1){
		printf("Waiting for opponent move...\n");
		fflush(stdout);

		// read input from opponent
		bzero(buffer, sizeof(buffer));
		int n = read(sockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not read from socket\n");
			exit(2);
		}
		else {
			int numPos = atoi(strtok(buffer, " "));
			int charPosToNum = atoi(strtok(NULL, " "));

			// determine if the opponent hit your ship
			char* message = hitShip(numPos, charPosToNum);

			if (strcmp(message, "0 You missed!") == 0){
				map[numPos - 1][charPosToNum - 1] = 3;
			} 
			
			printBoard();
			
			// check if you lost
			char* checkGameOver = isGameOver();
			bzero(buffer, sizeof(buffer));
			if (gameOver == 1) {
				sprintf(buffer, "%s\n", message);
			} else {
				sprintf(buffer, "%s\n", checkGameOver);
				printf("All of your ships are destroyed! You Lose!\n");
				fflush(stdout);
			}
		
			n = write(sockfd, buffer, sizeof(buffer));
			if (n < 0) {
				fprintf(stderr, "ERROR: could not write to socket\n");
				exit(2);
			}
		}
	}
}

//typedef struct {
//	int health;
//	int x[5];
//	int y[5];
//} ship;

//ship* INIT_SHIP(int healthPts){
//	ship *newShip = malloc(sizeof(ship));
//	newShip->health = healthPts;
//
//	int i;
//	for (i = 0; i < 5; i++) {
//		newShip->x[i] = -1;
//		newShip->y[i] = -1;
//	}
//
//	return newShip;
//}

//
// global variables and constants
//

int sockfd;			// server socket
int newsockfd;		// new socket connection with client
char buffer[256];	// buffer

int map[20][20];
int enemyMap[20][20];
int mapExtent;
//
//int totalHealth = 0;
//int gameOver = 1;

ship *listAircraftCarrier[2];
int numAircraftCarrier;

ship *listBattleship[3];
int numBattleship;

ship *listSubmarine[3];
int numSubmarine;

ship *listCruiser[3];
int numCruiser;

ship *listDestroyer[4];
int numDestroyer;

//
// method signatures
//

void createServerSocket(char *portNum);
void acceptConnection();
void closeSerSockets();

void configureGame();
//int checkValidPos(int startNumPos, int startCharPos, int length, char *direction);
//void setShipPos(ship *currentShip, int startNumPos, int startCharPos, char *direction);
//void chooseShipPositions(int type);

//void printBoard();
//void clearBoard();
//void printEnemyBoard();
//void clearEnemyBoard();

void serturn();
void serattackTurn();
void serdefendTurn();

//char *hitShip();
//char *hitAircraftCarrier();
char *hitBattleship();
char *hitSubmarine();
//char *hitCruiser();
//char *hitDestroyer();
//char *isGameOver();


int main(int argc, char *argv[]) {
	printf("input 1 run as client, otherwise as server, please run server first\n");
	int iType;
	scanf("%d", &iType);
	if (1 == iType){
		StartClient();
	}
	else
	{
		StartSer();	
	}	
	return 0;
}

int StartSer() {
	
	char szSerPortBuf[32] = {'\0'};
	printf("input server  port,for exp: 10000\n");
	scanf("%s", szSerPortBuf);
	createServerSocket(szSerPortBuf);
	acceptConnection();	
	clearBoard();
	configureGame();	
	int i;
	for (i = 0; i < 5; i++)
		chooseShipPositions(i);

	bzero(buffer, sizeof(buffer));
	sprintf(buffer, "Done configuring ships\n");
	printBoard();

	int n = write(newsockfd, buffer, sizeof(buffer));
	if (n < 0) {
		fprintf(stderr, "ERROR: could not write to socket\n");
		exit(2);
	}
	
	serturn();	
	closeSerSockets();	
	return 0;
}

// create and setup server socket
void createServerSocket(char *portNum){
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		fprintf(stderr, "ERROR: could not open server socket\n");
		exit(2);
	}

	struct sockaddr_in serv_addr; 
	bzero((char *) &serv_addr, sizeof(serv_addr));
	
	int portno = atoi(portNum);
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);
	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 
	  	fprintf(stderr, "ERROR: could not bind server socket\n");
		exit(2);
	}
}

// listen and accept incoming connection requests
void acceptConnection(){
	listen(sockfd, 5);	
	struct sockaddr_in cli_addr;
	socklen_t clilen = sizeof(cli_addr);	
	newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
	if (newsockfd < 0){
		fprintf(stderr, "ERROR: could not accept incoming connection request\n");
		exit(2);
	}
	fprintf(stderr, "an new player on line success\n");
	bzero(buffer, sizeof(buffer));
}

// close all sockets
void closeSerSockets(){
	close(newsockfd);	// close socket connection with client
	close(sockfd);		// close server socket
}

//Init Game Configure
void configureGame(){
	char input[100];
	char exitString[100] = "exit";	
	int n;	
	int isBoardSizeSet = 1;	
	mapExtent = 10;	
	bzero(buffer, sizeof(buffer));
	sprintf(buffer, "%d", mapExtent);
	
	n = write(newsockfd, buffer, sizeof(buffer));
	if (n < 0) {
		fprintf(stderr, "ERROR: could not write to socket\n");
		exit(2);
	}
	
	usleep(500);	
	while (numAircraftCarrier + numBattleship + numSubmarine + numCruiser + numDestroyer == 0) {		
		numAircraftCarrier = 1;
		totalHealth += (numAircraftCarrier * 5);		
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d\n", numAircraftCarrier);		
		n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}		
		usleep(500);
		numBattleship = 1;
		totalHealth += (numBattleship * 4);		
	
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d\n", numBattleship);		
		n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);

		numSubmarine = 1;
		totalHealth += (numSubmarine * 3);
		
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d\n", numSubmarine);
		
		n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);
		numCruiser = 1;
		totalHealth += (numCruiser * 3);		
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d\n", numCruiser);
		
		n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);		
		numDestroyer = 1;
		totalHealth += (numDestroyer * 2);		
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d\n", numDestroyer);
		
		n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);
		if (numAircraftCarrier + numBattleship + numSubmarine + numCruiser + numDestroyer == 0) {
			printf("Invalid number of ships. Try again.\n");
			fflush(stdout);
		}
	}
}

// Checks to see whether or not ship can be placed at this position
//int checkValidPos(int startNumPos, int startCharPos, int length, char *direction) {
//	int numPosOffset = 0;
//	int charPosOffset = 0;
//	int currNumPos = startNumPos;
//	int currCharPos = startCharPos;
//
//	if (strcmp(direction, "North") == 0 || strcmp(direction, "NORTH") == 0 || strcmp(direction, "north") == 0)
//		numPosOffset = -1;
//	else if (strcmp(direction, "East") == 0 || strcmp(direction, "EAST") == 0 || strcmp(direction, "east") == 0)
//		charPosOffset = 1;
//	else if (strcmp(direction, "South") == 0 || strcmp(direction, "SOUTH") == 0 || strcmp(direction, "south") == 0)
//		numPosOffset = 1;
//	else if (strcmp(direction, "West") == 0 || strcmp(direction, "WEST") == 0 || strcmp(direction, "west") == 0)
//		charPosOffset = -1;
//
//	int i;
//	for (i = 0; i < length; i++){
//		//printf("%d %d\n", currNumPos, currCharPos);
//		//fflush(stdout);
//		if (currNumPos < 1 || currNumPos > mapExtent || currCharPos < 1 || currCharPos > mapExtent)
//			return 0;
//		else if (map[currNumPos - 1][currCharPos - 1] != 0)
//			return 0;
//
//		currNumPos += numPosOffset;
//		currCharPos += charPosOffset;
//	}
//	return 1;
//}

// Configures the map using the placement of the ship
//void setShipPos(ship *currentShip, int startNumPos, int startCharPos, char *direction) {
//	int numPosOffset = 0;
//	int charPosOffset = 0;
//	int currNumPos = startNumPos;
//	int currCharPos = startCharPos;
//	int length = currentShip->health;
//
//	if (strcmp(direction, "North") == 0 || strcmp(direction, "NORTH") == 0 || strcmp(direction, "north") == 0)
//		numPosOffset = -1;
//	else if (strcmp(direction, "East") == 0 || strcmp(direction, "EAST") == 0 || strcmp(direction, "east") == 0)
//		charPosOffset = 1;
//	else if (strcmp(direction, "South") == 0 || strcmp(direction, "SOUTH") == 0 || strcmp(direction, "south") == 0)
//		numPosOffset = 1;
//	else if (strcmp(direction, "West") == 0 || strcmp(direction, "WEST") == 0 || strcmp(direction, "west") == 0)
//		charPosOffset = -1;
//
//	int i;
//	for (i = 0; i < length; i++){
//		currentShip->x[i] = currNumPos;
//		currentShip->y[i] = currCharPos;
//		map[currNumPos - 1][currCharPos - 1] = 1;
//
//		currNumPos += numPosOffset;
//		currCharPos += charPosOffset;
//	}
//}

// Takes in user input to determine where to put the ships on the board.
//void chooseShipPositions(int type) {
//	int numShips;
//	char *shipType;
//	int healthPts;
//	switch (type) {
//		case 0:
//			shipType = "Aircraft Carrier";
//			numShips = numAircraftCarrier;
//			healthPts = 5;
//			break;
//		case 1:
//			shipType = "Battleship";
//			numShips = numBattleship;
//			healthPts = 4;
//			break;
//		case 2:
//			shipType = "Submarine";
//			numShips = numSubmarine;
//			healthPts = 3;
//			break;
//		case 3:
//			shipType = "Cruiser";
//			numShips = numCruiser;
//			healthPts = 3;
//			break;
//		case 4:
//			shipType = "Destroyer";
//			numShips = numDestroyer;
//			healthPts = 2;
//			break;
//	}
//	
//	int i = 0;
//	while (i < numShips) {
//		ship *currentShip = INIT_SHIP(healthPts);
//		
//		int numPos = 0;
//		char charPos = 'A';
//		int charPosToNum = 0;
//		char direction[5] = "";
//		
//		printBoard();
//		printf("Where do you want to put %s %d? \nFormat: Num Char Direction (North, East, South, West) \nExample: 4 A South \n", shipType, i);
//		scanf("%d %c %s", &numPos, &charPos, &direction);
//
//		charPosToNum = charPos - 'A' + 1;
//
//		//printf("numPos:%d charPos:%d health:%d direction: %s\n", numPos, charPosToNum, currentShip->health, direction);
//		fflush(stdout);
//
//		if (checkValidPos(numPos, charPosToNum, currentShip->health, direction) == 1) {
//			setShipPos(currentShip, numPos, charPosToNum, direction);
//			
//			switch (type) {
//				case 0:
//					listAircraftCarrier[i] = currentShip;
//					break;
//				case 1:
//					listBattleship[i] = currentShip;
//					break;
//				case 2:
//					listSubmarine[i] = currentShip;
//					break;
//				case 3:
//					listCruiser[i] = currentShip;
//					break;
//				case 4:
//					listDestroyer[i] = currentShip;
//					break;
//			}
//			
//			i++;
//		} else
//			fprintf(stderr, "ERROR: position is not valid\n");
//	}
//}

// Prints out the current status of the board
//void printBoard() {
//	printf("Your Board: \n");
//	
//	int i, j, c, n;
//	printf("   ");
//	for (c = 65; c < 65 + mapExtent; c++) {
//		printf("%c ", c);
//	}
//	printf("\n");
//	for (i = 0; i < mapExtent; i++) {
//		if (i < 9)
//			printf("%d  ", (i + 1));
//		else
//			printf("%d ", (i + 1));
//		for (j = 0; j < mapExtent; j++) {
//			switch(map[i][j]) {
//				case 0:
//					printf("_ ");
//					break;
//				case 1:
//					printf("B ");
//					break;
//				case 2:
//					printf("X ");
//					break;
//				case 3:
//					printf("  ");
//					break;
//			}
//		}
//		printf("\n");
//	}
//	
//	fflush(stdout);
//}

// Sets all spots on the board to 0
//void clearBoard() {
//	int i, j;
//	for (i = 0; i < mapExtent; i++) {
//		for (j = 0; j < mapExtent; j++) {
//			map[i][j] = 0;
//		}
//	}
//}

//char *hitAircraftCarrier(int xPos, int yPos) {
//	int i;
//	for (i = 0; i < numAircraftCarrier; i++) {
//		if (listAircraftCarrier[i]->health > 0) {
//			int j;
//			for (j = 0; j < 5; j++) {
//				if (listAircraftCarrier[i]->x[j] == xPos && listAircraftCarrier[i]->y[j] == yPos) {
//					map[xPos - 1][yPos - 1] = 2;
//					listAircraftCarrier[i]->health = listAircraftCarrier[i]->health - 1;
//					totalHealth -= 1;
//					printf("Aircraft carrier number %d got hit!\n", i);
//					fflush(stdout);			
//					if (listAircraftCarrier[i]->health <= 0) {
//						printf("Aircraft carrier number %d was sunk!\n", i);
//						fflush(stdout);
//						return "1 You sunk your opponent's aircraft carrier!";
//					} else {
//						return "1 You hit one of your opponent's ships!";
//					}
//				}
//			}
//		}
//	}
//	return "0 You missed!";
//}

/*char *hitBattleship(int xPos, int yPos) {
	int i;
	for (i = 0; i < numBattleship; i++) {
		if (listBattleship[i]->health > 0) {
			int j;
			for (j = 0; j < 4; j++) {
				if (listBattleship[i]->x[j] == xPos && listBattleship[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listBattleship[i]->health = listBattleship[i]->health - 1;
					totalHealth -= 1;
					printf("Battleship number %d got hit!\n", i);
					fflush(stdout);
					if (listBattleship[i]->health <= 0) {
						printf("Battleship number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's battleship!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}*/

char *hitSubmarine(int xPos, int yPos) {
	int i;
	for (i = 0; i < numSubmarine; i++) {
		if (listSubmarine[i]->health > 0) {
			int j;
			for (j = 0; j < 3; j++) {
				if (listSubmarine[i]->x[j] == xPos && listSubmarine[i]->y[j] == yPos) {
					map[xPos - 1][yPos - 1] = 2;
					listSubmarine[i]->health = listSubmarine[i]->health - 1;
					totalHealth -= 1;
					printf("Submarine number %d got hit!\n", i);
					fflush(stdout);
					if (listSubmarine[i]->health <= 0) {
						printf("Submarine number %d was sunk!\n", i);
						fflush(stdout);
						return "1 You sunk your opponent's submarine!";
					} else {
						return "1 You hit one of your opponent's ships!";
					}
				}
			}
		}
	}
	return "0 You missed!";
}

//char *hitCruiser(int xPos, int yPos) {
//	int i;
//	for (i = 0; i < numCruiser; i++) {
//		if (listCruiser[i]->health > 0) {
//			int j;
//			for (j = 0; j < 3; j++) {
//				if (listCruiser[i]->x[j] == xPos && listCruiser[i]->y[j] == yPos) {
//					map[xPos - 1][yPos - 1] = 2;
//					listCruiser[i]->health = listCruiser[i]->health - 1;
//					totalHealth -= 1;
//					printf("Cruiser number %d got hit!\n", i);
//					fflush(stdout);
//					if (listCruiser[i]->health <= 0) {
//						printf("Cruiser number %d was sunk!\n", i);
//						fflush(stdout);
//						return "1 You sunk your opponent's cruiser!";
//					} else {
//						return "1 You hit one of your opponent's ships!";
//					}
//				}
//			}
//		}
//	}
//	return "0 You missed!";
//}

//char *hitDestroyer(int xPos, int yPos) {
//	int i;
//	for (i = 0; i < numDestroyer; i++) {
//		if (listDestroyer[i]->health > 0) {
//			int j;
//			for (j = 0; j < 2; j++) {
//				if (listDestroyer[i]->x[j] == xPos && listDestroyer[i]->y[j] == yPos) {
//					map[xPos - 1][yPos - 1] = 2;
//					listDestroyer[i]->health = listDestroyer[i]->health - 1;
//					totalHealth -= 1;
//					printf("Destroyer number %d got hit!\n", i);
//					fflush(stdout);
//					if (listDestroyer[i]->health <= 0) {
//						printf("Destroyer number %d was sunk!\n", i);
//						fflush(stdout);
//						return "1 You sunk your opponent's destroyer!";
//					} else {
//						return "1 You hit one of your opponent's ships!";
//					}
//				}
//			}
//		}
//	}
//	return "0 You missed!";
//}

// Checks to see if a ship has been 
//char *hitShip(int x, int y) {
//	char *message;
//	message = hitAircraftCarrier(x, y);
//	if (strcmp(message, "0 You missed!") != 0) {
//		return message;
//	}
//	message = hitBattleship(x, y);
//	if (strcmp(message, "0 You missed!") != 0) {
//		return message;
//	}
//	message = hitSubmarine(x, y);
//	if (strcmp(message, "0 You missed!") != 0) {
//		return message;
//	}
//	message = hitCruiser(x, y);
//	if (strcmp(message, "0 You missed!") != 0) {
//		return message;
//	}
//	message = hitDestroyer(x, y);
//	if (strcmp(message, "0 You missed!") != 0) {
//		return message;
//	}
//	return message;
//}

// Checks to see if the game is over
//char *isGameOver() {
//	if (totalHealth <= 0) {
//		gameOver = 0;
//		return "2 You sunk all of your opponent's ships! You Win!";
//	} else {
//		return "Not over";
//	}
//}

// Prints out the current status of the enemy board
//void printEnemyBoard() {
//	printf("Enemy Board: \n");
//	
//	int i, j, c, n;
//	printf("   ");
//	for (c = 65; c < 65 + mapExtent; c++) {
//		printf("%c ", c);
//	}
//	printf("\n");
//	for (i = 0; i < mapExtent; i++) {
//		if (i < 9)
//			printf("%d  ", (i + 1));
//		else
//			printf("%d ", (i + 1));
//		for (j = 0; j < mapExtent; j++) {
//			switch(enemyMap[i][j]) {
//				case 0:
//					printf("_ ");
//					break;
//				case 1:
//					printf("B ");
//					break;
//				case 2:
//					printf("X ");
//					break;
//				case 3:
//					printf("  ");
//					break;
//			}
//		}
//		printf("\n");
//	}
//	
//	fflush(stdout);
//}

// Sets all spots on the enemy board to 0
//void clearEnemyBoard() {
//	int i, j;
//	for (i = 0; i < mapExtent; i++) {
//		for (j = 0; j < mapExtent; j++) {
//			enemyMap[i][j] = 0;
//		}
//	}
//}

void serturn(){
	printf("Waiting for opponent to position their ships...\n");
	fflush(stdout);
	int n = read(newsockfd, buffer, sizeof(buffer));
	if (n < 0) {
		fprintf(stderr, "ERROR: could not read from socket\n");
		exit(2);
	}

	while(gameOver == 1){
		serattackTurn();
		serdefendTurn();
	}
}

void serattackTurn(){
	if (gameOver == 1){
		printEnemyBoard();
		
		int numPos;
		char charPos;
		int charPosToNum;
		
		// ask user for input
		int validAttack = 0;
		while (validAttack == 0){
			printf("What position do you want to hit? \nFormat: Num Char \nExample: 4 A \n");
			scanf("%d %c", &numPos, &charPos);

			charPosToNum = charPos - 'A' + 1;

			if (enemyMap[numPos - 1][charPosToNum - 1] == 0){
				validAttack = 1;
			} else {
				printf("You already attacked this position. Try again.\n");
				fflush(stdout);
			}
		}
		
		// send user input through socket to opponent to check
		bzero(buffer, sizeof(buffer));
		sprintf(buffer, "%d %d\n", numPos, charPosToNum);
		
		int n = write(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not write to socket\n");
			exit(2);
		}
		
		usleep(500);
		
		// read response from opponent
		bzero(buffer, sizeof(buffer));
		fflush(stdout);
		n = read(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not read from socket\n");
			exit(2);
		}
		else {
			int code;
			char* token;
			token = strtok(buffer, " ");
			code = atoi(token);
			while (token != NULL){
				token = strtok(NULL, ".");
				if (token != NULL) 
					printf("%s ", token);
			}
			printf("\n");
			
			if (code == 0) {			// miss
				enemyMap[numPos - 1][charPosToNum - 1] = 3;
			} else if (code == 1) {		// hit
				enemyMap[numPos - 1][charPosToNum - 1] = 2;
			} else if (code == 2) {		// game over
				enemyMap[numPos - 1][charPosToNum - 1] = 2;
				gameOver = 0;
			}
			
			printEnemyBoard();
		}
	}
}

void serdefendTurn(){
	if (gameOver == 1){
		printf("Waiting for opponent move...\n");
		fflush(stdout);
		
		// read input from opponent
		bzero(buffer, sizeof(buffer));
		int n = read(newsockfd, buffer, sizeof(buffer));
		if (n < 0) {
			fprintf(stderr, "ERROR: could not read from socket\n");
			exit(2);
		}
		else {
			int numPos = atoi(strtok(buffer, " "));
			int charPosToNum = atoi(strtok(NULL, " "));
			
			// determine if the opponent hit your ship
			char* message = hitShip(numPos, charPosToNum);

			if (strcmp(message, "0 You missed!") == 0){
				map[numPos - 1][charPosToNum - 1] = 3;
			}
			
			printBoard();

			// check if you lost
			char* checkGameOver = isGameOver();
			bzero(buffer, sizeof(buffer));
			if (gameOver == 1) {
				sprintf(buffer, "%s\n", message);
			} else {
				sprintf(buffer, "%s\n", checkGameOver);
				printf("All of your ships are destroyed! You Lose!\n");
				fflush(stdout);
			}

			n = write(newsockfd, buffer, sizeof(buffer));
			if (n < 0) {
				fprintf(stderr, "ERROR: could not write to socket\n");
				exit(2);
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值