Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (600)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Need some threading advice...  (Read 2360 times)
0 Members and 1 Guest are viewing this topic.
Offline Patdumpsite

Senior Newbie





« Posted 2005-07-03 02:20:50 »

I have been programming a board game and it plays very smoothly until I use a recursive AI that I have implemented.  The recursion is not the problem as the AI is working fine, the problem is that it uses up so many resources it causes everything on the computer to slow down to a crawl.  I have the moves being calculated in a separate runnable thread, but it still clogs everything up.  The game is set up so that if you choose, you can play only AI players against each other, but when such a game is set into motion the reset button won't work when it is clicked.

The reset button is a false button as it is simply painted on the screen and I have a method which takes the (x,y) position of a mouse click to see if this region has been clicked.

I have tried yield and sleep commands, I have tried setting the priority to the lowest setting.  I have even tried using Sun's SwingWorker class:

http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html#SwingWorker

but all the results are the same:  The system is at the mercy of this worker thread that is eating up all the resources.  The clicks are being "heard", as once the reset button is clicked the game resets the instant the AI has finished its business.

Does anyone have any suggestions on how to get the mouselistener interupt the working thread?
Offline Malohkan

Senior Devvie




while (true) System.out.println("WOO!!!!");


« Reply #1 - Posted 2005-07-03 02:44:53 »

perhaps periodically during the AI's working you could call Thread.yield();  Try adding that at the beginning of the recursive method.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline Patdumpsite

Senior Newbie





« Reply #2 - Posted 2005-07-03 04:19:40 »

I tried that to no avail...

I also set up a boolean flag that was checked periodically in the move search process.

I even went so far as to cause the flag to be set by simply clicking the mouse in the mousePressed method, but none of it gets heard until the game is over.  And I don't understand why.  The swing worker class supposedly takes the busy work to a thread outside of the event dispatch thread, so why are none of the events being taken care of until after the thread has finished its work?

This one little thing is driving me nuts.   Huh
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Malohkan

Senior Devvie




while (true) System.out.println("WOO!!!!");


« Reply #3 - Posted 2005-07-03 05:54:56 »

odd that that doesn't help... perhaps you're setting up your Thread wrong.  Could you show us some code?

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline Patdumpsite

Senior Newbie





« Reply #4 - Posted 2005-07-03 12:54:22 »

I am sure I am setting up this threading stuff wrong.   Wink

I finally scrapped the various thread attempts.  I tried so many different things I don't even know what I tried and why anymore...

I figure I will start at the beginning and explain what I have and what I (ideally) need as that will probably be best as opposed to trying to fix hacked/rigged code that I have been screwing up for the past day or so.  The following objects are what's in play at the moment:

The "Board" object that extends Canvas implements MouseListener - This object is the screen the player sees.  It collects the players moves and sends them to the BdData object to check for legality, sets the computer moves into motion, paints the canvas, etc.

"B" is a BdData object - this object holds all of the data of the board.  It checks moves to see if they're legal, executes them when commanded to, etc.

The Move objects, well obviously they jold the moves to be played.

I wanted to be able to play with different types and levels of AI, so the AI classes (e.g. redComp, yellowComp, etc) are called by handing them the board data in the getMove(B) method.

The reset flag is there to (ideally) prevent the computer moves from playing after the area with the painted reset button has been clicked, but the flag never gets called.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
//This method plays the comp moves.
    private void playCompMove(int comp){
       
        Move compMove;
       
        if (comp == RED) compMove = redComp.getMove(B);
        else if (comp == YELLOW) compMove = yellowComp.getMove(B);
        else if (comp == GREEN) compMove = greenComp.getMove(B);
        else compMove = blueComp.getMove(B);
       
        if (!reset) {
           
            boolean compMoveIsSuccessful = false;
       
            //If a null Move is returned we check to make sure the computer
            //really can't make any moves.  If a Move can be made, we end
            //the game with a game error to let the player know the AI screwed up.
            if (compMove == null  &&  (B.getFillMoves(comp) != null
                    || B.getJumpMoves(comp) != null)) {
                playError(comp);
            }
                           
            if (compMove != null  &&  B.isLegalFillMove(compMove, comp)) {
                clickCompMove(compMove);  //Allows the player to see the computer move before it is played.
                B.makeFillMove(compMove, comp);
                compMoveIsSuccessful = true;
            }
       
            else if (compMove != null  &&  B.isLegalJumpMove(compMove, comp)) {
                clickCompMove(compMove);
                B.makeJumpMove(compMove, comp);
                compMoveIsSuccessful = true;
            }
                           
            //If something screwed up.
            if (compMove != null  &&  compMoveIsSuccessful == false) {
                playError(comp + 4);
            }
       
            else if (B.isGameOver()) {
                gameOver = true;
                endOfGame();
            }
           
            else {
                resetClicks();
                paintWorld();
            }
           
        }
               
    }//End of playCompMove.


