C/C++ Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 



Go Back   Dev Articles Community ForumsProgrammingC/C++ Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old October 19th, 2006, 12:00 AM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Problem with Threads

I am trying to create a new thread to my program called NPCLoop, which will run separately from the main program in a continous loop making the NPCs in a game move around. I'm getting multiple compiler errors and I hope someone can help me with this code. I'm afraid I'm not quite so good at it. Here is my version of the stripped down code I'm testing out.

Its going to run on a Windows console program.

Code:

#include <iostream.h>
#include <stdio.h>
#include <windows.h>
#include <strsafe.h>
using namespace std;


class MySharedData
{
   bool  mainThreadFinished;
};

int main()
{
   // Create shared data
   MySharedData*  sharedData  = new MySharedData;

   // Create Thread
   DWORD  threadID;
   CreateThread(NULL,0,&NPCLoop,sharedData,0,&threadID);

   // Do User Stuff.
   GetUserInput();

   //  Tidy Up.
   // Can not delete shared data until we know the thread has finished using it.
   sharedData->mainThreadFinished = true;



   delete sharedData;

   return(0);
}

void* NPCLoop(void *data)
{
   MySharedData*  sharedData = reinterpret_cast<MySharedData*>(data);
   while(sharedData->mainThreadFinished)
   {
       cout << "meow";
   }
}


Here are the errors I'm getting.

Code:
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
threads.cpp:
Error E2187 c:\Borland\Bcc55\include\oleidl.h 2100: Unexpected end of file in co
nditional started on line 1994
Warning W8062 c:\Borland\Bcc55\include\oleidl.h 2100: Previous options and warni
ngs not restored
Error E2451 c:\Borland\Bcc55\include\oleidl.h 2098: Undefined symbol 'IRpcStubBu
ffer'
Error E2257 c:\Borland\Bcc55\include\servprov.h 90: , expected
Error E2238 c:\Borland\Bcc55\include\servprov.h 132: Multiple declaration for 'I
ServiceProvider'
Error E2344 c:\Borland\Bcc55\include\servprov.h 90: Earlier declaration of 'ISer
viceProvider'
Warning W8062 c:\Borland\Bcc55\include\urlmon.h 6737: Previous options and warni
ngs not restored
Warning W8062 c:\Borland\Bcc55\include\objbase.h 843: Previous options and warni
ngs not restored
Error E2187 c:\Borland\Bcc55\include\oleidl.h 2100: Unexpected end of file in co
nditional started on line 38

Reply With Quote
  #2  
Old October 19th, 2006, 02:45 PM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Well, hi! I found a few mistakes in your code! Don't worry though, "Thread Processing" is a tough part in C++(and in every language -- if you want my opinion). First, you didn't define your NPCLoop() function before main() -- probably you just forgot it . Also, the NPCLoop() function must be a "DWORD WINAPI" type, or else you need to convert it into a LPTHREAD_START_ROUTINE in the CreateThread() function(you'll how it's done in a minute). In addition, get rid of "stdio.h" and "strsafe.h" -- you don't need them.

Here's the code with your function being of void type:

Code:
#include <iostream>
#include <windows.h>
using namespace std;


class MySharedData
{
public:
	bool  mainThreadFinished;
};
void NPCLoop(void *data);

int main()
{
	char c;
   // Create shared data
   MySharedData*  sharedData  = new MySharedData;
   sharedData->mainThreadFinished = false;

   // Create Thread
   DWORD  threadID;
   CreateThread(NULL,0,LPTHREAD_START_ROUTINE(&NPCLoop),sharedData,0,&threadID); // see the conversion?

   // Do User Stuff.
   GetUserInput();

   //  Tidy Up.
   // Can not delete shared data until we know the thread has finished using it.
   sharedData->mainThreadFinished = true;



   delete sharedData;
   cin>>c; // to keep window open

   return(0);
}

void NPCLoop(void *data)
{
   MySharedData*  sharedData = reinterpret_cast<MySharedData*>(data);
   while(sharedData->mainThreadFinished == false)
   {
       cout << "meow";
   }
}


Here's the code with the function being of DWORD WINAPI type:

Code:
#include <iostream>
#include <windows.h>
using namespace std;


class MySharedData
{
public:
	bool  mainThreadFinished;
};
DWORD WINAPI NPCLoop(LPVOID lpParam);

int main()
{
	char c;
   // Create shared data
   MySharedData*  sharedData  = new MySharedData;
   sharedData->mainThreadFinished = false;

   // Create Thread
   DWORD  threadID;
   CreateThread(NULL,0,NPCLoop,sharedData,0,&threadID); // Do you see the difference?

   // Do User Stuff.
   GetUserInput();

   //  Tidy Up.
   // Can not delete shared data until we know the thread has finished using it.
   sharedData->mainThreadFinished = true;



   delete sharedData;
   cin>>c; // to keep window open

   return(0);
}

DWORD WINAPI NPCLoop(LPVOID lpParam)
{
   MySharedData*  sharedData = reinterpret_cast<MySharedData*>(lpParam);
   while(sharedData->mainThreadFinished == false)
   {
       cout << "meow";
   }
   return 0;  // must return a value
}


Hope I helped!!

Costas

Note: Search MSDN Library for more information!!! And KEEP PROGRAMMING !!!!

Reply With Quote
  #3  
Old October 19th, 2006, 11:54 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Saved my life, friend.

One or two questions left. Say I want to create a member of MySharedData in main()

Code:
MySharedData john;
john.test = 10;


Then in NPCLoop function

Code:
cout << sharedData->john.test;


This returns "there is no member john of MySharedData".

Do I have to pass this object to the NPCLoop as an argument? Or is there an easier way..Please tell me there is an easier way because then I'll have to pass 10+ arguments.

Reply With Quote
  #4  
Old October 20th, 2006, 08:35 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
The best way is to create a member of MySharedData outside and before the main() and then in main() just configure it!! Example:
Code:
// before main()
MySharedData john;
DWORD WINAPI NPCLoop(LPVOID lpParam); // Your function

// now in main()
john.test = 10;


Should work now!!

Costas

Reply With Quote
  #5  
Old October 20th, 2006, 05:02 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
I get the same error. Can't find the member of MySharedData. Is it possible that I have to create a "new" version in memory of each object?

I'm posting my full code now so we can figure this out.

Code:
class MySharedData
{
public:
int test;
	bool  mainThreadFinished;

};
	MySharedData john;
DWORD WINAPI NPCLoop(LPVOID lpParam);


int main()
{

	char c;

	john.test = 5;
   // Create shared data
   MySharedData*  sharedData  = new MySharedData;
   sharedData->mainThreadFinished = false;





   // Create Thread
   DWORD  threadID;
   CreateThread(NULL,0,NPCLoop,sharedData,0,&threadID); // Do you see the difference?

   // Do User Stuff.


   //  Tidy Up.
   // Can not delete shared data until we know the thread has finished using it.
   sharedData->mainThreadFinished = true;



   delete sharedData;
   cin>>c; /* Keeps the window open */

   return(0);
}

DWORD WINAPI NPCLoop(LPVOID lpParam)
{
   MySharedData*  sharedData = reinterpret_cast<MySharedData*>(lpParam);
 cout << sharedData->john.test;
   return 0;   /*must return a value*/
}

Reply With Quote
  #6  
Old October 20th, 2006, 06:27 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Nevermind, got it working. I didn't need the sharedData-> at all, just needed to access john.test directly.

Reply With Quote
  #7  
Old October 21st, 2006, 06:37 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Oh!! Glad you found it!

Reply With Quote
  #8  
Old October 21st, 2006, 05:56 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
While I'm on about the game here..

Anyone have any suggestions on the following:

I'm going to have 10 rooms in the game, obviously each room connected to different rooms. For instance room 9 has exits to rooms 8 and 10. The way I am thinking of making the NPCs move around is thusly:

