From 98add9ca2f029ec801290c3c874d02c9a3f09df5 Mon Sep 17 00:00:00 2001 From: Cpt-Adok Date: Thu, 23 May 2024 13:51:23 +0200 Subject: [PATCH] =?UTF-8?q?correction=20de=20problene=20et=20channel=20ter?= =?UTF-8?q?min=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 +- run.bat | 4 +- src/Characters/Personnage.java | 155 ------------- src/Characters/Players.java | 23 -- src/Characters/Robot.java | 136 ------------ src/Connexion/Channel.java | 86 +++----- src/Environnement/Map.java | 187 ---------------- src/Main.java | 22 +- src/Objects/Effects.java | 6 - src/Objects/Fruits.java | 31 --- src/display/Display.java | 150 +++++++++++++ src/display/Terminal.java | 117 ---------- src/display/TerminalChannel.java | 110 ---------- src/display/TerminalDisplay.java | 143 ------------ src/environnements/Map.java | 244 +++++++++++++++++++++ src/game/Terminal.java | 143 ++++++++++++ src/object/Effects.java | 23 ++ src/{Objects => object}/Items.java | 6 +- src/{Characters => object}/Mouvements.java | 11 +- src/{Objects => object}/Snake.java | 2 +- src/personnages/Personnage.java | 176 +++++++++++++++ src/personnages/Player.java | 47 ++++ src/personnages/Robot.java | 7 + src/tests/MapTest.java | 38 ++++ src/tests/PersonnageTest.java | 38 ++++ 25 files changed, 930 insertions(+), 979 deletions(-) delete mode 100644 src/Characters/Personnage.java delete mode 100644 src/Characters/Players.java delete mode 100644 src/Characters/Robot.java delete mode 100644 src/Environnement/Map.java delete mode 100644 src/Objects/Effects.java delete mode 100644 src/Objects/Fruits.java create mode 100644 src/display/Display.java delete mode 100644 src/display/Terminal.java delete mode 100644 src/display/TerminalChannel.java delete mode 100644 src/display/TerminalDisplay.java create mode 100644 src/environnements/Map.java create mode 100644 src/game/Terminal.java create mode 100644 src/object/Effects.java rename src/{Objects => object}/Items.java (88%) rename src/{Characters => object}/Mouvements.java (89%) rename src/{Objects => object}/Snake.java (97%) create mode 100644 src/personnages/Personnage.java create mode 100644 src/personnages/Player.java create mode 100644 src/personnages/Robot.java create mode 100644 src/tests/MapTest.java create mode 100644 src/tests/PersonnageTest.java diff --git a/Makefile b/Makefile index f0ee043..5f1ab88 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Paramètres .PHONY: all clean run -.SILENT: clean run +.SILENT: run clean # variables JAVAC = javac @@ -14,7 +14,7 @@ LIB_DIR = lib JAR = $(LIB_DIR)/* # main -all: clean $(MAIN_FILE) run clean +all: clean $(MAIN_FILE) run $(MAIN_FILE) : $(BIN_DIR)/$(MAIN_FILE).class diff --git a/run.bat b/run.bat index 8b3747c..e4a8c64 100644 --- a/run.bat +++ b/run.bat @@ -2,7 +2,9 @@ set "error_file=error.txt" -chcp 65001 +REM ceci est pour mettre un batch en utf-8 car sinon, nous aurons des problèmes avec les caractères. +chcp 65001 + make 2> %error_file% for %%A in ("%error_file%") do set "errror_size=%%~zA" diff --git a/src/Characters/Personnage.java b/src/Characters/Personnage.java deleted file mode 100644 index 06db73d..0000000 --- a/src/Characters/Personnage.java +++ /dev/null @@ -1,155 +0,0 @@ -package Characters; - -import java.util.ArrayList; -import java.util.Arrays; - -import Objects.Snake; - -/** - * Cet classe est la classe precurseur de tout les heritage pour creer un - * personnage jouable. - */ -public class Personnage { - public static int n; - private int round; - private int size = 0; - private String name; - private String effect; - - /** - *

la liste de toute les coordonnées en fonction de N. Si N = 2, - * tout les deux tours, la taille du serpent augmente de 1. Si N = 3, - * tous les 3 tours, ça va augmenter de 1. On peut l'ecrire comme - * Round/N (les deux variables en int). - *

Le premier index est la coordonnée de la tête et les autres - * sont les coordonnées de son corps. - */ - private ArrayList coordinate; - - /** - *

le constructor definie un arrayList pour {@link #coordinate} - * et defini n. - * - * @param n est une variable qui contient le nombre de tour avant - * l'augmentation de taille. - * @param coordinate est la variable qui contient les coordonnées - * qui sont placé par la suite dans {@link #coordinate}[0]} - */ - protected Personnage(String name, int[] coordinate) { - this.coordinate = new ArrayList(); - this.coordinate.add(coordinate); - - this.name = name; - } - - /** - *

cette fonction retourne la premiere coordonnée de la liste - * {@link #coordinate} qui la tête du personnage. - * @return la tête du personnage. - */ - public int[] getPrimaryCoordinate() { - return coordinate.get(0); - } - - /** - *

cette fonction retourne toute la liste - * {@link #coordinate} de coordonnée du serpent. - * @return toute la liste des coordonnées du serpent - */ - public ArrayList getCoordinate() { - return coordinate; - } - - /** - * @return augmente le tour après que le personnage a jouer - */ - public int incrementRound() { - return ++this.round; - } - - /** - * @return retourn un bool pour savoir si la taille s'est - * aggrandi - */ - public boolean isIncreaseSize() { - int size = this.round/n; - if (this.size < size) { - this.size = size; - return true; - } - return false; - } - - /** - * @return retourn un bool pour savoir si la taille s'est - * retreci. - */ - public boolean isDecreaseSize() { - int size = this.round/n; - if (this.size > size) { - this.size = size; - return true; - } - return false; - } - - /** - *

cette fonction est très pratique aggrandir le serpent - * car elle garde la derniere coordonnée et si on la fusionne - * avec {@link #increaseSnake()}, on peut l'utiliser - * ajouter la coordonnée pour justement l'aggrandir. - * @return garde la derniere coordonnée du serpent (sa queue) - */ - public int[] keepLatestCoordinate() { - return this.coordinate.get(getCoordinate().size()-1).clone(); - } - - /** - *

ajoute au dernier index, la valeur en parametre, très utile - * en combinant avec {@link #keepLatestCoordinate()} pour aggrandir - * le serpent. - * @param coordinate ajout de la nouvelle coordonnée - */ - public void increaseSnake(int[] coordinate) { - this.coordinate.add(coordinate); - } - - /** - *

modifie toute la liste {@link #coordinate} pour deplacer tout le - * serpent. - * @param mouvements le mouvement utilisé pour deplacer le serpent - */ - public void moveSnake(Mouvements mouvements) { - - int[] oldHeadPosition = getPrimaryCoordinate().clone(); - - for (int i = this.coordinate.size() - 1; i > 0; i--) { - this.coordinate.set(i, this.coordinate.get(i - 1).clone()); - } - mouvements.editCoordinate(oldHeadPosition); - this.coordinate.set(0, oldHeadPosition); - } - - public String getName() { - return name; - } - - public int getSize() { - return size; - } - - public String getEffects(Object item) { - return new String(); - } - - public Mouvements 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 - case 0x64: return Mouvements.DROITE; // d - case null: return null; - default: return null; - } - } -} diff --git a/src/Characters/Players.java b/src/Characters/Players.java deleted file mode 100644 index b7af422..0000000 --- a/src/Characters/Players.java +++ /dev/null @@ -1,23 +0,0 @@ -package Characters; - -public class Players extends Personnage { - public Players(String name, int[] coordinate) { - super(name, coordinate); - } - - public Integer changeCoordinate(String input) { - if (input.length() > 0) { - return (int)input.charAt(0); - } - return null; - } - - public boolean moveCoordinate(int keys) { - Mouvements value = getMouvement(keys); - if (value != null) { - moveSnake(value); - return true; - } - return false; - } -} diff --git a/src/Characters/Robot.java b/src/Characters/Robot.java deleted file mode 100644 index b0bab4f..0000000 --- a/src/Characters/Robot.java +++ /dev/null @@ -1,136 +0,0 @@ -package Characters; - -import java.util.ArrayList; -import javax.swing.JOptionPane; - -import Environnement.*; -import Objects.Effects; - -public class Robot extends Personnage { - - Map m; - Mouvements move; - - public Robot(String name, int[] coordinate,Map m) { - super(name, coordinate); - this.m=m; - move=this.compare(this.getCoordinate().get(0), this.choix().get(0)); - jouer(m); - } - - public String jouer(Map m){ - if (this.move==Mouvements.HAUT){ - return "U"; - }else if(this.move==Mouvements.BAS){ - return "D"; - }else if(this.move==Mouvements.GAUCHE){ - return "L"; - }else if(this.move==Mouvements.DROITE){ - return "R"; - } - return "Problème"; - } - - public boolean estPossible(int x,int y){ - JOptionPane.showInputDialog((this.m.getGrid().length+" "+ this.m.getGrid()[0].length).toString()); - Object [][] grille=new Object[][] {this.m.getGrid()}; - if (grille[x][y]==Effects.IMPASSABLE){ - return false; - } - return true; - } - - public int [] creerTab(int x,int y){ - int [] t=new int [] {x,y}; - return t; - } - - public ArrayList coupsPossibles(int [] co) { - ArrayList coupsValables=new ArrayList (); - if (this.estPossible(co[0]+1,co[1])){ - coupsValables.add(creerTab(co[0]+1, co[1])); - }else if (this.estPossible(co[0],co[1]+1)){ - coupsValables.add(creerTab(co[0], co[1]+1)); - }else if (this.estPossible(co[0]-1,co[1])){ - coupsValables.add(creerTab(co[0]-1, co[1])); - }else if (this.estPossible(co[0],co[1]-1)){ - coupsValables.add(creerTab(co[0], co[1]-1)); - } - return coupsValables; - } - - public ArrayList casesAutour(){ - ArrayList t =this.coupsPossibles(this.getCoordinate().get(0)); - ArrayList t2 = new ArrayList<> (); - for (int i=0;i fusion(ArrayList t, ArrayList t2){ - for (int [] e :t2){ - t.add(e); - } - return t; - } - - public ArrayList choix(){ - ArrayList cases=casesAutour(); - ArrayList > w=new ArrayList<>(); - for (int i=0;i max=w.get(0); - for (ArrayList e :w){ - if (e.size()>max.size()){ - max=e; - } - } - return max; - } - - public Mouvements compare(int[] t,int[] t2){ - if (t[0]>t2[0]){ - System.out.println("s"); - return Mouvements.BAS; - }else if (t[0]t2[1]){ - System.out.println("d"); - return Mouvements.DROITE; - } - return null; - } - - public ArrayList killDouble(ArrayList t){ - for (int i=0;i personnages; - int numJoueur; - TerminalChannel term; - Map m; - - public Channel(Reseau r, ArrayList p, int j,TerminalChannel term,Map m){ - this.reseau=r; - this.personnages=p; - this.numJoueur=j; - this.term=term; - this.m=m; + public Channel(Object[][] map, String channel) { + super(new int [] {19,19}); + reseau=new Reseau(channel); } - public String typePersonnage(int i){ - if (i>=0 && i cette classe est la classe qui cree et genere - * tout ce qui est important pour la Map du jeu - */ -public class Map { - /** - *

