AI de pong imparfait

19

Je commence donc à apprendre Java et certains OpenGL en utilisant le LWJGL. Pour commencer facilement, j'écris un clone de l'Atari Pong. J'ai configuré correctement l'écran du jeu, la détection des collisions, et tout le jeu fonctionne principalement, en fait, si c'était un jeu à 2 joueurs, je serais déjà fini, mais comme je prévois de le faire, un jeu à un seul joueur , Je dois trouver une IA simple pour contrôler le deuxième joueur.

Savoir où la balle frappera semble assez trivial, et créer une IA qui frappe toujours la balle semble être une chose facile à faire, mais je veux que le jeu puisse être gagné, donc je ne peux pas toujours faire en sorte que l'IA touche le Balle.

Voici donc ma question, comment dois-je coder cela pour ajouter des imperfections de type humain à l'IA. Dois-je décider au hasard si l'IA va échouer à un moment donné? Ou il y a quelque chose de plus intelligent (ou peut-être juste évident) que je manque ici?

Merci beaucoup.

Setzer22
la source
5
Eh bien, en général, vous faites que la batte AI ne bouge qu'à une certaine vitesse, donc si le ballon est bien placé par le joueur, l'IA ne peut pas l'atteindre ..
4
Je commencerais par limiter la vitesse à laquelle l'IA peut déplacer la pagaie et / ou la construction dans un délai aléatoire (court) avant que l'IA ne commence à répondre à un coup.
1
doublon possible de Qu'est
MichaelHouse
4
@ byte56 Je ne dirais pas vraiment que c'est une dupe de cette question. Cela ressemble à l'exemple donné ici blog.stackoverflow.com/2011/01/… sous "Si vous voulez fermer la question d'un utilisateur en tant que doublon, ce doit être un vrai doublon". Cette question est une bonne ressource (et quelqu'un pourrait probablement utiliser cette question pour obtenir une réponse elle-même étant donné le contenu), mais elle ne répond pas vraiment aux détails de cette question, je ne pense pas.
Tetrad
1
@Tetrad Je pense que les réponses finissent par être très similaires, mais, vous avez raison, les questions sont différentes. Je pense que cette question est une sorte de version plus spécifique de la question liée. Si le PO avait vu l'autre en premier, je ne sais pas si cette question aurait été posée. Lorsque j'ai voté, j'étais indécis, j'ai donc tous deux voté pour la question et les réponses et j'ai voté en double. Ça pourrait aller dans les deux sens pour moi.
MichaelHouse

Réponses:

20

Mon IA pong imparfaite préférée est brutalement simple, mais permet de faire un échec de l'IA plutôt agréable.

Invisible Ball AI

Configuration de l'IA : lorsque la balle se reflète sur votre pagaie, vous savez où elle se trouve et à quelle vitesse elle va. Faites apparaître une balle invisible à ce point mais à une plus grande vitesse. Il remontera où va la balle visible. A chaque image, faites avancer l'IA vers l'emplacement de la balle invisible. Arrêtez la balle invisible une fois qu'elle a atteint le côté de l'IA, c'est donc là que l'IA doit déplacer sa raquette.

Résultats : l'IA semble essayer de prédire la trajectoire de la balle. Supposons que le joueur ait réfléchi la balle à un angle raide afin qu'elle rebondisse contre un mur. L'IA traquera le ballon un peu, puis - étant plus lent que le ballon - ne parviendra pas à le retrouver assez rapidement. Vous avez trompé l'IA, et cela semble assez logique d'un point de vue humain. Vous pouvez voir l'ordinateur essayer de prédire où ira le ballon, puis - oh, il a raté, c'était trop lent, et vous avez gagné un point.

C'est bien mieux que d'insérer du hasard, car cela rend l'IA relativement intelligente. Un adversaire digne. Il permet également à l'IA de jouer selon les mêmes règles que l'humain, ce qui semble mieux au joueur et facilite votre travail.

Paramètres : vous pouvez également modifier la vitesse de la balle invisible, car cela déterminera dans quelle mesure l'IA planifiera. Plus la balle invisible est rapide, plus la pagaie devra se déplacer pour bloquer et plus le joueur devra viser.

DDR
la source
Toutes les réponses données ont fourni de très bonnes informations, mais comme je devais en marquer une pour être la bonne réponse, j'ai choisi celle-ci car j'aime vraiment votre approche. Ceci, combiné avec d'autres choses dites dans d'autres réponses (comme jouer avec le temps de réaction) pourrait obtenir une IA vraiment humaine, et avec une difficulté facilement réglable
Setzer22
Cela a parfaitement fonctionné pour ma configuration car j'ai des angles, une vitesse et une accélération variables en fonction de certains mouvements spéciaux, de sorte que la balle peut potentiellement être partout. L'IA devenait propriétaire, mais maintenant c'est beaucoup mieux. Je peux voir pourquoi cette méthode n'est pas la meilleure pour la vitesse verrouillée et les angles de 45 degrés, mais ce n'est pas du tout mon jeu.
jackrugile
1
Bien que j'aime cette approche, j'ai eu des problèmes avec ma mise en œuvre. Le problème étant que puisque la balle traceur se déplace plus vite que la balle qu'elle représente, il peut manquer des collisions qui se produiront avec la balle qu'elle représente. La raison étant, bien sûr, que la balle traceur se déplacera sur une plus grande distance entre les cadres.
Wolfgang Schreurs
Si vous souhaitez une plus grande fidélité, vous pouvez recalculer la position de la balle traceur deux fois par image et diviser par deux la vitesse pour chaque calcul.
DDR
22

Les jeux de Pong auxquels j'ai joué semblent se comporter de la manière suivante: la pagaie contrôlée par l'IA sait où la balle va frapper mais est limitée dans la rapidité avec laquelle elle peut atteindre cette position. Alors parfois ça manque. Je pense que c'est la façon la plus évidente de le faire.


la source
Cette. Cela n'aide pas l'IA à savoir où la balle frappera si elle ne peut se déplacer que, disons, 3 pixels par image et si elle doit se déplacer de haut en bas.
KeithS
14

Quand j'ai créé un clone presque pacman tellement génial sur ma TI83? calculatrice, le plus gros problème que j'ai rencontré était que les "fantômes" étaient beaucoup trop rapides. J'ai dû les ralentir d'une manière ou d'une autre. Donc, j'ai mis un gros vieux péché (cos (tan (coordonnée x))) là-dedans. Des niveaux plus faciles feraient ce calcul plusieurs fois, et des niveaux plus durs ne feraient qu'une seule des opérations.

Le point est, TEMPS DE RÉACTION. Recherchez ce qu'est un temps de réaction humain typique et ajoutez-y 10 ms. Utilisez cela comme point de départ. Comme les niveaux deviennent plus difficiles, retirez du temps du temps de réaction ... ce qui peut être simple Thread.sleep(time);pour l'IA. Attendez ce laps de temps avant que l'IA ne commence à bouger.

Vous pouvez également contrôler la vitesse à laquelle la pagaie se déplace ou, si vous voulez VRAIMENT devenir compliqué, déterminer où la balle sera basée sur différents degrés d'informations ... disons seulement 2 pixels plutôt qu'un vecteur. Ajoutez des modificateurs d'angle aux murs pour ajouter un degré d'aléatoire, forçant l'IA à recalculer.

Russell Uhl
la source
2
Pourriez-vous expliquer pourquoi vous l'avez utilisé exactement sin(cos(tan(x)))?
nullpotent
5
parce que j'étais jeune, stupide et sur une TI83, sin (cos (tan (x))) a créé une bonne unité de décalage dans l'IA. Aussi parce que, à ma connaissance, la calculatrice n'avait pas de commande d'attente pouvant utiliser des millisecondes. Peut-être un peu de clarté: je n'ai pas utilisé l'assembly ou le micro script ou le langage que vous pouvez compiler pour exécuter ces choses. J'ai utilisé le code de programmation intégré au firmware (le bouton prgm). J'avais MAXIMUM 8 lignes de code à l'écran à tout moment. Je ne me souvenais de rien de plus compliqué pendant un laps de temps.
Russell Uhl
2
J'ai appris à programmer sur le code intégré au firmware de la TI83. Ensuite, j'ai dû réapprendre la programmation structurée en C ++. Je dirais que la TI83 m'a appris ce qu'est le code de chaîne de spaghetti et pourquoi il est mauvais. Je n'ai pas utilisé de déclaration goto depuis. Bon moment cependant.
ContextSwitch
2
oh bon seigneur, les gotos. Je revisite le code de temps en temps ... et j'abandonne rapidement. Je ne sais pas comment j'ai réussi à programmer ce truc sur une période de semaines pendant mes cours de mathématiques.
Russell Uhl
1
Pas besoin d'être défensif sur votre délai de déclenchement. Les calculs en virgule flottante dans une boucle étaient une façon courante de faire une pause dans les programmes écrits il y a plusieurs décennies et les performances / capacités de vos calculatrices sont conformes à celles d'un ordinateur du début des années 80.
Dan Neely
6

Si vous ralentissez simplement la pagaie, à chaque fois que vous frappez la balle avec un angle aigu (c'est-à-dire que vous montez et descendez beaucoup au lieu de vous diriger directement de l'autre côté), l'ordinateur manquerait presque toujours parce que la balle se déplace de haut en bas. plus rapide que la pagaie ne peut compenser.

Au lieu de cela, je jouerais avec la vitesse de la pagaie et le point auquel l'IA réagit. Par exemple:

  • lorsque l'utilisateur frappe le ballon
    • l'IA peut réagir immédiatement et aller là où sera le ballon. S'il est assez rapide, il arrivera à temps
  • quand le ballon passe au milieu du terrain
    • l'IA doit attendre qu'elle traverse le milieu du terrain avant de réagir

Une autre chose à changer est la façon dont l'IA réagit. Vous avez mis en évidence une stratégie où la pagaie se déplace toujours à la position où la balle sera. Une personne ne peut pas toujours faire ça. Ils sont plus susceptibles de suivre le ballon de haut en bas, ne sachant pas exactement où le ballon se trouvera quand il les atteindra en raison de tous les rebonds.

Ainsi, une méthode de réaction plus humaine consiste à toujours se diriger vers le ballon. Par exemple, si le ballon monte, alors la raquette monte. Si la pagaie est assez rapide, elle peut réagir aux rebonds du haut et du bas. Si la pagaie n'est pas assez rapide, elle compensera trop en se déplaçant vers le haut lorsque la balle remonte, mais lorsqu'elle rebondit, la pagaie peut ne pas être en mesure de descendre suffisamment rapidement.

Enfin, vous pouvez également jouer avec la taille de la palette pour augmenter / diminuer la difficulté.

Trenin
la source
2

Un facteur à considérer est le caractère aléatoire - les joueurs humains ont toujours un certain degré de variation dans leur jeu, donc si vous voulez que votre IA ressemble à un humain, vous voudrez également avoir une certaine variation dans leur jeu.

Vous pouvez configurer des plages pour:

  • Temps de réaction (à quelle vitesse l'IA commence à bouger)
  • Vitesse (vitesse à laquelle l'IA déplace la pagaie)
  • Précision (à quelle distance l'IA arrivera-t-elle à l'endroit où elle veut réellement déplacer sa raquette, donnant une chance de sous-dépasser ou de dépasser où elle veut être)

Ensuite, à chaque coup de l'adversaire, l'IA peut choisir une valeur dans ces plages et prendre ses décisions (et mouvements) en fonction de cela. Pour les adversaires de l'IA plus faciles, vous pouvez rendre ces gammes plutôt médiocres, mais également avoir de larges gammes pour donner à l'IA des "coups de chance". Pour les adversaires plus difficiles, vous pouvez resserrer ces gammes et les mettre toutes dans la "bonne" gamme.

Blobinator
la source
2

Je vais suggérer une solution plus générale qui n'est pas spécifique au pong. Je crois que cela pourrait être appliqué à n'importe quel jeu - pas seulement au pong. Vous voulez un comportement humain, non? Pour qu'un humain ait l'impression de jouer un humain ... et donc par extension espère gagner. Donc que fais-tu?

Observez un humain! Comment un joueur peut-il perdre au pong? Eh bien, si nous regardons deux joueurs de pong, c'est assez évident. Habituellement, la perte est due au fait que le ballon est tout simplement trop rapide et que le temps de réaction des joueurs a été retardé. C'est deux paramètres, dont l'un est réglable. L'autre est la capacité des joueurs à appuyer dans la bonne direction. Vous avez donc une fréquence d'erreur et une fréquence de réaction - les deux peuvent être réglées en fonction de la difficulté.

Une IA facile aurait un décalage d'entrée plus élevé et aurait plus tendance à faire des erreurs aléatoires - alors qu'une IA plus difficile serait réglée pour que ces paramètres soient conçus pour être difficiles.

Cela peut être appliqué à presque tous les jeux - même un tel que le tic tac toe ou des modèles encore plus complexes. Cette approche se décompose dans des scénarios plus compliqués mais elle est largement suffisante lorsque les jeux dans lesquels le nombre de paramètres et la portée sont étroits.

Vaughan Hilts
la source
1

Voici une liste de quelques options, dont certaines ont déjà été couvertes:

  • Faites en sorte que les joueurs informatiques plus intelligents visent la balle de sorte qu'il soit plus difficile pour le joueur d'atteindre avec beaucoup de rebonds, et faites le contraire pour les adversaires faciles.
  • Un joueur intelligent déplacera sa raquette vers le milieu pendant que le ballon est en route vers l'adversaire et il ne sait pas où il reviendra.
  • Avant le rebond final, il est plus difficile pour un humain de prédire où finira le ballon. Faites en sorte que l'IA ait une inexactitude similaire.
  • Limitez la vitesse de la raquette pour qu'elle soit plus lente que la balle. Il doit être inférieur à la moitié de la vitesse verticale pour manquer avec un jeu parfait.
  • Augmentez la vitesse du ballon en fonction de la difficulté, de la durée du match, etc.
  • Les humains ne réagissent pas instantanément. Les joueurs IA ne devraient pas non plus.
  • Donnez à l'IA une chance aléatoire de faire une erreur et de rater la balle.
Adam
la source
0

J'ai aussi fait un petit clone de Pong (en LUA).

Mon IA est très simple mais ce n'est pas si mal, à mon humble avis.

Je vérifie simplement la position y de la balle et si plus bas je déplace la palette vers le bas, si plus haut je déplace la palette vers le haut.

Ensuite, pour affiner la difficulté, j'augmente ou diminue la distance de la balle à partir de laquelle la pagaie de l'ordinateur commence à se déplacer.

Pitto
la source