sharedData->room will set the NPC's current room.

When the code decides it is time for them to move, it will see what room they are in (sharedData->room) and then look for that room in an array of pointers.

I will then enter the number of the room into the array and it will give me a pointer to another array that holds that current room's exits. I will randomshuffle() that array to come up with which room to go into.

Needless to say this is going to suck. Can anyone think of an easier way? All it needs to do is be able to find which exits each room has and shuffle them.

Reply With Quote
  #9  
Old October 23rd, 2006, 02:49 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Well, one that came up now is to make a class named "room" that will control the rooms. It can have an array of objects to store the objects you want to have in this room. Also, it can have an array of NPCs to store the NPCs that are in the room. Finally, it can have an array with the name of the rooms that has the exits (e.g. "room_9", "room_6"). That way you can then get the two exits and suffle them to see where the NPC will go!


Note: This is something that came up when I read your post. I'll read your post again more carefully and tell you again.


Hope I helped!

Costas

Reply With Quote
  #10  
Old October 23rd, 2006, 03:39 AM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Ehee ironically I came up with all those ideas last night and coded em. But I was struggling with how to get the NPCs appear in the room, and your NPC array is a good idea.

Yeah what I did was create a class of rooms and a rooms table[MAX_ROOMS] for that class. Then I did some ifstream stuff and wrote a text file that I named main.are. The first word in the text file is the name of the room, then a space, then the # of the north exit from that room..etc..So my program reads those from a file and creates the rooms table[MAX_ROOMS] data.

I've gotten character movement working, as well as the "look" command which gets you the exits, the name of the exits and the directions of the exits. Now Im working on making a re-useable function for each of the NPCs to make them move.

Reply With Quote
  #11  
Old October 23rd, 2006, 05:17 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Good!! Could you post the code for the movement because I'm making a game with Threads and NPCs, too(that's why I new about thread processing) and I can't find a way to do that!

Costas

Reply With Quote
  #12  
Old October 23rd, 2006, 08:13 AM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Aye, sure. This is my full second thread plus another function.
Its not quite done, as Im working on how to do it for each and every NPC, but its goin quite well so far.

Let us assume we are doing this right now for npc #1, which is obviously npc[0]. I have a class npcs and then created

npcs npc[MAX_NPCS]; As a table for all their data. Say we want NPC #1 to move around.

Code:

