Help needed with Noughts and Crosses game

Ask for help with your homework/assignments in this forum!

Moderators: Darobat, RecursiveS, Dante Shamest, Bugdude, Wizard

Help needed with Noughts and Crosses game

Postby martinw30 » Wed Apr 25, 2012 3:09 am

Hi all,

For an assignment Ive created a noughts and crosses game which I was using a Server and client with winsock to transmit the objects containing the new moves.

For the last part our tutor wants us to use bitwise operators to compress the data using a GameData struct that holds two integers, send this information over and the uncompress it.

I cant figure this part out, Ive had a stab at it and Ive uploaded the two cpp files

Can someone nudge me in the right direction please?

Martin
Attachments
ServerBase.cpp
the Server Code
(7.71 KiB) Downloaded 65 times
ClientBase.cpp
the Client Code
(6.64 KiB) Downloaded 47 times
martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby martinw30 » Wed Apr 25, 2012 7:50 am

rather than having to download the code here it is posted correctly:

Server Code:
Code: Select all
#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;
   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:
Code: Select all
#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;
}


martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby Wizard » Thu Apr 26, 2012 8:57 am

Your board is 9 chars. Each space can have 3 possibilities: empty, X, or O. You simply need to compress your chars to bits and pack them into integers. To handle 3 options, you need 2 bits (2 bits actually gives you 4 options, so one is wasted but not much you can do). A complete board can therefore be stored in 18 bits. Assuming a 16 bit integer, you'd need two of them
Something like this:
Code: Select all
int toSend[2];
for (int i = 0; i < 9; ++i)
{
    if (i < 8)
    {
        toSend[0] <<= 2;
        switch (board[i])
        {
            case ' ': toSend[0] &= 0; break; // empty space
            case 'X': toSend[0] &= 1; break; // Cross
            case 'O': toSend[0] &= 2; break; // Naught
        }
    } else
    {
        toSend[1] <<= 2;
        switch (board[i])
        {
            case ' ': toSend[1] &= 0; break; // empty space
            case 'X': toSend[1] &= 1; break; // Cross
            case 'O': toSend[1] &= 2; break; // Naught
        }
    }
}

And now you have two integers which you can send with the complete board which you can unpack later. Does that make sense?
User avatar
Wizard
Site Admin
 
Posts: 3226
Joined: Mon Sep 22, 2003 4:52 pm
Location: ON, CA

Re: Help needed with Noughts and Crosses game

Postby martinw30 » Thu Apr 26, 2012 11:45 am

Wow Wizard,

Thanks for your help and reply.

So to assign those compressed bits to the integers within my GameData structure is it as simple as:

playerData = intToSend[0];

Also I need to use the code you gave me within my derived BitNoughtsAndCrosses class within a function, do I pass in the playerData and aiData ints to the new function?

Regards

Martin
martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby Wizard » Fri Apr 27, 2012 7:35 am

You need to do whatever makes the most sense. I haven't fully read your code so I'm not sure where this would go, but probably right before you send it would be a good place. Then, instead of sending the entire object, you send just these two integers. At the other end, you unpack them into a local object the opposite way.
User avatar
Wizard
Site Admin
 
Posts: 3226
Joined: Mon Sep 22, 2003 4:52 pm
Location: ON, CA

Re: Help needed with Noughts and Crosses game

Postby martinw30 » Sun Apr 29, 2012 1:15 pm

Hi Wizard,

