Help needed for Server/Client Battleship game C++

Hi, new here to C++ socket programming. Thus, in need for some help.
1) How do I let my program knows which position is being set (e.g. Patrol Boat @ Position D6, D7)

2) If user hit the Boat's position, and HIT will be displayed, else a MISS will be displayed.
SERVER.CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include <strings.h>
#include <stdlib.h>
#include <string>

using namespace std;

//function to handle the file and comparision
int clientside (int);

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

	
	int connfd, pid, portNo, listenfd;
	socklen_t len;
	bool loop = false;
	struct sockaddr_in servaddr, client_addr;

	//make sure the user setting up server enters in correct arguments
    	if (argc < 2)
    	{
        	cerr << "Syntax : ./server <port>" << endl;
        	return 0;
    	}

	portNo = atoi(argv[1]);	

	//only allows user setting up server to enter a certain range of port number
	if((portNo>65535) || (portNo<2000))
	{
		cerr<<"Please enter port number between 2000 - 65535"<<endl;
		return 0;
	}

    	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	//error msg if socket cannot be opened
	if (listenfd < 0)
	{
		cout<<"Cannot open socket!"<<endl;
		return 0;
	}

    	bzero((char *) &servaddr,sizeof(servaddr));

	servaddr.sin_family = AF_INET;
    	servaddr.sin_addr.s_addr = INADDR_ANY;
    	servaddr.sin_port = htons(portNo);

	//error msg if hostname and ip address cannot be binded
    	if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
	{
		cout<<"Cannot bind!"<<endl;
		return 0;
	}     	listen(listenfd,5);

    	len = sizeof(client_addr);

	//endless while loop for server to keep listening for incoming connections
    	while (loop==false)
    	{
		cout<<"Listening....."<<endl;	

        	connfd = accept(listenfd,(struct sockaddr *)&client_addr,&len);

		//error msg if server cannot accept incoming connection		
		if (connfd < 0)
		{
			cout<<"Cannot accept connection!"<<endl;
			return 0;
		}	

		//everytime a connection is made, the parent fork out a copy
		//this allows multiple connections to the server
        	pid = fork();
        	if (pid < 0)
        	{
            		cerr << "ERROR forking!" << endl;;
            		return 0;
        	}
        	if (pid == 0)
        	{
			close(listenfd);
            		clientside(connfd);//reading client's attacked coordinate
			return 0;
       		}
        	else 
		{
			close(connfd);
		}
    	}
    	return 0;		
}

int clientside (int connfd)
{
	bool questFound = false;
    	char test[150];
	char warship[150];
	char shipgrid[150];
	char exitCheck[] = "exit";
	char temp[150];
	string fline;
	string::size_type pos;

    	bzero(test,151);
    	read(connfd,test,150);// client's attacked coordinate  stored in test

	//open the warship and shipgrid file
	ifstream infile;
	infile.open("position.txt");

	strcpy(temp,test);

	//case insensitive for 'exit'
	for(int i=0;i<strlen(temp);i++)
	{
		temp[i] = toupper(temp[i]);
	}

	//if client enters 'exit', server will be notified
	if(strcmp(temp,exitCheck)==0)
	{
		cout<<"Client has disconnected!"<<endl;
		cout<<"Listening....."<<endl;
	}
	else
	{
		cout << "Message Received: " << test << endl;
		for(int i=0;i<strlen(test);i++)
		{
			test[i] = toupper(test[i]);
		}

	    	if (!infile)
	    	{
			cout << "Cannot open file" << endl;
			return 0;
	    	}
	    	else
	    	{
			//extracts data from file and compare
			while (getline(infile, fline) && questFound == false)
			{
		    		//cout<<fline<<endl;
					pos = fline.find(test, 0);
                                        //?????

	
			}
			//if warship not found, display this
		 	if (questFound == false)
	   	 	{
	   		 	write(connfd,"Missed",999);
	   	
			}			
			infile.close();
	  	}
	}
}
Last edited on
CLIENT.CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#include <string.h>
#include <cstring>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <strings.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <vector>

using namespace std;

int checkPast(string c);
void viewGrid();


string gBomb[100];
string hitlist[100];
int count, counthit;
time_t start,end;
double dif;

