-
April 24th, 2012, 10:07 AM
#1
Visual C++ TicTacToe game with Pre-Processor directives, server, client and bitwise
Hi all,
I'm working on an assignment where we have to have a client and server sending each other an integer that represents a noughts and crosses board. I had it working by simply sending back and forth the entire NoughtsAndCrosses class, but now we need to do it just using the integers in the GameData struct using the individual bits. This is where I've gotten lost, here is my code, I'm not looking for straight up answers since I need to learn for myself, maybe just some hints to nudge me in the right direction?
Here is the code:
Server:
Code:
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <ctime>
#include <math.h>
using namespace std;
#define BITWISEGAME 1
// Noughts and Crosses (Tic Tack Toe) game
class NoughtsAndCrosses{
protected:
// An array of integers holding the bits
// 3 by 3 board is represented as a one dimensional array
char board[9];
// Players symbols are either X or O
char playerSymbol;
char aiSymbol;
// Game state
bool playerWin,aiWin,draw;
// If there is a winner or a draw update the state
bool CheckWin(char symbol){
bool won = false;
// Is there a winner?
// Check horizontal
if (board[0] == symbol && board[1] == symbol && board[2] == symbol) won = true;
if (board[3] == symbol && board[4] == symbol && board[5] == symbol) won = true;
if (board[6] == symbol && board[7] == symbol && board[8] == symbol) won = true;
// Check vertical
if (board[0] == symbol && board[3] == symbol && board[6] == symbol) won = true;
if (board[1] == symbol && board[4] == symbol && board[7] == symbol) won = true;
if (board[2] == symbol && board[5] == symbol && board[8] == symbol) won = true;
// Check diagonals
if (board[0] == symbol && board[4] == symbol && board[8] == symbol) won = true;
if (board[2] == symbol && board[4] == symbol && board[6] == symbol) won = true;
// If there is a winner who won?
if (won){
if (symbol == aiSymbol) aiWin = true;
else playerWin = true;
return true;
}
// If no one has won then check to see if it is a draw
for(int n=0;n<9;n++)
if (board[n] == ' ') return false;
draw = true;
return true;
}
public:
int bits[9];
NoughtsAndCrosses(){
for(int n=0;n<9;n++){
board[n] = ' ';
}
// Initialise my bits
bits[0] = 1;
bits[1] = 2;
bits[2] = 4;
bits[3] = 8;
bits[4] = 16;
bits[5] = 32;
bits[6] = 64;
bits[7] = 128;
bits[8] = 256;
playerSymbol = 'X';
aiSymbol = 'O';
playerWin = aiWin = draw = false;
}
bool IsFinished(){
if (playerWin || aiWin || draw) return true;
else return false;
}
void DisplayWinner(){
if (playerWin)
cout << "\n The Player has won \n";
else if (aiWin)
cout << "\n The AI has won \n";
else
cout << "\n Its a draw \n";
}
bool Play(char symbol, int pos){
// Ensure the position is free
if(board[pos]== ' '){
board[pos] = symbol;
CheckWin(symbol);
return true;
}
else return false;
}
void AIPlay(){
srand((unsigned)time(0));
int index;
do{
index = rand();
index = index % 9;
}
while(! Play('O', index));
}
void Dump(){
cout << board[0] << " | " << board[1] << " | " << board[2] << "\n";
cout << "--------\n";
cout << board[3] << " | " << board[4] << " | " << board[5] << "\n";
cout << "--------\n";
cout << board[6] << " | " << board[7] << " | " << board[8] << "\n";
}
// Transmit the whole object to the opponent
void Send(SOCKET s){
// Create an array that can hold the object
char sendObject[sizeof(NoughtsAndCrosses)];
// Copy the object into an array
memcpy(sendObject, this, sizeof(NoughtsAndCrosses));
// Invoke send passing it the socket etc
send(s, sendObject, sizeof(NoughtsAndCrosses), 0);
}
};
// Contains game data to be transmitted
struct GameData{
int playerData,aiData;
};
// Derived class to transmit bits
class BitNoughtsAndCrosses : public NoughtsAndCrosses{
public:
// Create an object to access the struct
GameData myGame;
// Re initialise the variables for this object
int index;
BitNoughtsAndCrosses(){
for (int i=0;i<9;i++){
board[i]=' ';
}
playerSymbol = 'X';
aiSymbol = 'O';
playerWin = aiWin = draw = false;
}
void Send(SOCKET s){
send(s, (char*)myGame.aiData, sizeof(myGame.aiData), 0);
}
bool Play(char symbol, int pos){
// make sure the board has free space
if (board[pos]==' '){
myGame.aiData = myGame.aiData&bits[pos];
board[pos] = symbol;
CheckWin(symbol);
return true;
}
else return false;
}
void AIPlay(){
srand((unsigned)time(0));
do{
index = rand();
index = index % 9;
myGame.aiData = myGame.aiData & bits[index];
} while(! Play('O', index));
}
};
int main(int argc, char* argv[]){
SOCKADDR_STORAGE from;
int fromlen, retval, socket_type, bytesRecv, bytesSent;
char servstr[NI_MAXSERV], hoststr[NI_MAXHOST], startBuffer[50];
SOCKET serverSocket, acceptSocket;
int port = 55555;
WSADATA wsaData;
int wsaerr;
WORD wVersionRequested = MAKEWORD(2,2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
// Load the DLL
if (wsaerr != 0){
cout << "The winsock dll not found!" << endl;
return 0;
} else {
cout << "The winsock dll found!" << endl;
cout << "The status: "<< wsaData.szSystemStatus << endl;
}
// Create a socket
serverSocket = INVALID_SOCKET;
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET){
cout << "Error at socket(): " << WSAGetLastError() << endl;
WSACleanup();
return 0;
} else {
cout << "Socket() is ok!" << endl;
}
// Bind the socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(port);
if (bind(serverSocket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR){
cout << "bind() failed: " << WSAGetLastError() << endl;
closesocket(serverSocket);
WSACleanup();
return 0;
} else {
cout << "bind() is OK!" << endl;
}
// Listen for a new connection
if (listen(serverSocket, 1) == SOCKET_ERROR){
cout << "Listen(): Error listening on socket " << WSAGetLastError() << endl;
} else {
cout << "Listen() is ok, I'm waiting for connections..." << endl;
}
// Accept the connection
fromlen = sizeof(socket_type);
retval = getsockopt(serverSocket, SOL_SOCKET, SO_TYPE, (char*)&socket_type, &fromlen);
fromlen = sizeof(from);
acceptSocket = accept(serverSocket, (SOCKADDR*)&from, &fromlen);
if (acceptSocket == INVALID_SOCKET){
cout << "accept failed: " << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
retval = getnameinfo((SOCKADDR*)&from, fromlen, hoststr, NI_MAXHOST, servstr, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
if (retval != 0){
cout << "getnameinfo failed: " << retval << endl;
WSACleanup();
return -1;
}
cout << "Accepted connection from host " << hoststr << " and port " << servstr << endl;
cout << "Accepted connection" << endl;
// Receive the start game message
if (acceptSocket == INVALID_SOCKET){
cout << "Accept Failed!" << endl;
}
bytesRecv = recv(acceptSocket, startBuffer, 50, 0);
if (bytesRecv == SOCKET_ERROR){
cout << "Server: recv() error";
}
cout << startBuffer << endl;
// Define an array to hold the object received
char buffer[sizeof(NoughtsAndCrosses)];
//int bitBuffer = 0;
#if NONBITWISEGAME
NoughtsAndCrosses *tictactoe = new NoughtsAndCrosses();
#endif
#if BITWISEGAME
BitNoughtsAndCrosses *tictactoe = new BitNoughtsAndCrosses();
#endif
// while game is not finished
while(!(tictactoe->IsFinished())){
tictactoe->AIPlay();
tictactoe->Dump();
tictactoe->Send(acceptSocket);
// if game not finished
#if BITWISEGAME
bytesRecv = recv(acceptSocket, (char*)tictactoe->index, sizeof(tictactoe->myGame.playerData), 0);
tictactoe->myGame.playerData = tictactoe->myGame.playerData &tictactoe->index;
tictactoe->Play('X', tictactoe->bits[tictactoe->index]);
cout << "Received " << tictactoe->index << endl;
#endif
#if NONBITWISEGAME
bytesRecv = recv(acceptSocket, buffer, sizeof(NoughtsAndCrosses), 0);
memcpy(tictactoe, buffer, sizeof(NoughtsAndCrosses));
#endif
}
tictactoe->DisplayWinner();
system("PAUSE");
WSACleanup();
return 0;
}
Client:
Code:
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include <ctime>
#include <math.h>
using namespace std;
#define BITWISEGAME 1
// Noughts and Crosses (Tic Tack Toe) game
class NoughtsAndCrosses{
protected:
// 3 by 3 board is represented as a one dimensional array
char board[9];
// Players symbols are either X or O
char playerSymbol;
char aiSymbol;
// Game state
bool playerWin,aiWin,draw;
// If there is a winner or a draw update the state
bool CheckWin(char symbol){
bool won = false;
// Is there a winner?
// Check horizontal
if (board[0] == symbol && board[1] == symbol && board[2] == symbol) won = true;
if (board[3] == symbol && board[4] == symbol && board[5] == symbol) won = true;
if (board[6] == symbol && board[7] == symbol && board[8] == symbol) won = true;
// Check vertical
if (board[0] == symbol && board[3] == symbol && board[6] == symbol) won = true;
if (board[1] == symbol && board[4] == symbol && board[7] == symbol) won = true;
if (board[2] == symbol && board[5] == symbol && board[8] == symbol) won = true;
// Check diagonals
if (board[0] == symbol && board[4] == symbol && board[8] == symbol) won = true;
if (board[2] == symbol && board[4] == symbol && board[6] == symbol) won = true;
// If there is a winner who won?
if (won){
if (symbol == aiSymbol) aiWin = true;
else playerWin = true;
return true;
}
// If no one has won then check to see if it is a draw
for(int n=0;n<9;n++)
if (board[n] == ' ') return false;
draw = true;
return true;
}
public:
int bits[9];
NoughtsAndCrosses(){
for(int n=0;n<9;n++)
board[n] = ' ';
bits[0]=1;
bits[1]=2;
bits[2]=4;
bits[3]=8;
bits[4]=16;
bits[5]=32;
bits[6]=64;
bits[7]=128;
bits[8]=256;
playerSymbol = 'X';
aiSymbol = 'O';
playerWin = aiWin = draw = false;
}
bool IsFinished(){
if (playerWin || aiWin || draw) return true;
else return false;
}
void DisplayWinner(){
if (playerWin)
cout << "\n The Player has won \n";
else if (aiWin)
cout << "\n The AI has won \n";
else
cout << "\n Its a draw \n";
}
bool Play(char symbol, int pos){
// Ensure the position is free
if(board[pos]== ' '){
board[pos] = symbol;
CheckWin(symbol);
return true;
}
else return false;
}
void AIPlay(){
srand((unsigned)time(0));
int index;
do{
index = rand();
index = index % 9;
}
while(! Play('O', index));
}
void Dump(){
cout << board[0] << " | " << board[1] << " | " << board[2] << "\n";
cout << "--------\n";
cout << board[3] << " | " << board[4] << " | " << board[5] << "\n";
cout << "--------\n";
cout << board[6] << " | " << board[7] << " | " << board[8] << "\n";
}
// Transmit the whole object to the opponent
void Send(SOCKET s){
// Define an array that can hold the object
char sendObject[sizeof(NoughtsAndCrosses)];
// Copy the object into an array
memcpy(sendObject, this, sizeof(NoughtsAndCrosses));
// Invoke Send
send(s, sendObject, sizeof(NoughtsAndCrosses), 0);
}
~NoughtsAndCrosses(){
//delete board;
}
};
// Contains game data to be transmitted
struct GameData{
int playerData,aiData;
};
class BitNoughtsAndCrosses: public NoughtsAndCrosses
{
public:
BitNoughtsAndCrosses(){
for(int n=0;n<9;n++)
board[n] = ' ';
playerSymbol = 'X';
aiSymbol = 'O';
playerWin = aiWin = draw = false;
}
GameData myGame;
void Send(SOCKET s)
{
send(s,(char*)myGame.playerData,sizeof(myGame.playerData), 0);
}
bool Play(char symbol, int pos){
// Ensure the position is free
if(board[pos]== ' '){
myGame.playerData = myGame.playerData & bits[pos];
cout << myGame.playerData << endl;
board[pos] = symbol;
CheckWin(symbol);
return true;
}
else return false;
}
void AIPlay(){
srand((unsigned)time(0));
int index;
do{
index = rand();
index = index % 9;
}
while(! Play('O', index));
myGame.aiData = myGame.aiData & bits[index];
}
};
int main(int argc, char* argv[]){
SOCKET clientSocket;
int port = 55555;
WSADATA wsaData;
int wsaerr;
WORD wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0){
printf("The Winsock dll not found!\n");
return 0;
}
else{
printf("The Winsock dll found!\n");
printf("The status: %s.\n", wsaData.szSystemStatus);
}
clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket== INVALID_SOCKET){
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else {
printf("socket() is OK!\n");
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(port);
if (connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR){
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
else {
printf("Client: connect() is OK.\n");
printf("Client: Can start sending and receiving data...\n");
}
int byteCount = SOCKET_ERROR;
char msg[50] = "Play noughts and crosses";
byteCount = send(clientSocket, msg, 50, 0);
if(byteCount == SOCKET_ERROR){
printf("Client: send() error %ld.\n", WSAGetLastError());
}
else{
printf("Client: sent %ld bytes \n", byteCount);
}
int bytesRecv, index;
int intbuffer = 0;
char buffer[sizeof(NoughtsAndCrosses)];
#if NONBITWISEGAME
NoughtsAndCrosses *tictactoe = new NoughtsAndCrosses();
#endif
#if BITWISEGAME
BitNoughtsAndCrosses *tictactoe = new BitNoughtsAndCrosses();
while(!(tictactoe->IsFinished())){
bytesRecv = recv(clientSocket, (char*)intbuffer ,sizeof(tictactoe->myGame.aiData), 0);
tictactoe->myGame.aiData = tictactoe->myGame.aiData & intbuffer;
cout << "Received: " << intbuffer << endl;
tictactoe->Play('O', intbuffer);
cout << "AI has completed its move\n";
#endif
#if NONBITWISEGAME
while(!(tictactoe->IsFinished())){
bytesRecv = recv(clientSocket, buffer, sizeof(NoughtsAndCrosses), 0);
memcpy(tictactoe, buffer, sizeof(NoughtsAndCrosses));
cout << "AI has completed its move\n";
#endif
tictactoe->Dump();
if (!(tictactoe->IsFinished()))
{
do{
cout << "Enter the index ";
cin >> index;
}
while(!tictactoe->Play('X',index));
tictactoe->Dump();
tictactoe->Send(clientSocket);
}
}
tictactoe->DisplayWinner();
WSACleanup();
system("PAUSE");
return 0;
}
Any help would be much appreciated
thanks all
Martin
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|