Ive persisted with this code and with your help and Im getting no where. Ive slightly modified what you sent me as an option. Now I cant make heads or tales of it :oops:
Code: Select all
#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:
   NoughtsAndCrosses(){
      for(int n=0;n<9;n++){
         board[n] = ' ';
      }
      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;
   void compress(){
      //int toSend[2];
      for (int i = 0; i < 9; ++i)
      {
         if (i < 8)
         {
            myGame.aiData <<= 2;
            switch (board[i])
            {
               case ' ': myGame.aiData &= 0; break; // empty space
               case 'X': myGame.aiData &= 1; break; // Cross
               case 'O': myGame.aiData &= 2; break; // Naught
            }
         } else
         {
            //toSend[1] <<= 2;
            myGame.playerData <<= 2;
            switch (board[i])
            {
               case ' ': myGame.playerData &= 0; break; // empty space
               case 'X': myGame.playerData &= 1; break; // Cross
               case 'O': myGame.playerData &= 2; break; // Naught
            }
         }
      }
   }
   void Send(SOCKET s){
      send(s, (char*)myGame.aiData, sizeof(BitNoughtsAndCrosses), 0);
   }
   void unCompress(){

   }
};


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

   SOCKADDR_STORAGE from;
   int fromlen, retval, socket_type, bytesRecv;
   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)];   
   NoughtsAndCrosses *tictactoe = new NoughtsAndCrosses();
   BitNoughtsAndCrosses *theGame = new BitNoughtsAndCrosses();
   // while game is not finished
   while(!(tictactoe->IsFinished())){
      tictactoe->AIPlay();
      tictactoe->Dump();
      //tictactoe->Send(acceptSocket);
      theGame->Send(acceptSocket);
      // if game not finished
      if(!(tictactoe->IsFinished()))
      {
         bytesRecv = recv(acceptSocket, buffer, sizeof(NoughtsAndCrosses), 0);
         memcpy(tictactoe, buffer, sizeof(NoughtsAndCrosses));
         tictactoe->Dump();
      }
   }
   tictactoe->DisplayWinner();
   system("PAUSE");
   WSACleanup();
   return 0;
}


As you can see I have to pack the bits into the gamedata integers with the struct, not sure if im doing it right

regards

Martin
martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby Wizard » Mon Apr 30, 2012 9:24 am

aiData is an integer. You are casting it to a char pointer. That won't work. Try this instead:
Code: Select all
send(s, (char*)(&myGame.aiData), sizeof(myGame.aiData), 0);

You need to cast the address of aiData to the pointer in order to send it. Also the number of characters you're sending is sizeof(aiData), you are still trying to measure the size of the entire object so it is probably getting confused.
I am also not sure you understand the purpose of why I gave two integers. You've labeled them "aiData" and "playerData" but that's not what they are at all: they're the first 8 squares of the tic-tac-toe board, and the last square of the tic-tac-toe board.
User avatar
Wizard
Site Admin
 
Posts: 3226
Joined: Mon Sep 22, 2003 4:52 pm
Location: ON, CA

Re: Help needed with Noughts and Crosses game

Postby martinw30 » Mon Apr 30, 2012 1:23 pm

Hi Wizard,

I think your right I dont understand as my task is to pack the compressed bits into the two integers contained within my GameData Struct:

Struct GameData
{
int playerData, aiData;
}

Arrgghhh!! Usually Im quite confident with c++ but this task is baffling me

regards

Martin
martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby Wizard » Wed May 02, 2012 12:24 pm

Your probably better off approaching the teacher to get a better understanding of what needs to be done. I'm probably giving advice poorly and that is a setup for disaster.
User avatar
Wizard
Site Admin
 
Posts: 3226
Joined: Mon Sep 22, 2003 4:52 pm
Location: ON, CA

Re: Help needed with Noughts and Crosses game

Postby martinw30 » Sat May 05, 2012 7:49 am

Ok so this is what is needed from this assignment:

1. Implement the send() member function that is declared within the NoughtsAndCrosses class. This function should transmit the whole NoughtsAndCrosses object to the opponent (20%)
2. Add appropriate code to the main() function to allow the game to be played over the network (some of this has been done for you). After each turn the Dump member function should be invoked in order to display the current games state. (30%)
3. Derive a new class named BitNoughtsAndCrosses that transmits the current state of the board, using the individual bits within the two integer variables declared within the GameData structure. Embed pre-processor directives within both client and server projects to separate the code that implements the game using the BitNoughtsAndCrosses, from that of the solution to task 2. (50%)

Tasks 1 and 2 were completed in 30 minutes, its the last one thats giving me hassle. The pre-processor directives are simple to implement, its understanding the packing, sending and unpacking of the integers and then somehow getting that info onto the board.