int main(int argc, char *argv[])
{
	int listenfd, portNo;
	bool loop = false;
	struct sockaddr_in servaddr;
	struct hostent *server;
	char exitCheck[] = "EXIT";
	char test[150];
	char result[150];
	count=0;
	counthit=0;
	
	time (&start);
	//endless loop for questions
	while(loop==false)
	{
		//make sure the user connecting to the server enters in correct arguments
		if(argc < 3)
		{
			cerr<<"Syntax : ./client <host name> <port>"<<endl;
			return 0;
		}

		portNo = atoi(argv[2]);

		//only allows user setting up server to enter a certain range of port number
		if((portNo>65535) || (portNo<2000))
		{
			cerr<<"Please enter port number between 2000 - 65535"<<endl;
			return 0;
		}		

		listenfd = socket(AF_INET, SOCK_STREAM, 0);

		//error msg if socket cannot be opened
		if (listenfd < 0)
		{
			cout<<"Cannot open socket!"<<endl;
			return 0;
		}
	
		server = gethostbyname(argv[1]);
		
		//if server does not exist, display error msg
		if(server==NULL)
		{
			cout<<"Host does not exist!"<<endl;
			return 0;
		}	
	
		bzero((char *) &servaddr, sizeof(servaddr));
		servaddr.sin_family = AF_INET;

		bcopy((char *)server->h_addr,(char *) &servaddr.sin_addr.s_addr,server->h_length);

		servaddr.sin_port = htons(portNo);

		int checker = connect(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

		//if unable to connect to server, display error msg
		if (checker < 0)
		{
			cout<<"Cannot connect!"<<endl;
			return 0;
		}
		cout<<"\nEnter a square on the battle grid to bomb: ";
		bzero(test,151);
		cin.getline(test,150);

		string tester (test);

		for(int i=0;i<strlen(test);i++)
		{
			test[i] = toupper(test[i]);
		}

		int passed = checkPast(test);//to check if grid had been bombed previously
		cout<< "\x1b[2J\x1b[H";//to clear the screen
		cout<<"\E[32;40m\n\t\t\t************************************\E[0m"<<endl;
		if(passed==0 && count!=0){
		
		cout<<"\E[31;40m\t\t\tGrid have been bombed before!!\E[0m"<<endl;
		cout<<"\E[32;40m\t\t\t************************************\n\E[0m"<<endl;
		viewGrid();

		}else if (tester.length()==0)//if user enters nothing
		{
			cout<<"No grid to bomb!!"<<endl;
		}
		else
		{
			//write input to server
			int checker2 = write(listenfd,test,strlen(test));

			gBomb[count]=test;
		
			//error msg if cannot write to socket
			if (checker2 < 0)
			{
				cout<<"Cannot write to socket!"<<endl;
				return 0;
			}

			//check if user enters 'exit', if yes, exit loop and close socket
			if(strcmp(test,exitCheck)==0)
			{	time (&end);//end the time if user exits
				loop = true;
			}
			else
			{
				//bzero(result,151);
				int checker3 = read(listenfd,result,150);
			
				//error if cannot read from socket
				if (checker3 < 0)
				{
					cout<<"Cannot read from socket!"<<endl;
					return 0;
				}	
			
				cout<<"\t\t\t\tTotal tries: "<<count+1<<endl;
				if(strcmp(result,"Missed")==0){
					cout<<"\E[34;40m\t\t\t\t"<<test<<" ";
					cout<<result<<"\E[0m"<<endl;	
					
				}
				else{
					cout<<"\E[31;40m\t\t\t\t"<<result<<" got HIT at ";
					cout<<test<<"!!\E[0m"<<endl;
					string s = result;
					s = s.substr(0,1);
					hitlist[counthit]=s+test;
					counthit++;
				}
				time (&end);
				int dif = difftime (end,start);
				cout<<"\t\t\t\tTime Lapsed: "<<dif/60<<"min "<<dif%60<<"secs\n";//displaying the total time lapsed
			}	

		count++;	
		cout<<"\E[32;40m\t\t\t************************************\E[0m"<<endl;
		cout<<endl;
		viewGrid();
		}
	}
	close(listenfd);
	return 0;
}

//Function to check if user had previous bombed the grid
int checkPast(string c){
int pass = 0;

	for (int a=0; a<count; a++)
	{
		
		if (gBomb[a]==c){
		pass=0;
		a=count+1;
		}
		else {pass=1; }
	}
return pass;
}

void viewGrid(){
int col=8;
int row=8;
stringstream ss,tt;
string column[]={"A","B","C","D","E","F","G","H"};
string rows[]={"1","2","3","4","5","6","7","8"};
char cur[2];
int found=0;
string hit;
cout<<"    A   B   C   D   E   F   G   H"<<endl;
cout<<"----------------------------------"<<endl;
	for(int b=0;b<row;b++){
	cout<<rows[b]<<"";

		for(int a=0;a<col;a++){
		
		string s = column[a]+rows[b];
		cout<<"   ";

			for(int x = 0; x<count; x++){
				if(gBomb[x]==s){
				
				found=1;
					for(int y = 0; y<counthit; y++){

						if(gBomb[x]==hitlist[y].substr(1,2)) 
						{
						found=2;
						hit = hitlist[y].substr(0,1);
						y=counthit+1;
						}
					}
				x=count+1;
				}
			}

			if(found==1){
			cout<<"\E[34;40mX\E[0m";
			}	
			else if(found==2){
			cout<<"\E[31;40m"<<hit<<"\E[0m";
			}
			else {cout<<" ";}
			found=0;
		}
	cout<<endl;
	}
}
Last edited on
Need some assistance, please...
Topic archived. No new replies allowed.