So basically, I have removed all threading stuff in this code.  I guess ideally (there I go using that word again) the worker thread should call the getMove method.  I should make the reset flag a static variable and check it from time to time in the AI object.  But how do I get the mouseListener/follow up methods to set the flag?

I am obviously missing something simple, but can't seem to get around it.  Any help would be greatly appreciated.   Smiley
Offline Malohkan

Senior Devvie




while (true) System.out.println("WOO!!!!");


« Reply #5 - Posted 2005-07-03 22:53:16 »

Well the two big things you described doing were recursion, and Threading.  In that code neither exist Smiley  I'm not understanding what you want well enough to tell you where or how to place your threading, the only thing I wanted to see is your code for how you did it.  It's really easy for you to tell me what you THINK your code does, but I'm just interested in what it ACTUALLY does Smiley  Set something up you expect to work with the Threads and recursion, and I'll look at it and hopefully be able to tell you why it doesn't (assuming you don't fix your bug this next try!).

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline Patdumpsite

Senior Newbie





« Reply #6 - Posted 2005-07-03 23:54:24 »

Yeah, I am not always very good at asking for help.   Grin

I was just toying with this some more and here is some sample code that does not work, that mimics other examples I have seen, but does not allow the GUI to hear the mouselistener (all the time).

I also have a Thread.yield() request at the beginning of each call to recMove() in the AI, so theoretically, a yield request gets put in regularly, but it may be futile here since this is supposed to be happening in the worker thread.  I'm not sure.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
    //This method plays the comp moves.
    private void playCompMove(int comp){
       
        final AI tempAI;
       
        if (comp == RED) tempAI = redComp;
        else if (comp == YELLOW) tempAI = yellowComp;
        else if (comp == GREEN) tempAI = greenComp;
        else tempAI = blueComp;
       
        final SwingWorker worker = new SwingWorker() {
            public Object construct() {
                Move temp = tempAI.getMove(B);
                return temp;
            }
        };
        worker.start();
       
        Move compMove = (Move) worker.get();
       
        if (!reset) {
           
            boolean compMoveIsSuccessful = false;
       
            //If a null Move is returned we check to make sure the computer
            //really can't make any moves.  If a Move can be made, we end
            //the game with a game error to let the player know the AI screwed up.
            if (compMove == null  &&  (B.getFillMoves(comp) != null
                    || B.getJumpMoves(comp) != null)) {
                playError(comp);
            }
                           
            if (compMove != null  &&  B.isLegalFillMove(compMove, comp)) {
                clickCompMove(compMove);
                B.makeFillMove(compMove, comp);
                compMoveIsSuccessful = true;
            }
       
            else if (compMove != null  &&  B.isLegalJumpMove(compMove, comp)) {
                clickCompMove(compMove);
                B.makeJumpMove(compMove, comp);
                compMoveIsSuccessful = true;
            }
                           
            //If something screwed up.
            if (compMove != null  &&  compMoveIsSuccessful == false) {
                playError(comp + 4);
            }
       
            else if (B.isGameOver()) {
                gameOver = true;
                endOfGame();
            }
           
            else {
                resetClicks();
                paintWorld();
            }
           
        }
               
    }


Now supposedly the GUI is working in the event dispatch thread, but the worker thread seems to be getting all of the resources.

Above, I made a reference to "all of the time".  There is something strange going on here because in games where I have 3 AI and a human player (blue), if I let the human player get wiped out by the 3rd move the AI players continue on to finish the game (this is normal).  If I click on  the reset region, most of the time, the reset click is heard and the game resets after the computer plays its move.

