Project structure
Client
[professor@localhost servidor_4R]$ tree
.
├── 4enRatlla.c
├── f_sockets.c
├── include
│ ├── 4enRatlla.h
│ ├── client_joc1a1.h
│ ├── f_sockets.h
│ └── servidor_joc1a1.h
├── makefile
└── servidor_joc1a1.c
Server
[professor@localhost servidor_4R]$ tree
.
├── 4enRatlla.c
├── f_sockets.c
├── include
│ ├── 4enRatlla.h
│ ├── client_joc1a1.h
│ ├── f_sockets.h
│ └── servidor_joc1a1.h
├── makefile
└── servidor_joc1a1.c
Makefile client
D_I = include
PROGRAMES = client_joc1a1.o 4enRatlla.o f_sockets.o
client_joc1a1 : $(PROGRAMES)
gcc -o client_joc1a1 $(PROGRAMES)
client_joc1a1.o : client_joc1a1.c $(D_I)/client_joc1a1.h $(D_I)/4enRatlla.h $(D_I)/f_sockets.h
gcc -c $<
4enRatlla.o : 4enRatlla.c $(D_I)/4enRatlla.h
gcc -c $<
f_sockets.o : f_sockets.c $(D_I)/f_sockets.h
gcc -c $<
.PHONY : netejar
net :
$(RM) *.o
Makefile server
D_I = include
PROGRAMES = servidor_joc1a1.o 4enRatlla.o f_sockets.o
servidor_joc1a1 : $(PROGRAMES)
gcc -o servidor_joc1a1 $(PROGRAMES)
servidor_joc1a1.o : servidor_joc1a1.c $(D_I)/servidor_joc1a1.h $(D_I)/4enRatlla.h $(D_I)/f_sockets.h
gcc -c $<
4enRatlla.o : 4enRatlla.c $(D_I)/4enRatlla.h
gcc -c $<
f_sockets.o : f_sockets.c $(D_I)/f_sockets.h
gcc -c $<
.PHONY : netejar
net :
$(RM) *.o
4enRatlla.h
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define MAX 8
#define JUG_1 1
#define SJUG_1 '*'
#define JUG_2 2
#define SJUG_2 'O'
#define SBUIT '-'
#define RATLLA 4
#define _HRZT 1
#define _VERT 2
#define _DIAA 3
#define _DIAB 4
#define t_bool int
void inicialitzar();
char simbol_jugador(int jugador);
char simbol_buit();
t_bool jugar(char simbol,int *i,int *j);
t_bool ubicar(char simbol,int *fila,int columna);
t_bool evaluar_enratlla(int i,int j,int NR);
int num_simbols(int i,int j,int orientacio);
void seg_v(int *i,int *j);
void ant_v(int *i,int *j);
void seg_h(int *i,int *j);
void ant_h(int *i,int *j);
void seg_dA(int *i,int *j);
void ant_dA(int *i,int *j);
void seg_dB(int *i,int *j);
void ant_dB(int *i,int *j);
void canvia_jugador(int *jugador);
int X_obtener_columna();
void X_imprimir();
void X_torn(int jugador);
void X_msg_guanyador(int jugador);
void test(char *txt);
char tab[MAX][MAX];
t_bool fi_partida,jugada_valida;
4enRatlla.c
#include "include/4enRatlla.h"
char simbol_buit(){
return SBUIT;
}
void inicialitzar(){
int i,j;
for (i=0;i<MAX;i++)
for (j=0;j<MAX;j++)
tab[i][j]=simbol_buit();
}
char simbol_jugador(int jugador){
switch(jugador){
case JUG_1: return SJUG_1;
case JUG_2: return SJUG_2;
}
}
t_bool jugar(char simbol,int *i,int *j){
*j=X_obtener_columna();
return ubicar(simbol,i,*j);
}
t_bool ubicar(char simbol,int *fila,int columna){
*fila=0;
while((tab[*fila][columna])!=simbol_buit() && ((*fila)<MAX)) (*fila)++;
if ((*fila)<MAX) tab[*fila][columna]=simbol;
return ((*fila)<MAX);
}
t_bool evaluar_enratlla(int i,int j,int NR){
int nsimbols=0;
nsimbols=num_simbols(i,j,_HRZT);
if (nsimbols>=NR) return TRUE;
nsimbols=num_simbols(i,j,_VERT);
if (nsimbols>=NR) return TRUE;
nsimbols=num_simbols(i,j,_DIAA);
if (nsimbols>=NR) return TRUE;
nsimbols=num_simbols(i,j,_DIAB);
if (nsimbols>=NR) return TRUE;
return FALSE;
}
void seg_v(int *i,int *j){(*i)++;}
void ant_v(int *i,int *j){(*i)--;}
void seg_h(int *i,int *j){(*j)++;}
void ant_h(int *i,int *j){(*j)--;}
void seg_dA(int *i,int *j){(*i)++;(*j)++;}
void ant_dA(int *i,int *j){(*i)--;(*j)--;}
void seg_dB(int *i,int *j){(*i)++;(*j)--;}
void ant_dB(int *i,int *j){(*i)--;(*j)++;}
int num_simbols(int i,int j,int orientacio){
void (*seg)(int *,int *);
void (*ant)(int *,int *);
char simbol;
int n_simbols=1;
int f,c;
simbol=tab[i][j];
switch(orientacio){
case _HRZT:seg=&seg_h;
ant=&ant_h;
break;
case _VERT:seg=&seg_v;
ant=&ant_v;
break;
case _DIAA:seg=&seg_dA;
ant=&ant_dA;
break;
case _DIAB:seg=&seg_dB;
ant=&ant_dB;
break;
default: exit(-1);
}
f=i;c=j;
seg(&f,&c);
while ((f>=0)&&(f<MAX)&&(c>=0)&&(c<MAX)&&(tab[f][c]==simbol)){seg(&f,&c);n_simbols++;}
f=i;c=j;
ant(&f,&c);
while ((f>=0)&&(f<MAX)&&(c>=0)&&(c<MAX)&&(tab[f][c]==simbol)){ant(&f,&c);n_simbols++;}
return n_simbols;
}
void canvia_jugador(int *jugador){
switch(*jugador){
case JUG_1:(*jugador)=JUG_2;
break;
case JUG_2:(*jugador)=JUG_1;
break;
}
}
//Funcions X
int X_obtener_columna(){
int columna;
do{
printf("\nColumna? ");
scanf("%d",&columna);
}while((columna<0) || (columna>=MAX));
return(columna);
}
void X_imprimir(){
int i,j;
for (i=MAX-1;i>=0;i--){
for (j=0;j<MAX;j++)
printf("%3c",tab[i][j]);
printf("\n");
}
for (i=0;i<MAX;i++)
printf("%3d",i);
printf("\n");
}
void X_torn(int jugador){
switch(jugador){
case JUG_1:printf("%s (%c)","Torn de jugador 1",SJUG_1);
break;
case JUG_2:printf("%s (%c)","Torn de jugador 2",SJUG_2);
break;
}
}
void X_msg_guanyador(int jugador){
printf("\n*****************************************\n");
printf("\n ENHORABONA!! HAS GUANYAT jugador:%d\n",jugador);
printf("\n*****************************************\n");
}
void test(char *txt){
printf("%s",txt);getchar();
}
f_sockets.h
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define NUMPORT 3490
#define BACKLOG 10
#define MAXDATASIZE 256
int crea_socket();
void init_addres(struct sockaddr_in *addr);
void port_socket(int sockfd,struct sockaddr_in addr);
void espera_socket(int sockfd);
int acepta_socket(int sockfd,struct sockaddr_in *addr);
int enviar(int socket,char buffer[MAXDATASIZE]);
int rebre(int socket,char buffer[MAXDATASIZE]);
f_sockets.c
#include "include/f_sockets.h"
int crea_socket(){
int sockfd;
int yes=1;
if ((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("socket");
exit(1);
}
//Per permetre reutilitzar el port...
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1){
perror("setsockopt");
exit(1);
}
return sockfd;
}
void init_addres(struct sockaddr_in *addr){
addr->sin_family=AF_INET;
addr->sin_port=htons(NUMPORT);
addr->sin_addr.s_addr=INADDR_ANY;
memset(&(addr->sin_zero),'\0',8);
}
void port_socket(int sockfd,struct sockaddr_in addr){
if (bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr)) == -1){
perror("bind");
exit(1);
}
}
void espera_socket(int sockfd){
if (listen(sockfd,BACKLOG) == -1){
perror("listen");
exit(1);
}
}
int acepta_socket(int sockfd,struct sockaddr_in *addr){
int sin_size,new_fd;
sin_size=sizeof(struct sockaddr_in);
if ((new_fd=accept(sockfd,(struct sockaddr *)addr,&sin_size))==-1){
perror("accept");
return -1;
}
return new_fd;
}
int enviar(int socket,char buffer[MAXDATASIZE]){
if (send(socket,buffer,MAXDATASIZE,0) == -1) perror("send");
}
int rebre(int socket,char buffer[MAXDATASIZE]){
int numbytes;
if ((numbytes=recv(socket,buffer,MAXDATASIZE,0))==-1){perror("recv");exit(1);}
buffer[numbytes]='\0';
}
CLIENT PROGRAM
client_joc1a1.h
typedef struct{
int f;
int c;
char m[8][8];
}t_coord;
int empaquetar(char *d,t_coord *fc,int tam);
int desempaquetar(char *d,t_coord **fc);
client_joc1a1.c
#include "include/client_joc1a1.h"
#include "include/f_sockets.h"
#include "include/4enRatlla.h"
#include <sys/socket.h>
#include <netdb.h>
int main(int argc, char *argv[]){
int sockfd;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
int jugador,i=1,j;
t_coord coord,*coord_dest;
char *dades;
if (argc!=2){
fprintf(stderr,"usar: client hostname\n");
exit(1);
}
if ((he=(struct hostent *)gethostbyname(argv[1]))==NULL){
perror("gethostbyname");
exit(1);
}
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit(1);
}
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(NUMPORT);
their_addr.sin_addr=*((struct in_addr*)he->h_addr);
memset(&(their_addr.sin_zero),'\0',8);
if (connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr))==-1){
perror("connect");
exit(1);
}
fi_partida=FALSE;
jugada_valida=FALSE;
jugador=JUG_2;
inicialitzar();
while(1){
rebre(sockfd,buf);
coord_dest=(t_coord *)malloc(sizeof(t_coord));
desempaquetar(buf,&coord_dest);
i=coord_dest->f;
j=coord_dest->c;
tab[i][j]='*';
printf("\nf:%d c:%d \n",i,j);
X_imprimir();
//jugar
do{
X_torn(jugador);
jugada_valida=jugar(simbol_jugador(jugador),&i,&j);
}while (!jugada_valida);
X_imprimir();
if (evaluar_enratlla(i,j,RATLLA)){
X_msg_guanyador(jugador);
fi_partida=TRUE;
}
//empaquetar jugada i enviar
coord.f=i;
coord.c=j;
dades=(char *)malloc(sizeof(t_coord));
empaquetar(dades,&coord,sizeof(t_coord));
enviar(sockfd,dades);
}
close(sockfd);
return 0;
}
int empaquetar(char *d,t_coord *fc,int tam){
char *orig,*dest;
int i;
orig=(char *)fc;
dest=(char *)d;
for(i=0;i<tam;i++) {*dest=*orig;dest++;orig++;};
}
int desempaquetar(char *d,t_coord **fc){
(*fc)=(t_coord *)d;
}
SERVER PROGRAM
servidor_joc1a1.h
typedef struct{
int f;
int c;
char m[8][8];
}t_coord;
int empaquetar(char *d,t_coord *fc,int tam);
int desempaquetar(char *d,t_coord **fc);
servidor_joc1a1.c
#include "include/servidor_joc1a1.h"
#include "include/f_sockets.h"
#include "include/4enRatlla.h"
int main(){
int jugador,i,j;
int sockfd, new_fd;
struct sockaddr_in m_addr; //meua adreça
struct sockaddr_in s_addr; //seua adreça
char buf[MAXDATASIZE];
t_coord coord,*coord_dest;
char *dades;
sockfd=crea_socket();
init_addres(&m_addr);
port_socket(sockfd,m_addr);
espera_socket(sockfd);
new_fd=acepta_socket(sockfd,&s_addr);
printf("\nservidor: jugador s'ha conectat des de %s \n", inet_ntoa(s_addr.sin_addr));
fi_partida=FALSE;
jugada_valida=FALSE;
jugador=JUG_1;
inicialitzar();
while(1){
//jugar
do{
X_torn(jugador);
jugada_valida=jugar(simbol_jugador(jugador),&i,&j);
}while (!jugada_valida);
X_imprimir();
if (evaluar_enratlla(i,j,RATLLA)){
X_msg_guanyador(jugador);
fi_partida=TRUE;
}
//empaquetar jugada i enviar
coord.f=i;
coord.c=j;
dades=(char *)malloc(sizeof(t_coord));
empaquetar(dades,&coord,sizeof(t_coord));
enviar(new_fd,dades);
//rebre dades i desempaquetar
rebre(new_fd,buf);
coord_dest=(t_coord *)malloc(sizeof(t_coord));
desempaquetar(buf,&coord_dest);
printf("\nf:%d c:%d \n",coord_dest->f,coord_dest->c);
i=coord_dest->f;
j=coord_dest->c;
tab[i][j]='O';
X_imprimir();
}
close(new_fd);
close(sockfd);
return 0;
}
int empaquetar(char *d,t_coord *fc,int tam){
char *orig,*dest;
int i;
orig=(char *)fc;
dest=(char *)d;
for(i=0;i<tam;i++) {*dest=*orig;dest++;orig++;};
}
int desempaquetar(char *d,t_coord **fc){
(*fc)=(t_coord *)d;
}