Here is my up to date code:
Server:
Code: Select all
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <ctime>
#include <math.h>
#include <vector>

using namespace std;

#define BITWISEGAME 1

// Noughts and Crosses (Tic Tac 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:
   NoughtsAndCrosses()
   {
      for(int n=0;n<9;n++){
         board[n] = ' ';
      }
      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;
   // Create my BITS array
   int bits[9];
   BitNoughtsAndCrosses()
   {
      myGame.aiData = 0;
      myGame.playerData = 0;
      // initialise my BITS array
      int myBits = 1;
      for (int i = 0; i < 9; i++)
      {
         if (i == 0) bits[i] = myBits;
         else bits[i] = myBits << 1 * i;
      }
   }
   // Pack my data
   void compress()
   {
      // Check each element of the board then compresses the data
      for (int i = 0; i < 9; i++)
      {
         switch (board[i])
         {
            case ' ': myGame.aiData |= 0; myGame.playerData |= 0;break;
            case 'X': myGame.aiData |= (bits[i] << 8); myGame.playerData |= (bits[i] << 8);break;
            case 'O': myGame.aiData |= (bits[i+1] << 7); myGame.playerData |= (bits[i+1] << 7);break;
         }
      }
      //cout << myGame.aiData << endl;
      //cout << myGame.playerData << endl;
   }

   void Send(SOCKET s)
   {
      // create an array that can hold the object
      char sendStruct[sizeof(GameData)];
      // Copy the object into an array
      memcpy(sendStruct, (void*)(&myGame), sizeof(GameData));
      // Invoke send
      send(s, sendStruct , sizeof(GameData), 0);
   }

   void unCompress()
   {
      // Check each element of the board
      for (int i = 0; i < 9; i++)
      {
         switch (board[i])
         {
            case ' ': myGame.aiData &= 0; myGame.playerData &= 0;break;
            case 'X': myGame.aiData &= (bits[i] >> 8); myGame.playerData &= (bits[i] >> 8);break;
            case 'O': myGame.aiData &= (bits[i] >> 7); myGame.playerData &= (bits[i] >> 7);break;
         }
      }
   }
};


int main(int argc, char* argv[])
{
   SOCKADDR_STORAGE from;
   int fromlen, retval, socket_type, bytesRecv;
   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)];
   char bitBuffer[sizeof(GameData)];

   NoughtsAndCrosses *tictactoe = new NoughtsAndCrosses();
   BitNoughtsAndCrosses *theGame = new BitNoughtsAndCrosses();
   // while game is not finished
   while(!(tictactoe->IsFinished())){
      tictactoe->AIPlay();
      tictactoe->Dump();
      //theGame->compress();
      tictactoe->Send(acceptSocket);
      //theGame->Send(acceptSocket);
      // if game not finished
      if(!(tictactoe->IsFinished()))
      {
         //theGame->unCompress();
         bytesRecv = recv(acceptSocket, buffer, sizeof(NoughtsAndCrosses), 0);
         //bytesRecv = recv(acceptSocket, bitBuffer, sizeof(GameData), 0);
         memcpy(tictactoe, buffer, sizeof(NoughtsAndCrosses));
         //memcpy(theGame, bitBuffer, sizeof(GameData));
         tictactoe->Dump();
      }
   }
   tictactoe->DisplayWinner();
   system("PAUSE");
   WSACleanup();
   return 0;
}

Client:
Code: Select all

#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include <ctime>
#include <math.h>

using namespace std;

// 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:
   NoughtsAndCrosses(){
      for(int n=0;n<9;n++)
         board[n] = ' ';
      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 a character array that is large enough to hold the object
      char sendObject[sizeof(NoughtsAndCrosses)];
      // Copy the object into the character array
      memcpy(sendObject, this, sizeof(NoughtsAndCrosses));
      // Invoke send
      send(s,sendObject, sizeof(NoughtsAndCrosses),0);
   }
};
// Contains game data to be transmitted
struct GameData
{
   int playerData,aiData;
};