However, with the exact same code, if I play a game with all 4 spots as AI players, the reset will always go unheard.  This is the best I have been able to do so far in terms of interupting things.  Since this works for 3AI + human games and not 4 AI games, I probably should also present this code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
    //This method plays out the comp moves in the proper order.
    private void nextCompMove(int comp) {
       
        if (!reset) {
           
            if (comp == RED) playCompMove(RED);
            else if (comp == YELLOW  &&  yellowComp != null) playCompMove(YELLOW);
            else if (comp == GREEN  &&  greenComp != null) playCompMove(GREEN);
            else if (comp == BLUE  &&  blueComp != null) playCompMove(BLUE);
       
            comp++;
       
            if (!gameOver  &&  !reset) {
           
                if (comp > GREEN) {
           
                    if (blueComp != null) nextCompMove(BLUE);
           
                    //If human player has no legal moves...
                    else if (B.getFillMoves(BLUE) == null  &&  B.getJumpMoves(BLUE)  ==  null)
                        nextCompMove(YELLOW);
           
                    else {
                        playersMove = true;
                        paintWorld();
                    }
           
                }
       
                else nextCompMove(comp);
           
            }
           
        }
       
    }


This method plays the computer moves in their proper order.  As you can see, there is a little bit more work done around the BLUE player, since this player may be human or AI.  As things are now, this little bit of extra work seems to be enough to allow the mouselistening to occur when the human player is wiped out and can not make a legal move, as opposed to an AI player.

