2009-12-26 8 views
1

J'écris une simulation de Bananagrams pour le plaisir. Je veux utiliser la concurrence, mais je ne suis pas entièrement sûr de savoir comment.Java: Concurrence pour un jeu

J'ai une méthode principale dans une classe Game. Chacun des threads du lecteur travaille vers une solution. À certains moments, un joueur va "peler". Pendant cette opération, chaque joueur reçoit une nouvelle tuile. L'un des threads du lecteur doit notifier le thread Game.

Le pseudocode ressemblerait à quelque chose comme ceci:

while (no player has reported they are finished) { 
     if (player reports it is time to peel) { 
      everyone peel 
     } 
     everyone work towards completion of puzzle 
} 

Comment puis-je mettre en œuvre ce en Java? (Je ne cherche pas forcément des solutions complètes, juste pointez-moi dans la bonne direction.) Comment gérer les notifications entre les objets?

Pour clarifier: ce n'est pas un jeu d'interaction utilisateur. Je veux juste essayer différents algorithmes pour voir lequel peut résoudre le problème le plus rapidement. Si quelque chose, le "jeu" serait d'écrire un algorithme et de le brancher pour voir comment cela fonctionne.

Répondre

1

Selon exactement ce que votre processus est, vous pourriez ne pas avoir besoin de faire threading (qui, croyez-moi, est quelque chose que vous auriez plutôt éviter si possible, peu importe comment cool et amusant les grands enfants font pour être).

Une façon d'aborder le problème consiste à configurer une file d'attente d'événements.

dans pseudocode

enum EVENTTYPES = {PEEL=0, WORK=1}; 
struct Event = { 
    int eventType; 
    int* data; 
} 

filoQueue eventQueue; 

array sQuidPlayers = [new Squid(), new Squid(), new Squid()]; 
void eventLoop() { 
     int player; 
     for each player in sQuidPlayers { 
      eventQueue.push(new Event(EVENTTYPES.WORK, player.id)); 
     } 

     for each event in eventQueue { 
      game.doEvent(event) 
     } 

} 

Alors là, vous exécutez la boucle d'événements 25 fois, 30 fois ou 60 fois par seconde, quelle que soit la fréquence d'images que vous souhaitez fonctionner à. Vous utilisez une minuterie pour cela (je suis sûr qu'il y en a une dans Java quelque part)

Ensuite, doEvent va essayer de trouver une méthode de co-réponse sur l'instance du lecteur correspondant. La méthode de travail sur la classe Squid fera une minuscule parcelle de travail, puis s'arrêtera, attendant la prochaine fois dans la boucle. Chaque Squid dans le tableau obtient son tour de faire leur petit travail. La méthode de travail, à son tour, PEUT mettre un événement PEEL sur la file d'attente des événements.À ce moment, la prochaine fois autour de la boucle, une méthode de peel cooresponding peut être appelée. Peut-être sur une classe de jeu central, avec l'ID du joueur qui a créé l'événement de pelage. Vous mettez la logique de la manière d'envoyer ces événements dans la méthode doEvent. doEvent peut à son tour transmettre un objet à chaque récepteur d'événement, de sorte que le destinataire peut placer ses propres objets d'événement dans la file d'attente pour être exécuté la prochaine fois autour de la boucle. (alternativement, la boucle "pour chaque événement" s'exécute jusqu'à ce que la file d'attente soit vide, et cela inclut les nouveaux événements ajoutés par les précédents appels à doEvent, donc un nouvel événement peut être appelé immédiatement au lieu d'attendre la prochaine animation). L'astuce consiste à trouver comment décomposer votre long travail en une petite parcelle de travail, à trouver comment enregistrer les résultats de ce travail et à le reprendre plus tard là où vous l'avez laissé la prochaine fois que la méthode de travail est appelée. Si tous les joueurs se comportent bien, ils peuvent tous partager un fil sans se bloquer.

Si vous allez descendre le chemin fileté, les questions sur qui peut accéder à quel peu de mémoire et quand un peu plus compliqué.

1

Le modèle Observer peut être approprié. Tout le monde s'inscrit avec le thread principal pour recevoir des notifications sur les événements de pelage. Quand une personne signale qu'il est temps de peler, elle avertit le thread principal, qui notifie à son tour tous les threads enregistrés. La notification peut être effectuée à l'aide d'une variable locale spéciale thread (chaque thread du lecteur a le sien) qui est définie par le thread principal via un appel de méthode et vérifiée par le thread du lecteur à chaque itération de la boucle de jeu. Edit: voici un lien vers un article qui approfondit l'implémentation du modèle Observer en mode multithread dans Java. http://www.javaworld.com/jw-03-1999/jw-03-toolbox.html

4

Ce serait un bon endroit pour utiliser un Cyclic Barrier. En général, une barrière cyclique permet aux threads de travailler, puis tous les threads attendent jusqu'à ce qu'ils atteignent tous le même point, puis chaque thread recommence. Par conséquent, vous pouvez demander à chaque joueur de se décoller, puis appeler CyclicBarrier.await(). Tous les threads vont alors attendre jusqu'à ce que chacun ait atteint ce point. Ce qui semble être ce que tu veux.

(, vous ne vraiment pas besoin évidemment aussi pour cette :) concurrence