DWORD WINAPI NPCLoop(LPVOID lpParam)
{
MySharedData*  sharedData = reinterpret_cast<MySharedData*>(lpParam);

   while (1)
   {
      
  srand((unsigned)time(0));
    int random;

        random = (rand()%20)+1;

 wait(random);

Here we have just a basic rand number that gets passed to my wait function which simply is a timer. It more or less randomizes the NPC movements. Say if it was 10 it would wait 10 seconds then move the NPC.

Code:

 int exitarray[4];
 int qq=0;
 for (int i=0; i < MAX_EXITS ; i++)
 {
     if ( table[(npc[0].room)-1].exits[i] == 0)
     {
         continue;
     }
     exitarray[qq]=table[(npc[0].room)-1].exits[i];
     ++qq;
 }


Here it gets fairly complicated. I create an exitarray to hold all the exits for the current room. Now MAX_EXITS is a constant which has a value of 4.

table is my rooms class, and table[x].exits[0] points to the north exit, exits[1] to the south, etc. So we do table[npc's current room].exits and save them in the exit array. If exits[i] is zero there is no exit so it skips it.

Code:
 random_shuffle(exitarray,exitarray+qq);
 npc[0].room = exitarray[0];

 if ( ch->room == npc[0].room )
 {
     cout << npc[0].name << " comes hopping along.\n";
 }

   }
   return 0;   
}


This is a bit of genious though I do say so myself. Ok so we got the current exits for the NPC's room but he needs to pick a random direction to go off in..Use random_shuffle to shuffle all the numbers in the exitarray, and then simply set the NPC's current room (the room he has now moved into) to the first element of the exitarray. Also we alert the character if he is in the same room that the npc has arrived.

Code:
void wait ( int seconds )
{
  clock_t endwait;
  endwait = clock () + seconds * CLK_TCK ;
  while (clock() < endwait) {}
}


Thats my wait function.

Right now Im working on making all the above movement code into a function so I can pass a random NPC to it and move that one around. Shouldn't be too difficult. Really all I need is a void function void npcmove (int npcnumber) :P and thats it.

BTW the reason there are so many -1s everywhere is because Room 1 for instance is actually room 0 of course, because table[] starts at 0.

Reply With Quote
  #13  
Old October 23rd, 2006, 08:24 AM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
I have also figured out a way to make the room and npc creation and storage of data much easier, as well as letting the user change them if he wants. It allows me also to change things without coding and recompiling. I believe it was you who posted answering the guy about how to read stuff from a file a few days ago, and that inspired me to create this system.

I have two files, main.are which has all the room data and main.npc which has all the NPC data.

Code:
/* Program reads the main area file to load the rooms table. */

    char next;
int q = 0;
    ifstream areafile;
	areafile.open("main.are");
	while(!areafile.eof())
	{
		areafile >> table[q].name;   /*Get the name of the room*/

		for (int i = 0; i < MAX_EXITS; i++)
		{
		    /* Reads the next number and stops at a space. Does this until the
		    number of max exits have been reached. */
		areafile>>table[q].exits[i];

		}

areafile.get(next);   /* Move to next position in the file*/
		q++;
	}


Here's the second line from my main.are file:
Hall 1 0 0 4

So automatically the program knows that is the 2nd room (2nd line), named Hall with a north exit to room 1 and a west exit to room 4.

And here is my NPC code.

Code:
q = 0;
    ifstream npcfile;
	npcfile.open("main.npc");
	while(!npcfile.eof())
	{
		npcfile >> npc[q].name;   /*Get the name of the npc*/
		

		for (int i = 0; i < MAX_NPCSTAT; i++)
		{
		    /* Reads the next number and stops at a space. Does this until the
		    number of max stats have been reached. */
		npcfile>>npc[q].stats[i];
		

		}
getline(npcfile,npc[q].motto); /* Get the NPC's motto */

npcfile.get(next);   /* Move to next position in the file*/
		q++;
	}


I even made it get a full string, the NPC's "motto" as it were.

Here's the first line from my main.npc file.

Weiner 30 5 25 60 50 20 10 0 19 As long as you're happy...

Each number corresponds to one of the NPC's attributes that I will use later in the programming. It reads em all and works perfectly

I think this is a big improvement on the way I was going to do it, now the game is not only simpler to finish the players can add their own NPCs or rooms if they so choose.

Reply With Quote
  #14  
Old October 23rd, 2006, 01:28 PM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
To add more realism, you can add npc states! You know like work, eat, sleep e.t.c. Also, the problem is to make a statemachine that switches between their states! e.g. when one NPC's fatigue is over 7 , quit everything he's doing and go to his house and have a nap. I've programmed that with the aid of a book! Well, as it is clear, when the NPC changes state, he also changes location, but I don't won't him to change its location immediately but you know make him moving with some speed and based on the distance make some time to reach its destination!! I'm reading a book on steering behaviors but it has too many information and I think I have to grow older in programming(and in real ages - I'm 15) to understand it. Any ideas?? (if you want the code for the states and statemachine I mentioned -- I can give it to you)!!

Costas

Reply With Quote
  #15  
Old October 23rd, 2006, 01:29 PM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Also, I got a little with your code!! Could you post it as it is in your file(I mean the whole files)???

Reply With Quote
  #16  
Old October 24th, 2006, 03:31 AM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Its 500 lines of code, but if you want it, you got it Not quite finished but this is how it is at the current moment. There is old stuff that Im not going to use just lying around, like I said its not even close to complete.I havent finished the NPC movement in the thread, so at the moment that is just a testing area.



Code:
/* The Cedar 211 Game.  Copyright 2006
Chase Morrison, morriso_chas@bentley.edu */

#include <iostream>
#include <cctype>
#include <string>
#include <sstream>
#include <windows.h>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;


/* Definitions */
#define MAX_EXITS 4 /* max exits per room */
#define MAX_ROOMS 100 /* So I can change it later, perhaps when reading from a file. */
#define MAX_NPC 10 /* Max amount of NPCs */
#define MAX_NPCSTAT 9 /* Max amount of stats the NPC has */


class MySharedData
{
public:
int test;
	bool  mainThreadFinished;
	

};


class characters
{
    public:
    string name;
    int laziness;
    int wigger;
    int liverage;
    int intelligence;
    int sketch;
    int age;
    int pissed; /* How pissed each char is based on previous actions */
    int brain; /* how drug-fried each char's brain is. */
    int puke; /* How likely a character is to puke */
    int room; /* The current room # they are in */
    int hit; /*char's hitpoints - for fights */
    string motto;
};

class npcs
{
    public:
    string name;
  int stats[MAX_NPCSTAT]; /* NPC Stat array */
    string motto;

    int randomnpcaction()
    {
        /* Do a rand and make the npc do one of say 10 different actions */
        return 0;
    }

    void npcrespondaction(int chaction)
    {
        /* Say if Raynor turns on the music really gayly and an npc's pissed
        rating is high, he might kick raynor's ass. */
    }

    void npcmove()
    {
      /* NPCs move into different rooms and hallways randomly. Needs to be part
      of a separate thread */
    }

};

npcs npc[MAX_NPC];

class rooms
{

    public:
    string name;
    int exits[MAX_EXITS];
};


rooms table[MAX_ROOMS]; /* Create an array of rooms */



void dofun (string function,string arg,characters* ch);
void stringlower(string &strToConvert);
void music (string music,characters* ch);
void time ();
void chgetexits(characters* ch); /* Defining exits for a room. */
npcs *npcp; /* Pointer to NPC objects */
characters* ch;
DWORD WINAPI NPCLoop(LPVOID lpParam);
void wait(int seconds);
void test (characters* now);
char* direction[] = {"north", "south", "east","west"};








int main()
{

/* Program reads the main area file to load the rooms table. */

    char next; /* Just to skip the \n */
int q = 0;
    ifstream areafile;
	areafile.open("main.are");
	while(!areafile.eof())
	{
		areafile >> table[q].name;   /*Get the name of the room*/

		for (int i = 0; i < MAX_EXITS; i++)
		{
		    /* Reads the next number and stops at a space. Does this until the
		    number of max exits have been reached. */
		areafile>>table[q].exits[i];

		}

areafile.get(next);   /* Move to next position in the file*/
		q++;
	}

	/* Program reads the main npc file and loads the npc table */


q = 0;
    ifstream npcfile;
	npcfile.open("main.npc");
	while(!npcfile.eof())
	{
		npcfile >> npc[q].name;   /*Get the name of the npc*/
		cout << npc[q].name;

		for (int i = 0; i < MAX_NPCSTAT; i++)
		{
		    /* Reads the next number and stops at a space. Does this until the
		    number of max stats have been reached. */
		npcfile>>npc[q].stats[i];
		cout << npc[q].stats[i] << " ";

		}
getline(npcfile,npc[q].motto); /* Get the NPC's motto */
cout << npc[q].motto;
npcfile.get(next);   /* Move to next position in the file*/
		q++;
	}


/* Define objects */

characters raynor;
characters chase;
npcs jacque;
npcs manit;
npcs weiner;
npcs cole;

/* Define all the names and attributes for each character */

raynor.name = "JRay";
raynor.laziness = 10;
raynor.wigger = 100;
raynor.liverage = 47;
raynor.intelligence = 50;
raynor.sketch = 70;
raynor.puke = 5;
raynor.pissed = 0;
raynor.brain = 5;
raynor.age = 19;
raynor.room = 5;
raynor.motto = "blah";

chase.name = "Chase";
chase.laziness = 100;
chase.wigger = 0;
chase.liverage = 22;
chase.intelligence = 100;
chase.sketch = 30;
chase.puke = 10;
chase.pissed = 30;
chase.brain = 90;
chase.age = 20;
chase.motto = "I don't care anymore.";



string character;
int choosecharacter = 0;
string command;

char c;




if (choosecharacter == 0)
{
cout << "Choose your character.\n";
cin >> character;
cin.get(); /* Need this to get rid of the \n left over by the cin >> operator.
If not, it will skip the getline function later in the program. */
choosecharacter++;
stringlower(character); /* Make the string lowercase*/

if ( character == "raynor" )
{
    cout << "Raynor";
 ch = &raynor;

    /* If they choose Raynor as a char, set the ch pointer to raynor object */
}

if ( character == "chase" )
{
ch = &chase;

}
ch->room = 1;
}


// Create shared data
   MySharedData*  sharedData  = new MySharedData;
   sharedData->mainThreadFinished = false;
sharedData->weinerroom = 4;
// Create Thread
   DWORD  threadID;
   CreateThread(NULL,0,NPCLoop,sharedData,0,&threadID);

for (;command != "quit";)
{



/* Main interpretation of user input. For instance if user types in:
buy apple
We get that with getline and convert it to into a stringstream. The stream
will automatically separate the two words and we can grab them and stick them
in two separate strings - command and arg. Now we know what the user wants to
do. */


string arg;

std::string  input;
cout << "\n\n>>";
std::getline(std::cin,input);

std::stringstream  stream(input);


 int i=0;

while(stream)
{
   string value;
   stream >> value;
   stringlower(value); /* Convert input to lowercase */

   if (i==0)
   {
       command = value;
       if (command == "quit")
       {
           break;
       }
       }

       if (i==1)
       {
           arg = value;
           }
   i++;
}

cout << command << "\n";
cout << arg;

dofun(command, arg,ch);

} /* End main loop. */

 //  Tidy Up.
   // Can not delete shared data until we know the thread has finished using it.
   sharedData->mainThreadFinished = true;



   delete sharedData;
   cin>>c; /* Keeps the window open */

   return 0;
}

/* Command Table. If the user's input matches a function, do the function.*/

void dofun (string function,string arg,characters* ch)
{

    string testfunction = "testfunction";
if ( function == testfunction)
{


    ch->wigger = 95;
    return;

}
if ( function == "time")
{
    time();
    return;
}

/* The movement. It sets the char's room to the north exit of his current room. */
if ( function == "north")
{
    cout << "You move north.\n";
    ch->room = table[(ch->room)-1].exits[0];
return;
}

if ( function == "south")
{
     cout << "You move south.\n";
    ch->room = table[(ch->room)-1].exits[1];


return;
}

if ( function == "east")
{
     cout << "You move east.\n";
    ch->room = table[(ch->room)-1].exits[2];


return;
}

if ( function == "west")
{
     cout << "You move west.\n";
    ch->room = table[(ch->room)-1].exits[3];


return;
}

if ( function == "look")
{
chgetexits(ch);
return;
}
/* Pass a pointer to the character object to the functions. */

if ( function == "music")
{
    if ( arg  == "\0")
    {
        cout << "You have to enter a type of music.\n";
        return;
    }
music(arg,ch);
return;
}
if ( function == "quit")
{
    return;
}
else
{
    cout << "\nInvalid Command";
    return;

}
}



void stringlower(string &strToConvert)
{//change each element of the string to lower case
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = tolower(strToConvert[i]);
   }

}

void music (string music,characters* ch)
{
if ( music == "rap" )
{
    if ( ch->wigger < 95 )
    {
ch->wigger += 5;
cout << ch->wigger;

    }
    cout << "\nYou horrible beast.";
}
}

void time ()
{
    cout << "\nThe time is:";
}

DWORD WINAPI NPCLoop(LPVOID lpParam)
{
MySharedData*  sharedData = reinterpret_cast<MySharedData*>(lpParam);

   while (1)
   {
      
  srand((unsigned)time(0));
    int random;

        random = (rand()%20)+1;

 wait(random);

 int exitarray[4];
 int qq=0;
 for (int i=0; i < MAX_EXITS ; i++)
 {
     if ( table[(sharedData->weinerroom)-1].exits[i] == 0)
     {
         continue;
     }
     exitarray[qq]=table[(sharedData->weinerroom)-1].exits[i];
     ++qq;
 }
 random_shuffle(exitarray,exitarray+qq);
 sharedData->weinerroom = exitarray[0];
 cout << "Weiner goes to room " << sharedData->weinerroom;
 if ( ch->room == sharedData->weinerroom )
 {
     cout << "Weiner comes hopping along.\n";
 }

   }
   return 0;   /*must return a value*/
}

void wait ( int seconds )
{
  clock_t endwait;
  endwait = clock () + seconds * CLK_TCK ;
  while (clock() < endwait) {}
}

void test (characters* now)
{
    cout << now->wigger;
    return;
}



void chgetexits (characters* ch)
{
    cout << "Exits\n";
cout << table[(ch->room)-1].name << "\n";
for (int i=0;i < MAX_EXITS; i++)
{

    if ( table[(ch->room)-1].exits[i] == 0 )
    {
        continue;
    }
cout << direction[i] << ": ";
cout << table[(table[(ch->room)-1].exits[i])-1].name << " ";

}
}

void npcgetexits (npcs * npc)
{
    int currentexits[MAX_EXITS];
for (int i=0, z=0;i < MAX_EXITS; i++)
{
if ( table[npc->room].exits[i] == 0 )
    {
        continue;
    }

currentexits[z] = table[npc->room].exits[i];
z++;
}

}

Reply With Quote
  #17  
Old October 25th, 2006, 10:05 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Gee, Thanks!!!

Reply With Quote
  #18  
Old October 27th, 2006, 05:10 PM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Hey feldmarschall,
Really nice work!! Only two comments and one question(not really about your code).
Comments: 1) try putting each class in different header files (e.g. rooms.h) and include them in your main.cpp(it's a lot easier to read and correct)! 2) try making the file IO part a function(or two), you know "read_room_data()" , "read_npc_data()". Question: Well, I want to include a file "locations.h", that has some objects of class location, in multiple files, but the compiler gives me link errors("class fields(name of object) has been already defined in main.obj" -- something like that)! Any ideas????


Costas

Reply With Quote
  #19  
Old October 27th, 2006, 05:46 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Yeah that would probably be best. I haven't even considered streamlining the program yet, its not even half complete

I dunno, are you defining the object twice?

Reply With Quote
  #20  
Old October 28th, 2006, 06:30 AM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
In a way yes, but I don't want that. How can I include it without defining the object twice???

Reply With Quote
  #21  
Old October 28th, 2006, 01:21 PM
feldmarschall feldmarschall is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2006
Posts: 24 feldmarschall User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 h 35 m 30 sec
Reputation Power: 0
Quote:
Originally Posted by costas
In a way yes, but I don't want that. How can I include it without defining the object twice???


Well I took your advice and made a class.h with all my class information and #defines..But I dont define the object, say

Code:
characters char1;


Until main.cpp. I dunno though, maybe you should post the full error or some of the code and we can take a look.

Reply With Quote
  #22  
Old October 28th, 2006, 01:51 PM
costas costas is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2006
Posts: 407 costas User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 3 Days 3 h 25 m 24 sec
Reputation Power: 12
Never mind, I found it! Not excactly!! I put the code of the class in main and consulte with it from there!!

Reply With Quote
Reply

Viewing: Dev Articles Community ForumsProgrammingC/C++ Help > Problem with Threads


Developer Shed Advertisers and Affiliates


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap