ajustement et correction

This commit is contained in:
2024-08-14 22:31:54 +02:00
parent cb2173d717
commit a8f0e7cdca
7 changed files with 110 additions and 56 deletions

View File

@@ -20,7 +20,7 @@ C'est un projet de fin de Licence L1 en Informatique à UPEC, la création d'un
- La partie **PROBLÈME ET SOLUTION RENCONTRÉES** - La partie **PROBLÈME ET SOLUTION RENCONTRÉES**
## AVANT TOUT : Comment lancer le jeu. ## AVANT TOUT : Comment lancer le jeu
Pour lancer le jeu, nous pouvons utiliser les addons de vscode en appuyant sur ***run*** sur la methode **main**. Pour lancer le jeu, nous pouvons utiliser les addons de vscode en appuyant sur ***run*** sur la methode **main**.
@@ -35,6 +35,7 @@ Les commandes pour le makefile :
- `Make run` : il va uniquement lancer l'interpréteur java (Attention à ne pas supprimer le bin avant) - `Make run` : il va uniquement lancer l'interpréteur java (Attention à ne pas supprimer le bin avant)
Pour lancer le jeu en multijoueur avec Makefile (mot1 et mot2 sont des mots à changer en fonction du canal): Pour lancer le jeu en multijoueur avec Makefile (mot1 et mot2 sont des mots à changer en fonction du canal):
- `Make channel=mot1 adversaire=mot2` : compile tout le programme et le lance en multijoueur. - `Make channel=mot1 adversaire=mot2` : compile tout le programme et le lance en multijoueur.
- `Make run channel=mot1 adversaire=mot2` : lance uniquement le programme en multijoueur. - `Make run channel=mot1 adversaire=mot2` : lance uniquement le programme en multijoueur.
@@ -42,6 +43,67 @@ Sur windows, vous avez une autre option que personnellement je vous encourage, c
- `run.bat mot1 mot2` : il va uniquement lancer `Make channel=mot1 adversaire=mot2` et en même temps lancer `chcp 65001` qui va mettre l'utf-8. - `run.bat mot1 mot2` : il va uniquement lancer `Make channel=mot1 adversaire=mot2` et en même temps lancer `chcp 65001` qui va mettre l'utf-8.
## Fichier de configuration
- Le fichier de configuration sert à créer une partie sans recompiler en `.class` le programme. Étant en format xml, il ressemble à des balises html et donc plus facile à comprendre.
Pour que le programme comprenne le fichier xml, il doit y avoir des balises spécifiques:
- `Configuration` est la racine du programme, il a comme attribut n pour la taille du snake. Exemple :
```xml
<Configuration n="2"></Configuration>
```
- `Map` est la balise principale pour la gestion de la carte du jeu. Il y a comme attribut la taille x et y de la carte. Il permet aussi de placer les balises fraises et des murs. Exemple :
```xml
<Map x="22" y="22"></Map>
```
- `Fraise` et `Wall` sont des balises pour placer une fraise ou un mur avec comme attributs x et y. Exemple :
```xml
<Wall x="3" y="4"/>
<Fraise x="5" y="6"/>
```
- `Personnage` est la balise principale pour la gestion des personnages du jeu. Il permet de placer des balises IA, Robot et Player. Exemple :
```xml
<Personnage></Personnage>
```
- `Player`, `Robot` et `IA` sont des balises pour placer des personnages avec des attributs comme name, x et y. Sur la balise IA, on doit aussi mettre QTable avec le dossier ou le fichier qui sert a stocker l'apprentissage de l'IA. Exemple :
```xml
<Player name="Philippe_Etchebest" x="2" y="2"/>
<Robot name="R2D2" x="19" y="19"/>
<IA name="incognito" x="19" y="19" QTable="res/save"/>
```
**Exemple de configuration :**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Configuration globale -->
<Configuration n="2">
<!-- Configuration de la map -->
<Map x="22" y="22">
<Wall x="1" y="2"/>
<Fraise x="5" y="6"/>
</Map>
<!-- Configuration des personnages -->
<Personnage>
<IA name="incognito" x="19" y="19" QTable="res/save"/>
<Robot name="R2D2" x="19" y="19"/>
</Personnage>
</Configuration>
```
``
# JEU et GAMEPLAY # JEU et GAMEPLAY
@@ -66,7 +128,6 @@ Le channel récupère les données contenues sur le channel qui y est dédié (l
Nous avons testé Channel à distance sur 2 machines et la partie s'est déroulée correctement. Nous avons testé Channel à distance sur 2 machines et la partie s'est déroulée correctement.
# IA (Q-Learning) # IA (Q-Learning)
## - Explications ## - Explications
@@ -95,11 +156,14 @@ Ce calcul sera la valeur de toutes les actions que l'IA va enregistrer dans sa b
- $Q(s_t, a_t)$ : est la valeur de Q actuelle, il contient $s_t$ qui l'état et $a_t$ qui est l'action de Q. - $Q(s_t, a_t)$ : est la valeur de Q actuelle, il contient $s_t$ qui l'état et $a_t$ qui est l'action de Q.
- $\alpha$ : est le taux d'apprentissage, c'est lui qui détermine si on doit écraser les valeurs ou non. - $\alpha$ : est le taux d'apprentissage, c'est lui qui détermine si on doit écraser les valeurs ou non.
- $R_t$ : est la récompense de l'action, si c'est une bonne action ou non. - $R_t$ : est la récompense de l'action, si c'est une bonne action ou non.
- $\gamma$ : est l'importance des futures récompenses. - $\gamma$ : est l'importance des futures récompenses.
- $\max(Q(s_{t+1}, a))$ : est la valeur maximale de Q du prochain tour parmi toute sa base de donnée. - $\max(Q(s_{t+1}, a))$ : est la valeur maximale de Q du prochain tour parmi toute sa base de donnée.
## Resultat : ## Resultat :
![IA](res/video/ia_solo_15min_apprentissage.gif) ![IA](res/video/ia_solo_15min_apprentissage.gif)
@@ -116,7 +180,7 @@ Quand elle est coincée et qu'aucune des cases l'entourant n'est un choix possib
Les choix qu'elle fait sont donc partiellement aléatoires et évitent essentiellement une mort au coup suivant. Les choix qu'elle fait sont donc partiellement aléatoires et évitent essentiellement une mort au coup suivant.
# GRAPHIQUE # GRAPHIQUE
Nous avons utiliser le terminal pour faire notre parti graphique avec de l'utf-8, il est très important d'activer l'utf-8 sur les terminaux avant de lancer le jeu car vous pourrez avoir des problèmes comme des "?". Nous avons utiliser le terminal pour faire notre parti graphique avec de l'utf-8, il est très important d'activer l'utf-8 sur les terminaux avant de lancer le jeu car vous pourrez avoir des problèmes comme des "?".
@@ -129,7 +193,7 @@ Cependant, grâce à lui j'ai énormément appris et son aide m'a souvent été
Je trouve notre projet bien construit, utilisant des moyens adaptés à chacuns des points du jeu. La division des classes est pertinente et les commentaires apportent une grande plus-value à ceux qui voudrait l'utiliser. Je trouve notre projet bien construit, utilisant des moyens adaptés à chacuns des points du jeu. La division des classes est pertinente et les commentaires apportent une grande plus-value à ceux qui voudrait l'utiliser.
## - Impressions GUEZO Loïc ## - Impressions GUEZO Loïc:
Durant ce projet, j'ai pu tester et apprendre de nouvelles choses. J'ai pu aussi "tester" à gérer une "mini équipe" (on etait que 2). Mon camarade s'est quand même bien débrouillé comparé à notre différence de penser et comment gérer les problèmes. Durant ce projet, j'ai pu tester et apprendre de nouvelles choses. J'ai pu aussi "tester" à gérer une "mini équipe" (on etait que 2). Mon camarade s'est quand même bien débrouillé comparé à notre différence de penser et comment gérer les problèmes.

View File

@@ -1,13 +1,7 @@
import java.io.File;
import java.io.ObjectInputFilter.Config;
import java.util.ArrayList;
import configuration.ConfigGame; import configuration.ConfigGame;
import game.Terminal; import game.Terminal;
import game.environnement.*; import game.environnement.*;
import personnage.*; import personnage.*;
import personnage.IAQLearning.QTable;
import tests.IATest;
public class Main { public class Main {
/** /**

View File

@@ -1,22 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Configuration globale --> <!-- Configuration globale -->
<Configuration> <Configuration n="2">
<Size n="2"/>
<!-- Configuration de la map --> <!-- Configuration de la map -->
<Map> <Map x="22" y="22"></Map>
<Coordinate x="22" y="22"/>
<Wall x="1" y="2"/>
<Wall x="3" y="4"/>
<Fraise x="5" y="6"/>
</Map>
<!-- Configuration des personnages --> <!-- Configuration des personnages -->
<Personnage> <Personnage>
<Player name="Philippe_Etchebest" x="2" y="2"/> <Player name="Philippe_Etchebest" x="2" y="2"/>
<!-- <Player name="Luke Skywalker" x="19" y="19"/> --> <Player name="Luke Skywalker" x="19" y="19"/>
<!-- <IA name="" x="19" y="19" QTable=""/> -->
<Robot name="R2D2" x="19" y="19"/>
</Personnage> </Personnage>
</Configuration> </Configuration>

View File

@@ -23,21 +23,27 @@ public class ConfigGame {
try { try {
FileReaderXml fileReaderXml = new FileReaderXml(path); FileReaderXml fileReaderXml = new FileReaderXml(path);
this.data = fileReaderXml.getElements(); this.data = fileReaderXml.getElements();
if (this.data.get("Configuration") == null || this.data == null) {
System.err.println("Erreur: le fichier de configuration est introuvable.");
System.exit(-1);
}
} catch (IOException | SAXException | ParserConfigurationException e) { } catch (IOException | SAXException | ParserConfigurationException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public Map getMap() { public Map getMap() {
ArrayList<HashMap<String,String>> mapList = data.get("Map.Coordinate"); ArrayList<HashMap<String,String>> mapList = data.get("Configuration.Map");
if (data.get("Configuration.Map") == null) { if (mapList == null) {
System.err.println("Erreur: La balise Map est introuvable."); System.err.println("Erreur: La balise Map est introuvable.");
System.exit(-1); System.exit(-1);
} }
if (mapList.size() != 1) { if (mapList.size() != 1) {
System.err.println("Erreur: Plusieurs Coordonnées trouvées."); System.err.println("Erreur: Plusieurs ou Aucune Coordonnées trouvées.");
System.exit(-1); System.exit(-1);
} }
@@ -52,13 +58,13 @@ public class ConfigGame {
} }
public int getN() { public int getN() {
ArrayList<HashMap<String, String>> n; HashMap<String, String> n;
if ((n = data.get("Configuration.Size")) == null) { if ((n = data.get("Configuration").get(0)).isEmpty()) {
return 4; return 4;
} }
return Integer.parseInt(n.get(0).get("n")); return Integer.parseInt(n.get("n"));
} }
public Personnage[] getPersonnages() { public Personnage[] getPersonnages() {

View File

@@ -36,36 +36,39 @@ public class FileReaderXml {
protected HashMap<String, ArrayList<HashMap<String, String>>> getElements() { protected HashMap<String, ArrayList<HashMap<String, String>>> getElements() {
HashMap<String, ArrayList<HashMap<String, String>>> elementsMap = new HashMap<>(); HashMap<String, ArrayList<HashMap<String, String>>> elementsMap = new HashMap<>();
NodeList nodeList = document.getDocumentElement().getChildNodes(); Node nodeList = document.getDocumentElement();
readElements(elementsMap, nodeList); readElements(elementsMap, nodeList);
return elementsMap; return elementsMap;
} }
private void readElements(HashMap<String, ArrayList<HashMap<String, String>>> elementsMap, NodeList nodeList) { private void readElements(HashMap<String, ArrayList<HashMap<String, String>>> elementsMap, Node currentNode) {
for (int i = 0; i < nodeList.getLength(); i++) { if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
Node childNodeList = nodeList.item(i); HashMap<String, String> attributeMap = new HashMap<>();
NamedNodeMap attributes = currentNode.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node attribute = attributes.item(j);
attributeMap.put(attribute.getNodeName(), attribute.getNodeValue());
}
String parentNodeName, fullNodeName;
if ((parentNodeName = currentNode.getParentNode().getNodeName()).charAt(0) == '#') {
fullNodeName = currentNode.getNodeName();
} else {
fullNodeName = parentNodeName + "." + currentNode.getNodeName();
}
if (childNodeList.getNodeType() == Node.ELEMENT_NODE) { if (!elementsMap.containsKey(fullNodeName)) {
HashMap<String, String> attributeMap = new HashMap<>(); elementsMap.put(fullNodeName, new ArrayList<>());
NamedNodeMap attributes = childNodeList.getAttributes(); }
for (int j = 0; j < attributes.getLength(); j++) {
Node attribute = attributes.item(j);
attributeMap.put(attribute.getNodeName(), attribute.getNodeValue());
}
String fullNodeName = childNodeList.getParentNode().getNodeName() + "." + childNodeList.getNodeName(); elementsMap.get(fullNodeName).add(attributeMap);
if (!elementsMap.containsKey(fullNodeName)) { NodeList childNodes = currentNode.getChildNodes();
elementsMap.put(fullNodeName, new ArrayList<>()); for (int i = 0; i < childNodes.getLength(); i++) {
} readElements(elementsMap, childNodes.item(i));
elementsMap.get(fullNodeName).add(attributeMap);
if (childNodeList.hasChildNodes()) {
readElements(elementsMap, childNodeList.getChildNodes());
}
} }
} }
} }

View File

@@ -3,8 +3,6 @@ package tests;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import display.Display;
import game.environnement.Grid;
import game.environnement.Map; import game.environnement.Map;
import personnage.IA; import personnage.IA;
import personnage.Personnage; import personnage.Personnage;

View File

@@ -5,8 +5,6 @@ import configuration.ConfigGame;
public class XmlReaderTest { public class XmlReaderTest {
public static void main(String[] args) { public static void main(String[] args) {
ConfigGame configXml = new ConfigGame(null); ConfigGame configXml = new ConfigGame(null);
System.out.println(configXml.getPersonnages());
System.out.println(configXml.getN());
System.out.println(configXml.getMap()); System.out.println(configXml.getMap());
} }
} }