-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.cpp
205 lines (159 loc) · 6.61 KB
/
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
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
/*****************************************************************
* Projekt z przedmiotu Sieci Komputerowe *
* Temat projektu: C. Gra odgadywanie slow *
* Autorzy: Zuzanna Wieczorek (291565), Adam Wisniewski (291569) *
* Grupa: sk-cz-12-p *
*****************************************************************/
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace std;
void error(string msg){
cerr << msg << endl;
exit(1);
}
int main(int argc, char *argv[]){
int sockfd, newsockfd, portno; //gniazdo servera, gniazdo clienta i numer portu
char lvl; //poziom trudnosci (ilosc mozliwych bledow)
socklen_t clilen;
char buffer[255]; //sluzy do komunikacji
char buffer0[255]; //slowo do zgadniecia
char used[255]; //przechowuje wykorzystane literki
bool guessed[255]; //sluzy do zaslaniania literek
//***********************************************
//* kod ponizej zostal stworzony na podstawie: *
//* https://www.youtube.com/watch?v=CMDBF84vSRk *
//* https://www.youtube.com/watch?v=Ts8eXOkx8TE *
//***********************************************
struct sockaddr_in serv_addr, cli_addr; //adresy servera i clienta
int n;
if (argc < 2) {
cerr << "Nie podano numeru portu!" << endl;
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0); //otwieranie gniazda servera
if (sockfd < 0)
error("Blad podczas otwierania gniazda");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
n = bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)); //bindowanie
if (n < 0)
error("Blad podczas bindowania");
cout << "Oczekiwanie na dolaczenie zgadujacego..." << endl;
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); //otwieranie gniazda clienta kiedy sie polaczy
if (newsockfd < 0)
error("Blad akceptacji");
//*******************************************************
//* kod ponizej zostal stworzony przez autorow projektu *
//*******************************************************
cout << "*************************" << endl;
cout << "* Witaj w grze WISIELEC *" << endl;
cout << "* Jestes wieszajacym! *" << endl;
cout << "*************************" << endl;
cout << "Podaj slowo do zgadywania:" << endl;
bzero(buffer,255); //czyszczenie bufora
cin >> buffer0; //podanie slowa
unsigned int l = strlen(buffer0); //dlugosc podanego slowa
for(unsigned int i = 0; i < l; i++){
guessed[i] = false; //ustawienie guessed na same false-y
}
char slowo[l + 1]; //+ 1 bo jeszcze miejsce na informacje o ilosci mozliwych bledow
for(unsigned int i = 0; i < l; i++){
slowo[i] = '_'; //zaszyfrowanie slowa
}
while(1){ //podanie poziomu trudnosci (ilosci bledow)
cout << "Podaj ilosc bledow jakie moze popelnic zgadujacy (0 - 9): ";
cin >> lvl;
if(!isdigit(lvl)) cout << "Nie podales cyfry!" << endl;
else break;
}
slowo[l] = lvl; //wstawiamy ilosc szans na blad na koniec slowa
n = read(newsockfd,buffer,255); //0. probne odczytanie czegokolwiek - inaczej server nie dziala
if (n < 0)
error("Blad czytania z gniazda\n");
bzero(buffer,255);
n = write(newsockfd,slowo,l + 1); //1. wyslanie zaszyfrowanego slowa i ilosci szans
if (n < 0)
error("Blad pisania do gniazda\n");
unsigned int counter = 0;
while(1){ //zaczynamy zgadywanie
bzero(buffer,255);
n = read(newsockfd,buffer,255); //2. odebranie literki
if (n < 0)
error("Blad czytania z gniazda");
if(!isalpha(buffer[0])){
bzero(buffer,255);
n = write(newsockfd, "1", 1); //3a. jesli zgadujacy nie wyslal literki, to wysylamy mu '1', zeby wiedzial ze zrobil zle
}
bool wasUsed = false;
for(unsigned int i = 0; i < strlen(used); i++){ //sprawdzamy czy dana litera juz sie nie pojawila
if(used[i] == buffer[0]){
wasUsed = true;
break;
}
}
if(wasUsed && isalpha(buffer[0])){ //3f. jesli zgadujacy wyslal litere ktora juz wczesniej zostala uzyta
bzero(buffer,255);
n = write(newsockfd, "5", 1);
}
else {
used[strlen(used)] = buffer[0];
}
cout << "Zgadujacy wybral literke " << buffer << endl;
unsigned int oldcounter = counter;
counter = 0; //counter do liczenia ilosci pasujacych literek
for(unsigned int i = 0; i < l; i++){ //sprawdzenie czy literka pasuje do slowa
if(buffer0[i] == buffer[0]){
guessed[i] = true; //jesli literka na danym miejscu w slowie sie zgadza, to bedzie ona wyswietlana
}
if(guessed[i]) counter++; //liczenie ilosci zgadzajacych sie literek
}
if(counter == l){
cout << "Koniec gry - zgadujacemu udalo sie zgadnac slowo!" << endl;
bzero(buffer,255);
n = write(newsockfd,"2",1); //3b. wyslanie informacji o wygranej zgadujacego
}else if(counter - oldcounter == 0 && !wasUsed && isalpha(buffer[0])){
lvl--;
if(lvl - 48 < 0) { //3c. wyslanie informacji o przegranej (utracie wszystkich szans na blad) (lvl - 48 bo ASCII)
bzero(buffer,255);
n = write(newsockfd,"3",1);
cout << "Zgadujacy utracil wszystkie szanse i przegrywa!" << endl;
}
else { //3d. wyslanie informacji o utracie jednej szansy na blad
bzero(buffer,255);
n = write(newsockfd,"4",1);
cout << "Zgadujacy utracil jedna szanse na blad!" << endl;
}
}
if (n < 0)
error("Blad pisania do gniazda\n");
for(unsigned int i = 0; i < l; i++){ //formowanie slowa do wyslania
if(guessed[i])
slowo[i] = buffer0[i];
else
slowo[i] = '_';
}
slowo[l] = lvl;
//cout << slowo << endl;
for(unsigned int i = 0; i < strlen(used); i++){
slowo[l + 1 + i] = used[i];
}
bzero(buffer,255);
cout << "buffer: " << buffer;
n = write(newsockfd,slowo,l + 1 + strlen(used)); //3e. wyslanie slowa razem z iloscia szans i lista wykorzystanych liter z powrotem
if (n < 0)
error("Blad pisania do gniazda\n");
}
close(newsockfd);
close(sockfd);
return 0;
}