Multithreading/AI question (poss. O/T)
OK, I'm new to AI, so please be gentle. I am writing a chess program (not exactly chess, but perfect info nonetheless.) I am trying to get multithreading working, so my whole app doesn't go catatonic while it's thinking. I am programming with MFC (needed to support other features in the whole app) with Document/View architecture, using VC++6, running on an XP Home machine. I have class CCujo, which takes the current board state, and can figure everything else from there. It also has two member variables, char's which hold the numbers of the board spaces affected by the move (one is the location of the piece that needs to move, the other where it's headed.) After the minimax/alpha-beta search, these two contain the info for least worst move found. I am running into the problem of finding out when the thread has terminated, then extracting the move info from it. The last idea I gave up on was using a struct that includes three things: the "From" and "To" spaces and a bool that indicates the thread hasn't yet termed. I initialize all the members of that struct in my calling class, then pass a pointer to that struct as a member variable of CCujo (the "brain"). When CCujo exits the move-search function at the top level, it sets the bool bit to TRUE, to indicate that the function is finished, and so the thread is done. The calling class checks every half-second or so to see if this bool is set to TRUE. (The thinking here is that anything done to a variable's pointer by a function is done to the variable. This is probably where I'm going wrong.) The problem I am running into with this approach (which, quite frankly, is the best I've come up with) is if the search function is not finished by the first time the calling class checks that bool, the thread will eventually term, but that bool will never be set to TRUE, and the calling class just continuously checks, w/o ever getting the info it's going for, nor the command to stop looking. But wait, it gets weirder... When I do not execute the search as part of a new (worker) thread, it gives me moves that make sense. As a separate thread, however, through the use of TRACE macro, I am able to see the moves it's coming up with, and it's doing things it's not supposed to do. (Leaving a very important piece threatened and undefended, for example.) Perhaps the search gets cutoff early, or by accessing the struct with the calling class, I somehow block any further access by CCujo to that struct? (Just ideas, I'm sure they're wrong, built on complete conjecture as they are.) I'm sure there is something fundamental about multithreading, passing pointers to structs into classes used in threads, etc. that I'm not understanding. Could someone take just a couple of seconds and tell me what I'm missing, or if it's a little more complicated than that, at least nudge me in the right direction? Even a nicely-worded "blow it out an orifice" would do. Just an answer. (I am only too happy to post code. Just ask, and I'll figure out how to do it.) Thanks y'all, Scott
jatlh Huch, 'ach bom yuch!"Money talks, but chocolate sings!"
ngabwI,
testing threads is painfull. Testing minimax also. Testing minimax inside a thread can be a nightmare :). So, keep it simple, one problem at a time.
Create a thread that just stops for a couple of seconds and test your boolean synchronizing method. If it does not work check pointer/structure/class. If you cannot find the problem, try a global boolean variable. Everybody will tell you globals are bad programming practice. They are. But we are just testing, and it will not hurt you :-). When it works, go step by step to the pointer/structure again.
The minimax. Check for common data that you update in the main program while the thread uses it. If needed make a local copy using another set of boolean to stop the main process while making the local copy.
Just an idea: suspend the thread when done. Main can resume the thread and check return value. If it was not suspended ... it has not finished :). (I don't know any method of testing for thread status without resuming it).
Just curious: wich game are you working on?
Hope it helps.
[Edited by - DeepButi on January 19, 2005 3:47:05 AM]
testing threads is painfull. Testing minimax also. Testing minimax inside a thread can be a nightmare :). So, keep it simple, one problem at a time.
Create a thread that just stops for a couple of seconds and test your boolean synchronizing method. If it does not work check pointer/structure/class. If you cannot find the problem, try a global boolean variable. Everybody will tell you globals are bad programming practice. They are. But we are just testing, and it will not hurt you :-). When it works, go step by step to the pointer/structure again.
The minimax. Check for common data that you update in the main program while the thread uses it. If needed make a local copy using another set of boolean to stop the main process while making the local copy.
Just an idea: suspend the thread when done. Main can resume the thread and check return value. If it was not suspended ... it has not finished :). (I don't know any method of testing for thread status without resuming it).
Just curious: wich game are you working on?
Hope it helps.
[Edited by - DeepButi on January 19, 2005 3:47:05 AM]
_______________________The best conversation I had was over forty million years ago ... and that was with a coffee machine.
Thanks for the ideas. I'll give them a go (I'll need a couple of days), and report back here w/ the results. Would you mind terribly of I were to pick your brain again here re: this subject?
OK, if you promise not to laugh too loudly. :)
It's for a game called Klin Zha, created for the Klingons of Star Trek. (They're the ones who look like someone glued a horseshoe crab to their foreheads.) It was introduced in and played a large part in the plot of the book "The Final Reflection" by John M. Ford (Pocket Books, 1985). A more thorough description of its history and rules can be found at The Authorized Klin Zha Homepage.
I first played it about two years ago, and was immediately hopelessly addicted. Then I started playing it by email, and quickly realized the ASCII boards that were so favored by so many were a complete pain. So I started to use my limited knowledge of programming to make an electronic board, one that would record the moves for you and keep track of who's where. Two years later, I'm still working on it, constantly adding new features, and learning alot. Now I want to know about AI, and I am slowly going completely bonkers trying to learn it. :D
Did I mention I have a pathological need to ramble? :P
Sorry about that, I'll report back in a couple of days..
--ngabwI'
Quote:
Just curious: wich game are you working on?
OK, if you promise not to laugh too loudly. :)
It's for a game called Klin Zha, created for the Klingons of Star Trek. (They're the ones who look like someone glued a horseshoe crab to their foreheads.) It was introduced in and played a large part in the plot of the book "The Final Reflection" by John M. Ford (Pocket Books, 1985). A more thorough description of its history and rules can be found at The Authorized Klin Zha Homepage.
I first played it about two years ago, and was immediately hopelessly addicted. Then I started playing it by email, and quickly realized the ASCII boards that were so favored by so many were a complete pain. So I started to use my limited knowledge of programming to make an electronic board, one that would record the moves for you and keep track of who's where. Two years later, I'm still working on it, constantly adding new features, and learning alot. Now I want to know about AI, and I am slowly going completely bonkers trying to learn it. :D
Did I mention I have a pathological need to ramble? :P
Sorry about that, I'll report back in a couple of days..
--ngabwI'
jatlh Huch, 'ach bom yuch!"Money talks, but chocolate sings!"
Quote:
Original post by ngabwI
Would you mind terribly of I were to pick your brain again here re: this subject?
Not at all, glad to help although I don't promise anything :)
Quote:
OK, if you promise not to laugh too loudly. :)
I cannot see any reason to laugh. Being myself a table game pasionate, Klin Zha looks perfectly well. And yes, I remember Klingons ... I'm older than you probably think ;).
Wich kind of minimax are you using? I have some issues about getting PV so perhaps we could share. Send me a private message if you prefer.
_______________________The best conversation I had was over forty million years ago ... and that was with a coffee machine.
define a user message
const WM_BRAIN_DONE = WM_USER + 100;
at the end of your thread post the message.
::PostMessage( ( HWND )pParam, WM_BRAIN_DONE, 0, 0 );
pParam is the argument passed to your thread object, in my case a pointer to the View.
the MESSAGE_MAP ( in the View ) has a entry to process the message
ON_MESSAGE( WM_BRAIN_DONE, OnBrainDone )
OnBrainDone is a fuction that does something when the thread finishes.
const WM_BRAIN_DONE = WM_USER + 100;
at the end of your thread post the message.
::PostMessage( ( HWND )pParam, WM_BRAIN_DONE, 0, 0 );
pParam is the argument passed to your thread object, in my case a pointer to the View.
the MESSAGE_MAP ( in the View ) has a entry to process the message
ON_MESSAGE( WM_BRAIN_DONE, OnBrainDone )
OnBrainDone is a fuction that does something when the thread finishes.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement