Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
/* Name of player must be equal to or less than 50 characters in length */
#define MAX_NAME_LENGTH 50
/* Integer values of colors when sending a code guess to the server */
#define COLOR_EMPTY 0
#define COLOR_RED 1
#define COLOR_BLUE 2
#define COLOR_YELLOW 3
#define COLOR_GREEN 4
#define COLOR_WHITE 5
#define COLOR_ORANGE 6
/* Possible return values from the send_code function */
#define SEND_STATUS_SUCCESS 0
#define SEND_STATUS_ERROR_NULL_USER 1
#define SEND_STATUS_ERROR_NULL_REQUEST 2
#define SEND_STATUS_ERROR_NULL_RESPONSE 3
#define SEND_STATUS_ERROR_LONG_USER 4
#define SEND_STATUS_ERROR_HOST_DNS 5
#define SEND_STATUS_ERROR_SOCKET_OPEN 6
#define SEND_STATUS_ERROR_NO_SERVER 7
#define SEND_STATUS_ERROR_SEND 8
#define SEND_STATUS_ERROR_RECEIVE 9
/* Server information */
#define GAME_SERVER_HOST "cnfolio.com"
#define GAME_SERVER_PORT 80
#define GAME_SERVER_COMMAND "GET /Mastermind?A=%d&B=%d&C=%d&D=%d&E=%s HTTP/1.0\r\nHost: %s\r\n\r\n"
#define GAME_SERVER_API ":API:"
/*
user : Array of characters that contain the name of the player.
Must contain only alphanumeric characters.
Must be 50 or less characters in length.
request : Array of 4 integers that contain the colors of the guess code.
The first array element is the leftmost peg of the row.
response : Array of 4 integers for storing the response from the server.
The first array element is the leftmost peg of the row.
session : Address of an integer variable to toggle between 1 and 0 when a new game starts.
The function returns an integer value that indicates success or type of error.
*/
// Sets up Storage Space
int main(void)
{
char user[50], x;
char guess[4];
char result[BUFSIZ];
char ret[2];
int request[4], response[4], session[1], again, again1, y, t[1], g, status;
int quit = 1;
printf("\nTo win the game you will need to enter 4 guesses in the correct order, from the following\n");
printf("colours: Red, Blue, Yellow, Green, White and Orange. The colours appear in a \n");
printf("random position. The code can contain the same colour more than once.\n");
printf("To play, enter the initial of the colour you want to try.\n");
printf("After your guesses, the program will tell you which colours are right\n");
printf("and which ones are right and in the right position:\n");
printf("[0] = Guess which is correct in both color and position\n");
printf("[*] = Guess which is correct in color only\n");
printf("[-] = Incorect guess\n");
printf("\nTime To Play\n");
printf("\nPress Q to Quit");
printf("\n\nPlease enter a username: ");
scanf("%s", user);
{ if(user[0]=='q' || user[0]== 'Q') quit = 0;
if (quit == 0)
{
printf("\nThank you for playing mastermind");
return 0;
}
else quit = 1;
}
printf("\n\nWelcome to Mastermind\n");
do{
do{ for(g=0; g<4; g++) request[g]=0;
again = 0; session[0]= t[0];
printf("\nPress Q to Quit");
printf("\nPlease enter a guess [Red= R, Blue= B, Yellow= Y, Green= G, White= W, Orange= O]...\n\nFirst Pin: ");
scanf("%s", &guess[0]);
{ if(guess[0]=='q' || guess[0]== 'Q') quit = 0;
if (quit == 0)
{
printf("\nThank you for playing mastermind");
return 0;
}
else quit = 1;
}
printf("Second Pin: ");
scanf("%s", &guess[1]);
{ if(guess[1]=='q' || guess[1]== 'Q') quit = 0;
if (quit == 0)
// Terminates the program if they do not wish to try again //
{
printf("\nThank you for playing mastermind");
return 0;
}
else quit = 1;
}
printf("Third Pin: ");
scanf("%s", &guess[2]);
{ if(guess[2]=='q' || guess[2]== 'Q') quit = 0;
if (quit == 0)
{
printf("\nThank you for playing mastermind");
return 0;
}
else quit = 1;
}
printf("Fourth Pin: ");
scanf("%s", &guess[3]);
{ if(guess[3]=='q' || guess[3]== 'Q') quit = 0;
if (quit == 0)
{
printf("\nThank you for playing mastermind");
return 0;
}
else quit = 1;
}
for(g=0; g<4; g++){
if(guess[g]=='r' || guess[g]== 'R') request[g]= COLOR_RED;
if(guess[g]=='b' || guess[g]== 'B') request[g]= COLOR_BLUE;
if(guess[g]=='y' || guess[g]== 'Y') request[g]= COLOR_YELLOW;
if(guess[g]=='g' || guess[g]== 'G') request[g]= COLOR_GREEN;
if(guess[g]=='w' || guess[g]== 'W') request[g]= COLOR_WHITE;
if(guess[g]=='o' || guess[g]== 'O') request[g]= COLOR_ORANGE;
}
for(y=0; y<4; y++){
if(request[y] == 0){
printf("Invalid Entry!\nUse Only Colour Initials\n[Red= R, Blue= B, Yellow= Y, Green= G, White= W, Orange= O]\n"); again = 1; y=4;}
}
}while(again == 1);
status = send_code(user, request, response, &session);
if(status != SEND_STATUS_SUCCESS) {
printf("\nTHE SERVER IS NOT RESPONDING!\nPLEASE RESTART PROGRAM AND TRY AGAIN!\n");
return 0;
}
printf("\n[0] = Guess which is correct in both color and position\n[*] = Guess which is correct in color only\n[-] = Incorect guess\n");
printf("\nThe response to your guess is: ");
if(response[0]==COLOR_EMPTY) printf("[-] [-] [-] [-]");
else {
for(g=0; g<4; g++){
if(response[g]==COLOR_RED) strcpy(result, "[0]");
if(response[g]==COLOR_WHITE) strcpy(result, "[*]");
if(response[g]==COLOR_EMPTY) strcpy(result, "[-]");
printf("%s ", result);
}}
if(response[3]== 1)
{
printf("\n\n****************************\n");
printf("* *\n");
printf("* CONGRATULATIONS! *\n");
printf("* *\n");
printf("* YOU CRACKED *\n");
printf("* THE CODE!!! *\n");
printf("* *\n");
printf("****************************\n\n\n");
printf("A New Game Has Started!");}
do{
printf("\nContinue? [Y/N]: ");
scanf("%s", &ret[0]);
if(ret[0]=='y' || ret[0]=='Y'){ again=1; again1=0;}
else{ if(ret[0]=='n' || ret[0]=='N') again1=0;
else{ printf("Please Type Y to Continue or N to Quit"); again1=1;}}
}while(again1 == 1);
}while(again == 1);
printf("\nThank you for playing mastermind");
return 0;
}
int send_code( char* user, int* request, int* response, int* session )
{
int sock_fail = -1;
int cmd_success = sock_fail + 1;
int cmd_fail = cmd_success + 1;
char cmd[ 512 ] = { '\0' };
int cmdsize = 512;
char buffer[ 768 ] = { '\0' };
int bufsize = 767;
struct hostent *server_info = NULL;
struct sockaddr_in server_addr;
int sock_id, sock_stat, counter;
char *api_data = NULL;
if ( user == NULL ) return cmd_fail;
if ( request == NULL ) return ( cmd_fail + 1 );
if ( response == NULL ) return ( cmd_fail + 2 );
if ( strlen( user ) > MAX_NAME_LENGTH ) return ( cmd_fail + 3 );
for ( counter = 0; counter < strlen( user ); counter++ )
if ( ! isalnum( user[ counter ] ) ) user[ counter ] = '_';
server_info = gethostbyname( GAME_SERVER_HOST );
if ( server_info == NULL ) return ( cmd_fail + 4 );
sock_id = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock_id == sock_fail ) return ( cmd_fail + 5 );
memset( &server_addr, 0, sizeof( server_addr ) );
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( GAME_SERVER_PORT );
server_addr.sin_addr = *(struct in_addr *) server_info->h_addr;
sock_stat = connect( sock_id, (void *) &server_addr, sizeof( server_addr ) );
if ( sock_stat == sock_fail )
{
close( sock_id );
return ( cmd_fail + 6 );
}
snprintf( cmd, cmdsize, GAME_SERVER_COMMAND, request[0], request[1], request[2], request[3], user, GAME_SERVER_HOST );
sock_stat = send( sock_id, (void*) cmd, strlen( cmd ), 0 );
if ( sock_stat == sock_fail )
{
close( sock_id );
return ( cmd_fail + 7 );
}
response[ 0 ] = response[ 1 ] = response[ 2 ] = response[ 3 ] = 0;
while ( ( sock_stat != sock_fail ) && ( sock_stat != 0 ) )
{
sock_stat = recv( sock_id, (void*) buffer, bufsize, 0 );
buffer[ sock_stat ] = '\0';
api_data = strstr( buffer, ":API:" );
if ( api_data != NULL )
{
if ( strlen( api_data ) >= 9 )
{
for ( counter = 0; counter < 4; counter++ )
{
sprintf( cmd, "%c", api_data[ counter + 5 ] );
response[ counter ] = atoi( cmd );
}
if ( session != NULL )
{
sprintf( cmd, "%c", api_data[ counter + 5 ] );
*session = atoi( cmd );
}
close( sock_id );
return cmd_success;
}
else
break;
}
}
close( sock_id );
return ( cmd_fail + 8 );
}