If you want to see the recMove code I can post it, but it seems to be working fine, it is just processor intensive for 3-4 seconds per move, so if someone gets bored watching an all AI game (like me, after seeing 100's of them) it would be nicer if the reset button could interupt the game.

Not sure if any of this helps, Malohkan.  Thanks again though for responding at all.  Wink
Offline Jeff

JGO Coder




Got any cats?


« Reply #7 - Posted 2005-07-04 03:16:25 »

Job one of ANY poerformacne problem:  PROFILE YOUR CODE

I can't say that too emphatically. Unilt you have done that you have no idea what is really causing the slow down.

There is a fre eprofiler for Netbeans. Go get it and use it.  Check to see if you are using too much memory.  If your heap seems fine then do a call trace and find out what parts of your cocdee are actually the problem.  Myself, just based on the symptoms you described, my money is on an object leak but I could well be wrong.  Only the Profiler knows for sure!

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Jackal von ÖRF

Junior Devvie





« Reply #8 - Posted 2005-07-04 09:27:32 »

1  
2  
3  
        worker.start();
       
        Move compMove = (Move) worker.get();

That does not make sense. You start the worker in another thread, but then you block the current thread and wait for the worker thread to finish. That is essentially the same as if you would use no threads at all.

Offline Patdumpsite

Senior Newbie





« Reply #9 - Posted 2005-07-04 20:02:52 »

Good to see computer "scientists" never fail to disappoint...   Roll Eyes

The profiler won't seem to work with what it installs and I seem to have to upgrade to the latest java update 1.5_4 or whatever ridiculous number scheme they are using for the latest update.  What happened to the good old days when things were just numbered consecutively and named with a little intuition...

Naturally, I can't update at the moment, because sun is having overuse issues with their servers.  Yet, it seems to me that the profiler ought to come with whatever it needs to work, but what do I know about this computer stuff.  I tried looking through the attachment wizard, but the wizard was a bit vague, so I go online to get a little extra help and it basically says follow the wizard...   Roll Eyes

Now that's just pure genius...  I'll report back when I get the update so the profiler will work and get some results.

Jackal von ÖRF:  Well done!  You've pointed out that I am having problems with the code, because you know, I was just here trying to show off how well it worked.   Tongue

If you want to make yourself useful, show me a methodology that will allow things to progress properly.  As that is written, it seems to me that it ought to work.  The idea is that a separate thread is off doing the computation, so that the event handling thread is still open to recieve the mouselistener events.  If my understanding of thread usage is way off, that is fine, but please explain why.

Even better, explain why the above works with 3 AI and a human player, but does not with 4 AI.  I would prefer to understand the rationalization as to how the code works as opposed to the correct syntax/order of events needed.

I am here to learn something.  I am not here to just look for the correct answer.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #10 - Posted 2005-07-04 20:16:33 »

If you don't/won't/can't use Netbean's profiler, you can just use the built-in profiling. Have a look in the javadocs for the 'java' command, especially -XProf command line flags. Then you just need to run the output files though something like HP's JMeter (free download somewhere).

Although that's largely irrelevant as your problem has already been pointed out to you. Heres a hint:  worker.get(); *blocks* and jams up your event handling thread (how else would it work?). How you solve it depends on your app. You could possibly try doing all the work in the worker thread (eliminating the need for a block) or you could have some kind of update loop that polls for the result at infrequent intervals (and goes to sleep in between).

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline Patdumpsite

Senior Newbie





« Reply #11 - Posted 2005-07-12 05:12:44 »

Just wanted to say thanks for the help in this thread.

Right about the time the forums went down I figured out a way to get things working properly by extending the SwingWorker class.

Thanks again.   Grin
Offline Jeff

JGO Coder




Got any cats?


« Reply #12 - Posted 2005-07-13 06:57:28 »

Good to see computer "scientists" never fail to disappoint...   Roll Eyes

The profiler won't seem to work with what it installs and I seem to have to upgrade to the latest java update 1.5_4 or whatever ridiculous number scheme they are using for the latest update.  What happened to the good old days when things were just numbered consecutively and named with a little intuition...

There are instructions on the webstie. I follwoed them and goit it working imemdiately.

Sounds like an RTFM problem to me.


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Patdumpsite

Senior Newbie





« Reply #13 - Posted 2005-07-16 15:46:04 »

Sorry to disappoint you Jeff, but I am quite adept at reading manuals.

Typically, when things like this happen to me, the manuals aren't updated as often as the product and I am sure this was the case here.  I don't recall exactly what the problem was now, it was nearly two weeks ago....

Again, computer "scientists" at their best... making stuff without adequate documentation.   Roll Eyes
Offline Jeff

JGO Coder




Got any cats?


« Reply #14 - Posted 2005-07-18 00:13:06 »

Worked for me when i installed it before.

Works for me when I install it now.

I suggest you drop the attitude and re-read the docs.  Then post what steps you too kand what failed
sans-attitude and someone might actually want to help you.


P.S.  You DID read tjhat you need to use Mustang with it, right?  Since your so good with docs and all.....

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Patdumpsite

Senior Newbie





« Reply #15 - Posted 2005-07-20 19:43:06 »

OI!  I said I was all set and thought the matter was dropped several posts ago, but if you insist...

I apologize that I let my frustration show with my words here, but the fact of the matter is documentation is usually weak at best.

I recall my issues at hand with the profiler:  I was one version behind with the current JRE and the profiler didn't like it.  No problem normally, but at the time I was unable to DL the most current version because sun's DL site was unavailable.  However, the precious profiler documentation led me to believe that their was a version that would work that came with the profiler, so I forged on trying to find it.  Naturally, this is not the case, but I was not able to figure that out based on the documentation, because as I said, it  wasn't clear to me and I was under the impression that it should have been there.

Moving on with this documentation, I tried to set thigs up with the wizard, but again was confused by one of the options, so I go online to check out the documentation and all I found, if you would allow me to paraphrase, was "Follow the wizard".

Not exactly the most helpful.

Again, I apologize if my frustration is evident in the former passages, but it would have been unnecessary if the documentation were a bit better.

I hope that clarifies my point. 
Offline Jeff

JGO Coder




Got any cats?


« Reply #16 - Posted 2005-07-23 04:15:01 »

OI!  I said I was all set and thought the matter was dropped several posts ago, but if you insist...

I apologize that I let my frustration show with my words here, but the fact of the matter is documentation is usually weak at best.

I recall my issues at hand with the profiler:  I was one version behind with the current JRE and the profiler didn't like it.

I can see how you missed this....

"#  Note: Please read
the documentation on supported JVMs carefully. Depending on the version of the JVM (bundled customized JDK 1.4.2 or standard JDK 5/6) that you would like to run your profiled applications on, you may need to download additional files and/or change some settings for your project inside the IDE."

After all, it was only in bold blue in the middle of the download page, 4th instruction in the incredibly badly named "Installation Instructions".

Ya know, a lot of us from time to time don't read the docs.  But msot of us don't blame the documentation writers for it.


'nuff said.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (40 views)
2014-12-09 22:41:13

BurntPizza (75 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (47 views)
2014-11-29 21:32:03

toopeicgaming1999 (114 views)
2014-11-26 15:22:04

toopeicgaming1999 (102 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!