class BitNoughtsAndCrosses : public NoughtsAndCrosses{
public:
   // Create an object to access the struct
   GameData myGame;
   // Setup bit constants
   int bits[9];
   BitNoughtsAndCrosses()
   {
      // Give each integer a 0 bit value
      myGame.aiData = 0;
      myGame.playerData = 0;
      // initialise my BITS array
      int myBits = 1;
      for (int i = 0; i < 9; i++)
      {
         if (i == 0) bits[i] = myBits;
         else bits[i] = myBits << 1 * i;
      }
   }

   void compress()
   {
      // Check each element of the board
      for (int i = 0; i < 9; i++)
      {
         switch (board[i])
         {
            case ' ': myGame.aiData |= 0; myGame.playerData |= 0;break;
            case 'X': myGame.aiData |= (bits[i] << 8); myGame.playerData |= (bits[i] << 8);break;
            case 'O': myGame.aiData |= (bits[i+1] << 7); myGame.playerData |= (bits[i+1] << 7);break;
         }
      }
      //cout << myGame.aiData << endl;
      //cout << myGame.playerData << endl;
   };

   void Send(SOCKET s)
   {
      // create an array that can hold the object
      char sendStruct[sizeof(GameData)];
      // Copy the object into an array
      memcpy(sendStruct, (void*)(&myGame), sizeof(GameData));
      // Invoke send
      send(s, sendStruct , sizeof(GameData), 0);
   }
   void unCompress()
   {
      // Check each element of the board
      for (int i = 0; i < 9; i++)
      {
         switch (board[i])
         {
            case ' ': myGame.aiData &= 0; myGame.playerData &= 0;break;
            case 'X': myGame.aiData &= (bits[i] >> 8); myGame.playerData &= (bits[i] >> 8);break;
            case 'O': myGame.aiData &= (bits[i] >> 7); myGame.playerData &= (bits[i] >> 7);break;
         }
      }
   }
};

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;
   char buffer[sizeof(NoughtsAndCrosses)];
   char bitBuffer[sizeof(GameData)];

   NoughtsAndCrosses *tictactoe = new NoughtsAndCrosses();
   BitNoughtsAndCrosses *theGame = new BitNoughtsAndCrosses();
   // while game is not finished
   while(!(tictactoe->IsFinished())){
      // receive the bits
      // bytesRecv = recv(clientSocket, bitBuffer, sizeof(GameData), 0);
      // theGame->unCompress();
      bytesRecv = recv(clientSocket, buffer,sizeof(NoughtsAndCrosses), 0);
      memcpy(tictactoe, buffer, sizeof(NoughtsAndCrosses));
      //memcpy(theGame, bitBuffer, sizeof(GameData));
      cout << "AI has completed its move\n";
      tictactoe->Dump();
      if (!(tictactoe->IsFinished()))
      {
         do{
            cout << "Enter the index ";
            cin >> index;
         }
         while(!tictactoe->Play('X',index));
         tictactoe->Dump();
         tictactoe->Send(clientSocket);
         // theGame->Send(clientSocket);
      }
   }
   tictactoe->DisplayWinner();
   system("pause");
    WSACleanup();
    return 0;
}


Again another nudge would be greatly appreciated

many thanks

Martin
martinw30
 
Posts: 6
Joined: Wed Apr 25, 2012 3:04 am

Re: Help needed with Noughts and Crosses game

Postby Wizard » Mon May 07, 2012 7:57 am

You are currently sending the entire game object. You don't need to send the entire object, you just need to send the board. Your board is currently an array of 9 characters. Try doing this in simpler steps:
First, instead of sending the entire object, send just that array, 9 bytes, and copy it into the local object at the other end.
Once you are successfully able to send just those 9 bytes (as opposed to the entire object) you can figure out how to compress 9 bytes into 2 integers. The code I posted before is a very naive way of compressing the 9 bytes into 2 integers and could even be improved, but it'll get what needs to be done.
User avatar
Wizard
Site Admin
 
Posts: 3226
Joined: Mon Sep 22, 2003 4:52 pm
Location: ON, CA


Return to Homeworks

Who is online

Users browsing this forum: No registered users and 1 guest