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.Random;
import object.*;
import types.*;
import personnages.*;
@@ -16,17 +16,17 @@ public class Map {
* cette variable est toute la grille où se
* 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}.
*/
private ArrayList<Object> ObjectItems;
private ArrayList<Grid> GridItems;
/**
* 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;
@@ -45,9 +45,9 @@ public class Map {
this.longueur = longueur;
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.fillGrid();
@@ -61,7 +61,7 @@ public class Map {
private void fillGrid() {
for(int i = 0; i < this.grid.length; i++) {
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.
*/
public Object[][] getGrid() {
public Grid[][] getGrid() {
return grid.clone();
}
@@ -83,9 +83,9 @@ public class Map {
* @param coordinate
* @return un {@link Effects}
*/
public Effects getEffect(int[] coordinate) {
Object object = this.grid[coordinate[1]][coordinate[0]];
return (object instanceof Items) ? ((Items)object).getEffects() : ((Snake)object).getEffects();
public Effect getEffect(int[] coordinate) {
Grid gridCoordinate = this.grid[coordinate[1]][coordinate[0]];
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.
*/
public Object[][] getInverseGrid() {
Object[][] grid = getGrid();
Object[][] inverseGrid = new Object[this.largeur][this.longueur];
public Grid[][] getInverseGrid() {
Grid[][] grid = getGrid();
Grid[][] inverseGrid = new Grid[this.largeur][this.longueur];
int k = 0;
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
* @param object
* @param Grid
* @param x
* @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.ObjectItems.add(object);
this.GridItems.add(Grid);
}
/**
* cette fonction ajoute dans {@link #grid} les
* objects contenu dans {@link #coordinateItems}
* et {@link #ObjectItems}.
* @param objects prend le type d'objets que vous voulez
* Grids contenu dans {@link #coordinateItems}
* et {@link #GridItems}.
* @param Grids prend le type d'objets que vous voulez
* mettre dedans.
* @param number prend le nombre d'objets global que
* vous voulez mettre dedans.
*/
public void addObjectsRandomize(Object[] objects, int number) {
int lengthObjects = objects.length-1;
public void addObjectsRandomize(Item[] item, int number) {
int lengthGrids = item.length-1;
Random random = new Random();
for(int i = 0; i<lengthObjects; i++) {
for(int i = 0; i<lengthGrids; i++) {
int value = random.nextInt(number);
number -= value;
randomize(objects[i], value);
randomize(item[i], value);
}
randomize(objects[lengthObjects], number);
placeObjects();
randomize(item[lengthGrids], number);
}
/**
@@ -153,10 +152,10 @@ public class Map {
for (int[] coordinate : personnage.getCoordinate()) {
if (index == 0) {
this.grid[coordinate[1]][coordinate[0]] = Snake.HEAD;
this.grid[coordinate[1]][coordinate[0]] = SnakePart.HEAD;
} else {
this.grid[coordinate[1]][coordinate[0]] = Snake.BODY;
this.grid[coordinate[1]][coordinate[0]] = SnakePart.BODY;
}
index++;
}
@@ -171,14 +170,14 @@ public class Map {
* de 1 dedans donc (1, 1) dans grid = (2, 2) dans edgesGrid
* @return la liste avec les murs.
*/
public Object[][] addEdges() {
Object[][] grid = this.getGrid();
Object[][] edgesGrid = new Object[this.largeur+2][this.longueur+2];
public Grid[][] addEdges() {
Grid[][] grid = this.getGrid();
Grid[][] edgesGrid = new Grid[this.largeur+2][this.longueur+2];
for(int i = 0; i < edgesGrid.length; i++) {
for(int k = 0; k < edgesGrid[0].length; k++) {
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 {
edgesGrid[i][k] = grid[i-1][k-1];
}
@@ -201,7 +200,7 @@ public class Map {
int[] itemCoordinate = this.coordinateItems.get(i);
if (itemCoordinate[0] == coordinate[0] && itemCoordinate[1] == coordinate[1]) {
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++) {
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
* pas deja occupé par un item ou un corps sinon, il
* recommence.
* @param object
* @param Grid
* @param number
*/
private void randomize(Object object, int number) {
private void randomize(Item Grid, int number) {
Random random = new Random();
for (int i = 0; i<number; i++) {
int x = random.nextInt(this.grid[0].length);
int y = random.nextInt(this.grid.length);
if(!(this.grid[y][x] instanceof Snake) && (Items)this.grid[y][x] == Items.VOID) {
this.coordinateItems.add(new int[] {x, y});
this.ObjectItems.add(object);
}
else {
if(this.grid[y][x] == Item.VOID) {
this.addObjects(Grid, x, y);
} else {
i--;
}
}

View File

@@ -1,9 +1,7 @@
import environnements.Map;
import environnements.*;
import game.Terminal;
import object.Items;
import personnages.Personnage;
import personnages.Player;
import tests.*;
import personnages.*;
import types.Item;
public class Main {
public static void main(String[] args) {
@@ -15,8 +13,9 @@ public class Main {
};
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 object.*;
import environnements.*;
import types.*;
/**
* Cette classe est la primitive des classes
@@ -10,7 +11,7 @@ import object.*;
* tout le necessaire pour tout les personnages
* jouable du jeu.
*/
public class Personnage {
public abstract class Personnage {
/**
* cette variable contient la valeur dans laquelle on sait
* quand le corps du snake grandi. il est le même pour tout
@@ -77,7 +78,7 @@ public class Personnage {
* retourner false
* </code></pre>
*/
public boolean applyEffects(Effects effect) {
public boolean applyEffects(Effect effect) {
switch (effect) {
case DECREASESIZE:
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,
* GAUCHE et DROITE.
*/
public void moveSnake(Mouvements mouvement) {
public void moveSnake(Mouvement mouvement) {
int[] latestCoordinate = getLatestCoordinate();
for (int i = this.coordinate.size() - 1; i > 0; i--) {
@@ -173,4 +174,6 @@ public class Personnage {
private void increaseSnake(int[] 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;
import object.*;
import java.util.Scanner;
import environnements.Map;
import types.*;
/**
* la classe Player a comme classe parent {@link Personnage}
@@ -25,7 +28,7 @@ public class Player extends Personnage {
}
public boolean moveCoordinate(int keys) {
Mouvements value = getMouvement(keys);
Mouvement value = getMouvement(keys);
if (value != null) {
moveSnake(value);
@@ -34,14 +37,58 @@ public class Player extends Personnage {
return false;
}
public Mouvements getMouvement(Integer keys) {
public Mouvement getMouvement(Integer keys) {
switch (keys) {
case 0x77: case 0x7A: return Mouvements.HAUT; // w ou z
case 0x73: return Mouvements.BAS; // s
case 0x61: case 0x71: return Mouvements.GAUCHE; // a ou q
case 0x64: return Mouvements.DROITE; // d
case 0x77: case 0x7A: return Mouvement.HAUT; // w ou z
case 0x73: return Mouvement.BAS; // s
case 0x61: case 0x71: return Mouvement.GAUCHE; // a ou q
case 0x64: return Mouvement.DROITE; // d
case null: 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;
import java.util.ArrayList;
import object.*;
import personnages.*;
import environnements.Grid;
import personnages.Personnage;
import types.Item;
public class Display {
/**
@@ -18,133 +17,51 @@ public class Display {
* cette fonction dessine la grille avec des noms
* pour chaque items.
*/
public static void printMap(Object[][] map) {
for (Object[] object : map) {
for (Object value : object) {
System.out.print(value.toString() + " ");
public static void printMapName(Grid[][] map) {
for(Grid[] mapLine : map) {
for(Grid mapValue : mapLine) {
System.out.print(" " + mapValue.getName());
}
System.out.println();
}
}
/**
* 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) {
public static void printMap(Grid[][] map) {
for (int i = 0; i<map.length; i++) {
for(int k = 0; k<map[0].length; k++) {
Object object = map[i][k];
if(object instanceof Items) printItems((Items)object, map, k, i);
if(object instanceof Snake) printSnake((Snake)object, personnages, k, i);
if (map[i][k] == Item.WALL) printWall(map, k, i);
print(map[i][k]);
}
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();
System.out.println(
"Round : " + round + " | N : " + Personnage.n +
"\n Joueur " + (playerIndex+1) + " : " + personnage.getName() + " (" +
coordinate[0]+", "+ coordinate[1] +") | size : " + personnage.getSize()
"Round : " + round + " | N : " + Personnage.n +"\n Joueur : " + personnage.getName() +
" (" + 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;
import display.*;
import personnages.*;
import environnements.*;
import java.util.Scanner;
import display.Display;
import environnements.Map;
import personnages.Personnage;
public class Terminal {
private int round = 0;
Map map;
Personnage[] personnages;
private static Map map;
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) {
private void placePersonnages() {
for(Personnage personnage : personnages) {
map.placePersonnages(personnage);
}
}
/**
* cette fonction est spécialement conçu pour gerer le gameplay du joueur.
* @param player
* @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 Terminal(Map map, Personnage[] personnages) {
this.personnages = personnages;
this.map = map;
}
/**
* 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;
public void run() {
int i = 0;
while(!isGameOver) {
for (i = 0;i<personnages.length; i++) {
Personnage personnage = personnages[i];
while(true) {
for(Personnage personnage : personnages) {
Display.clearTerminal();
map.placeObjects();
placePersonnages(personnages);
placePersonnages();
Display.printInformation(this.round, i, personnage);
map.placeObjects();
Display.printMap(map.addEdges(), personnages);
isGameOver = instancePersonnage(personnage);
if(!isGameOver) placePersonnages(personnages);
else break;
System.out.println(1);
Display.printInformation(i++, personnage);
Display.printMap(map.addEdges());
if(personnage.round(map)) {
Display.clearTerminal();
System.out.println(personnage.getName() + " à perdu!");
return;
}
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 environnements.Map;
import object.Items;
import personnages.Personnage;
import personnages.Player;
import types.Item;
public class MapTest {
public static void creationMap() {
Map map = new Map(30, 30);
map.addObjects(Items.FRAISE, 29, 29);
map.addObjects(Item.FRAISE, 29, 29);
map.placeObjects();
Display.printMap(map.addEdges());
@@ -17,20 +16,20 @@ public class MapTest {
public static void drawMap() {
Map map = new Map(30, 30);
Display.printMap(map.addEdges(), null);
Display.printMap(map.addEdges());
}
public static void placePersonnageMap() {
Map map = new Map(30, 30);
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() {
Map map = new Map(5, 1);
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()));
System.out.println(player.getSize());

View File

@@ -1,15 +1,15 @@
package tests;
import object.Effects;
import object.Mouvements;
import personnages.Personnage;
import personnages.Player;
import types.Effect;
import types.Mouvement;
public class PersonnageTest {
public static void avancerPersonnage() {
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();
System.out.println(coordinate[0] + " " + coordinate[1]);
@@ -20,18 +20,18 @@ public class PersonnageTest {
Player player = new Player(new int[]{1, 1}, "test");
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()) {
System.out.println(coordinate[0] + " " + coordinate[1]);
}
}
public static void effectsPersonnage() {
public static void effectPersonnage() {
Personnage.n = 2;
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());
}

View File

@@ -1,23 +1,23 @@
package object;
package types;
/**
* cette enumérateur {@link Effects} contient tout les effets
* necessaire pour le bon déroulement du jeu et quelque effets
* 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,
/**
* tue le joueur si contact.
* Effet : Intransposable, entraînant la mort du joueur lors du contact.
*/
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;
import java.io.Serializable;
package types;
/**
* Cet enumerateur prend en charge tout les mouvements possible
* 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 Mouvements implements Serializable {
public enum Mouvement {
/**
* HAUT prend comme coordonnée (0, -1) pour se déplacer.
* @param x = 0
@@ -40,7 +37,7 @@ public enum Mouvements implements Serializable {
private final int deltaX;
private final int deltaY;
Mouvements(int deltaX, int deltaY) {
Mouvement(int deltaX, int deltaY) {
this.deltaX = deltaX;
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;
}
}