changement de tout le programme avec ajout de plein de nouvelle chose et coorection de chose pour le rendre plus pratique

This commit is contained in:
2024-05-23 15:21:47 +02:00
parent 0f645c891f
commit 7f17674f5a
18 changed files with 344 additions and 679 deletions

View File

@@ -1,281 +0,0 @@
package connexion;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.net.ssl.HttpsURLConnection;
import static java.util.Arrays.copyOfRange;
/**
* <p> Cette classe est destiné un projet de fin d'année de L1, ne pas l'utiliser dans
* d'autre circonstance que dans ce projet. Elle contient plusieurs fonctions qui est
* utile pour la communication entre la machine et le site Padifac.
*
* @author Loïc GUEZO
* @version 1.0.0
* @since 2024
* @see <a href="https://cervelle.pages.lacl.fr/padiflac/test_ocaml2.html"> Padiflac </a>
*/
@SuppressWarnings("deprecation")
public class Reseau {
private static final String ADDRESS = "https://prog-reseau-m1.lacl.fr/padiflac/";
private String CHANNEL;
private URL url;
private ArrayList<String> wordArrayList;
private ArrayList<String> newerWordArrayList;
private int index;
/**
* <p>Le constructeur defini quelque information cruciale puis appelle directement la
* fonction {@code #searchContent()}.
*
* @param channel Ce string est utilisé pour se connecter à un channel dans le serveur web
*/
public Reseau(String channel) {
this.CHANNEL = channel;
this.wordArrayList = new ArrayList<String>();
this.newerWordArrayList = new ArrayList<String>();
this.connexion();
}
/**
* <p>cette fonction redefini quelque information cruciale puis appelle directement la
* fonction {@code #searchContentSorted()}.
*
* @param channel Ce string est utilisé pour se reconnecter à un channel dans le serveur web
*/
public void reconnexion(String channel) {
this.CHANNEL = channel;
this.wordArrayList.clear();
this.newerWordArrayList.clear();
this.connexion();
}
/**
* @return cette fonction renvoie tout ce qui est disponible sur le site quand on appelle la
* fonction searchContent et qui mets tout le texte dans le {@link ArrayList}
*/
public ArrayList<String> getArrayContent() {
return this.wordArrayList;
}
/**
* @return cette fonction renvoie uniquement les nouveauté de qui est disponible sur le site
* quand on appelle la fonction searchContent et qui mets tout le texte dans le {@link ArrayList}
*/
public ArrayList<String> getNewArrayListContent() {
return this.newerWordArrayList;
}
/**
* <p> cette fonction est en parallèle avec {@code #getLastedContent()} qui récupère le dernier indice
* utilisé lors de l'appelle de {@code #getLastedContent()}.
* @return renvoie le dernier indice
*/
public int getIndex() {
return this.index;
}
/**
* <p> cette fonction est en parallèle avec {@code #getLastedContent()} et {@code #getIndex()}. Elle va
* reset l'indice.
*/
public void resetIndex() {
this.index = 0;
}
/**
* @return cette fonction renvoie le String de l'indice puis l'incrémenter. Si c'est la fin de la liste,
* il renvoie null sans incrémenter
*/
public String getLastedContent() {
return (this.getArrayContent().size() > this.index) ? getArrayContent().get(this.index++) : null;
}
/**
* <p>cherche les informations et trie seulement les nouvelles entre eux :
* <pre><code>
* Reseau reseau = new Reseau("ChatTest"); // dans le serveur : {"arbre", "pomme", "chocolat", "arbre"}
*System.out.println(reseau.searchContentSorted().toString()); // {"arbre", "arbre", "pomme", "chocolat"}
* </code></pre>
* @return il renvoie le {@link ArrayList} de la liste
*/
public ArrayList<String> searchContentSorted() {
ArrayList<String> localNewerArrayList = this.searchContent();
if (this.getArrayContent().isEmpty()) this.addContentToContent(localNewerArrayList);
else this.searchDuplicates(localNewerArrayList);
return this.wordArrayList;
}
/**
* <p> cherche les informations mais ne trie pas les nouvelles entre eux :
* <pre><code>
* Reseau reseau = new Reseau("ChatTest"); // dans le serveur : {"arbre", "pomme", "chocolat", "arbre"}
*System.out.println(reseau.searchContentSorted().toString()); // {"arbre", "arbre", "pomme", "chocolat"}
* </code></pre>
* <p> attention, il peut y avoir des erreurs en rajoutant par exemple {"arbre", "pomme", "chocolat", "pomme"}
* @return
*/
public ArrayList<String> searchArrayListNotSorted() {
ArrayList<String> localNewerArrayList = this.searchContent();
this.addContentToContent(localNewerArrayList);
return this.wordArrayList;
}
/**
* <p> ce programme essaye d'envoyer le String en parametre. Attention, la communication entre le serveur et la machine
* peut prendre du temps !
* @param content Le contenu de texte que vous voulez renvoyer
*/
public void sendContent(String content) {
try {
this.url = new URL(ADDRESS + CHANNEL + "?nonce=" + this.generateNonce());
HttpsURLConnection connection = (HttpsURLConnection)this.url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
OutputStream outputStream = connection.getOutputStream();
outputStream.write(serializeToString(content));
outputStream.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
inputStream.close();
} else {
System.out.println("Erreur lors de l'envoi de la requête. Code de réponse : " + responseCode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private ArrayList<String> searchContent() {
try {
byte[] bytes = this.url.openConnection().getInputStream().readAllBytes();
ArrayList<String> localNewerArrayList = new ArrayList<String>();
StringBuffer textContent = new StringBuffer();
for(int i = 0; i < bytes.length; i++) {
byte charByte = bytes[i];
if(charByte == '|' && textContent.length() > 0) {
int size = Integer.parseInt(textContent.toString());
byte[] buffer = copyOfRange(bytes, i + 1, i + 1 + size);
localNewerArrayList.add(new String(buffer));
i += size;
textContent.setLength(0);
} else {
textContent.append((char)charByte);
}
}
return localNewerArrayList;
} catch (Exception e) {
return null;
}
}
private void addContentToContent(ArrayList<String> localArrayList) {
int arrayListLength = this.getArrayContent().size();
this.newerWordArrayList.clear();
for(int i = arrayListLength; i < localArrayList.size(); i++) {
String arrayListValue = localArrayList.get(i);
this.wordArrayList.add(arrayListValue);
this.newerWordArrayList.add(arrayListValue);
}
}
private void searchDuplicates(ArrayList<String> localArrayList) {
HashMap<String, Integer> counterHashMap = this.compareHashMap(
arrayListToHashmapCounter(this.wordArrayList),
arrayListToHashmapCounter(localArrayList)
);
this.newerWordArrayList.clear();
for(Map.Entry<String, Integer> value : counterHashMap.entrySet()) {
String arrayListValue = value.getKey();
for(int i =0; i<value.getValue(); i++) {
this.wordArrayList.add(arrayListValue);
this.newerWordArrayList.add(arrayListValue);
}
}
}
private HashMap<String, Integer> arrayListToHashmapCounter(ArrayList<String> list) {
HashMap<String, Integer> hashmapListCounter = new HashMap<String, Integer>();
for(int i = 0; i<list.size(); i++) {
String key = list.get(i);
Integer value = 0;
if(hashmapListCounter.containsKey(key)) {
value = Integer.sum(hashmapListCounter.get(key), 1);
} else {
value = 1;
}
hashmapListCounter.put(key, value);
}
return hashmapListCounter;
}
private HashMap<String, Integer> compareHashMap(HashMap<String, Integer> olderHashMap, HashMap<String, Integer> newerHashMap) {
HashMap<String, Integer> hashMapCompared = new HashMap<String, Integer>();
for (Map.Entry<String, Integer> entry : newerHashMap.entrySet()) {
String key = entry.getKey();
Integer newValue = entry.getValue();
Integer oldValue = olderHashMap.get(key);
if (oldValue == null) {
hashMapCompared.put(key, newValue);
} else if (newValue > oldValue) {
hashMapCompared.put(key, newValue - oldValue);
}
}
return hashMapCompared;
}
private String generateNonce() {
return UUID.randomUUID().toString().replace("-", "")+
UUID.randomUUID().toString().replace("-", "");
}
private byte[] serializeToString(String text) throws IOException {
return text.getBytes();
}
private void connexion() {
try {
this.url = new URL(ADDRESS + CHANNEL);
this.searchContentSorted();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,13 @@
package environnements;
import types.Effect;
public interface Grid {
public default String getName() { return this.toString().toLowerCase(); }
public default Effect get() { return null; }
public void updateStringCode(String textCode);
public String getStringCode();
public Grid[] getValues();
}

View File

@@ -3,7 +3,7 @@ package environnements;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import object.*; import types.*;
import personnages.*; import personnages.*;
@@ -16,17 +16,17 @@ public class Map {
* cette variable est toute la grille où se * cette variable est toute la grille où se
* passe tout le jeu. * passe tout le jeu.
*/ */
private Object grid[][]; private Grid grid[][];
/** /**
* cette variable recupere tout les objects stockés, * cette variable recupere tout les Grids stockés,
* elle complete {@link #coordinateItems}. * elle complete {@link #coordinateItems}.
*/ */
private ArrayList<Object> ObjectItems; private ArrayList<Grid> GridItems;
/** /**
* cette variable recupere tout les coordonnées des * cette variable recupere tout les coordonnées des
* objects stockés, elle complete {@link #ObjectItems}. * Grids stockés, elle complete {@link #GridItems}.
*/ */
private ArrayList<int[]> coordinateItems; private ArrayList<int[]> coordinateItems;
@@ -45,9 +45,9 @@ public class Map {
this.longueur = longueur; this.longueur = longueur;
this.largeur = largeur; this.largeur = largeur;
this.grid = new Object[this.largeur][this.longueur]; this.grid = new Grid[this.largeur][this.longueur];
this.ObjectItems = new ArrayList<>(); this.GridItems = new ArrayList<>();
this.coordinateItems = new ArrayList<>(); this.coordinateItems = new ArrayList<>();
this.fillGrid(); this.fillGrid();
@@ -61,7 +61,7 @@ public class Map {
private void fillGrid() { private void fillGrid() {
for(int i = 0; i < this.grid.length; i++) { for(int i = 0; i < this.grid.length; i++) {
for(int k = 0; k < this.grid[0].length; k++) { for(int k = 0; k < this.grid[0].length; k++) {
this.grid[i][k] = Items.VOID; this.grid[i][k] = Item.VOID;
} }
} }
} }
@@ -69,7 +69,7 @@ public class Map {
/** /**
* renvoie la grille du jeu. * renvoie la grille du jeu.
*/ */
public Object[][] getGrid() { public Grid[][] getGrid() {
return grid.clone(); return grid.clone();
} }
@@ -83,9 +83,9 @@ public class Map {
* @param coordinate * @param coordinate
* @return un {@link Effects} * @return un {@link Effects}
*/ */
public Effects getEffect(int[] coordinate) { public Effect getEffect(int[] coordinate) {
Object object = this.grid[coordinate[1]][coordinate[0]]; Grid gridCoordinate = this.grid[coordinate[1]][coordinate[0]];
return (object instanceof Items) ? ((Items)object).getEffects() : ((Snake)object).getEffects(); return gridCoordinate.get();
} }
/** /**
@@ -96,12 +96,12 @@ public class Map {
} }
/** /**
* inverse toute la grille pour soit mettre 0, 0 en bas * inverse toute la grille pour soit mettre (0, 0) en bas
* ou en haut. * ou en haut.
*/ */
public Object[][] getInverseGrid() { public Grid[][] getInverseGrid() {
Object[][] grid = getGrid(); Grid[][] grid = getGrid();
Object[][] inverseGrid = new Object[this.largeur][this.longueur]; Grid[][] inverseGrid = new Grid[this.largeur][this.longueur];
int k = 0; int k = 0;
for (int i = grid.length; i> 0; --i) { for (int i = grid.length; i> 0; --i) {
@@ -113,35 +113,34 @@ public class Map {
/** /**
* ajoute les coordonnées et les objets de façon non aléatoire * ajoute les coordonnées et les objets de façon non aléatoire
* @param object * @param Grid
* @param x * @param x
* @param y * @param y
*/ */
public void addObjects(Object object, int x, int y) { public void addObjects(Grid Grid, int x, int y) {
this.coordinateItems.add(new int[]{x, y}); this.coordinateItems.add(new int[]{x, y});
this.ObjectItems.add(object); this.GridItems.add(Grid);
} }
/** /**
* cette fonction ajoute dans {@link #grid} les * cette fonction ajoute dans {@link #grid} les
* objects contenu dans {@link #coordinateItems} * Grids contenu dans {@link #coordinateItems}
* et {@link #ObjectItems}. * et {@link #GridItems}.
* @param objects prend le type d'objets que vous voulez * @param Grids prend le type d'objets que vous voulez
* mettre dedans. * mettre dedans.
* @param number prend le nombre d'objets global que * @param number prend le nombre d'objets global que
* vous voulez mettre dedans. * vous voulez mettre dedans.
*/ */
public void addObjectsRandomize(Object[] objects, int number) { public void addObjectsRandomize(Item[] item, int number) {
int lengthObjects = objects.length-1; int lengthGrids = item.length-1;
Random random = new Random(); Random random = new Random();
for(int i = 0; i<lengthObjects; i++) { for(int i = 0; i<lengthGrids; i++) {
int value = random.nextInt(number); int value = random.nextInt(number);
number -= value; number -= value;
randomize(objects[i], value); randomize(item[i], value);
} }
randomize(objects[lengthObjects], number); randomize(item[lengthGrids], number);
placeObjects();
} }
/** /**
@@ -153,10 +152,10 @@ public class Map {
for (int[] coordinate : personnage.getCoordinate()) { for (int[] coordinate : personnage.getCoordinate()) {
if (index == 0) { if (index == 0) {
this.grid[coordinate[1]][coordinate[0]] = Snake.HEAD; this.grid[coordinate[1]][coordinate[0]] = SnakePart.HEAD;
} else { } else {
this.grid[coordinate[1]][coordinate[0]] = Snake.BODY; this.grid[coordinate[1]][coordinate[0]] = SnakePart.BODY;
} }
index++; index++;
} }
@@ -171,14 +170,14 @@ public class Map {
* de 1 dedans donc (1, 1) dans grid = (2, 2) dans edgesGrid * de 1 dedans donc (1, 1) dans grid = (2, 2) dans edgesGrid
* @return la liste avec les murs. * @return la liste avec les murs.
*/ */
public Object[][] addEdges() { public Grid[][] addEdges() {
Object[][] grid = this.getGrid(); Grid[][] grid = this.getGrid();
Object[][] edgesGrid = new Object[this.largeur+2][this.longueur+2]; Grid[][] edgesGrid = new Grid[this.largeur+2][this.longueur+2];
for(int i = 0; i < edgesGrid.length; i++) { for(int i = 0; i < edgesGrid.length; i++) {
for(int k = 0; k < edgesGrid[0].length; k++) { for(int k = 0; k < edgesGrid[0].length; k++) {
if (i == 0 || i == edgesGrid.length - 1 || k == 0 || k == edgesGrid[0].length - 1) { if (i == 0 || i == edgesGrid.length - 1 || k == 0 || k == edgesGrid[0].length - 1) {
edgesGrid[i][k] = Items.WALL; edgesGrid[i][k] = Item.WALL;
} else { } else {
edgesGrid[i][k] = grid[i-1][k-1]; edgesGrid[i][k] = grid[i-1][k-1];
} }
@@ -201,7 +200,7 @@ public class Map {
int[] itemCoordinate = this.coordinateItems.get(i); int[] itemCoordinate = this.coordinateItems.get(i);
if (itemCoordinate[0] == coordinate[0] && itemCoordinate[1] == coordinate[1]) { if (itemCoordinate[0] == coordinate[0] && itemCoordinate[1] == coordinate[1]) {
this.coordinateItems.remove(i); this.coordinateItems.remove(i);
this.ObjectItems.remove(i); this.GridItems.remove(i);
} }
} }
} }
@@ -214,7 +213,7 @@ public class Map {
for(int i = 0; i<this.coordinateItems.size(); i++) { for(int i = 0; i<this.coordinateItems.size(); i++) {
int[] coordinate = this.coordinateItems.get(i); int[] coordinate = this.coordinateItems.get(i);
this.grid[coordinate[1]][coordinate[0]] = ObjectItems.get(i); this.grid[coordinate[1]][coordinate[0]] = GridItems.get(i);
} }
} }
@@ -222,21 +221,19 @@ public class Map {
* prend des coordonnées au hasard et regarde si c'est * prend des coordonnées au hasard et regarde si c'est
* pas deja occupé par un item ou un corps sinon, il * pas deja occupé par un item ou un corps sinon, il
* recommence. * recommence.
* @param object * @param Grid
* @param number * @param number
*/ */
private void randomize(Object object, int number) { private void randomize(Item Grid, int number) {
Random random = new Random(); Random random = new Random();
for (int i = 0; i<number; i++) { for (int i = 0; i<number; i++) {
int x = random.nextInt(this.grid[0].length); int x = random.nextInt(this.grid[0].length);
int y = random.nextInt(this.grid.length); int y = random.nextInt(this.grid.length);
if(!(this.grid[y][x] instanceof Snake) && (Items)this.grid[y][x] == Items.VOID) { if(this.grid[y][x] == Item.VOID) {
this.coordinateItems.add(new int[] {x, y}); this.addObjects(Grid, x, y);
this.ObjectItems.add(object); } else {
}
else {
i--; i--;
} }
} }

View File

@@ -1,9 +1,7 @@
import environnements.Map; import environnements.*;
import game.Terminal; import game.Terminal;
import object.Items; import personnages.*;
import personnages.Personnage; import types.Item;
import personnages.Player;
import tests.*;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
@@ -15,8 +13,9 @@ public class Main {
}; };
Map map = new Map(20, 20); Map map = new Map(20, 20);
map.addObjectsRandomize(new Object[] {Items.FRAISE}, 2); // map.addObjects(Item.FRAISE, 0, 0);
// map.addObjectsRandomize(new Item[] {Item.FRAISE}, 1);
new Terminal(map, personnages); new Terminal(map, personnages).run();
} }
} }

View File

@@ -2,7 +2,8 @@ package personnages;
import java.util.ArrayList; import java.util.ArrayList;
import object.*; import environnements.*;
import types.*;
/** /**
* Cette classe est la primitive des classes * Cette classe est la primitive des classes
@@ -10,7 +11,7 @@ import object.*;
* tout le necessaire pour tout les personnages * tout le necessaire pour tout les personnages
* jouable du jeu. * jouable du jeu.
*/ */
public class Personnage { public abstract class Personnage {
/** /**
* cette variable contient la valeur dans laquelle on sait * cette variable contient la valeur dans laquelle on sait
* quand le corps du snake grandi. il est le même pour tout * quand le corps du snake grandi. il est le même pour tout
@@ -77,7 +78,7 @@ public class Personnage {
* retourner false * retourner false
* </code></pre> * </code></pre>
*/ */
public boolean applyEffects(Effects effect) { public boolean applyEffects(Effect effect) {
switch (effect) { switch (effect) {
case DECREASESIZE: case DECREASESIZE:
if (this.coordinate.size() > 1) {this.coordinate.removeLast();} break; if (this.coordinate.size() > 1) {this.coordinate.removeLast();} break;
@@ -155,7 +156,7 @@ public class Personnage {
* @param mouvement est le mouvement du personnage, comme HAUT, BAS, * @param mouvement est le mouvement du personnage, comme HAUT, BAS,
* GAUCHE et DROITE. * GAUCHE et DROITE.
*/ */
public void moveSnake(Mouvements mouvement) { public void moveSnake(Mouvement mouvement) {
int[] latestCoordinate = getLatestCoordinate(); int[] latestCoordinate = getLatestCoordinate();
for (int i = this.coordinate.size() - 1; i > 0; i--) { for (int i = this.coordinate.size() - 1; i > 0; i--) {
@@ -173,4 +174,6 @@ public class Personnage {
private void increaseSnake(int[] coordinate) { private void increaseSnake(int[] coordinate) {
if(round > 0 && n > 0) if (round%n == 0) this.coordinate.add(coordinate); if(round > 0 && n > 0) if (round%n == 0) this.coordinate.add(coordinate);
} }
public abstract boolean round(Map map);
} }

View File

@@ -1,6 +1,9 @@
package personnages; package personnages;
import object.*; import java.util.Scanner;
import environnements.Map;
import types.*;
/** /**
* la classe Player a comme classe parent {@link Personnage} * la classe Player a comme classe parent {@link Personnage}
@@ -25,7 +28,7 @@ public class Player extends Personnage {
} }
public boolean moveCoordinate(int keys) { public boolean moveCoordinate(int keys) {
Mouvements value = getMouvement(keys); Mouvement value = getMouvement(keys);
if (value != null) { if (value != null) {
moveSnake(value); moveSnake(value);
@@ -34,14 +37,58 @@ public class Player extends Personnage {
return false; return false;
} }
public Mouvements getMouvement(Integer keys) { public Mouvement getMouvement(Integer keys) {
switch (keys) { switch (keys) {
case 0x77: case 0x7A: return Mouvements.HAUT; // w ou z case 0x77: case 0x7A: return Mouvement.HAUT; // w ou z
case 0x73: return Mouvements.BAS; // s case 0x73: return Mouvement.BAS; // s
case 0x61: case 0x71: return Mouvements.GAUCHE; // a ou q case 0x61: case 0x71: return Mouvement.GAUCHE; // a ou q
case 0x64: return Mouvements.DROITE; // d case 0x64: return Mouvement.DROITE; // d
case null: return null; case null: return null;
default: return null; default: return null;
} }
} }
/**
* transforme le String en prennant le premier char et
* le mets en ascii dans la classe Integer.
* @param input
* @return
*/
private Integer changeCoordinate(String input) {
if (input.length() > 0) {
return (int)input.charAt(0);
}
return null;
}
/**
* Cette fonction est uniquement destiné pour la classe
* Players pour recuperer l'input dans le terminal.
* @param player
* @return il retourne int qui est le char en ascii
*/
@SuppressWarnings("resource")
private int getInput() {
Scanner scanner = new Scanner(System.in);
Integer input = null;
while(this.getMouvement(input) == null) {
input = this.changeCoordinate(scanner.nextLine());
}
// scanner.close();
return input.intValue();
}
@Override
public boolean round(Map map) {
this.moveCoordinate(this.getInput());
int[] coordinate = this.getHeadCoordinate();
if(map.isGameOver(coordinate) || this.applyEffects(map.getEffect(coordinate))) return true;
map.deleteItems(coordinate);
this.increaseRound();
return false;
}
} }

View File

@@ -1,7 +0,0 @@
package personnages;
public class Robot extends Personnage {
public Robot(int[] coordinate) {
super(coordinate);
}
}

View File

@@ -1,9 +1,8 @@
package display; package display;
import java.util.ArrayList; import environnements.Grid;
import personnages.Personnage;
import object.*; import types.Item;
import personnages.*;
public class Display { public class Display {
/** /**
@@ -18,133 +17,51 @@ public class Display {
* cette fonction dessine la grille avec des noms * cette fonction dessine la grille avec des noms
* pour chaque items. * pour chaque items.
*/ */
public static void printMap(Object[][] map) { public static void printMapName(Grid[][] map) {
for (Object[] object : map) { for(Grid[] mapLine : map) {
for (Object value : object) { for(Grid mapValue : mapLine) {
System.out.print(value.toString() + " "); System.out.print(" " + mapValue.getName());
} }
System.out.println(); System.out.println();
} }
} }
/** public static void printMap(Grid[][] map) {
* cette fonction print le snake dans le terminal avec des
* caracteres speciaux, (du utf-8).
* @param map
* @param personnages
*/
public static void printMap(Object[][] map, Personnage[] personnages) {
for (int i = 0; i<map.length; i++) { for (int i = 0; i<map.length; i++) {
for(int k = 0; k<map[0].length; k++) { for(int k = 0; k<map[0].length; k++) {
Object object = map[i][k]; if (map[i][k] == Item.WALL) printWall(map, k, i);
print(map[i][k]);
if(object instanceof Items) printItems((Items)object, map, k, i);
if(object instanceof Snake) printSnake((Snake)object, personnages, k, i);
} }
System.out.println(); System.out.println();
} }
} }
public static void printInformation(int round, int playerIndex, Personnage personnage) { private static void print(Grid gridTypes) {
for(Grid value : gridTypes.getValues()) {
if (value == gridTypes) System.out.print(value.getStringCode());
}
}
private static void printWall(Grid[][] map, int x, int y) {
// TOP BOT LEFT RIGHT
boolean[] position = new boolean[] {
(y > 0) ? map[y - 1][x] == Item.WALL : false,
(y < map.length - 1) ? map[y+1][x] == Item.WALL : false,
(x > 0) ? map[y][x - 1] == Item.WALL : false,
(x < map[y].length - 1) ? map[y][x + 1] == Item.WALL : false,
};
for(Wall value : Wall.values()) {
if(value.isEqual(position)) map[y][x].updateStringCode(value.getAscii());
}
}
public static void printInformation(int round, Personnage personnage) {
int[] coordinate = personnage.getHeadCoordinate(); int[] coordinate = personnage.getHeadCoordinate();
System.out.println( System.out.println(
"Round : " + round + " | N : " + Personnage.n + "Round : " + round + " | N : " + Personnage.n +"\n Joueur : " + personnage.getName() +
"\n Joueur " + (playerIndex+1) + " : " + personnage.getName() + " (" + " (" + coordinate[0]+", "+ coordinate[1] +") | size : " + personnage.getSize()
coordinate[0]+", "+ coordinate[1] +") | size : " + personnage.getSize()
); );
} }
private static void printSnake(Snake item, Personnage[] personnages, int x, int y) {
switch (item) {
case BODY: System.out.print(" \u25A1 "); break;
case HEAD: printHead(personnages, x, y); break;
}
}
private static void printItems(Items item, Object[][] map, int x, int y) {
switch (item) {
case FRAISE: System.out.print(" \uF353 "); break;
case WALL: printWall(map, x, y); break;
case VOID: System.out.print(" "); break;
}
}
private static void printWall(Object[][] map, int x, int y) {
// TOP BOT LEFT RIGHT
boolean[] position = new boolean[] {
(y > 0) ? map[y - 1][x] == Items.WALL : false,
(y < map.length - 1) ? map[y+1][x] == Items.WALL : false,
(x > 0) ? map[y][x - 1] == Items.WALL : false,
(x < map[y].length - 1) ? map[y][x + 1] == Items.WALL : false,
};
System.out.print(whichWall(position));
}
private static String whichWall(boolean[] isWall) {
String positionWall = new String();
if (isWall[0] && isWall[1] && isWall[2] && isWall[3]) positionWall = "\u2550\u256C\u2550";
else if (isWall[0] && isWall[1] && isWall[3]) positionWall = "\u2560";
else if (isWall[0] && isWall[1] && isWall[2]) positionWall = "\u2563";
else if (isWall[0] && isWall[2] && isWall[3]) positionWall = "\u2550\u2569\u2550";
else if (isWall[1] && isWall[2] && isWall[3]) positionWall = "\u2550\u2566\u2550";
else if (isWall[0] && isWall[1]) positionWall = "\u2551";
else if (isWall[2] && isWall[3]) positionWall = "\u2550\u2550\u2550";
else if (isWall[0] && isWall[2]) positionWall = "\u255D ";
else if (isWall[0] && isWall[3]) positionWall = "\u255A";
else if (isWall[1] && isWall[2]) positionWall = "\u2557 ";
else if (isWall[1] && isWall[3]) positionWall = "\u2554";
else positionWall = "\u2550\u256C\u2550";
return positionWall;
}
private static void printHead(Personnage[] personnages, int x, int y) {
Personnage personnage = searchSnake(personnages, x, y);
if (personnage != null) {
ArrayList<int[]> personnageCoordinate = personnage.getCoordinate();
int[] primaryCoordinate = personnage.getHeadCoordinate();
if (personnageCoordinate.size() > 1) {
int[] secondCoordinate = personnageCoordinate.get(1);
// UP DOWN LEFT RIGHT
boolean[] isHead = new boolean[] {
primaryCoordinate[0] == secondCoordinate[0] && primaryCoordinate[1] > secondCoordinate[1], // UP
primaryCoordinate[0] == secondCoordinate[0] && primaryCoordinate[1] < secondCoordinate[1], // DOWN
primaryCoordinate[1] == secondCoordinate[1] && primaryCoordinate[0] > secondCoordinate[0], // LEFT
primaryCoordinate[1] == secondCoordinate[1] && primaryCoordinate[0] < secondCoordinate[0] // RIGHT
};
if (isHead[0]) {System.out.print(" \u21E9 ");return;}
else if (isHead[1]) {System.out.print(" \u21E7 ");return;}
else if (isHead[2]) {System.out.print(" \u21E8");return;}
else if (isHead[3]) {System.out.print("\u21E6 ");return;}
}
}
System.out.print(" \u25CF ");
}
private static Personnage searchSnake(Personnage[] personnages, int x, int y) {
for (Personnage personnage : personnages) {
int[] primaryCoordinate = personnage.getHeadCoordinate();
int primaryY = primaryCoordinate[1] + 1;
int primaryX = primaryCoordinate[0] + 1;
if (primaryX == x && primaryY == y) {
return personnage;
}
}
return null;
}
} }

43
src/display/Wall.java Normal file
View File

@@ -0,0 +1,43 @@
package display;
import java.util.Arrays;
public enum Wall {
ALL("\u2550\u256C\u2550", new boolean[] {true, true, true, true}),
AUCUN("\u2550\u256C\u2550", new boolean[] {false, false, false, false}),
HAUT_BAS("\u2551", new boolean[] {true, true, false, false}),
GAUCHE_DROITE("\u2550\u2550\u2550", new boolean[] {false, false, true, true}),
HAUT_GAUCHE("\u255D ", new boolean[]{true, false, true, false}),
HAUT_DROITE("\u255A", new boolean[]{true, false, false, true}),
BAS_GAUCHE("\u2557 ", new boolean[]{false, true, true, false}),
BAS_DROITE("\u2554", new boolean[] {false, true, false, true}),
HAUT_BAS_DROITE("\u2560", new boolean[] {true, true, false, true}),
HAUT_BAS_GAUCHE("\u2563", new boolean[] {true, true, true, false}),
HAUT_GAUCHE_DROITE("\u2550\u2569\u2550", new boolean[] {true, false, true, true}),
BAS_GAUCHE_DROITE("\u2550\u2566\u2550", new boolean[] {false, true, true, true});
private final boolean[] POSITION;
private final String ASCII;
Wall(String ascii, boolean[] position) {
this.POSITION = position;
this.ASCII = ascii;
}
public String getAscii() {
return this.ASCII;
}
public boolean isEqual(boolean[] position) {
return Arrays.equals(this.POSITION, position);
}
public boolean[] getPosition() {
return POSITION;
}
}

View File

@@ -1,143 +1,44 @@
package game; package game;
import display.*; import display.Display;
import personnages.*; import environnements.Map;
import environnements.*; import personnages.Personnage;
import java.util.Scanner;
public class Terminal { public class Terminal {
private int round = 0; Map map;
Personnage[] personnages;
private static Map map; private void placePersonnages() {
private static Personnage[] personnages;
private static Scanner scanner;
public Terminal(Map m, Personnage[] personnage) {
scanner = new Scanner(System.in);
personnages = personnage;
map = m;
run();
}
/**
* Cette fonction est uniquement destiné pour la classe
* Players pour recuperer l'input dans le terminal.
* @param player
* @return il retourne int qui est le char en ascii
*/
private static int getInput(Player player) {
String value = new String();
Integer input = null;
do {
value = scanner.nextLine();
input = changeCoordinate(value);
}while(player.getMouvement(input) == null);
return input.intValue();
}
/**
* transforme le String en prennant le premier char et
* le mets en ascii dans la classe Integer.
* @param input
* @return
*/
private static Integer changeCoordinate(String input) {
if (input.length() > 0) {
return (int)input.charAt(0);
}
return null;
}
/**
* place tout les personnages dans la fonction {@link #map.placePersonnages()}
* @param personnages
*/
private static void placePersonnages(Personnage[] personnages) {
for(Personnage personnage : personnages) { for(Personnage personnage : personnages) {
map.placePersonnages(personnage); map.placePersonnages(personnage);
} }
} }
/** public Terminal(Map map, Personnage[] personnages) {
* cette fonction est spécialement conçu pour gerer le gameplay du joueur. this.personnages = personnages;
* @param player this.map = map;
* @return
*/
private static boolean playerRound(Player player) {
player.moveCoordinate(getInput(player));
int[] coordinate = player.getHeadCoordinate();
if(map.isGameOver(coordinate) || player.applyEffects(map.getEffect(coordinate))) return true;
map.deleteItems(coordinate);
player.increaseRound();
return false;
} }
/** public void run() {
* cette fonction est spécialement conçu pour gerer le gameplay du robot.
* @param player
* @return
*/
private static boolean robotRound(Robot robot) {
return false;
}
/**
* cette fonction cherche si le personnage mis en paramètre
* est un {@link Player} ou un {@link Robot}.
* @param player
* @return
*/
private static boolean instancePersonnage(Personnage personnage) {
if (personnage instanceof Player) {
// tour du Player
return playerRound((Player)personnage);
}
if (personnage instanceof Robot) {
// tour du robot
return robotRound((Robot)personnage);
}
return false;
}
/**
* la fonction principal qui lance tout le jeu en terminal.
*/
private void run() {
boolean isGameOver = false;
int i = 0; int i = 0;
while(!isGameOver) { while(true) {
for (i = 0;i<personnages.length; i++) { for(Personnage personnage : personnages) {
Personnage personnage = personnages[i];
Display.clearTerminal(); Display.clearTerminal();
map.placeObjects(); map.placeObjects();
placePersonnages(personnages); placePersonnages();
Display.printInformation(this.round, i, personnage); Display.printInformation(i++, personnage);
Display.printMap(map.addEdges());
map.placeObjects(); if(personnage.round(map)) {
Display.printMap(map.addEdges(), personnages); Display.clearTerminal();
System.out.println(personnage.getName() + " à perdu!");
isGameOver = instancePersonnage(personnage); return;
if(!isGameOver) placePersonnages(personnages); }
else break;
System.out.println(1);
map.clearMap(); map.clearMap();
} }
this.round++;
} }
System.out.println("GAMEOVER \nLe joueur " + (i+1) + " à perdu !");
} }
} }

View File

@@ -1,34 +0,0 @@
package object;
public enum Items {
WALL("WALL", Effects.IMPASSABLE),
VOID("VOID", Effects.VOID),
FRAISE("FRAISE", Effects.DECREASESIZE);
private final String NAME;
private final Effects EFFECT;
Items(String name, Effects effect) {
this.NAME = name;
this.EFFECT = effect;
}
/**
* <p> type de variable pour recuperer le nom de l'item:
* <pre><code>String name = Item.WALL.getName()</code></pre>
* @return Avoir le nom de l'item
*/
public String getName() {
return this.NAME;
}
/**
* <p> type de variable pour recuperer l'effet de l'item:
* <pre><code>Effects effect = Item.WALL.getEffects()</code></pre>
* @return Avoir l'effet de l'item
*/
public Effects getEffects() {
return this.EFFECT;
}
}

View File

@@ -1,32 +0,0 @@
package object;
public enum Snake {
HEAD("TETE", Effects.IMPASSABLE),
BODY("BODY", Effects.IMPASSABLE);
private final String NAME;
private final Effects EFFECT;
Snake(String name, Effects effect) {
this.NAME = name;
this.EFFECT = effect;
}
/**
* <p> type de variable pour recuperer le nom du corps du snake:
* <pre><code>String name = Snake.HEAD.getName()</code></pre>
* @return Avoir le nom de l'item
*/
public String getName() {
return this.NAME;
}
/**
* <p> type de variable pour recuperer l'effet du corps du snake:
* <pre><code>Effects effect = Snake.HEAD.getEffects()</code></pre>
* @return Avoir l'effet de l'item
*/
public Effects getEffects() {
return this.EFFECT;
}
}

View File

@@ -2,14 +2,13 @@ package tests;
import display.Display; import display.Display;
import environnements.Map; import environnements.Map;
import object.Items;
import personnages.Personnage;
import personnages.Player; import personnages.Player;
import types.Item;
public class MapTest { public class MapTest {
public static void creationMap() { public static void creationMap() {
Map map = new Map(30, 30); Map map = new Map(30, 30);
map.addObjects(Items.FRAISE, 29, 29); map.addObjects(Item.FRAISE, 29, 29);
map.placeObjects(); map.placeObjects();
Display.printMap(map.addEdges()); Display.printMap(map.addEdges());
@@ -17,20 +16,20 @@ public class MapTest {
public static void drawMap() { public static void drawMap() {
Map map = new Map(30, 30); Map map = new Map(30, 30);
Display.printMap(map.addEdges(), null); Display.printMap(map.addEdges());
} }
public static void placePersonnageMap() { public static void placePersonnageMap() {
Map map = new Map(30, 30); Map map = new Map(30, 30);
map.placePersonnages(new Player(new int[]{1, 1}, "null")); map.placePersonnages(new Player(new int[]{1, 1}, "null"));
Display.printMap(map.addEdges(), new Personnage[] {new Player(new int[]{1, 1}, "null")}); Display.printMap(map.addEdges());
} }
public static void effects() { public static void effects() {
Map map = new Map(5, 1); Map map = new Map(5, 1);
Player player = new Player(new int[] {0, 0}, "null"); Player player = new Player(new int[] {0, 0}, "null");
map.addObjects(Items.FRAISE, 0, 0); map.addObjects(Item.FRAISE, 0, 0);
player.applyEffects(map.getEffect(player.getHeadCoordinate())); player.applyEffects(map.getEffect(player.getHeadCoordinate()));
System.out.println(player.getSize()); System.out.println(player.getSize());

View File

@@ -1,15 +1,15 @@
package tests; package tests;
import object.Effects;
import object.Mouvements;
import personnages.Personnage; import personnages.Personnage;
import personnages.Player; import personnages.Player;
import types.Effect;
import types.Mouvement;
public class PersonnageTest { public class PersonnageTest {
public static void avancerPersonnage() { public static void avancerPersonnage() {
Player player = new Player(new int[]{1, 1}, "test"); Player player = new Player(new int[]{1, 1}, "test");
player.moveSnake(Mouvements.HAUT); // si la position s'est avancé, c'est normal player.moveSnake(Mouvement.HAUT); // si la position s'est avancé, c'est normal
int[] coordinate = player.getHeadCoordinate(); int[] coordinate = player.getHeadCoordinate();
System.out.println(coordinate[0] + " " + coordinate[1]); System.out.println(coordinate[0] + " " + coordinate[1]);
@@ -20,18 +20,18 @@ public class PersonnageTest {
Player player = new Player(new int[]{1, 1}, "test"); Player player = new Player(new int[]{1, 1}, "test");
player.increaseRound(); player.increaseRound();
player.moveSnake(Mouvements.HAUT); // si il y a 2 valeurs, c'est normal player.moveSnake(Mouvement.HAUT); // si il y a 2 valeurs, c'est normal
for (int[] coordinate : player.getCoordinate()) { for (int[] coordinate : player.getCoordinate()) {
System.out.println(coordinate[0] + " " + coordinate[1]); System.out.println(coordinate[0] + " " + coordinate[1]);
} }
} }
public static void effectsPersonnage() { public static void effectPersonnage() {
Personnage.n = 2; Personnage.n = 2;
Player player = new Player(new int[]{1, 1}, "test"); Player player = new Player(new int[]{1, 1}, "test");
player.applyEffects(Effects.DECREASESIZE); // si c'est vide c'est que ça marche player.applyEffects(Effect.DECREASESIZE); // si c'est vide c'est que ça marche
System.out.println(player.getCoordinate()); System.out.println(player.getCoordinate());
} }

View File

@@ -1,23 +1,23 @@
package object; package types;
/** /**
* cette enumérateur {@link Effects} contient tout les effets * cette enumérateur {@link Effects} contient tout les effets
* necessaire pour le bon déroulement du jeu et quelque effets * necessaire pour le bon déroulement du jeu et quelque effets
* amusant qui pousse un peu plus les mecaniques du jeu. * amusant qui pousse un peu plus les mecaniques du jeu.
*/ */
public enum Effects { public enum Effect {
/** /**
* reduis le corps de 1. * Effet : duit la taille du serpent de 1 segment.
*/ */
DECREASESIZE, DECREASESIZE,
/** /**
* tue le joueur si contact. * Effet : Intransposable, entraînant la mort du joueur lors du contact.
*/ */
IMPASSABLE, IMPASSABLE,
/** /**
* le vide. * Effet : Vide, aucun effet.
*/ */
VOID; VOID;
} }

67
src/types/Item.java Normal file
View File

@@ -0,0 +1,67 @@
package types;
import environnements.Grid;
/**
* cette enum représente différents types d'objets dans le jeu.
*/
public enum Item implements Grid {
/**
* Mur impassable.
* Effet associé : <pre>{@code types.Effect.IMPASSABLE}</pre>
* utf : null car c'est un autre programme qui gère le mur.
*/
WALL(Effect.IMPASSABLE, null),
/**
* Zone vide sans effet.
* Effet associé : <pre>{@code types.Effect.VOID}</pre>
* utf : vide
*/
VOID(Effect.VOID, " "),
/**
* Fraise.
* Effet associé : <pre>{@code types.Effect.DECREASESIZE}</pre>
* utf : un drapeau (0x26FF)
*/
FRAISE(Effect.DECREASESIZE, " \u26FF ");
private final Effect EFFECT;
private String utfCode;
/**
* @param effect L'effet associé à l'objet.
*/
Item(Effect effect, String utf) {
this.EFFECT = effect;
this.utfCode = utf;
}
/**
* cette methode donne l'effet associé à l'objet.
*
* @return L'effet associé à l'objet.
*/
@Override
public Effect get() {
return this.EFFECT;
}
@Override
public Item[] getValues() {
return values();
}
@Override
public String getStringCode() {
return this.utfCode;
}
@Override
public void updateStringCode(String textCode) {
this.utfCode = textCode;
}
}

View File

@@ -1,14 +1,11 @@
package object; package types;
import java.io.Serializable;
/** /**
* Cet enumerateur prend en charge tout les mouvements possible * Cet enumerateur prend en charge tout les mouvements possible
* pour le serpent, il a uniquement la possibilité de se déplacer * pour le serpent, il a uniquement la possibilité de se déplacer
* grâce a {@link Mouvements} pour la classe Player et Robot. * grâce a {@link Mouvement} pour la classe Player et Robot.
*/ */
@SuppressWarnings("unused") public enum Mouvement {
public enum Mouvements implements Serializable {
/** /**
* HAUT prend comme coordonnée (0, -1) pour se déplacer. * HAUT prend comme coordonnée (0, -1) pour se déplacer.
* @param x = 0 * @param x = 0
@@ -40,7 +37,7 @@ public enum Mouvements implements Serializable {
private final int deltaX; private final int deltaX;
private final int deltaY; private final int deltaY;
Mouvements(int deltaX, int deltaY) { Mouvement(int deltaX, int deltaY) {
this.deltaX = deltaX; this.deltaX = deltaX;
this.deltaY = deltaY; this.deltaY = deltaY;
} }

36
src/types/SnakePart.java Normal file
View File

@@ -0,0 +1,36 @@
package types;
import environnements.Grid;
public enum SnakePart implements Grid {
HEAD(Effect.IMPASSABLE, " \u25CF "),
BODY(Effect.IMPASSABLE, " \u25A1 ");
private final Effect EFFECT;
private String utfCode;
SnakePart(Effect effect, String utf) {
this.EFFECT = effect;
this.utfCode = utf;
}
@Override
public Effect get() {
return this.EFFECT;
}
@Override
public SnakePart[] getValues() {
return values();
}
@Override
public String getStringCode() {
return this.utfCode;
}
@Override
public void updateStringCode(String textCode) {
this.utfCode = textCode;
}
}