cette variable est toute la grille où se - * passe tout le jeu. - */ - private Object[][] grid; - - /** - *

cette variable recupere tout les objects stockés - */ - private ArrayList ObjectItems; - - /** - *

cette variable recupere tout les coordonnées des - * objects stockés - */ - private ArrayList coordinateItems; - - private int longueur; - private int largeur; - - /** - *

le constructeur crée une grille "vide" qui - * contient uniquement l'enumerateur Items.VOID - * avec la longueur et la largeur en paramètre. - * - * @param longueur pour la grille du jeu - * @param largeur pour la grille du jeu - */ - public Map(int longueur, int largeur) { - this.longueur = longueur; - this.largeur = largeur; - - this.grid = new Object[this.longueur][this.largeur]; - - this.ObjectItems = new ArrayList<>(); - this.coordinateItems = new ArrayList<>(); - - this.fillGrid(); - } - - /** - *

cette fonction clear toute la grille qui - * contient le jeu. - */ - public void clearMap(boolean edges) { - this.fillGrid(); - if(edges) this.addEdges(); - } - - /** - *

cette fonction renvoie toute la grille Object[][] - * qui contient tout la grille du jeu - * @return la grille du jeu - */ - public Object[][] getGrid() { - return grid; - } - - /** - *

cette fonction ajoute les bordures sur la grille - */ - public void addEdges() { - for(int i = 0; i < this.grid.length; i++) { - for(int k = 0; k < this.grid[0].length; k++) { - if (i == 0 || i == this.grid.length - 1 || k == 0 || k == this.grid[0].length - 1) { - this.grid[i][k] = Items.WALL; - } - } - } - } - - /** - *

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 - * mettre dedans. - * @param number prend le nombre d'objets global que - * vous voulez mettre dedans. - */ - public void addObjects(Object[] objects, int number) { - int lengthObjects = objects.length-1; - Random random = new Random(); - - for(int i = 0; i cette fonction place les objets dans la grille du - * jeu. - */ - public void placeObjects() { - for(int i = 0; i type de variable pour recuperer le nom des fruits: - *

String name = Item.FRAISE.getName()
- * @return Avoir le nom de l'item - */ - public String getName() { - return this.NAME; - } - - /** - *

type de variable pour recuperer l'effet des fruits: - *

Effects effect = Item.FRAISE.getEffects()
- * @return Avoir l'effet de l'item - */ - public Effects getEffects() { - return this.EFFECT; - } -} diff --git a/src/display/Display.java b/src/display/Display.java new file mode 100644 index 0000000..816185c --- /dev/null +++ b/src/display/Display.java @@ -0,0 +1,150 @@ +package display; + +import java.util.ArrayList; + +import object.*; +import personnages.*; + +public class Display { + /** + * cette fonction clear le terminal et le remet en + * haut a gauche de la ligne. + */ + public static void clearTerminal() { + System.out.println("\u001b[2J \u001b[H"); + } + + /** + * 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() + " "); + } + 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) { + for (int i = 0; i 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 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; + } +} diff --git a/src/display/Terminal.java b/src/display/Terminal.java deleted file mode 100644 index 41c088b..0000000 --- a/src/display/Terminal.java +++ /dev/null @@ -1,117 +0,0 @@ -package display; - -import java.io.IOError; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Scanner; - -import Characters.*; -import Environnement.*; -import Objects.*; - -public class Terminal { - private static Scanner scanner; - private static Map map; - private static Personnage[] personnages; - public int round = 0; - - public static boolean edges = false; - - public Terminal(Map m, Personnage[] personnage) { - scanner = new Scanner(System.in); - personnages = personnage; - map = m; - - run(); - if (edges) map.addEdges(); - } - - private static void placePersonnages(Personnage[] personnages) { - for(Personnage personnage : personnages) { - map.placePersonnages(personnage); - } - } - - /** - *

Cette fonction est uniquement destiné pour la classe - * Players pour recuperer l'input dans le terminal. - * @param scanner - * @param player - * @return il retourne int qui est le char en ascii - */ - private static int getInput(Scanner scanner, Players player) { - String value = new String(); - Integer input = null; - - do { - value = scanner.nextLine(); - input = player.changeCoordinate(value); - }while(player.getMouvement(input) == null); - - return input.intValue(); - } - - private static boolean playerRound(Players player) { - TerminalDisplay.printMap(map, personnages); - // TerminalDisplay.printMapType(map); - - int[] latestCoordinate = player.keepLatestCoordinate(); - int input = getInput(scanner, player); - player.moveCoordinate(input); - - if(map.isGameOver(input, player)) {TerminalDisplay.clearTerminal(); System.out.println("GameOver"); return false;} - if(player.isIncreaseSize()) player.increaseSnake(latestCoordinate); - - TerminalDisplay.clearTerminal(); - map.clearMap(edges); - player.incrementRound(); - return true; - } - - private static boolean robotRound(Robot robot) { - return false; - } - - private static boolean instancePersonnage(Personnage personnage) { - if (personnage instanceof Players) { - // tour du Player - return playerRound((Players)personnage); - } - - if (personnage instanceof Robot) { - // tour du robot - return robotRound((Robot)personnage); - } - - return false; - } - - public void run() { - TerminalDisplay.clearTerminal(); - if (edges) map.addEdges(); - boolean isNotGameOver = true; - int i = 0; - - // place les personnages dans la grille. - placePersonnages(personnages); - - while(isNotGameOver) { - for (i = 0; i Cette fonction est uniquement destiné pour la classe - * Players pour recuperer l'input dans le terminal. - * @param scanner - * @param player - * @return il retourne int qui est le char en ascii - */ - - public boolean playerRound(Players player) { - TerminalDisplay.printMap(map, personnages); - // TerminalDisplay.printMapType(map); - - int[] latestCoordinate = player.keepLatestCoordinate(); - int input=getInput(null); - player.moveCoordinate(input); - - if(map.isGameOver(input, player)) {TerminalDisplay.clearTerminal(); System.out.println("GameOver"); return false;} - if(player.isIncreaseSize()) player.increaseSnake(latestCoordinate); - - TerminalDisplay.clearTerminal(); - map.clearMap(edges); - player.incrementRound(); - return true; - } - - private static boolean robotRound(Robot robot) { - return false; - } - - private boolean instancePersonnage(Personnage personnage) { - if (personnage instanceof Players) { - // tour du Player - return playerRound((Players)personnage); - } - - if (personnage instanceof Robot) { - // tour du robot - return robotRound((Robot)personnage); - } - - return false; - } - - public boolean run() { - TerminalDisplay.clearTerminal(); - if (edges) map.addEdges(); - boolean isNotGameOver = true; - int i = 0; - - // place les personnages dans la grille. - placePersonnages(personnages); - - while(isNotGameOver) { - for (i = 0; i personnageCoordinate = personnage.getCoordinate(); - - int[] primaryCoordinate = personnage.getPrimaryCoordinate(); - - 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(" \u21E8 ");return; - } - - - - private static Personnage searchSnake(Personnage[] personnages, int x, int y) { - for (Personnage personnage : personnages) { - int[] primaryCoordinate = personnage.getPrimaryCoordinate(); - - int primaryY = primaryCoordinate[0]; - int primaryX = primaryCoordinate[1]; - - if (primaryX == x && primaryY == y) { - return personnage; - } - } - return null; - } - - private static void printWall(Object[][] map, int x, int y) { - // UP DOWN LEFT RIGHT - boolean[] isWall = new boolean[4]; - - if (y > 0) isWall[0] = map[y - 1][x] == Items.WALL; else isWall[0] = false; - if (y < map.length - 1) isWall[1] = map[y + 1][x] == Items.WALL; else isWall[1] = false; - if (x > 0) isWall[2] = map[y][x - 1] == Items.WALL; else isWall[2] = false; - if (x < map[0].length - 1) isWall[3] = map[y][x + 1] == Items.WALL; else isWall[3] = false; - - System.out.print(whichWall(isWall)); - } - - 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; - } -} diff --git a/src/environnements/Map.java b/src/environnements/Map.java new file mode 100644 index 0000000..55061fd --- /dev/null +++ b/src/environnements/Map.java @@ -0,0 +1,244 @@ +package environnements; + +import java.util.ArrayList; +import java.util.Random; + +import object.*; +import personnages.*; + + +/** + * cette classe est la classe qui cree et genere + * tout ce qui est important pour la Map du jeu. + */ +public class Map { + /** + * cette variable est toute la grille où se + * passe tout le jeu. + */ + private Object grid[][]; + + /** + * cette variable recupere tout les objects stockés, + * elle complete {@link #coordinateItems}. + */ + private ArrayList ObjectItems; + + /** + * cette variable recupere tout les coordonnées des + * objects stockés, elle complete {@link #ObjectItems}. + */ + private ArrayList coordinateItems; + + private int longueur; + private int largeur; + + /** + * le constructeur crée une grille "vide" qui + * contient uniquement l'enumerateur Items.VOID + * avec la longueur et la largeur en paramètre. + * + * @param longueur pour la grille du jeu + * @param largeur pour la grille du jeu + */ + public Map(int longueur, int largeur) { + this.longueur = longueur; + this.largeur = largeur; + + this.grid = new Object[this.largeur][this.longueur]; + + this.ObjectItems = new ArrayList<>(); + this.coordinateItems = new ArrayList<>(); + + this.fillGrid(); + } + + /** + * rempli toute la grille de Items.VOID pour eviter + * des problemes de null ou des problemes de + * collisions. + */ + 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; + } + } + } + + /** + * renvoie la grille du jeu. + */ + public Object[][] getGrid() { + return grid.clone(); + } + + public boolean isGameOver(int[] coordinate) { + return coordinate[0] < 0 || coordinate[0] >= this.grid[0].length || + coordinate[1] < 0 || coordinate[1] >= this.grid.length; + } + + /** + * renvoie l'effet + * @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(); + } + + /** + * clear la map. + */ + public void clearMap() { + this.fillGrid(); + } + + /** + * 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]; + int k = 0; + + for (int i = grid.length; i> 0; --i) { + inverseGrid[k++] = inverseGrid[i]; + } + + return inverseGrid; + } + + /** + * ajoute les coordonnées et les objets de façon non aléatoire + * @param object + * @param x + * @param y + */ + public void addObjects(Object object, int x, int y) { + this.coordinateItems.add(new int[]{x, y}); + this.ObjectItems.add(object); + } + + /** + * 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 + * 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; + Random random = new Random(); + + for(int i = 0; i 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) { + 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; + } + + /** + * 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; + + while(!isGameOver) { + for (i = 0;i + * Personnage.n = 2 sans appeler + * player ou robot, les deux valeurs vont "automatiquement" + * changer. + */ + public static int n; + + /** + * cette variable est le nombre de round fait par le snake, + * il s'incremente tout les tours quand le snake avance. + */ + private int round; + + /** + * cette variable est le nom du snake présent dans le tournois, + * il peut etre un mot aléatoire ou quelque chose de personnalisé + */ + protected String name; + + /** + * cette variable accumule toute les coordonnées du serpent, elle + * contient le corps et la tête et la première coordonnées est la tête. + * Le programme peut ajouter des coordonnées en fonction de round et n, + * exemple : + *

+     * si n > 0 et round > 0 -> 
+     *    retourner round%n == 0
+     * sinon
+     *    retourner faux
+     * 
+ */ + private ArrayList coordinate; + + /** + * Le constructor initialise la variable {@link + * #coordinate} et prend en paramètre + * personnageCoordinate qui est la tête + * de notre snake. Il place dans la liste {@link + * #coordinate} la coordonnée. Nous pourrons + * recuperer les coordonnées de la tête en + * utilisant la fonction {@link #getHeadCoordinate()}. + */ + protected Personnage(int[] personnageCoordinate) { + coordinate = new ArrayList<>(); + coordinate.add(personnageCoordinate); + } + + /** + * cette fonction applique tout les effets defini dans + * {@link Effects} et en même temps, sert de fermeture + * du programme avec le boolean si l'effet choisi est + * IMPASSABLE. + * @param effect est la variable qui contient tout les + * effets de {@link Effects} + * @return

+     * si effect == IMPASSABLE ->
+     *      retourner true
+     *sinon
+     *      retourner false
+     * 
+ */ + public boolean applyEffects(Effects effect) { + switch (effect) { + case DECREASESIZE: + if (this.coordinate.size() > 1) {this.coordinate.removeLast();} break; + + case VOID: break; + case IMPASSABLE: return true; + } + + return false; + } + + /** + * cette fonction renvoie la tête du snake mais en clone + * donc elle fait une copie de la position existante pour + * eviter de prendre l'adresse mémoire de la liste et pouvoir + * utiliser celle là comme on veut sans affecter la liste. + */ + public int[] getHeadCoordinate() { + return this.coordinate.getFirst().clone(); + } + + /** + * cette fonction renvoie la queue du snake mais en clone + * donc elle fait une copie de la position existante pour + * eviter de prendre l'adresse mémoire de la liste et pouvoir + * utiliser celle là comme on veut sans affecter la liste. + */ + public int[] getLatestCoordinate() { + return this.coordinate.getLast().clone(); + } + + /** + * cette fonction renvoie un clone de la liste de coordonnée + * donc elle fait une copie des positions existante pour + * eviter de prendre l'adresse mémoire de l'ArrayList et pouvoir + * utiliser celle là comme on veut sans affecter l'ArrayList. + */ + public ArrayList getCoordinate() { + return new ArrayList<>(this.coordinate); + } + + /** + * cette fonction incremente la variable {@link #round}. + */ + public void increaseRound() { + ++this.round; + } + + /** + * cette fonction renvoie la variable {@link #round}. + */ + public int getRound() { + return round; + } + + /** + * cette fonction renvoie la variable {@link #name}. + */ + public String getName() { + return name; + } + + /** + * cette fonction renvoie la longueur de {@link #getCoordinate()}. + */ + public int getSize() { + return this.getCoordinate().size(); + } + + /** + * cette fonction change tout les coordonnées du serpent en mettant + * la coordonnée de celui d'avant, il prend [1, 2, 3, 4] et fais en + * premier temps [1, 1, 2, 3] puis modifie la premiere coordonnée + * avec Mouvement, si il y a -1, ça fait [0, 1, 2, 3]. + * @param mouvement est le mouvement du personnage, comme HAUT, BAS, + * GAUCHE et DROITE. + */ + public void moveSnake(Mouvements mouvement) { + int[] latestCoordinate = getLatestCoordinate(); + + for (int i = this.coordinate.size() - 1; i > 0; i--) { + this.coordinate.set(i, this.coordinate.get(i - 1).clone()); + } + + mouvement.updateCoordinate(this.coordinate.getFirst()); + increaseSnake(latestCoordinate); + } + + /** + * ajoute la coordonnée mis en paramètre dans le dernier emplacement si + * round > 0 et n > 0 et round%n = 0. + */ + private void increaseSnake(int[] coordinate) { + if(round > 0 && n > 0) if (round%n == 0) this.coordinate.add(coordinate); + } +} diff --git a/src/personnages/Player.java b/src/personnages/Player.java new file mode 100644 index 0000000..b16040a --- /dev/null +++ b/src/personnages/Player.java @@ -0,0 +1,47 @@ +package personnages; + +import object.*; + +/** + * la classe Player a comme classe parent {@link Personnage} + * et qui contient tout les besoins primaire pour le bon + * fonctionnement de la classe Player. cette classse est très + * utile pour qu'un humain puisse jouer. + */ +public class Player extends Personnage { + /** + * la classe Player a comme classe parent {@link Personnage} + * et qui contient tout les besoins primaire pour le bon + * fonctionnement de la classe Player. Il comporte les coordonnées + * initiales pour placer correctement le personnage dans la grille + * du jeu. + * @param coordinate + * @param name + */ + public Player(int[] coordinate, String name) { + super(coordinate); + + this.name = name; + } + + public boolean moveCoordinate(int keys) { + Mouvements value = getMouvement(keys); + + if (value != null) { + moveSnake(value); + return true; + } + return false; + } + + public Mouvements 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 null: return null; + default: return null; + } + } +} diff --git a/src/personnages/Robot.java b/src/personnages/Robot.java new file mode 100644 index 0000000..ca1d9b5 --- /dev/null +++ b/src/personnages/Robot.java @@ -0,0 +1,7 @@ +package personnages; + +public class Robot extends Personnage { + public Robot(int[] coordinate) { + super(coordinate); + } +} diff --git a/src/tests/MapTest.java b/src/tests/MapTest.java new file mode 100644 index 0000000..e613d51 --- /dev/null +++ b/src/tests/MapTest.java @@ -0,0 +1,38 @@ +package tests; + +import display.Display; +import environnements.Map; +import object.Items; +import personnages.Personnage; +import personnages.Player; + +public class MapTest { + public static void creationMap() { + Map map = new Map(30, 30); + map.addObjects(Items.FRAISE, 29, 29); + map.placeObjects(); + + Display.printMap(map.addEdges()); + } + + public static void drawMap() { + Map map = new Map(30, 30); + Display.printMap(map.addEdges(), null); + } + + 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")}); + } + + 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); + + player.applyEffects(map.getEffect(player.getHeadCoordinate())); + System.out.println(player.getSize()); + } +} diff --git a/src/tests/PersonnageTest.java b/src/tests/PersonnageTest.java new file mode 100644 index 0000000..9dcaa64 --- /dev/null +++ b/src/tests/PersonnageTest.java @@ -0,0 +1,38 @@ +package tests; + +import object.Effects; +import object.Mouvements; +import personnages.Personnage; +import personnages.Player; + +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 + int[] coordinate = player.getHeadCoordinate(); + + System.out.println(coordinate[0] + " " + coordinate[1]); + } + + public static void taillePersonnage() { + Personnage.n = 2; + + Player player = new Player(new int[]{1, 1}, "test"); + player.increaseRound(); + player.moveSnake(Mouvements.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() { + 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 + + System.out.println(player.getCoordinate()); + } +}