Construction (#2)

* Add files via upload

* correction

* changement de dossiers

* changement de beaucoup de class et ajout de Mouvement

* ajout de plein de fonction et suppression des anciennes classes

* ajout de plein d'autre fonction

* changement de plein de fonction

* Ajout et correction

* deplacer les fichiers

* changement de plein de trucs (manque juste a regler un probleme)

* programme basique fini

* mise en place d'un runner pour windows (UTF-8)

* correction de plein de chose dans le programme

---------

Co-authored-by: Cpt-Adok <126670243+Cpt-Adok@users.noreply.github.com>
This commit is contained in:
Loïc GUEZO
2024-05-17 18:39:21 +02:00
committed by GitHub
parent 687e810e70
commit 08a7333db2
21 changed files with 1199 additions and 149 deletions

View File

@@ -1,6 +1,6 @@
# Paramètres # Paramètres
.PHONY: all clean run .PHONY: all clean run
.SILENT: clean run .SILENT: run clean
# variables # variables
JAVAC = javac JAVAC = javac
@@ -14,7 +14,7 @@ LIB_DIR = lib
JAR = $(LIB_DIR)/* JAR = $(LIB_DIR)/*
# main # main
all: $(MAIN_FILE) run all: clean $(MAIN_FILE) run
$(MAIN_FILE) : $(BIN_DIR)/$(MAIN_FILE).class $(MAIN_FILE) : $(BIN_DIR)/$(MAIN_FILE).class

171
res/ASCII-Table.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.5 MiB

19
run.bat Normal file
View File

@@ -0,0 +1,19 @@
@echo off
set "error_file=error.txt"
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"
if %errror_size% gtr 0 (
@echo Vous avez besoin d'installer make ou allez sur le repertoire ou contient Makefile pour lancer correctement le programme.
)
del /Q %error_file%
pause > null
exit

View File

@@ -1,3 +1,5 @@
package Connexion;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;

244
src/Environnements/Map.java Normal file
View File

@@ -0,0 +1,244 @@
package Environnements;
import java.util.ArrayList;
import java.util.Random;
import Objets.Effects;
import Objets.Items;
import Personnages.Personnage;
import Personnages.Snake;
/**
* 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<Object> ObjectItems;
/**
* cette variable recupere tout les coordonnées des
* objects stockés, elle complete {@link #ObjectItems}.
*/
private ArrayList<int[]> 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[coordinate[1]].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<lengthObjects; i++) {
int value = random.nextInt(number);
number -= value;
randomize(objects[i], value);
}
randomize(objects[lengthObjects], number);
placeObjects();
}
/**
* cette fonction prend toutes les coordonnées du personnage
* et la place dans la grille
*/
public void placePersonnages(Personnage personnage) {
int index = 0;
for (int[] coordinate : personnage.getCoordinate()) {
if (index == 0) {
this.grid[coordinate[1]][coordinate[0]] = Snake.HEAD;
} else {
this.grid[coordinate[1]][coordinate[0]] = Snake.BODY;
}
index++;
}
}
/**
* cette fonction prend la grille et renvoie la meme grille
* mais avec de vrais bordures avec {@link #WALL}, cette fonction
* cree une nouvelle liste et ajoute l'ancienne avec toute les
* coordonnées dedans, les coordonnées mis dans grid seront ajouté
* 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];
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;
} else {
edgesGrid[i][k] = grid[i-1][k-1];
}
}
}
return edgesGrid;
}
/**
* cette fonction regarde la coordonnée de la tete du
* snake et si il est egal au coordonnée d'un fruit,
* il le supprime pour eviter qu'il reste sur le terrain.
*
* Il faut le placer apres le gameover pour pas qu'il enleve un mur.
* @param coordinate
*/
public void deleteItems(int[] coordinate) {
for(int i = 0; i<this.coordinateItems.size(); i++) {
if (this.coordinateItems.get(i) == coordinate) {
this.coordinateItems.remove(i);
this.ObjectItems.remove(i);
}
}
}
/**
* cette fonction place les objets dans la grille du
* jeu.
*/
public void placeObjects() {
for(int i = 0; i<this.coordinateItems.size(); i++) {
int[] coordinate = this.coordinateItems.get(i);
this.grid[coordinate[1]][coordinate[0]] = ObjectItems.get(i);
}
}
/**
* 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 number
*/
private void randomize(Object object, 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 {
i--;
}
}
}
}

View File

@@ -1,29 +0,0 @@
package Item;
/**
* <p>Ceci est l'enumération où il y aura tout les effets disponible dans le projet.
*/
public enum Effects {
/**
* <p>pouvoir faire un dash de 4 ligne pendant le round prochain après
* la recupération.
*/
POWER,
/**
* <p> Modifie la valeur de N pendant 2 tours en le multipliant par 2
* <p> <strong>Exemple : </strong> si N = 2, il va être *2 donc N sera
* egal à 4 et le prochain tour quand N = 3, il sera égal à 6.
*/
BOOST,
/**
* <p>pouvoir etre invincible pendant le prochain round.
*/
INVINCIBILITY,
/**
* <p> impossible à passer à travers.
*/
IMPASSABLE;
}

View File

@@ -1,40 +0,0 @@
package Item;
/**
* Cette enumération contient tout les items à effets disponnible dans le jeu.
*/
public enum Items {
Mur("mur", Effects.IMPASSABLE),
Body("corps", Effects.IMPASSABLE),
ABRICOT("fraise", Effects.INVINCIBILITY),
ORANGE("orange", Effects.POWER),
BANANE("banane", Effects.BOOST);
private final String nom;
private final Effects effect;
Items(String nom, Effects effects) {
this.nom = nom;
this.effect = effects;
}
/**
* <p> type de variable pour recuperer le nom :
* <pre><code>String name = Item.FRAISE.getName()</code></pre>
* @return Avoir le nom de l'item
*/
public String getName() {
return this.nom;
}
/**
* <p> type de variable pour recuperer l'effet :
* <pre><code>Effects effect = Item.FRAISE.getEffects()</code></pre>
* @return Avoir l'effet de l'item
*/
public Effects getEffects() {
return effect;
}
}

View File

@@ -1,8 +1,21 @@
import Item.Items; import Display.Terminal;
import personnages.*; import Environnements.Map;
import Objets.Items;
import Personnages.Personnage;
import Personnages.Player;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
Personnage.n = 2;
}
Map map = new Map(12, 30);
map.addObjects(Items.FRAISE, 5, 5);
Personnage[] personnages = new Personnage[] {
new Player(new int[] {0, 0}, "Phillipe")
};
new Terminal(map, personnages);
}
} }

23
src/Objets/Effects.java Normal file
View File

@@ -0,0 +1,23 @@
package Objets;
/**
* 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 {
/**
* reduis le corps de 1.
*/
DECREASESIZE,
/**
* tue le joueur si contact.
*/
IMPASSABLE,
/**
* le vide.
*/
VOID;
}

34
src/Objets/Items.java Normal file
View File

@@ -0,0 +1,34 @@
package Objets;
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

@@ -0,0 +1,63 @@
package Personnages;
/**
* 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.
*/
public enum Mouvements {
/**
* HAUT prend comme coordonnée (0, -1) pour se déplacer.
* @param x = 0
* @param y = -1
*/
HAUT(0, -1),
/**
* BAS prend comme coordonnée (0, 1) pour se déplacer.
* @param x = 0
* @param y = 1
*/
BAS(0, 1),
/**
* GAUCHE prend comme coordonnée (1, 0) pour se déplacer.
* @param x = -1
* @param y = 0
*/
GAUCHE(-1, 0),
/**
* @DROITE prend comme coordonnée (-1, 0) pour se déplacer.
* @param x = 1
* @param y = 0
*/
DROITE(1, 0);
private final int deltaX;
private final int deltaY;
Mouvements(int deltaX, int deltaY) {
this.deltaX = deltaX;
this.deltaY = deltaY;
}
/**
* Cette fonction prend les coordonnées mis en paramètre et
* modifie avec les coordonnées de l'enum.
* @param coordinate prend principalement les coordonnées du
* personnage
*/
public void updateCoordinate(int[] coordinate) {
coordinate[0] += this.deltaX;
coordinate[1] += this.deltaY;
}
/**
* Cette fonction retourne les coordonnées des valeurs du mouvement.
* @return la liste qui contient [0] = x et [1] = y
*/
public int[] getCoordinate() {
return new int[] {this.deltaX, this.deltaY};
}
}

View File

@@ -0,0 +1,175 @@
package Personnages;
import java.util.ArrayList;
import Objets.Effects;
/**
* Cette classe est la primitive des classes
* {@link Player} et {@link Robot}. Elle contient
* tout le necessaire pour tout les personnages
* jouable du jeu.
*/
public class Personnage {
/**
* cette variable contient la valeur dans laquelle on sait
* quand le corps du snake grandi. il est le même pour tout
* les personnages du jeu et c'est pour ça que c'est un
* static. on peut le changer directement dans le main en
* faisant la commande par exemple : <pre><code>
* Personnage.n = 2</code></pre> 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 :
* <pre><code>
* si n > 0 et round > 0 ->
* retourner round%n == 0
* sinon
* retourner faux
* </code></pre>
*/
private ArrayList<int[]> coordinate;
/**
* Le constructor initialise la variable {@link
* #coordinate} et prend en paramètre <strong>
* personnageCoordinate</strong> 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 <pre><code>
* si effect == IMPASSABLE ->
* retourner true
*sinon
* retourner false
* </code></pre>
*/
public boolean applyEffects(Effects effect) {
switch (effect) {
case DECREASESIZE: 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<int[]> 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);
}
}

View File

@@ -0,0 +1,45 @@
package Personnages;
/**
* 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;
}
}
}

View File

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

View File

@@ -0,0 +1,34 @@
package Personnages;
import Objets.Effects;
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;
}
}

65
src/Tests.java Normal file
View File

@@ -0,0 +1,65 @@
import Objets.Effects;
import Objets.Items;
import Display.Display;
import Environnements.Map;
import Personnages.Mouvements;
import Personnages.Personnage;
import Personnages.Player;
public class Tests {
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());
}
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, 1, 0);
}
}

152
src/display/Display.java Normal file
View File

@@ -0,0 +1,152 @@
package Display;
import java.util.ArrayList;
import Environnements.Map;
import Objets.Items;
import Personnages.Personnage;
import Personnages.Snake;
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<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);
}
System.out.println();
}
}
public static void printInformation(int round, int playerIndex, 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()
);
}
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;
}
}

146
src/display/Terminal.java Normal file
View File

@@ -0,0 +1,146 @@
package Display;
import java.util.Scanner;
import Environnements.Map;
import Objets.Effects;
import Objets.Items;
import Personnages.Mouvements;
import Personnages.Personnage;
import Personnages.Player;
import Personnages.Robot;
public class Terminal {
private int round = 0;
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) {
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) {
int input = getInput(player);
player.moveCoordinate(input);
int[] coordinate = player.getHeadCoordinate();
if(map.isGameOver(player.getHeadCoordinate()) || player.applyEffects(map.getEffect(coordinate))) return true;
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<personnages.length; i++) {
Personnage personnage = personnages[i];
Display.clearTerminal();
map.placeObjects();
placePersonnages(personnages);
Display.printInformation(this.round, i, personnage);
map.placeObjects();
Display.printMap(map.addEdges(), personnages);
isGameOver = instancePersonnage(personnage);
if(!isGameOver) placePersonnages(personnages);
else break;
map.clearMap();
}
this.round++;
}
System.out.println("GAMEOVER \nLe joueur " + (i+1) + " à perdu !");
}
}

View File

@@ -1,37 +0,0 @@
package personnages;
import java.util.ArrayList;
import Item.Effects;
public class Personnage {
private int size;
protected int[] coordinate;
private ArrayList<Effects> effectsList;
protected Personnage(int size, int[] coordinate) {
this.coordinate = coordinate;
this.size = size;
}
public int getSize() {
return size;
}
public void incrementSize(long size) {
this.size += size;
}
public void addEffects(Effects effect) {
this.effectsList.add(effect);
}
public ArrayList<Effects> getEffects() {
return this.effectsList;
}
public boolean haveEffect(Effects effect) {
return effectsList.contains(effect);
}
}

View File

@@ -1,30 +0,0 @@
package personnages;
public class Player extends Personnage {
public Player(int size, int[] coordinate) {
super(size, coordinate);
}
public void moveCoordinate(int keys) {
switch (keys) {
case 77: // w
this.coordinate[1]++;
break;
case 73: // s
this.coordinate[1]--;
break;
case 61: // a
this.coordinate[0]--;
break;
case 64: // d
this.coordinate[0]++;
break;
default: // autre
break;
}
}
}

View File

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