Skip to content

Repository files navigation

Lode_Runner

C'est un projet académique de création d'un programme C qui controle le joueur du jeu Lode Runner. Les règles du jeu sont les mêmes que celles du jeu original et le jeu est implémenté dans le fichier source lode_runner.c. À chaque fois que le joueur peut jouer, le fichier source lode_runner.c va appeler la fonction de signature action lode_runner(levelinfo, character_list, bonus_list, bomb_list) qui est implémenté dans le fichier source player.c et qui renvoie l'action que le joueur doit exécuter. La stratégie à implémenter ne devra uniquement prendre en compte comme information l'état courrant de la partie. Donc on ne peut pas stocker des information d'un tour à l'autre.

Stratégie

Pour que le joueur soit capable de capturer tous les bonus puis de prendre la porte de sortie sans se faire toucher par les ennemis, il faut d'abord implémenter un algorithme qui soit capable d'aller de bonus en bonus et d'atteindre la sortie sans prendre en compte la présence des ennemis, puis il faut modifier cet algorithme pour le joueur évite les ennemis. Il est possible que le joueur se retrouve dans l'incapacité d'atteindre un objectif (bonus ou porte) en évitant les ennemis, en d'autres termes le joueur est encerclé. Dans une telle situation il faut que le joueur soit capable de poser des bombes pour se défendre et ainsi se désencercler.

Atteindre les objectifs

Dans un premier temps pour que le joueur soit capable d'atteindre les objectifs il faut pouvoir calculer le plus court chemin vers l'objectif le plus proche. Il suffit donc de considérer le niveau comme un graphe dont chaque case est un noeud et de considérer qu'il y ait un arc d'un noeud A à un noeud B si et seulement si le noeud B est accessible depuis le noeud A pour le joueur. Il faut ensuite appliquer un parcourt en largeur sur ce graphe. Il n'est pas pertinant d'appliquer Djikstra car la pondération de chaque arc est de 1, donc Djikstra revient à un parcourt en largeur simple. À noter qu'il n'est pas nécessaire de construire explicitement le graphe du niveau et qu'il suffit de le parcourir implicitement. Ainsi, tous les niveaux sans ennemis sont solvables à 100%.

Eviter les ennemis

Dans un premier temps, on peut considérer les ennemis comme de simples obstacles, c'est-à-dire considérer les cases avec des ennemis comme non atteignable pour le joueur. Le premier problème est que le joueur choisir d'aller vers une case inoccupé par les ennemis mais qui est la prochaine case d'un ennemi adjacent. Donc cette approche n'est pas suffisante. On peut modifier le parcourt en largeur pour qu'à chaque fois que la profondeur du parcourt augmente, on simule un tour de jeu, mais étant donné que les ennemis sont deux fois moins rapide et que par conséquent ils se déplacent un tour sur deux et qu'on ne peut pas savoir si le tour courrant est un tour de déplacement, on devra considérer deux positions différentes par ennemi, l'une correspondant au cas où le tour courrant est un tour de déplacement ennemi et l'autre position pour le cas complémentaire. Cette stratégie permet aussi de considérer des chemins initialement bloqués par un ennemi mais qui au fur et à mesure du déplacement du joueur sur ce chemin, sera dégagé par le déplacement de l'ennemi qui bloquait ce chemin. Et inversement à ne pas considérer les chemins qui ne sont initialement pas bloqués puis qui le seront plusieurs coups plutard. À noter que cette approche revient à un algorithme de backtracking avec un heuristique d'élagage interdisant au joueur de "revenir sur ses pas", ce qui permet de conserver une complexité linéaire en le nombre de case du niveau au lieu de la complexité exponentielle de l'algorithme de backtracking naïf.

Se désencercler

On peut penser dans un premier temps à faire poser bombe lorsqu'il y a un ennemi proche en direction de l'ennemi. Sauf que cette stratégie n'est pas toujours possible car on ne peut pas poser de bombe n'importe où. Puis c'est largement insuffisant lorsqu'il y a plus de deux ennemis, car si on attend que l'ennemi soit à proximité pour poser une bombe, alors un premier ennemi sera piégé par la bombe, mais un autre ennemi peut survenir derrière le premier, lui passer dessus et toucher le joueur sans marge de manoeuvre pour poser une seconde bombe. La stratégie adoptée est de seulement considérer les cases accessibles depuis la position courrante sachant que le joueur est encerclé. Puis d'avoir une fonction qui attribue un score de défendabilité à chaque case pour que le joueur se déplace vers la case ayant le score le plus élevé et si le joueur s'y trouve alors il doit attendre qu'un ennemi soit suffisamment proche pour poser une bombe. On choisit une fonction de calcul de score de défendabilité de telle sorte que la case idéale (celle ayant le score le plus élevé) soit celle qui d'un côté a une case d'écart avec un ennemi et il doit être possible de poser une bombe sur cette case. Tandis que de l'autre côté il doit y avoir un maximum de cases contigus sur lesquelles on peut poser des bombes. Ainsi, lorsque le joueur sera encerclé, il se rapprochera d'un ennemi, posera une bombe et reculera si nécessaire, ce qui sera possible car il aura énormément de cases libres derrière lui.

Résultats

Sur les niveaux 0, 1 et 2 le joueur a un taux de réussite de 100%, sur le niveau 3 le taux de réussite est de 99.6% et sur le niveau 4 le taux de réussite est de 99.9%. Ces précédents niveaux sont des niveaux qui ont été fourni par défaut avec le code source du jeu. Les niveaux 5 et 6 sont juste des copies du niveau 3 avec bien plus d'ennemis. Ces niveaux ont pour but de tester les limites du programme. Avec 12 ennemis au niveau 6, le taux de réussite du programme est de 60%.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages