Compare commits
	
		
			16 Commits
		
	
	
		
			Rapport
			...
			MenuProtot
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 56ed89d668 | |||
| a273e7736a | |||
| d5db1b14af | |||
| 
						
						
							
						
						37cc19f49a
	
				 | 
					
					
						|||
| 
						
						
							
						
						a6fc46a0ea
	
				 | 
					
					
						|||
| 78e50549d0 | |||
| d4f254139c | |||
| fbbda476b4 | |||
| 70fef807d5 | |||
| 90f25b1c26 | |||
| 5bfb2aba9b | |||
| a99a53868b | |||
| bb5e2ff401 | |||
| 895b20b680 | |||
| 5911d88918 | |||
| 49d2c5d7ab | 
@ -5,14 +5,14 @@ name: Check_Requirement
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
  - name: base_check
 | 
			
		||||
    image: gradle:jdk11-alpine
 | 
			
		||||
    image: gradle:jdk11-alpine 
 | 
			
		||||
    commands:
 | 
			
		||||
      - ./gradlew clean
 | 
			
		||||
      - ./gradlew build
 | 
			
		||||
      - ./gradlew test
 | 
			
		||||
 | 
			
		||||
  - name: syntax_check
 | 
			
		||||
    image: gradle:jdk11-alpine
 | 
			
		||||
    image: gradle:jdk11-alpine 
 | 
			
		||||
    commands:
 | 
			
		||||
      - ./gradlew check
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,6 @@ depends_on:
 | 
			
		||||
  - Check_Requirement
 | 
			
		||||
---
 | 
			
		||||
kind: signature
 | 
			
		||||
hmac: 6b154c74ec624ce2d5867386bb7a6ee51cae9153457a8ce15f53e54546ccbc0e
 | 
			
		||||
hmac: 9ca9095fdb69d7b89fda6b4db867877e76666c109607cc7b1e513814ad42bb7e
 | 
			
		||||
 | 
			
		||||
...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -53,4 +53,3 @@ build
 | 
			
		||||
 | 
			
		||||
.idea/
 | 
			
		||||
.settings/
 | 
			
		||||
*.slevel
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								JournalDeBord/rapport/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								JournalDeBord/rapport/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,2 +0,0 @@
 | 
			
		||||
rapport.aux
 | 
			
		||||
rapport.toc
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1,278 +0,0 @@
 | 
			
		||||
\documentclass[12pt,a4paper]{article}
 | 
			
		||||
 | 
			
		||||
\usepackage{amsmath}
 | 
			
		||||
\usepackage{listings}
 | 
			
		||||
\usepackage{tikz}
 | 
			
		||||
\usepackage{csquotes}
 | 
			
		||||
 | 
			
		||||
\begin{document}
 | 
			
		||||
 | 
			
		||||
\title{Rapport du projet informatique 2023 \\ "Road to Master"}
 | 
			
		||||
\author{Debucquoy Anthony \and Matteo Di Leto}
 | 
			
		||||
\date{May 2023}
 | 
			
		||||
 | 
			
		||||
\maketitle
 | 
			
		||||
\newpage
 | 
			
		||||
 | 
			
		||||
\tableofcontents
 | 
			
		||||
\newpage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
\section*{Introduction}
 | 
			
		||||
 | 
			
		||||
Lors de ce deuxième quadrimèstre, le projet Informatique proposé par notre université fut partie intégrante de notre emploi du temps.
 | 
			
		||||
Régulièrement nous nous sommes rassemblés pour nous organiser et trouver une direction dans laquelle nous voulions voir notre projet évoluer.
 | 
			
		||||
Grâce aux objectifs fixés par nos enseignants, nous sommes - je le pense - maintenant plus apte à nous confronter à ce genre d'objectifs. Tant au niveau personel qu'en tant que groupe.
 | 
			
		||||
Il va sans dire que comme pour tout projets, notre chemin a été semé d'embuches. En l'occurence, nous souhaitons faire part de l'abandon d'un de nos membre. Eddy Jiofak qui souhaite se réorienter.
 | 
			
		||||
Nous lui souhaitons une bonne reconversion.
 | 
			
		||||
 | 
			
		||||
\section*{Objectifs}
 | 
			
		||||
 | 
			
		||||
Voici l'objectif fixé par nos enseignants. (document de consignes)
 | 
			
		||||
 | 
			
		||||
\begin{displayquote}
 | 
			
		||||
 | 
			
		||||
Le but final de ce projet est de réaliser une application graphique en Java permettant de
 | 
			
		||||
jouer au jeu "Cats Organized Neatly". Ce jeu est un jeu de type "puzzle" où le joueur doit
 | 
			
		||||
placer des pièces de formes différentes pour combler l'aire de jeu. L'application devra permettre
 | 
			
		||||
de sauvegarder et charger une partie et de créer des niveaux automatiquement.
 | 
			
		||||
 | 
			
		||||
\end{displayquote}
 | 
			
		||||
 | 
			
		||||
\newpage
 | 
			
		||||
 | 
			
		||||
\section{Organisation}
 | 
			
		||||
 | 
			
		||||
Lors de nos rassemblement pour le projet, toutes les idées émises se sont retrouvés sur un blog afin de pouvoir y accéder de manière efficace.
 | 
			
		||||
Ce blog nous sert également à garder une trace de l'évolution du projet.
 | 
			
		||||
 | 
			
		||||
\subsection{Choix}
 | 
			
		||||
 | 
			
		||||
\begin{itemize}
 | 
			
		||||
	\item{le VCS git pour garder une trace de l'avancement du projet. Avec comme remote une instance privée de gitea nous permettant de vérifier les MR/PR plus efficacement.}
 | 
			
		||||
	\item{Une instance de DroneCI permettant de vérifier que le projet soit toujours compilable et que les tests ne soient pas ratés sans que nous nous en rendions compte.}
 | 
			
		||||
	\item{Javafx, comme recommandé par nos enseignants.}
 | 
			
		||||
	\item{Les pièces et niveaux sont stockées sous forme de matrice de booléen}
 | 
			
		||||
	\item{Un parser de fichiers efficace et donnant des fichier légers.}
 | 
			
		||||
\end{itemize}
 | 
			
		||||
 | 
			
		||||
\subsubsection*{Shapes}
 | 
			
		||||
 | 
			
		||||
Les pièces ainsi que la carte sont représentés par une matrice de booléen \verb|boolean[][]|.
 | 
			
		||||
Nous avons donc une classe \verb|shape|, parent de \verb|Map| et de \verb|Piece| dans lequel nous stockons notre matrice.
 | 
			
		||||
Ensuite, \verb|Map| Contient une liste de \verb|Piece|. Ces pièces contiennent une position représentée par la classe \verb|Vec2|.
 | 
			
		||||
Cette position est la position du carré supérieur gauche dans la \verb|Map|.
 | 
			
		||||
Avec toutes ces informations nous avons le nécessaire pour le moteur du jeu.
 | 
			
		||||
 | 
			
		||||
Il est facilement possible de manipuler la carte et les pièces. Il nous suffit alors de faire correspondre l'affichage avec
 | 
			
		||||
ces différentes classes. Ce qui est entrepris par la classe \verb|GameUI|.
 | 
			
		||||
 | 
			
		||||
Le tout est géré par la classe \verb|Controller| qui permet de choisir entre l'affichage d'un menu ou d'une partie en cours.
 | 
			
		||||
 | 
			
		||||
% \subsection{Difficultés}
 | 
			
		||||
 | 
			
		||||
\section{Points Forts}
 | 
			
		||||
 | 
			
		||||
\subsection{Parser de fichiers}
 | 
			
		||||
 | 
			
		||||
Pour la rétention des niveaux, plusieurs possibilités s'offraient à nous. Nous avons alors décidés d'accomplir une série d'objectifs propre à notre projet avec un parser de fichiers dédié.
 | 
			
		||||
Nous voulions que ce parser accomplisse les objectifs suivants:
 | 
			
		||||
\begin{itemize}
 | 
			
		||||
	\item{Les données du niveau seront encapsulées dans un header/footer pour laisser la possibilité d'enregistrer plus d'informations (images/musiques) dans un seul fichier dans le futur.}
 | 
			
		||||
	\item{La taille du fichier devra être aussi petite que possible, tout en gardant les informations nécessaire au bon fonctionnement du jeu.}
 | 
			
		||||
	\item{Il sera possible d'enregistrer l'état d'une partie en cours.}
 | 
			
		||||
\end{itemize}
 | 
			
		||||
 | 
			
		||||
Ce parser est implémenté par la classe \verb|BinaryParser|.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{spécification}
 | 
			
		||||
 | 
			
		||||
\begin{description}
 | 
			
		||||
	\item[Header/Footer]{ Les données du niveau commencent par les 3 \emph{caractères} 'S', 'M', 'S' (ou \verb|0x534D53|) et se terminent par les 3 \emph{caractères} 'S', 'M', 'E' (ou \verb|0x534D45|)}
 | 
			
		||||
	\item[Taille de carte]{ Le premier octet des données représente la largeur de la carte, le second sa hauteur.}
 | 
			
		||||
	\item[Forme de la carte]{ Chaques cellules de la carte est représenté par un 1 ou un 0. le 1 représente un emplacement libre, un 0 une cellule vide.
 | 
			
		||||
		La forme de la carte peut alors être répartie sur un nombre indéterminé d'octets.
 | 
			
		||||
		Nous pouvons déterminer ce nombre grace à
 | 
			
		||||
		$$\frac{\text{largeur} * \text{hauteur } (+1 \text{ si multiple de } 8)}{8}$$ 
 | 
			
		||||
		en division entière.}
 | 
			
		||||
	\item[Nombre de pièce]{ L' (les) octet(s) qui forme(nt) la carte représente le nombre de pièce}
 | 
			
		||||
	\item[Pour chaques pièces]{
 | 
			
		||||
			\
 | 
			
		||||
			\begin{description}
 | 
			
		||||
				\item[Taille de la pièce]{La taille est représentée sur un seul octet sous forme de nibble\footnote{https://en.wikipedia.org/wiki/Nibble}. La première partie du nibble est la largeur. La seconde partie du nibble est la hauteur }
 | 
			
		||||
				\item[Forme de la pièce]{ Chaques cellules de la pièce est représentée par un 1 ou un 0. la manière de le représenter et exactement la même que pour la forme de la carte }
 | 
			
		||||
			\end{description}
 | 
			
		||||
			Dans le cas où le fichier sauvegarde l'état de la partie, à la fin, et pour chaques pièces dans le même ordre que l'apparition des pièces:
 | 
			
		||||
			\begin{description}
 | 
			
		||||
				\item[Position de la pièce]{2 octets par pièces, 1 octet pour sa position en x et 1 octet pour sa position en y.
 | 
			
		||||
					Dans le cas où la pièce est flotante (n'est pas placée dans la carte.), les octets contenant les caractères F puis L (0x464C) remplacent les coordonées}
 | 
			
		||||
			\end{description}
 | 
			
		||||
		}
 | 
			
		||||
\end{description}
 | 
			
		||||
 | 
			
		||||
\subsubsection*{Exemple}
 | 
			
		||||
 | 
			
		||||
Voici le 'hexdump' du niveau 11
 | 
			
		||||
 | 
			
		||||
\begin{verbatim}
 | 
			
		||||
53 4d 53 05 05 e7 ff ff  80 06 33 ff 80 22 f0 22  |SMS.......3.."."|
 | 
			
		||||
b0 22 70 22 b0 11 80 53  4d 45                    |."p"...SME|
 | 
			
		||||
\end{verbatim}
 | 
			
		||||
 | 
			
		||||
représente une carte de la forme :
 | 
			
		||||
 | 
			
		||||
\begin{tikzpicture}
 | 
			
		||||
	\filldraw[blue] (0,0) -- (0,5) -- (3,5) -- (3,4) -- (5,4) -- (5,0) -- cycle;
 | 
			
		||||
	\draw[step=1cm,gray] (0, 0) grid (5,5);
 | 
			
		||||
\end{tikzpicture}
 | 
			
		||||
 | 
			
		||||
avec les pièces :
 | 
			
		||||
 | 
			
		||||
\begin{tikzpicture}
 | 
			
		||||
	\fill[red] (1,1) rectangle (4,4);
 | 
			
		||||
	\fill[red] (5,1) rectangle (7,3);
 | 
			
		||||
	\fill[red] (8,1) -- (8,3) -- (9,3) -- (9,2) -- (10,2) -- (10,1) -- cycle;
 | 
			
		||||
	\fill[red] (11,1) -- (11,2) -- (12,2) -- (12,3) -- (13,3) -- (13,1) -- cycle;
 | 
			
		||||
	\fill[red] (1,-2) -- (1,0) -- (2,0) -- (2,-1) -- (3,-1) -- (3,-2) -- cycle;
 | 
			
		||||
	\fill[red] (4, -2) rectangle (5, -1);
 | 
			
		||||
	\draw[step=1cm,gray] (0.5, -2.5) grid (13.5, 4.5);
 | 
			
		||||
\end{tikzpicture}
 | 
			
		||||
 | 
			
		||||
En plus de ce parser, et dans le cas où ce premier parser ne serait pas capable de stocker certaine carte (par exemple si une pièce mesure plus de 15x15).
 | 
			
		||||
Nous avons également implémenté un parser très simple en utilisant l'interface \verb|Serialize| de java. Ce parser est implémenté et fonctionnel,
 | 
			
		||||
mais n'est pas utilisé dans le projet à l'heure actuelle.
 | 
			
		||||
 | 
			
		||||
Ces deux parseurs implémentent l'interface \verb|FileParser|.
 | 
			
		||||
 | 
			
		||||
Finalement, La classe \verb|FileParserFactory| permet une utilisation simple de ces parseurs. Celle-ci contient deux fonctions statiques.
 | 
			
		||||
\begin{itemize}
 | 
			
		||||
	\item{\verb|Map loadMapFromFile(File)|}
 | 
			
		||||
		permet de retourner la Map d'un fichier chargé.
 | 
			
		||||
	\item{\verb|void saveFileFromMap(File, Map)|}
 | 
			
		||||
		permet de sauvegarder une map dans un fichier.
 | 
			
		||||
\end{itemize}
 | 
			
		||||
 | 
			
		||||
Dans le cas d'une sauvegarde ou d'un chargement, le parser est choisi en fonction de l'extension de fichier ('.level', '.slevel', .'serialized', '.sserialized').
 | 
			
		||||
 | 
			
		||||
L'avantage de ce system est que nous pouvons facilement ajouter d'autres parser de fichier dans le futurs.
 | 
			
		||||
 | 
			
		||||
\subsection{Générateur de niveaux}
 | 
			
		||||
 | 
			
		||||
Le générateur de niveaux a été conçu de sorte à proposer 3 difficultés différentes
 | 
			
		||||
 | 
			
		||||
\begin{itemize}
 | 
			
		||||
	\item{Niveau Facile}
 | 
			
		||||
	\item{Niveau Moyen}
 | 
			
		||||
	\item{Niveau Difficile}
 | 
			
		||||
\end{itemize}
 | 
			
		||||
 | 
			
		||||
L'algorithme derrière est le même en voici le principe :
 | 
			
		||||
 | 
			
		||||
\subsubsection*{Gestion du plateau}
 | 
			
		||||
 | 
			
		||||
Le joueur choisi une difficultée. En fonction de la difficultée choisie la grandeur du plateau de jeu sera différente.
 | 
			
		||||
Si la difficulté choisie est facile ou moyenne, alors un curseur parcour les extrémités du niveau.
 | 
			
		||||
Ce curseur sélectionne aléatoirement les cellules qui seront gardés ou non.
 | 
			
		||||
Grâce à ça, la forme du plateau n'est pas trop carrée.
 | 
			
		||||
 | 
			
		||||
Nous nous sommes basé sur le même principe pour le niveau de difficulté difficile mais en plus d'une taille encore plus grande,
 | 
			
		||||
le curseur parcours les extrémités avec une profondeur de 2 afin de faire varier la carte plus grande.
 | 
			
		||||
Cela introduit le problème des cases isolés. c'est pourquoi une boucle vérifie chaques cellules et la supprime si celle si est isolée.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{Gestion des pièces}
 | 
			
		||||
 | 
			
		||||
Peu importe la difficulté du niveau voici le fonctionnement :
 | 
			
		||||
 | 
			
		||||
Une taille maximum des pièces a été fixée au préalable à 3x3.
 | 
			
		||||
Par la suite, un curseur parcours des cases de la carte préalablement conçue de manière aléatoire.
 | 
			
		||||
Pour chaques cases, l'algorithme teste pour chaques cases de la pièce, si l'espace est disponible.
 | 
			
		||||
Si ca n'est pas le cas, alors la pièce est modifiée afin de faire correspondre la pièce et la carte.
 | 
			
		||||
 | 
			
		||||
L'avantage de cette méthode est que les niveaux sont tous très différents.
 | 
			
		||||
Les désavantages sont que, par malchance, il est possible d'avoir énormément de piece 1x1.
 | 
			
		||||
Ainsi qu'il est plus difficile d'appliquer des textures et dessins - à l'image du jeu de base - sur les pièces.
 | 
			
		||||
 | 
			
		||||
Malgrés tout, avec nos nombreux test, ce générateur de niveaux nous satisfait vraiment bien et la difficultée des niveaux coorespond bien aux attentes.
 | 
			
		||||
 | 
			
		||||
\subsection{Interface graphique}
 | 
			
		||||
L'interface graphique du jeu tient sur 5 classes différentes.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{Controller}
 | 
			
		||||
Classe principale. Elle s'occupe de la gestion des autres classe, et de la cohérence entre elles.
 | 
			
		||||
Toutes les autres classes (présentes dans le package \verb|Scenes|) sont des sous classe de Parents.
 | 
			
		||||
Celà permet de les afficher grace à la méthode statique \verb|switchRoot|.
 | 
			
		||||
C'est aussi le point d'entrée du programme.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{MenuAccueil}
 | 
			
		||||
Classe s'occupant de générer la page d'accueil du jeu.
 | 
			
		||||
C'est-à-dire la première page que vera l'utilisateur.
 | 
			
		||||
Cette page permet d'accéder aux niveaux du jeu de base, mais également de générer les niveaux aléatoires.
 | 
			
		||||
De plus un dernier boutons "Load Game" permet de revenir sur la dernière partie en cours du joueur.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{MenuLevel}
 | 
			
		||||
Classe s'occupant d'afficher les niveaux proposés dans le jeu, et qui,
 | 
			
		||||
en fonction du jour choisir, change les boutons et les niveaux disponibles.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{ScreenLevelFinish}
 | 
			
		||||
Classe qui s'affiche à l'écran dès que le joueur a fini le niveau.
 | 
			
		||||
Celle-ci propose également de réessayer le niveau ou de retourner au menu principal.
 | 
			
		||||
 | 
			
		||||
\subsubsection*{GameUI}
 | 
			
		||||
Classe s'occupant de l'affichage d'un niveau.
 | 
			
		||||
S'occupe dans un premier temps d'afficher le plateau au milieu de l'écrant.
 | 
			
		||||
Par la suite, les pièces sont dispérsées à la gauche de l'écrant et sont rendu disponible à l'utilisateurs.
 | 
			
		||||
Ces pièces sont déplacables à l'aide de la souris.
 | 
			
		||||
Si elles sont lachées sur un emplacement disponible du plateau, alors elle vont s'alligner avec ses cellules.
 | 
			
		||||
Pour se faire, nous regardons si le centre d'une cellule (la plus en haut à gauche) est présente dans une cellule du plateau.
 | 
			
		||||
Ensuite, on vérifie que toutes les cellules de la pièces ont bien la place dans le plateau pour se poser. si c'est le cas, alors la pièce est posée.
 | 
			
		||||
 | 
			
		||||
\section{Points Faibles}
 | 
			
		||||
 | 
			
		||||
Bien que l'interface graphique permet de naviguer de manière fluide dans le jeu, il y a clairement un manque d'animation et de dynamisme
 | 
			
		||||
\emph{i.e}: transition de page à une autre, apparition des boutons ainsi qu'un manque de musique.
 | 
			
		||||
Toujours concernant l'affichage l'adaptation à la taille de l'écran peut être revue.
 | 
			
		||||
 | 
			
		||||
De plus suite à la perte de notre membre nous n'avons pas su gérer la partie du projet qui concerne le design/textures des pièces ainsi que l'histoire jeu préparée auparavant.
 | 
			
		||||
 | 
			
		||||
\section{Apports Positifs et négatifs}
 | 
			
		||||
 | 
			
		||||
\subsection{Anthony}
 | 
			
		||||
 | 
			
		||||
Personellement, ce projet m'a permis de me plonger dans la conception d'un format de fichier personnalisé.
 | 
			
		||||
C'est une chôse que je n'avais pas encore fait jusqu'à maintenant.
 | 
			
		||||
Et malgré mes efforts pour prévoir un maximum de choses à l'avance afin d'éviter de devoir 
 | 
			
		||||
modifier ma spécification pendant le dévelopement. Je me suis vite rendu compte que je n'avais pas pensé
 | 
			
		||||
à tout et que je devrais changer des choses pour pouvoir arriver à mes fins.
 | 
			
		||||
Je pense que ce parser de fichier est vraiment améliorable mais je suis relativement fier du résultat.
 | 
			
		||||
 | 
			
		||||
J'ai pu présenter ce parser à Dr Quoitin qui a pu me conseiller sur différentes approches à ce problème.
 | 
			
		||||
J'en prend bonne notes.
 | 
			
		||||
 | 
			
		||||
\subsection{Matteo}
 | 
			
		||||
 | 
			
		||||
Il est clair que je peux tirer plusieurs enseignement grâce à la réalisation de notre projet.
 | 
			
		||||
Tout d'abord, j'ai pu en apprendre beaucoup plus concernant la P.O.O en java, mais aussi  j'en ai appris
 | 
			
		||||
d'avantage sur l'utilisation de la bibliotheque JavaFx.
 | 
			
		||||
 | 
			
		||||
De plus, durant la réalisation du projet, comme dit précédemment nous avons utilisé plusieurs outils et dont la plus grande découverte pour moi :
 | 
			
		||||
Git. Qui révèle son intérêt pour les travaux de groupes, et qui selon moi se révélera tout aussi essentiel pour mes futurs projets
 | 
			
		||||
scolaires ainsi que professionnels.
 | 
			
		||||
 | 
			
		||||
\section{conclusion}
 | 
			
		||||
 | 
			
		||||
En conclusion nous pouvons séparer notre travail en trois partie différentes
 | 
			
		||||
 | 
			
		||||
\begin{enumerate}
 | 
			
		||||
	\item Le parser de fichier (gestion sauvegarder/charger partie)
 | 
			
		||||
	\item Logique du jeu (Map,Vec2,Shapes)
 | 
			
		||||
	\item Liaison à l'UI (Javafx)
 | 
			
		||||
\end{enumerate}
 | 
			
		||||
 | 
			
		||||
Malgré notre travail concentré sur le bon fonctionnement du jeu avec un parser suivant nos objectifs, une utilisation de la P.O.O de manière très efficace,
 | 
			
		||||
ainsi qu'une approche correcte de l'utilisation du framework Javafx, d'autre améliorations sont toujours possible !
 | 
			
		||||
En effet l'idée de rajouter une histoire, des trophées, un easter egg, des pièces spéciales ou un encore un table de score basée sur le temps,
 | 
			
		||||
reste possible afin de rendre notre jeu encore plus complet.
 | 
			
		||||
 | 
			
		||||
En conclusion, notre jeu a encore plein de possibilité afin d'être encore plus complet et amusant!
 | 
			
		||||
 | 
			
		||||
\end{document}
 | 
			
		||||
@ -6,10 +6,6 @@
 | 
			
		||||
- [Deuxième entrevue](./rapports/200223.md)
 | 
			
		||||
- [Troisième entrevue](./rapports/230323.md)
 | 
			
		||||
 | 
			
		||||
# Specification
 | 
			
		||||
 | 
			
		||||
- [File Parser](./spec/FileParser.md)
 | 
			
		||||
 | 
			
		||||
# Histoire
 | 
			
		||||
 | 
			
		||||
- [Plot Story](./histoire/plot_story.md)
 | 
			
		||||
@ -1,50 +0,0 @@
 | 
			
		||||
<!-- --- -->
 | 
			
		||||
<!-- title: File Parser -->
 | 
			
		||||
<!-- author: Debucquoy Anthony (tonitch) -->
 | 
			
		||||
<!-- date: 5 March 2023 -->
 | 
			
		||||
<!-- --- -->
 | 
			
		||||
# File Parser Specification
 | 
			
		||||
 | 
			
		||||
For the Project, I wanted to challenge myself, I decided to do my own file parser with my own specification that would
 | 
			
		||||
have the special objective of being really small.
 | 
			
		||||
 | 
			
		||||
## The File format
 | 
			
		||||
 | 
			
		||||
The file would use the .level file extension.
 | 
			
		||||
 | 
			
		||||
The file can contain anything, the used data is enclosed between a header and a footer.
 | 
			
		||||
This could be used to add: musics, images and other stuff in the level file itself 
 | 
			
		||||
 | 
			
		||||
Only one Header and One Footer should be present in the file.
 | 
			
		||||
The parser will only read the first one it finds so to avoid problem, it is best practise to put the
 | 
			
		||||
level data at the top of the file.
 | 
			
		||||
 | 
			
		||||
- The HEADER will be defined by the succesion of the characters 'S', 'M' then 'S' 
 | 
			
		||||
- The FOOTER will be defined by the succesion of the characters 'S', 'M', then 'E'
 | 
			
		||||
- The bytes in between are the level data
 | 
			
		||||
  - byte 1: Width of the map
 | 
			
		||||
  - byte 2: Height of the map
 | 
			
		||||
  - bytes 3 -> Width * Height (+1 if Width * Height % 8 is not 0)
 | 
			
		||||
  - byte after Map Data: Pieces amount
 | 
			
		||||
  - for each pieces
 | 
			
		||||
    - 1 byte: size of the piece
 | 
			
		||||
      - 4 first bits : width
 | 
			
		||||
      - 4 last bits: height
 | 
			
		||||
    - next bytes -> Width * Height (+1 if Width * Height % 8 is not 0)
 | 
			
		||||
 | 
			
		||||
### Saved file
 | 
			
		||||
 | 
			
		||||
For saved file, the extension will be .slevel
 | 
			
		||||
The only difference is that at the end of the map data (after the pieces and before the
 | 
			
		||||
Footer. there will be the position of each pieces from their top-left corner in the map.
 | 
			
		||||
following this pattern for each pieces
 | 
			
		||||
 | 
			
		||||
  - 'F' and 'L' on 2 bytes for floating positions when the piece is not placed
 | 
			
		||||
  - x and y on 2 bytes for position if the piece is placed
 | 
			
		||||
 | 
			
		||||
## Known Limitation
 | 
			
		||||
 | 
			
		||||
1) by putting the piece size on one byte. We limit the maximum piece size to 15 x 15 (1111 | 1111)
 | 
			
		||||
I don't think we will ever need a piece larger than 5x5 so this is clearly a feature, not a bug! :-)
 | 
			
		||||
We might use the same methods for the pieces positions but there could be a posibility to have
 | 
			
		||||
larger map if I use 2 bytes for the positions.
 | 
			
		||||
@ -19,9 +19,7 @@ repositories {
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    // Use JUnit Jupiter for testing.
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.2'
 | 
			
		||||
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
 | 
			
		||||
 | 
			
		||||
    // This dependency is used by the application.
 | 
			
		||||
    implementation 'com.google.guava:guava:31.1-jre'
 | 
			
		||||
@ -29,7 +27,7 @@ dependencies {
 | 
			
		||||
 | 
			
		||||
application {
 | 
			
		||||
    // Define the main class for the application.
 | 
			
		||||
    mainClass = project.hasProperty("mainClass") ? project.getProperty("mainClass") : 'school_project.Controller'
 | 
			
		||||
    mainClass = 'school_project.Controller'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
javafx {
 | 
			
		||||
@ -41,7 +39,3 @@ tasks.named('test') {
 | 
			
		||||
    // Use JUnit Platform for unit tests.
 | 
			
		||||
    useJUnitPlatform()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
run{
 | 
			
		||||
standardInput = System.in
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,69 +1,222 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
package school_project;  
 | 
			
		||||
import javafx.application.Application;
 | 
			
		||||
import javafx.scene.Parent;
 | 
			
		||||
import javafx.scene.Node;
 | 
			
		||||
import javafx.event.EventHandler;
 | 
			
		||||
import javafx.scene.Group;
 | 
			
		||||
import javafx.scene.Scene;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.input.KeyCode;
 | 
			
		||||
import javafx.scene.input.KeyCombination;
 | 
			
		||||
import javafx.stage.Screen;
 | 
			
		||||
import javafx.scene.Cursor;
 | 
			
		||||
import javafx.scene.input.KeyEvent;
 | 
			
		||||
import javafx.scene.input.MouseEvent;
 | 
			
		||||
import javafx.scene.paint.Color;  
 | 
			
		||||
import javafx.scene.shape.Polygon;
 | 
			
		||||
import javafx.scene.transform.Rotate;
 | 
			
		||||
import javafx.animation.RotateTransition;
 | 
			
		||||
import javafx.stage.Stage;
 | 
			
		||||
import school_project.Menu.MenuAccueil;
 | 
			
		||||
import school_project.Parsers.FileParserFactory;
 | 
			
		||||
import javafx.util.Duration;
 | 
			
		||||
public class Controller extends Application{
 | 
			
		||||
	
 | 
			
		||||
	double x;
 | 
			
		||||
	double y;
 | 
			
		||||
	
 | 
			
		||||
	 
 | 
			
		||||
	public void start(Stage primaryStage) throws Exception {
 | 
			
		||||
		
 | 
			
		||||
		Polygon piece1 = new Polygon();
 | 
			
		||||
		Polygon piece2 = new Polygon();
 | 
			
		||||
		Polygon piece3 = new Polygon();
 | 
			
		||||
		Polygon piece4 = new Polygon();
 | 
			
		||||
		Polygon piece5 = new Polygon();
 | 
			
		||||
		Polygon piece6 = new Polygon();
 | 
			
		||||
		Polygon piece7 = new Polygon();
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		 piece1.getPoints().addAll(new Double [] {
 | 
			
		||||
				 0.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,200.0,
 | 
			
		||||
				 100.0,200.0,
 | 
			
		||||
				 100.0,100.0,
 | 
			
		||||
				 0.0,100.0});
 | 
			
		||||
		 
 | 
			
		||||
		 piece2.getPoints().addAll(new Double [] {
 | 
			
		||||
				 100.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,300.0,
 | 
			
		||||
				 100.0,300.0,
 | 
			
		||||
				 });
 | 
			
		||||
		 
 | 
			
		||||
		 piece3.getPoints().addAll(new Double [] {
 | 
			
		||||
				 0.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,200.0,
 | 
			
		||||
				 0.0,200.0,
 | 
			
		||||
				 });
 | 
			
		||||
		 
 | 
			
		||||
		 piece4.getPoints().addAll(new Double [] {
 | 
			
		||||
				 0.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,300.0,
 | 
			
		||||
				 0.0,300.0,
 | 
			
		||||
				 
 | 
			
		||||
		 });
 | 
			
		||||
		 
 | 
			
		||||
		 piece5.getPoints().addAll(new Double [] {
 | 
			
		||||
				 0.0,0.0,
 | 
			
		||||
				 100.0,0.0,
 | 
			
		||||
				 100.0,100.0,
 | 
			
		||||
				 0.0,100.0,
 | 
			
		||||
				 });
 | 
			
		||||
		 
 | 
			
		||||
		 piece6.getPoints().addAll(new Double [] {
 | 
			
		||||
				 0.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,300.0,
 | 
			
		||||
				 100.0,300.0,
 | 
			
		||||
				 100.0,100.0,
 | 
			
		||||
				 0.0,100.0});
 | 
			
		||||
		 
 | 
			
		||||
		 piece7.getPoints().addAll(new Double [] {
 | 
			
		||||
				 100.0,0.0,
 | 
			
		||||
				 200.0,0.0,
 | 
			
		||||
				 200.0,200.0,
 | 
			
		||||
				 100.0,200.0,
 | 
			
		||||
				 });
 | 
			
		||||
		
 | 
			
		||||
		 /*for(int i ; i<tab.lenght ; i++ ) {
 | 
			
		||||
			for (int j , i<tab.widnth , j++) {
 | 
			
		||||
				
 | 
			
		||||
				if (tab[0][0]==TRUE;) {
 | 
			
		||||
					if(tab[
 | 
			
		||||
				
 | 
			
		||||
					
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}*/
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
	
 | 
			
		||||
		 Group root = new Group();  
 | 
			
		||||
	        root.getChildren().addAll(piece2,piece1,piece3,piece4,piece5,piece6,piece7/*,....,pieceN*/);  
 | 
			
		||||
	        Scene scene = new Scene(root,690,650,Color.WHEAT);  
 | 
			
		||||
	        root.getChildren().forEach(n -> makeDraggable((Polygon) n));
 | 
			
		||||
	        root.getChildren().forEach(n -> rotation((Polygon) n, scene));
 | 
			
		||||
	        primaryStage.setScene(scene);  
 | 
			
		||||
	        primaryStage.setTitle("piece 1"); 
 | 
			
		||||
	        
 | 
			
		||||
	        primaryStage.show(); 
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		 
 | 
			
		||||
		 piece1.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece1.setStroke(Color.BLACK);
 | 
			
		||||
		 piece1.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece2.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece2.setStroke(Color.BLACK);
 | 
			
		||||
		 piece2.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece3.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece3.setStroke(Color.BLACK);
 | 
			
		||||
		 piece3.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece4.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece4.setStroke(Color.BLACK);
 | 
			
		||||
		 piece4.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece5.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece5.setStroke(Color.BLACK);
 | 
			
		||||
		 piece5.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece6.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece6.setStroke(Color.BLACK);
 | 
			
		||||
		 piece6.setStrokeWidth(3);
 | 
			
		||||
		 
 | 
			
		||||
		 piece7.setFill(Color.LIMEGREEN);
 | 
			
		||||
		 piece7.setStroke(Color.BLACK);
 | 
			
		||||
		 piece7.setStrokeWidth(3);
 | 
			
		||||
		 		 
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	//double click delayed bug to fix
 | 
			
		||||
	//ftm just the last piece implemented can be rotated 
 | 
			
		||||
	public static void rotaterght (Node node) {
 | 
			
		||||
		 RotateTransition rotaterght = new RotateTransition();
 | 
			
		||||
			//setting attributes for the RotateTransition  
 | 
			
		||||
			 rotaterght.setByAngle(90);
 | 
			
		||||
			 rotaterght.autoReverseProperty();
 | 
			
		||||
			 rotaterght.setDuration(Duration.millis(1000));
 | 
			
		||||
			 rotaterght.setNode(node);
 | 
			
		||||
			 rotaterght.setAxis(Rotate.Z_AXIS);
 | 
			
		||||
			 rotaterght.play();}
 | 
			
		||||
	 
 | 
			
		||||
	 public static void rotatelft (Node node) {	 
 | 
			
		||||
			
 | 
			
		||||
			 RotateTransition rotatelft = new RotateTransition();
 | 
			
		||||
			 
 | 
			
		||||
			 rotatelft.setByAngle(-90);// minus to rotate to the left
 | 
			
		||||
			 rotatelft.autoReverseProperty();
 | 
			
		||||
			 rotatelft.setDuration(Duration.millis(1000));
 | 
			
		||||
			 rotatelft.setNode(node);
 | 
			
		||||
			 rotatelft.setAxis(Rotate.Z_AXIS);
 | 
			
		||||
			 rotatelft.play();}
 | 
			
		||||
	 
 | 
			
		||||
	 public void rotation (Polygon node, Scene scene) {
 | 
			
		||||
		  scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
 | 
			
		||||
			 public void handle(KeyEvent event) {// 'event' means corresponds to clicking on the clipboard
 | 
			
		||||
				 switch (event.getCode()) {// 'getCode' gets the code of the key pressed on the clipboard
 | 
			
		||||
				 case RIGHT: rotaterght(node);   break;
 | 
			
		||||
				 //args to set 
 | 
			
		||||
				 case LEFT: rotatelft(node);  break;
 | 
			
		||||
				 default: System.out.println("this case hasn't been taken in charge yet");
 | 
			
		||||
				 
 | 
			
		||||
				 }
 | 
			
		||||
			 }
 | 
			
		||||
	  });
 | 
			
		||||
	  }
 | 
			
		||||
			  
 | 
			
		||||
	 
 | 
			
		||||
 | 
			
		||||
	  public void makeDraggable(Polygon node) {
 | 
			
		||||
		 	node.setOnMousePressed(new EventHandler<MouseEvent>() {
 | 
			
		||||
			  @Override public void handle(MouseEvent mouseEvent) {
 | 
			
		||||
			    // record a (x,y) distance for the drag and drop operation.
 | 
			
		||||
			    x = node.getLayoutX() - mouseEvent.getSceneX();
 | 
			
		||||
			    y = node.getLayoutY() - mouseEvent.getSceneY();
 | 
			
		||||
			    node.requestFocus();
 | 
			
		||||
			    node.setFocusTraversable(true);
 | 
			
		||||
			    node.focusedProperty();
 | 
			
		||||
			    node.focusVisibleProperty();
 | 
			
		||||
			    /*node.setFocused(true);*/
 | 
			
		||||
			    node.setCursor(Cursor.CLOSED_HAND);
 | 
			
		||||
			    node.setFill(Color.AZURE);
 | 
			
		||||
			  }
 | 
			
		||||
			});
 | 
			
		||||
		 
 | 
			
		||||
			node.setOnMouseReleased(new EventHandler<MouseEvent>() {
 | 
			
		||||
			  @Override public void handle(MouseEvent mouseEvent) {
 | 
			
		||||
			    node.setCursor(Cursor.HAND);
 | 
			
		||||
			    node.setFill(Color.LIMEGREEN);
 | 
			
		||||
			  }
 | 
			
		||||
			});
 | 
			
		||||
			
 | 
			
		||||
			node.setOnMouseDragged(new EventHandler<MouseEvent>() {
 | 
			
		||||
			  @Override public void handle(MouseEvent mouseEvent) {
 | 
			
		||||
			    node.setLayoutX(mouseEvent.getSceneX() + x);
 | 
			
		||||
			    node.setLayoutY(mouseEvent.getSceneY() + y);
 | 
			
		||||
			  }
 | 
			
		||||
			});
 | 
			
		||||
			
 | 
			
		||||
			node.setOnMouseEntered(new EventHandler<MouseEvent>() {
 | 
			
		||||
			  @Override public void handle(MouseEvent mouseEvent) {
 | 
			
		||||
			    node.setCursor(Cursor.HAND);
 | 
			
		||||
			  }
 | 
			
		||||
			});
 | 
			
		||||
			
 | 
			
		||||
		 }
 | 
			
		||||
 | 
			
		||||
public class Controller extends Application {
 | 
			
		||||
    private static Stage stage;
 | 
			
		||||
    Parent root;
 | 
			
		||||
    public static Vec2 screen_size;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void start(Stage primaryStage) throws IOException {
 | 
			
		||||
        new File("save.slevel");
 | 
			
		||||
        stage = primaryStage;
 | 
			
		||||
        screen_size = new Vec2(
 | 
			
		||||
            (int) Screen.getPrimary().getBounds().getWidth(),
 | 
			
		||||
            (int) Screen.getPrimary().getBounds().getHeight()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        stage.setTitle("ROAD TO MASTER YOU");
 | 
			
		||||
 | 
			
		||||
        // Full Screen mode
 | 
			
		||||
 | 
			
		||||
        root = new MenuAccueil();
 | 
			
		||||
 | 
			
		||||
        switchRoot(root);
 | 
			
		||||
        stage.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static void switchRoot(Parent root){
 | 
			
		||||
        Scene scene = new Scene(root);
 | 
			
		||||
        if(root instanceof GameUI){
 | 
			
		||||
            scene.setOnKeyPressed(event ->{
 | 
			
		||||
                GameUI game = (GameUI) root;
 | 
			
		||||
                if(event.getCode() == KeyCode.ESCAPE){
 | 
			
		||||
                    try {
 | 
			
		||||
                        FileParserFactory.saveFileFromMap(new File("save.slevel"), game.getLevel());
 | 
			
		||||
                        switchRoot(new MenuAccueil());
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        throw new RuntimeException(e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        stage.setScene(scene);
 | 
			
		||||
 | 
			
		||||
        stage.setFullScreen(true);
 | 
			
		||||
        stage.setFullScreenExitHint("");
 | 
			
		||||
        stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
 | 
			
		||||
    }
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        launch();
 | 
			
		||||
	
 | 
			
		||||
	public static void main(String[] args) {  
 | 
			
		||||
        launch(args);  
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,96 +0,0 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.Group;
 | 
			
		||||
import javafx.scene.input.MouseButton;
 | 
			
		||||
 | 
			
		||||
import school_project.Menu.ScreenLevelFinish;
 | 
			
		||||
import school_project.Utils.MatrixShape;
 | 
			
		||||
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
 | 
			
		||||
public class GameUI extends Group{
 | 
			
		||||
    public final static int SEGMENT_SIZE = 50;
 | 
			
		||||
    public final static int SPACE_SIZE = 5;
 | 
			
		||||
    private final Vec2 piece_pos_click = new Vec2();
 | 
			
		||||
 | 
			
		||||
    private Map level;
 | 
			
		||||
 | 
			
		||||
    public GameUI(Map level) throws FileNotFoundException {
 | 
			
		||||
        super();
 | 
			
		||||
        this.level = level;
 | 
			
		||||
 | 
			
		||||
        MatrixShape grid = new MatrixShape(level);
 | 
			
		||||
 | 
			
		||||
        //center the grid
 | 
			
		||||
        grid.setLayoutX((Controller.screen_size.x - grid.boundary_size.x) >> 1);
 | 
			
		||||
        grid.setLayoutY((Controller.screen_size.y - grid.boundary_size.y) >> 1);
 | 
			
		||||
 | 
			
		||||
        getChildren().add(grid);
 | 
			
		||||
 | 
			
		||||
        Vec2 piece_space = new Vec2(SPACE_SIZE, SPACE_SIZE);
 | 
			
		||||
        int column = 0;
 | 
			
		||||
        for (Piece p : level.getPieces()) {
 | 
			
		||||
            MatrixShape _piece = new MatrixShape(p);
 | 
			
		||||
 | 
			
		||||
            if(piece_space.y + _piece.boundary_size.y >= Controller.screen_size.y){
 | 
			
		||||
                column++;
 | 
			
		||||
                piece_space.y = SPACE_SIZE;
 | 
			
		||||
                piece_space.x = (SEGMENT_SIZE*3 + SPACE_SIZE*4 )* column;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _piece.setLayoutX(piece_space.x);
 | 
			
		||||
            _piece.setLayoutY(piece_space.y);
 | 
			
		||||
 | 
			
		||||
            piece_space.y += _piece.boundary_size.y;
 | 
			
		||||
 | 
			
		||||
            if(p.getPosition() != null){
 | 
			
		||||
                _piece.setLayoutX(grid.getLayoutX() + p.getPosition().y * (SEGMENT_SIZE+SPACE_SIZE));
 | 
			
		||||
                _piece.setLayoutY(grid.getLayoutY() + p.getPosition().x * (SEGMENT_SIZE+SPACE_SIZE));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Pieces Events
 | 
			
		||||
            _piece.setOnMouseClicked(event -> {
 | 
			
		||||
                if(event.getButton() == MouseButton.SECONDARY){
 | 
			
		||||
                    ((Piece) _piece.shape).RotateRight(1);
 | 
			
		||||
                    _piece.update();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            _piece.setOnMousePressed(event -> {
 | 
			
		||||
                piece_pos_click.x = (int) event.getX();
 | 
			
		||||
                piece_pos_click.y = (int) event.getY();
 | 
			
		||||
            });
 | 
			
		||||
            _piece.setOnMouseDragged(event -> {
 | 
			
		||||
                _piece.toFront();
 | 
			
		||||
                _piece.setLayoutX(event.getSceneX() - piece_pos_click.x);
 | 
			
		||||
                _piece.setLayoutY(event.getSceneY() - piece_pos_click.y);
 | 
			
		||||
            });
 | 
			
		||||
            _piece.setOnMouseReleased(event -> {
 | 
			
		||||
                if(event.getButton() != MouseButton.PRIMARY)
 | 
			
		||||
                    return;
 | 
			
		||||
                p.setPosition(null);
 | 
			
		||||
                if(event.getSceneX() > grid.getLayoutX() && event.getSceneX() < grid.getLayoutX() + grid.boundary_size.x
 | 
			
		||||
                    && event.getSceneY() > grid.getLayoutY() && event.getSceneY() < grid.getLayoutY() + grid.boundary_size.y )
 | 
			
		||||
                {
 | 
			
		||||
                    // Inverted because screen is x →; y ↓ and matrix is x ↓; y →
 | 
			
		||||
                    Vec2 piece_position_in_grid = new Vec2(
 | 
			
		||||
                            (int) (_piece.getLayoutY() + (SEGMENT_SIZE+SPACE_SIZE)/2 - grid.getLayoutY())/(SEGMENT_SIZE+SPACE_SIZE),
 | 
			
		||||
                            (int) (_piece.getLayoutX() + (SEGMENT_SIZE+SPACE_SIZE)/2 - grid.getLayoutX())/(SEGMENT_SIZE+SPACE_SIZE)
 | 
			
		||||
                    );
 | 
			
		||||
                    level.placePiece(p, piece_position_in_grid);
 | 
			
		||||
                    if(p.getPosition() != null){
 | 
			
		||||
                        _piece.setLayoutX(grid.getLayoutX() + p.getPosition().y * (SEGMENT_SIZE+SPACE_SIZE));
 | 
			
		||||
                        _piece.setLayoutY(grid.getLayoutY() + p.getPosition().x * (SEGMENT_SIZE+SPACE_SIZE));
 | 
			
		||||
                    }
 | 
			
		||||
                    if(level.gameDone()){
 | 
			
		||||
                        Controller.switchRoot(new ScreenLevelFinish(level));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            getChildren().add(_piece);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Map getLevel() {
 | 
			
		||||
        return level;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -14,72 +14,11 @@ public class Map extends Shape{
 | 
			
		||||
        super(matrix);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Map() {
 | 
			
		||||
        super();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addPiece(Piece piece){
 | 
			
		||||
        piece.setLinked_map(this);
 | 
			
		||||
        pieces.add(piece);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addPiece(Piece[] pieces) {
 | 
			
		||||
        for (Piece p : pieces)
 | 
			
		||||
            this.addPiece(p);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * try to place a piece on the map, return true if succeed and false if it failed
 | 
			
		||||
     * @param piece the piece to place
 | 
			
		||||
     * @param pos the position to place the piece in matrix position
 | 
			
		||||
     * @return true if the piece can and is placed and false if it can't and won't not be palced
 | 
			
		||||
     */
 | 
			
		||||
    public boolean placePiece(Piece piece, Vec2 pos){
 | 
			
		||||
 | 
			
		||||
        if(!pieces.contains(piece))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        piece.setPosition(null);
 | 
			
		||||
        // In the map limits
 | 
			
		||||
        if (    pos.x + piece.height > height
 | 
			
		||||
                || pos.y+piece.width > width
 | 
			
		||||
                || pos.x < 0
 | 
			
		||||
                || pos.y < 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        ArrayList<Vec2> occupation = new ArrayList<>();
 | 
			
		||||
        for(Piece p: pieces){
 | 
			
		||||
            if(p.getPosition() == null || p == piece)
 | 
			
		||||
                continue;
 | 
			
		||||
            for (Vec2 o : p.getOccupation()) {
 | 
			
		||||
                occupation.add(o);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int x = pos.x; x < pos.x + piece.height; x++) {
 | 
			
		||||
            for (int y = pos.y; y < pos.y + piece.width; y++) {
 | 
			
		||||
                if ((!getShape()[x][y] || occupation.contains(new Vec2(x, y))) && piece.getShape()[x - pos.x][y - pos.y]) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        piece.setPosition(pos);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if every pieces has a space on the board to know if the game is finished
 | 
			
		||||
     * @return true if the game is finished, false if not
 | 
			
		||||
     */
 | 
			
		||||
    public boolean gameDone(){
 | 
			
		||||
        ArrayList<Vec2> posList = getPosList();
 | 
			
		||||
        for(Piece p: pieces){
 | 
			
		||||
            posList.removeAll(p.getOccupation());
 | 
			
		||||
        }
 | 
			
		||||
        return posList.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return a matrix with all used space on the map to see if a piece can fit in a space
 | 
			
		||||
     *
 | 
			
		||||
@ -94,8 +33,6 @@ public class Map extends Shape{
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Piece p : pieces) {
 | 
			
		||||
            if(p.getPosition() == null)
 | 
			
		||||
                continue;
 | 
			
		||||
            for(int x = 0; x < p.height; x++){
 | 
			
		||||
                for(int y = 0; y < p.width; y++){
 | 
			
		||||
                    if (p.getShape()[x][y]){
 | 
			
		||||
@ -106,31 +43,4 @@ public class Map extends Shape{
 | 
			
		||||
        }
 | 
			
		||||
        return used;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<Piece> getPieces() {
 | 
			
		||||
        return pieces;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * return a new Clean Map without any pieces on it for saving purpose
 | 
			
		||||
     * @return a New Map Object without any pieces or saved data
 | 
			
		||||
     */
 | 
			
		||||
    public Map getCleanedMap() {
 | 
			
		||||
        try {
 | 
			
		||||
            Map ret = (Map) this.clone();
 | 
			
		||||
            ret.getPieces().clear();
 | 
			
		||||
            return ret;
 | 
			
		||||
        } catch (CloneNotSupportedException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * set the position of each pieces in the map to null
 | 
			
		||||
     */
 | 
			
		||||
    public void resetPiecesPositions(){
 | 
			
		||||
        for (Piece p : pieces) {
 | 
			
		||||
            p.setPosition(null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,102 +0,0 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import school_project.Utils.Array;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
public class MapGenerator {
 | 
			
		||||
    private static final Random rand = new Random();
 | 
			
		||||
    public enum Difficulty {
 | 
			
		||||
        Easy,
 | 
			
		||||
        Medium,
 | 
			
		||||
        Difficult,
 | 
			
		||||
    }
 | 
			
		||||
    public static Map generate(Difficulty difficulty){
 | 
			
		||||
        Vec2 map_size;
 | 
			
		||||
        int depth = 1; // how much the map shape generator could grind
 | 
			
		||||
 | 
			
		||||
        // define map size depending on the difficulty
 | 
			
		||||
        switch (difficulty){
 | 
			
		||||
            case Easy:
 | 
			
		||||
                map_size = new Vec2(rand.nextInt(2) + 3, rand.nextInt(2) + 3);
 | 
			
		||||
                break;
 | 
			
		||||
            case Medium:
 | 
			
		||||
                map_size = new Vec2(rand.nextInt(3)+5, rand.nextInt(3)+5);
 | 
			
		||||
                break;
 | 
			
		||||
            case Difficult:
 | 
			
		||||
                map_size = new Vec2(rand.nextInt(2)+8, rand.nextInt(2)+8);
 | 
			
		||||
                depth = 2;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                map_size = new Vec2();
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Cut edges
 | 
			
		||||
        boolean[][] map_shape = new boolean[map_size.x][map_size.y];
 | 
			
		||||
        for (boolean[] b : map_shape) {
 | 
			
		||||
            Arrays.fill(b, true);
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < map_shape.length; i++) {
 | 
			
		||||
            for (int j = 0; j < map_shape[0].length; j++) {
 | 
			
		||||
                if(i > depth - 1 && i < map_shape.length - depth && j > depth - 1 && j < map_shape[0].length - depth){
 | 
			
		||||
                        j = map_shape[0].length - depth;
 | 
			
		||||
                }
 | 
			
		||||
                map_shape[i][j] = rand.nextBoolean();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //delete lonely piece
 | 
			
		||||
        for (int i =0;i<map_shape.length;i++){
 | 
			
		||||
            for (int j = 0; j<map_shape[i].length;j++){
 | 
			
		||||
                boolean test = false;
 | 
			
		||||
                if(map_shape[i][j]){
 | 
			
		||||
                    for(int k = Math.max(i - 1, 0); k<= Math.min(i+1,map_shape.length-1); k++){
 | 
			
		||||
                        for (int l = Math.max(j - 1, 0); l<= Math.min(j+1,map_shape[i].length-1); l++){
 | 
			
		||||
                            if (k==i && l == j)
 | 
			
		||||
                                continue;
 | 
			
		||||
                            if (map_shape[k][l])
 | 
			
		||||
                                test = true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!test)
 | 
			
		||||
                        map_shape[i][j] = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Map ret = new Map(map_shape);
 | 
			
		||||
        boolean[][] piece_layout = Array.MatrixCopyOf(map_shape);
 | 
			
		||||
        ArrayList<Vec2> EmptySlots = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < piece_layout.length; i++) {
 | 
			
		||||
            for (int j = 0; j < piece_layout[i].length; j++) {
 | 
			
		||||
                if(piece_layout[i][j]){
 | 
			
		||||
                    EmptySlots.add(new Vec2(i, j));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (EmptySlots.size() > 0){
 | 
			
		||||
            Collections.shuffle(EmptySlots);
 | 
			
		||||
            Vec2 selected = EmptySlots.get(0);
 | 
			
		||||
            int size = 3;
 | 
			
		||||
            boolean[][] shape = new boolean[size][size];
 | 
			
		||||
            for(int i = 0; i < size; i++){
 | 
			
		||||
                for (int j = 0; j < size; j++) {
 | 
			
		||||
                    Vec2 checked = new Vec2(i, j).add(selected);
 | 
			
		||||
                    if(EmptySlots.contains(checked)){
 | 
			
		||||
                        EmptySlots.remove(checked);
 | 
			
		||||
                        piece_layout[checked.x][checked.y] = false;
 | 
			
		||||
                        shape[i][j] = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            ret.addPiece(new Piece(shape));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //generate pieces
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								app/src/main/java/school_project/Menu.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/src/main/java/school_project/Menu.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import javafx.application.Application;
 | 
			
		||||
import javafx.scene.Scene;
 | 
			
		||||
import javafx.scene.layout.BorderPane;
 | 
			
		||||
import javafx.stage.Stage;
 | 
			
		||||
 | 
			
		||||
public class Menu extends Application {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        launch(args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void start(Stage primaryStage) {
 | 
			
		||||
        //set up the page
 | 
			
		||||
        BorderPane root = new BorderPane();
 | 
			
		||||
        Scene scene = new Scene(root,300,200);
 | 
			
		||||
        primaryStage.setScene(scene);
 | 
			
		||||
        primaryStage.show();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
package school_project.Menu;
 | 
			
		||||
import javafx.geometry.Insets;
 | 
			
		||||
import javafx.geometry.Pos;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.control.ChoiceBox;
 | 
			
		||||
import javafx.scene.control.Label;
 | 
			
		||||
import javafx.scene.layout.StackPane;
 | 
			
		||||
import javafx.scene.paint.Color;
 | 
			
		||||
import javafx.scene.text.Font;
 | 
			
		||||
import school_project.Controller;
 | 
			
		||||
import school_project.GameUI;
 | 
			
		||||
import school_project.MapGenerator;
 | 
			
		||||
import school_project.Parsers.FileParserFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class MenuAccueil extends StackPane {
 | 
			
		||||
    public MenuAccueil(){
 | 
			
		||||
        super();
 | 
			
		||||
        //create all the objet that I need
 | 
			
		||||
        ChoiceBox<String> SlctDifficulty = new ChoiceBox<>();
 | 
			
		||||
        SlctDifficulty.getItems().addAll("Easy", "Medium", "Difficult");
 | 
			
		||||
 | 
			
		||||
        Label RdmLvl = new Label("Random Level : ");
 | 
			
		||||
        Button LoadLvl = new Button("Load game");
 | 
			
		||||
        Button SelectLevel= new Button("Select Level");
 | 
			
		||||
 | 
			
		||||
        Label Title = new Label("Welcome to Road to Master");
 | 
			
		||||
            SlctDifficulty.setOnAction(event -> {
 | 
			
		||||
                String choosediff = SlctDifficulty.getSelectionModel().getSelectedItem();
 | 
			
		||||
                System.out.println(choosediff);
 | 
			
		||||
                switch (choosediff) {
 | 
			
		||||
                    case "Easy":
 | 
			
		||||
                        try {
 | 
			
		||||
                            Controller.switchRoot(new GameUI(MapGenerator.generate(MapGenerator.Difficulty.Easy)));
 | 
			
		||||
                        } catch (FileNotFoundException e) {
 | 
			
		||||
                            throw new RuntimeException(e);
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    case "Medium":
 | 
			
		||||
                            try {
 | 
			
		||||
                                Controller.switchRoot(new GameUI(MapGenerator.generate(MapGenerator.Difficulty.Medium)));
 | 
			
		||||
                            } catch (FileNotFoundException e) {
 | 
			
		||||
                                throw new RuntimeException(e);
 | 
			
		||||
                            }
 | 
			
		||||
                        break;
 | 
			
		||||
                    case "Difficult":
 | 
			
		||||
                            try {
 | 
			
		||||
                                Controller.switchRoot(new GameUI(MapGenerator.generate(MapGenerator.Difficulty.Difficult)));
 | 
			
		||||
                            } catch (FileNotFoundException e) {
 | 
			
		||||
                                throw new RuntimeException(e);
 | 
			
		||||
                            }
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        //set up all the Button where I need
 | 
			
		||||
 | 
			
		||||
        getChildren().addAll(Title,SlctDifficulty,SelectLevel,RdmLvl,LoadLvl);
 | 
			
		||||
        RdmLvl.setFont(Font.font(25));
 | 
			
		||||
        RdmLvl.setTextFill(Color.GOLD);
 | 
			
		||||
        Title.setFont(Font.font(40));
 | 
			
		||||
        Title.setTextFill(Color.RED);
 | 
			
		||||
        setAlignment(Title, Pos.TOP_CENTER);
 | 
			
		||||
        setAlignment(LoadLvl,Pos.BOTTOM_CENTER);
 | 
			
		||||
        setAlignment(SlctDifficulty,Pos.CENTER_LEFT);
 | 
			
		||||
        setAlignment(SelectLevel,Pos.CENTER_RIGHT);
 | 
			
		||||
        setAlignment(RdmLvl, Pos.CENTER_LEFT);
 | 
			
		||||
 | 
			
		||||
        setMargin(RdmLvl,new Insets(0,0,0,100));
 | 
			
		||||
        setMargin(SlctDifficulty,new Insets(0,0,0,300));
 | 
			
		||||
        setMargin(SelectLevel,new Insets(0,300,0,0));
 | 
			
		||||
        setMargin(Title,new Insets(200,0,0,0));
 | 
			
		||||
        setMargin(LoadLvl,new Insets(0,0,200,0));
 | 
			
		||||
 | 
			
		||||
        SelectLevel.setOnAction(event ->  Controller.switchRoot(new MenuLevel(1)));
 | 
			
		||||
        LoadLvl.setOnAction(event -> {
 | 
			
		||||
            try {
 | 
			
		||||
                Controller.switchRoot(new GameUI(FileParserFactory.loadMapFromFile(new File("save.slevel"))));
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        getStyleClass().add("BorderPane");
 | 
			
		||||
        getStylesheets().add(String.valueOf(getClass().getResource("StyleMenuAcceuil.css")));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,123 +0,0 @@
 | 
			
		||||
package school_project.Menu;
 | 
			
		||||
 | 
			
		||||
import javafx.geometry.HPos;
 | 
			
		||||
import javafx.geometry.Insets;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.layout.ColumnConstraints;
 | 
			
		||||
import javafx.scene.layout.GridPane;
 | 
			
		||||
import javafx.scene.layout.RowConstraints;
 | 
			
		||||
import school_project.Controller;
 | 
			
		||||
import school_project.GameUI;
 | 
			
		||||
import school_project.Parsers.FileParserFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class MenuLevel extends GridPane {
 | 
			
		||||
    private int StartLevel;
 | 
			
		||||
    public MenuLevel(int choose_day) {
 | 
			
		||||
 | 
			
		||||
        //create all Object that I need
 | 
			
		||||
        RowConstraints[] Rows = new RowConstraints[5];
 | 
			
		||||
        ColumnConstraints[] Columns = new ColumnConstraints[3];
 | 
			
		||||
        Button[] Days = new Button[3];
 | 
			
		||||
        Button BckMenu = new Button("Back to menu");
 | 
			
		||||
 | 
			
		||||
        BckMenu.setOnAction(event -> Controller.switchRoot(new MenuAccueil()));
 | 
			
		||||
        setHalignment(BckMenu,HPos.CENTER);
 | 
			
		||||
        add(BckMenu,2,4);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < Days.length; i++){
 | 
			
		||||
            Days[i] = new Button("Day"+(i+1));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //it's here that I know which day I can show on the screen
 | 
			
		||||
 | 
			
		||||
        if (choose_day == 1) {
 | 
			
		||||
            StartLevel = 1;
 | 
			
		||||
            add(Days[1],0,0);
 | 
			
		||||
            add(Days[2],2,0);
 | 
			
		||||
            setHalignment(Days[1], HPos.CENTER);
 | 
			
		||||
            setHalignment(Days[2], HPos.CENTER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        else if (choose_day == 2) {
 | 
			
		||||
            StartLevel = 11;
 | 
			
		||||
            add(Days[0], 0, 0);
 | 
			
		||||
            add(Days[2], 2, 0);
 | 
			
		||||
            setHalignment(Days[0], HPos.CENTER);
 | 
			
		||||
            setHalignment(Days[2], HPos.CENTER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        else if (choose_day == 3) {
 | 
			
		||||
            StartLevel = 21;
 | 
			
		||||
            add(Days[0], 0, 0);
 | 
			
		||||
            add(Days[1], 2, 0);
 | 
			
		||||
            setHalignment(Days[0], HPos.CENTER);
 | 
			
		||||
            setHalignment(Days[1], HPos.CENTER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Days[0].setOnAction(event -> Controller.switchRoot(new MenuLevel(1)));
 | 
			
		||||
        Days[1].setOnAction(event -> Controller.switchRoot(new MenuLevel(2)));
 | 
			
		||||
        Days[2].setOnAction(event -> Controller.switchRoot(new MenuLevel(3)));
 | 
			
		||||
 | 
			
		||||
        //It's here that I put all buttons where I need (base on column not row)
 | 
			
		||||
        for (int i = 0; i < 3; i++) {
 | 
			
		||||
            for (int j = 1; j < 5; j++) {
 | 
			
		||||
				Button levelButton = new Button("level "+(StartLevel));
 | 
			
		||||
                levelButton.setOnAction(event -> {
 | 
			
		||||
                    try {
 | 
			
		||||
                        String levelName = ((Button)event.getSource()).getText().replace(" ", "") + ".level";
 | 
			
		||||
                        System.out.println(levelName);
 | 
			
		||||
                        GameUI level = new GameUI(FileParserFactory.loadMapFromFile(new File(Controller.class.getResource("levels/" + levelName).getFile())));
 | 
			
		||||
                        Controller.switchRoot(level);
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        System.out.println("Le niveau " + StartLevel + "n'existe pas.");
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                if(i==0){
 | 
			
		||||
                    StartLevel+=3;
 | 
			
		||||
                    add(levelButton,i,j);
 | 
			
		||||
                    setHalignment(levelButton,HPos.CENTER);
 | 
			
		||||
                    if(j==4){
 | 
			
		||||
                        StartLevel-=11;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(i==1&&j!=4) {
 | 
			
		||||
                    StartLevel += 3;
 | 
			
		||||
                    add(levelButton, i, j);
 | 
			
		||||
                    setHalignment(levelButton,HPos.CENTER);
 | 
			
		||||
                    if (j == 3) {
 | 
			
		||||
                        StartLevel -=8;
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(i==2&&j!=4){
 | 
			
		||||
                    StartLevel+=3;
 | 
			
		||||
                    add(levelButton,i,j);
 | 
			
		||||
                    setHalignment(levelButton,HPos.CENTER);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for(int i=0;i<=2;i++){
 | 
			
		||||
            Columns[i] = new ColumnConstraints();
 | 
			
		||||
            Columns[i].setPercentWidth(33);
 | 
			
		||||
            getColumnConstraints().addAll(Columns[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i= 0;i<=4;i++){
 | 
			
		||||
            Rows[i] = new RowConstraints();
 | 
			
		||||
            Rows[i].setPercentHeight(20);
 | 
			
		||||
            getRowConstraints().addAll(Rows[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        setHgap(20);
 | 
			
		||||
        setVgap(20);
 | 
			
		||||
        setPadding(new Insets(20,10,10,20));
 | 
			
		||||
        getStyleClass().add("GridPane");
 | 
			
		||||
        getStylesheets().add(String.valueOf(getClass().getResource("StyleMenuAcceuil.css")));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,52 +0,0 @@
 | 
			
		||||
package school_project.Menu;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import javafx.geometry.Insets;
 | 
			
		||||
import javafx.geometry.Pos;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.control.Label;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.layout.StackPane;
 | 
			
		||||
import javafx.scene.text.Font;
 | 
			
		||||
import school_project.Controller;
 | 
			
		||||
import school_project.GameUI;
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
 | 
			
		||||
public class ScreenLevelFinish extends StackPane {
 | 
			
		||||
 | 
			
		||||
    public ScreenLevelFinish(Map lastlevel){
 | 
			
		||||
        super();
 | 
			
		||||
        Button retry = new Button("Retry Level");
 | 
			
		||||
        Label CongraMess  = new Label(" LEVEL DONE GREAT JOB ");
 | 
			
		||||
        CongraMess.setFont(Font.font(40));
 | 
			
		||||
        Button BckMenu = new Button("Back to Menu");
 | 
			
		||||
        BckMenu.setFont(Font.font(25));
 | 
			
		||||
        Button ChooseLvl = new Button("Choose level");
 | 
			
		||||
        ChooseLvl.setFont(Font.font(25));
 | 
			
		||||
 | 
			
		||||
        BckMenu.setOnAction(event -> Controller.switchRoot(new MenuAccueil()));
 | 
			
		||||
        ChooseLvl.setOnAction(event -> Controller.switchRoot(new MenuLevel(1)));
 | 
			
		||||
        retry.setOnAction(event -> {
 | 
			
		||||
            try {
 | 
			
		||||
                lastlevel.resetPiecesPositions();
 | 
			
		||||
                Controller.switchRoot(new GameUI(lastlevel));
 | 
			
		||||
            } catch (FileNotFoundException e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        getChildren().addAll(BckMenu,ChooseLvl,CongraMess,retry);
 | 
			
		||||
        setAlignment(retry,Pos.BOTTOM_CENTER);
 | 
			
		||||
        setAlignment(BckMenu, Pos.CENTER_RIGHT);
 | 
			
		||||
        setAlignment(ChooseLvl, Pos.CENTER_LEFT);
 | 
			
		||||
        setAlignment(CongraMess, Pos.TOP_CENTER);
 | 
			
		||||
        setMargin(BckMenu, new Insets(0,300,0,0 ));
 | 
			
		||||
        setMargin(ChooseLvl,new Insets(0,0,0,300));
 | 
			
		||||
        setMargin(CongraMess,new Insets(300,0,0,0));
 | 
			
		||||
        setMargin(retry,new Insets(0,0,300,0));
 | 
			
		||||
 | 
			
		||||
        getStyleClass().add("StackPane");
 | 
			
		||||
        getStylesheets().add(String.valueOf(getClass().getResource("StyleMenuAcceuil.css")));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,221 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import school_project.Piece;
 | 
			
		||||
import school_project.Utils.Bitwise;
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
public class BinaryParser implements FileParser {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map getLevel(File file, boolean saved_data) throws IOException {
 | 
			
		||||
        Map ret;
 | 
			
		||||
 | 
			
		||||
        FileInputStream fileStream = new FileInputStream(file);
 | 
			
		||||
 | 
			
		||||
        byte[] level_data = ExtractLevelData(fileStream);
 | 
			
		||||
 | 
			
		||||
        ret = new Map(ExtractMapFromLevelData(level_data));
 | 
			
		||||
 | 
			
		||||
        ret.addPiece(ExtractPiecesFromLevelData(level_data, saved_data));
 | 
			
		||||
        
 | 
			
		||||
        fileStream.close();
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveLevel(File file, Map level_data, boolean save_data) throws IOException {
 | 
			
		||||
        int byteSize = getByteSizeForMap(level_data, save_data);
 | 
			
		||||
        byte[] data = new byte[byteSize];
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        data[i++] = 'S'; data[i++] = 'M'; data[i++] = 'S';
 | 
			
		||||
        data[i++] = (byte) level_data.getWidth(); data[i++] = (byte) level_data.getHeight();
 | 
			
		||||
        for(byte b : BuildByteFromMatrix(level_data.getShape())){
 | 
			
		||||
            data[i++] = b;
 | 
			
		||||
        }
 | 
			
		||||
        data[i++] = (byte) level_data.getPieces().size();
 | 
			
		||||
        for (Piece p : level_data.getPieces()) {
 | 
			
		||||
            data[i++] = Bitwise.NibbleToByte((byte) p.getWidth(), (byte) p.getHeight());
 | 
			
		||||
            for(byte b : BuildByteFromMatrix(p.getShape())){
 | 
			
		||||
                data[i++] = b;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (save_data){
 | 
			
		||||
            for (Piece p : level_data.getPieces()) {
 | 
			
		||||
                Vec2 _piece_pos = p.getPosition();
 | 
			
		||||
                if(_piece_pos == null){
 | 
			
		||||
                    data[i++] = 'F';
 | 
			
		||||
                    data[i++] = 'L';
 | 
			
		||||
                }else{
 | 
			
		||||
                    data[i++] = (byte) _piece_pos.x;
 | 
			
		||||
                    data[i++] = (byte) _piece_pos.y;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        data[i++] = 'S'; data[i++] = 'M'; data[i++] = 'E';
 | 
			
		||||
        FileOutputStream save_file = new FileOutputStream(file);
 | 
			
		||||
        save_file.write(data);
 | 
			
		||||
        save_file.flush();
 | 
			
		||||
        save_file.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Extract Level data from file content
 | 
			
		||||
     * @param fileStream file stream to read extract data from
 | 
			
		||||
     * @return Level data as an array of byte
 | 
			
		||||
     * @throws IOException Expected if we can't read the file
 | 
			
		||||
     */
 | 
			
		||||
    static byte[] ExtractLevelData(InputStream fileStream) throws IOException {
 | 
			
		||||
 | 
			
		||||
        byte[] bytes = fileStream.readAllBytes();
 | 
			
		||||
 | 
			
		||||
        int start_position = 0, end_position = 0;
 | 
			
		||||
        for (int i = 0; i < bytes.length; i++) {
 | 
			
		||||
            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 83){ // SMS
 | 
			
		||||
                start_position = i+3;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i = start_position; i < bytes.length - 2; i++) {
 | 
			
		||||
            if(bytes[i] == 83 && bytes[i+1] == 77 && bytes[i+2] == 69){ // SME
 | 
			
		||||
                end_position = i;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Arrays.copyOfRange(bytes, start_position, end_position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get Pieces out of the level data
 | 
			
		||||
     *
 | 
			
		||||
     * @param levelData  full data of the level without header and footer
 | 
			
		||||
     * @param saved_data Should extract saved data and included it in the pieces
 | 
			
		||||
     * @return array of Piece from level data
 | 
			
		||||
     */
 | 
			
		||||
    static Piece[] ExtractPiecesFromLevelData(byte[] levelData, boolean saved_data) {
 | 
			
		||||
        byte map_width = levelData[0], map_height = levelData[1];
 | 
			
		||||
        byte piece_count = levelData[2 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0)];
 | 
			
		||||
        Piece[] ret = new Piece[piece_count];
 | 
			
		||||
        byte[] pieces_data = Arrays.copyOfRange(levelData, 3 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0), levelData.length);
 | 
			
		||||
        byte[] pieces_positions = saved_data ? Arrays.copyOfRange(levelData, levelData.length - piece_count*2,levelData.length ): null;
 | 
			
		||||
        int piece_offset = 0;
 | 
			
		||||
        for (int piece_index = 0; piece_index < piece_count; piece_index++) {
 | 
			
		||||
            Vec2 _piece_size = Bitwise.ByteToNible(pieces_data[piece_index + piece_offset]);
 | 
			
		||||
 | 
			
		||||
            byte[] _piece_data = Arrays.copyOfRange(pieces_data, piece_index + piece_offset + 1, piece_index + piece_offset + 1 + _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
            boolean[][] _piece_matrix = BuildMatrixFromBytes(_piece_size.x, _piece_size.y, _piece_data);
 | 
			
		||||
 | 
			
		||||
            ret[piece_index] = new Piece(_piece_matrix);
 | 
			
		||||
 | 
			
		||||
            if(saved_data){
 | 
			
		||||
                Vec2 _piece_pos = (pieces_positions[piece_index*2] == 70 && pieces_positions[piece_index*2+1] == 76) ?
 | 
			
		||||
                        null : new Vec2(pieces_positions[piece_index*2], pieces_positions[piece_index*2 + 1]);
 | 
			
		||||
                ret[piece_index].setPosition(_piece_pos);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            piece_offset += _piece_size.x * _piece_size.y / 8 + (_piece_size.x * _piece_size.y % 8 != 0 ? 1 : 0);
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the Map Matrix out of the level data
 | 
			
		||||
     * @param level_data full data of the level without header and footer
 | 
			
		||||
     * @return boolean matrix of the map
 | 
			
		||||
     */
 | 
			
		||||
    static boolean[][] ExtractMapFromLevelData(byte[] level_data){
 | 
			
		||||
        int map_width = level_data[0], map_height = level_data[1];
 | 
			
		||||
        byte[] map_data = Arrays.copyOfRange(level_data, 2, 2 + map_width * map_height / 8 + (map_height * map_width % 8 != 0 ? 1 : 0));
 | 
			
		||||
        return BuildMatrixFromBytes(map_width, map_height, map_data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * take a boolean matrix and build an array of byte following the specs of the parser
 | 
			
		||||
     * @param shape bolean matrix where true are 1 and false are 0
 | 
			
		||||
     * @return byte array with each element compiled for file format
 | 
			
		||||
     */
 | 
			
		||||
    static byte[] BuildByteFromMatrix(boolean[][] shape){
 | 
			
		||||
        int width = shape[0].length , height = shape.length;
 | 
			
		||||
        boolean[] b_list = new boolean[width * height];
 | 
			
		||||
        for (int x = 0; x < shape.length; x++) {
 | 
			
		||||
            for (int y = 0; y < shape[x].length; y++) {
 | 
			
		||||
                b_list[x * shape[x].length + y] = shape[x][y];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        byte[] ret = new byte[width * height  / 8 + (width * height % 8 == 0 ? 0 : 1)];
 | 
			
		||||
        for (int i = 0; i < ret.length; i++) {
 | 
			
		||||
            byte current_byte = 0;
 | 
			
		||||
            boolean[] current_byte_data = Arrays.copyOfRange(b_list, i * 8, i * 8 + 8);
 | 
			
		||||
            for (boolean curr_data: current_byte_data) {
 | 
			
		||||
                current_byte = (byte) (current_byte << 1);
 | 
			
		||||
                current_byte = (byte) (current_byte | (curr_data ? 1 : 0));
 | 
			
		||||
            }
 | 
			
		||||
            ret[i] = current_byte;
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Build a boolean Matrix From a byte array
 | 
			
		||||
     * Each Byte is composed of 8 bit, each bit is 1 or 0
 | 
			
		||||
     *  if the bit is 0 then it's a false for this cell
 | 
			
		||||
     *  else it's true for this cell
 | 
			
		||||
     * @param matrix_width width of the matrix
 | 
			
		||||
     * @param matrix_height height of the matrix
 | 
			
		||||
     * @param matrix_data byte array of the data to export
 | 
			
		||||
     * @return boolean Matrix of the data decompiled
 | 
			
		||||
     */
 | 
			
		||||
    static boolean[][] BuildMatrixFromBytes(int matrix_width, int matrix_height, byte[] matrix_data){
 | 
			
		||||
        boolean[][] ret = new boolean[matrix_height][matrix_width];
 | 
			
		||||
 | 
			
		||||
        // Transforming the bit from matrix_data's byte into boolean array for better manipulation
 | 
			
		||||
        boolean[] b_array = new boolean[matrix_height * matrix_width];
 | 
			
		||||
        int index = 0;
 | 
			
		||||
        for(byte b: matrix_data){
 | 
			
		||||
            for (int i = 0; i < 8; i++) { // because 8 bit in a byte
 | 
			
		||||
                b_array[index] = Bitwise.IsBitSetAt(b, i);
 | 
			
		||||
                index++;
 | 
			
		||||
                if(index >= matrix_height * matrix_width)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Transforming b_array to a 2D matrix
 | 
			
		||||
        for (int x = 0; x < matrix_height; x++) {
 | 
			
		||||
            for (int y = 0; y < matrix_width; y++) {
 | 
			
		||||
                ret[x][y] = b_array[y + x * matrix_width];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * give the amount of byte needed to store the given Map
 | 
			
		||||
     * following the binary file format
 | 
			
		||||
     * @param level the map to check
 | 
			
		||||
     * @param data should add save data or only level data
 | 
			
		||||
     * @return integer of the ammount of byte needed
 | 
			
		||||
     */
 | 
			
		||||
    public static int getByteSizeForMap(Map level, boolean data){
 | 
			
		||||
        int ret = 6; // header + footer
 | 
			
		||||
        ret += 2; //size of the piece
 | 
			
		||||
        ret += ((level.getWidth() * level.getHeight()) / 8); // size of the map
 | 
			
		||||
        ret += level.getHeight() * level.getWidth() % 8 == 0 ? 0 : 1; // Add 1 if the size of map is not a mult of 8
 | 
			
		||||
        ret += 1; // amount of pieces
 | 
			
		||||
        for(Piece p: level.getPieces()){
 | 
			
		||||
            ret += 1; // size of the piece
 | 
			
		||||
            ret += p.getHeight() * p.getWidth() / 8;
 | 
			
		||||
            ret += p.getHeight() * p.getWidth() % 8 == 0 ? 0 : 1; // add 1 if the size of the piece is not mult of 8
 | 
			
		||||
            if(data){
 | 
			
		||||
                ret += 2; // if the piece is not placed, only one byte else 2
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public interface FileParser {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse the file and create a Map with its shape and pieces setup
 | 
			
		||||
     *
 | 
			
		||||
     * @param file file to parse
 | 
			
		||||
     * @param saved_data does the saved data should be added to the map
 | 
			
		||||
     * @return Map Object parsed with file data
 | 
			
		||||
     * @see <a href="http://school.debucquoy.me/spec/FileParser.html#file-parser-specification"> Parser Specification</a>
 | 
			
		||||
     * @throws FileNotFoundException if the file was not found or was not accessible
 | 
			
		||||
     * @throws IOException if an I/O occurs
 | 
			
		||||
     */
 | 
			
		||||
    Map getLevel(File file, boolean saved_data) throws IOException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Save Map to a file without all it's data
 | 
			
		||||
     * Could be used for generating level file. might not be used in game.
 | 
			
		||||
     * @param file the file where to save
 | 
			
		||||
     * @param levelData the map to save
 | 
			
		||||
     * @param save_data should save the map data (need to be false only in development I think)
 | 
			
		||||
     * @throws FileNotFoundException The file could not be created
 | 
			
		||||
     * @throws IOException if an I/O occurs
 | 
			
		||||
     */
 | 
			
		||||
    void saveLevel(File file, Map levelData, boolean save_data) throws IOException;
 | 
			
		||||
}
 | 
			
		||||
@ -1,132 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import javafx.util.Pair;
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import school_project.Piece;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.NotSerializableException;
 | 
			
		||||
import java.util.Scanner;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is used to find the right parser to parser a save/level file.
 | 
			
		||||
 * This should be the only right way to save/load a file! you can just use `Map loadMapFromFile(File)` to load a file
 | 
			
		||||
 * and `void saveFileFromMap(File, Map)` to save a file
 | 
			
		||||
 *
 | 
			
		||||
 * <p>
 | 
			
		||||
 * there is currently 2 file format with 2 variation each (save file or level file)
 | 
			
		||||
 * - BinaryParser
 | 
			
		||||
 *  - ".level"
 | 
			
		||||
 *  - ".slevel"
 | 
			
		||||
 * - SerializeParser
 | 
			
		||||
 *  - ".serialized"
 | 
			
		||||
 *  - ".sserialized"
 | 
			
		||||
 * </p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>
 | 
			
		||||
 * More file format can be added in the future by adding a new class that implement parser
 | 
			
		||||
 * and adding it to this file
 | 
			
		||||
 * </p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author tonitch
 | 
			
		||||
 */
 | 
			
		||||
public class FileParserFactory {
 | 
			
		||||
    /**
 | 
			
		||||
     * Load a file and return a map
 | 
			
		||||
     * If this is a save map, return the map with its save data
 | 
			
		||||
     * @param file file to get data from
 | 
			
		||||
     * @return Map generated from the file
 | 
			
		||||
     * @throws FileNotFoundException if the file was not found or was not accessible
 | 
			
		||||
     * @throws IOException if an I/O occurs
 | 
			
		||||
     */
 | 
			
		||||
    public static Map loadMapFromFile(File file) throws IOException {
 | 
			
		||||
        Pair<FileParser, Boolean> parser= getFileParser(file);
 | 
			
		||||
        return parser.getKey().getLevel(file, parser.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Save a file in a specific format, this format is defined by the file extension
 | 
			
		||||
     * This file extention could be: ".level", ".slevel", ".serialized", ".sserialized"
 | 
			
		||||
     * for save file use the .s variations
 | 
			
		||||
     * @param file file name to be saved to with the right extension
 | 
			
		||||
     * @param map map file to save
 | 
			
		||||
     * @throws NotSerializableException the file extension is not recognised
 | 
			
		||||
     * @throws FileNotFoundException The file could not be created
 | 
			
		||||
     * @throws IOException if an I/O occurs
 | 
			
		||||
     */
 | 
			
		||||
    public static void saveFileFromMap(File file, Map map) throws IOException {
 | 
			
		||||
        Pair<FileParser, Boolean> parser= getFileParser(file);
 | 
			
		||||
        parser.getKey().saveLevel(file, map, parser.getValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Pair<FileParser, Boolean> getFileParser(File file) throws NotSerializableException {
 | 
			
		||||
        FileParser fileParser;
 | 
			
		||||
        boolean save_data;
 | 
			
		||||
 | 
			
		||||
        if (file.toString().toLowerCase().endsWith(".level")){
 | 
			
		||||
            fileParser = new BinaryParser();
 | 
			
		||||
            save_data = false;
 | 
			
		||||
        }else if(file.toString().toLowerCase().endsWith(".slevel")){
 | 
			
		||||
            fileParser = new BinaryParser();
 | 
			
		||||
            save_data = true;
 | 
			
		||||
        }else if(file.toString().toLowerCase().endsWith(".serialized")){
 | 
			
		||||
            fileParser = new SerializeParser();
 | 
			
		||||
            save_data = false;
 | 
			
		||||
        }else if(file.toString().toLowerCase().endsWith(".sserialized")) {
 | 
			
		||||
            fileParser = new SerializeParser();
 | 
			
		||||
            save_data = true;
 | 
			
		||||
        }else {
 | 
			
		||||
            throw new NotSerializableException("This file format is not supported");
 | 
			
		||||
        }
 | 
			
		||||
        return new Pair<FileParser, Boolean>(fileParser, save_data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) throws IOException {
 | 
			
		||||
        Scanner in = new Scanner(System.in);
 | 
			
		||||
        Map level = new Map();
 | 
			
		||||
 | 
			
		||||
        System.out.print("Entrez le nom du fichier:");
 | 
			
		||||
        File file = new File(in.nextLine());
 | 
			
		||||
 | 
			
		||||
        System.out.print("Entrez la largeur de la map:");
 | 
			
		||||
        int map_width = in.nextInt();
 | 
			
		||||
 | 
			
		||||
        System.out.print("Entrez la hauteur de la map:");
 | 
			
		||||
        int map_height = in.nextInt();
 | 
			
		||||
 | 
			
		||||
        boolean[][] map_shape = new boolean[map_height][map_width];
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < map_height; i++) {
 | 
			
		||||
            for (int j = 0; j < map_width; j++) {
 | 
			
		||||
                System.out.print("mur (" + i + ", " + j + ")? (y/n):");
 | 
			
		||||
                map_shape[i][j] = in.next(".").charAt(0) != 'y';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        level.setShape(map_shape);
 | 
			
		||||
        System.out.println(level);
 | 
			
		||||
        System.out.print("Entrez le nombre de pieces:");
 | 
			
		||||
        int piece_amount = in.nextInt();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < piece_amount; i++) {
 | 
			
		||||
            System.out.print("Entrez la largeur de la piece" + (i+1) +": ");
 | 
			
		||||
            int _piece_width = in.nextInt();
 | 
			
		||||
 | 
			
		||||
            System.out.print("Entrez la hauteur de la piece" + (i+1) +": ");
 | 
			
		||||
            int _piece_height = in.nextInt();
 | 
			
		||||
            boolean[][] _piece_shape = new boolean[_piece_height][_piece_width];
 | 
			
		||||
 | 
			
		||||
            for (int k = 0; k < _piece_height; k++) {
 | 
			
		||||
                for (int j = 0; j < _piece_width; j++) {
 | 
			
		||||
                    System.out.print("mur (" + k + ", " + j + ")? (y/n):");
 | 
			
		||||
                    _piece_shape[k][j] = in.next(".").charAt(0) != 'y';
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            level.addPiece(new Piece(_piece_shape));
 | 
			
		||||
        }
 | 
			
		||||
        saveFileFromMap(file, level);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
 | 
			
		||||
public class SerializeParser implements FileParser{
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map getLevel(File file, boolean saved_data) throws IOException {
 | 
			
		||||
        // saved_data is ignored in this case because the file is serialized data and it already knows if should have saved_data or not at this point
 | 
			
		||||
        FileInputStream fileStream = new FileInputStream(file);
 | 
			
		||||
        ObjectInputStream objectStream = new ObjectInputStream(fileStream);
 | 
			
		||||
        try {
 | 
			
		||||
            return (Map) objectStream.readObject();
 | 
			
		||||
        } catch (ClassNotFoundException e) {
 | 
			
		||||
            throw new IOException("the serialized file format has not found any object in the file");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveLevel(File file, Map levelData, boolean save_data) throws IOException {
 | 
			
		||||
        FileOutputStream fileStream = new FileOutputStream(file);
 | 
			
		||||
        ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
 | 
			
		||||
        objectStream.writeObject(save_data ? levelData : levelData.getCleanedMap());
 | 
			
		||||
 | 
			
		||||
        objectStream.close();
 | 
			
		||||
        fileStream.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +1,5 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.paint.Color;
 | 
			
		||||
import javafx.scene.paint.Paint;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represent a Piece in the game.
 | 
			
		||||
 * Every Piece should be contained in a Map Object.
 | 
			
		||||
@ -16,21 +10,13 @@ public class Piece extends Shape{
 | 
			
		||||
 | 
			
		||||
    private Vec2 Position;
 | 
			
		||||
    private Map linked_map;
 | 
			
		||||
    private transient Paint color; // https://www.baeldung.com/java-transient-keyword
 | 
			
		||||
 | 
			
		||||
    public Piece() {
 | 
			
		||||
        super();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Piece(boolean[][] matrix) {
 | 
			
		||||
        super(matrix);
 | 
			
		||||
        Random rand = new Random();
 | 
			
		||||
        // the %.8 is there to avoid pieces that are too "white" so that we can see them
 | 
			
		||||
        color = new Color(rand.nextDouble()%.8, rand.nextDouble() %.8, rand.nextDouble()%.8, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setColor(Paint p){
 | 
			
		||||
        color = p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Paint getColor(){
 | 
			
		||||
        return color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Vec2 getPosition() {
 | 
			
		||||
@ -38,21 +24,11 @@ public class Piece extends Shape{
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setPosition(Vec2 position){
 | 
			
		||||
        this.Position = position;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<Vec2> getOccupation(){
 | 
			
		||||
        ArrayList<Vec2> ret = new ArrayList<>();
 | 
			
		||||
        if(Position == null)
 | 
			
		||||
            return ret;
 | 
			
		||||
        for (int x = 0; x < height; x++) {
 | 
			
		||||
            for (int y = 0; y < width; y++) {
 | 
			
		||||
               if(getShape()[x][y]){
 | 
			
		||||
                   ret.add(new Vec2(getPosition().x + x, getPosition().y + y));
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
        if (linked_map == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
        this.Position = position;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -78,20 +54,6 @@ public class Piece extends Shape{
 | 
			
		||||
            }
 | 
			
		||||
            times--;
 | 
			
		||||
            matrix = temp_matrix;
 | 
			
		||||
            height = matrix.length;
 | 
			
		||||
            width = matrix[0].length;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object obj) {
 | 
			
		||||
        if(obj instanceof Piece){
 | 
			
		||||
            Piece pieceObj = (Piece) obj;
 | 
			
		||||
            if (pieceObj.getPosition() != null && this.getPosition() != null){
 | 
			
		||||
                return pieceObj.getPosition().equals(this.getPosition()) && pieceObj.getShape().equals(getShape());
 | 
			
		||||
            }
 | 
			
		||||
            return pieceObj.getShape().equals(getShape());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,17 +1,12 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import school_project.Utils.Array;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for everything that is a shape kind, like map and pieces
 | 
			
		||||
 * it contain a matrix of boolean where the shape is defined by the true's
 | 
			
		||||
 */
 | 
			
		||||
public class Shape implements Serializable, Cloneable{
 | 
			
		||||
    
 | 
			
		||||
public class Shape {
 | 
			
		||||
 | 
			
		||||
    protected boolean[][] matrix;
 | 
			
		||||
    protected int height, width;
 | 
			
		||||
 | 
			
		||||
@ -24,52 +19,14 @@ public class Shape implements Serializable, Cloneable{
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setShape(boolean[][] matrix) throws IllegalArgumentException{
 | 
			
		||||
 | 
			
		||||
        for (boolean[] row: matrix){
 | 
			
		||||
            if(row.length != matrix[0].length){
 | 
			
		||||
                throw new IllegalArgumentException("The argument should be a square matrix");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < matrix.length; i++) {
 | 
			
		||||
            if(!Array.isRowOnlyFalse(matrix, i)) {
 | 
			
		||||
                for (int j = 0; j < i; j++) {
 | 
			
		||||
                    matrix = Array.MatrixRemoveRow(matrix, 0);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i = matrix.length-1; i >= 0; i--) {
 | 
			
		||||
            if(!Array.isRowOnlyFalse(matrix, i)) {
 | 
			
		||||
                for (int j = matrix.length-1; j > i; j--) {
 | 
			
		||||
                    matrix = Array.MatrixRemoveRow(matrix, j);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < matrix[0].length; i++) {
 | 
			
		||||
            if(!Array.isColumnOnlyFalse(matrix, i)) {
 | 
			
		||||
                for (int j = 0; j < i; j++) {
 | 
			
		||||
                    matrix = Array.MatrixRemoveColumn(matrix, 0);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int i = matrix[0].length-1; i >= 0; i--){
 | 
			
		||||
            if(!Array.isColumnOnlyFalse(matrix, i)) {
 | 
			
		||||
                for (int j = matrix[0].length-1; j > i; j--) {
 | 
			
		||||
                    matrix = Array.MatrixRemoveColumn(matrix, j);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        height = matrix.length;
 | 
			
		||||
        width = matrix[0].length;
 | 
			
		||||
 | 
			
		||||
        for (boolean[] row: matrix){
 | 
			
		||||
            if(row.length != width){
 | 
			
		||||
                throw new IllegalArgumentException("The argument should be a square matrix");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.matrix = matrix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -84,33 +41,4 @@ public class Shape implements Serializable, Cloneable{
 | 
			
		||||
    public boolean[][] getShape() {
 | 
			
		||||
        return matrix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the list of all the open possition of the map
 | 
			
		||||
     * @return ArrayList of vec2 of all the positions
 | 
			
		||||
     */
 | 
			
		||||
    public ArrayList<Vec2> getPosList(){
 | 
			
		||||
        ArrayList<Vec2> ret = new ArrayList<>();
 | 
			
		||||
        for (int x = 0; x < height; x++) {
 | 
			
		||||
            for (int y = 0; y < width; y++) {
 | 
			
		||||
                if(matrix[x][y]){
 | 
			
		||||
                    ret.add(new Vec2(x, y));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        String ret = "";
 | 
			
		||||
        for (boolean[] row : matrix) {
 | 
			
		||||
            for (boolean el : row) {
 | 
			
		||||
                if(el) ret = ret.concat("⬛");
 | 
			
		||||
                else ret = ret.concat("⬜");
 | 
			
		||||
            }
 | 
			
		||||
            ret = ret.concat("\n");
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,61 +0,0 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
public class Array{
 | 
			
		||||
    public static boolean[][] MatrixCopyOf(boolean[][] o){
 | 
			
		||||
        boolean[][] ret =  new boolean[o.length][];
 | 
			
		||||
        for (int i = 0; i < o.length; i++){
 | 
			
		||||
            ret[i] = Arrays.copyOf(o[i], o[i].length);
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean[][] MatrixRemoveRow(boolean[][] o, int row){
 | 
			
		||||
        boolean[][] newMatrix = new boolean[o.length - 1][o[0].length];
 | 
			
		||||
        int newRow = 0;
 | 
			
		||||
        for (int i = 0; i < o.length; i++) {
 | 
			
		||||
            if(i == row)
 | 
			
		||||
                i++;
 | 
			
		||||
            if(i >= o.length)
 | 
			
		||||
                continue;
 | 
			
		||||
            newMatrix[newRow] = o[i];
 | 
			
		||||
            newRow++;
 | 
			
		||||
        }
 | 
			
		||||
        return newMatrix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean[][] MatrixRemoveColumn(boolean[][] o, int col){
 | 
			
		||||
        boolean[][] newMatrix = new boolean[o.length][o[0].length - 1];
 | 
			
		||||
        for (int i = 0; i < o.length; i++) {
 | 
			
		||||
            int newCol = 0;
 | 
			
		||||
            for(int j = 0; j < o[0].length; j++){
 | 
			
		||||
                if(j == col)
 | 
			
		||||
                    j++;
 | 
			
		||||
                if(j >= o[0].length)
 | 
			
		||||
                    continue;
 | 
			
		||||
                newMatrix[i][newCol] = o[i][j];
 | 
			
		||||
                newCol++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return newMatrix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isRowOnlyFalse(boolean[][] o, int row){
 | 
			
		||||
        boolean mark = true;
 | 
			
		||||
        for (int i = 0; i < o[row].length; i++) {
 | 
			
		||||
            if(o[row][i])
 | 
			
		||||
                mark = false;
 | 
			
		||||
        }
 | 
			
		||||
        return mark;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isColumnOnlyFalse(boolean[][] o, int column){
 | 
			
		||||
        boolean mark = true;
 | 
			
		||||
        for (int i = 0; i < o.length; i++) {
 | 
			
		||||
            if(o[i][column])
 | 
			
		||||
                mark = false;
 | 
			
		||||
        }
 | 
			
		||||
        return mark;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
public class Bitwise {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the bit at pos is 1 or 0
 | 
			
		||||
     * @param b byte to test
 | 
			
		||||
     * @param pos position in b to check
 | 
			
		||||
     * @return true if the bit at pos is 1 or false if it is 0
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean IsBitSetAt(byte b, int pos){
 | 
			
		||||
        pos = 7 - pos;
 | 
			
		||||
        return (b & (1 << pos))!= 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Transform a byte (8 bit) to two Nible (4 bit) with a split in the middle
 | 
			
		||||
     * Exemple:
 | 
			
		||||
     * in = 01000101 (=69)
 | 
			
		||||
     * out = { 00000100, 00000101 } (={4, 5})
 | 
			
		||||
     *
 | 
			
		||||
     * @param in the byte to split
 | 
			
		||||
     * @return an arrya of 2 byte ret[0] = left part; ret[1] = right part
 | 
			
		||||
     */
 | 
			
		||||
    public static Vec2 ByteToNible(byte in){
 | 
			
		||||
        Vec2 ret = new Vec2();
 | 
			
		||||
        ret.x = (byte) (in >> 4);
 | 
			
		||||
        ret.y = (byte) (in & 15); // apply the mask '00001111'
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Transform 2 byte into 1 with a left part ( 4 bits ) and a right part ( 4 bits)
 | 
			
		||||
     * @param left first 4 bits
 | 
			
		||||
     * @param right last 4 bits
 | 
			
		||||
     * @return concatenated byte
 | 
			
		||||
     */
 | 
			
		||||
    public static byte NibbleToByte(byte left, byte right){
 | 
			
		||||
        return (byte) ((left << 4) | right);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.Node;
 | 
			
		||||
import javafx.scene.image.Image;
 | 
			
		||||
import javafx.scene.image.ImageView;
 | 
			
		||||
import javafx.scene.layout.GridPane;
 | 
			
		||||
import javafx.scene.layout.Pane;
 | 
			
		||||
import javafx.scene.paint.Paint;
 | 
			
		||||
import javafx.scene.shape.Rectangle;
 | 
			
		||||
import school_project.*;
 | 
			
		||||
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
 | 
			
		||||
public class MatrixShape extends GridPane {
 | 
			
		||||
    public Shape shape;
 | 
			
		||||
    public Vec2 boundary_size = new Vec2();
 | 
			
		||||
    private Paint color;
 | 
			
		||||
    public MatrixShape(Shape shape) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.shape = shape;
 | 
			
		||||
        if(shape instanceof Piece){
 | 
			
		||||
            Piece p = (Piece) shape;
 | 
			
		||||
            color = p.getColor();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        update();
 | 
			
		||||
 | 
			
		||||
        setHgap(GameUI.SPACE_SIZE);
 | 
			
		||||
        setVgap(GameUI.SPACE_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void update(){
 | 
			
		||||
        getChildren().clear();
 | 
			
		||||
        boolean[][] shape_matrix = shape.getShape();
 | 
			
		||||
        for (int i = 0; i < shape_matrix.length; i++) {
 | 
			
		||||
            for (int j = 0; j < shape_matrix[i].length; j++) {
 | 
			
		||||
                Node _cell;
 | 
			
		||||
                if(shape_matrix[i][j]){
 | 
			
		||||
                    if(shape instanceof Piece){
 | 
			
		||||
                        Piece p = (Piece) shape;
 | 
			
		||||
                        _cell = new Rectangle(GameUI.SEGMENT_SIZE, GameUI.SEGMENT_SIZE);
 | 
			
		||||
                        ((Rectangle) _cell).setFill(color);
 | 
			
		||||
                    }else{
 | 
			
		||||
                        try {
 | 
			
		||||
                          _cell = new ImageView(new Image(new FileInputStream(Controller.class.getResource("tile.png").getFile())));
 | 
			
		||||
                        } catch (FileNotFoundException e) {
 | 
			
		||||
                            throw new RuntimeException(e);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else{
 | 
			
		||||
                    _cell = new Pane();
 | 
			
		||||
                    ((Pane) _cell).setPrefSize(GameUI.SEGMENT_SIZE, GameUI.SEGMENT_SIZE);
 | 
			
		||||
                }
 | 
			
		||||
                add(_cell, j, i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        boundary_size = new Vec2((GameUI.SEGMENT_SIZE + GameUI.SPACE_SIZE) * shape.getWidth(), (GameUI.SEGMENT_SIZE + GameUI.SPACE_SIZE) * shape.getHeight());
 | 
			
		||||
    }
 | 
			
		||||
    public void setColor(Paint p) {
 | 
			
		||||
        color = p;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,12 +1,10 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is used to represent a position/vector/... any ensemble of 2 elements that have to work together in
 | 
			
		||||
 * a plan. This way we can use some basic operations over them.
 | 
			
		||||
 */
 | 
			
		||||
public class Vec2 implements Serializable {
 | 
			
		||||
public class Vec2 {
 | 
			
		||||
    public int x, y;
 | 
			
		||||
 | 
			
		||||
    public Vec2() {
 | 
			
		||||
@ -18,22 +16,4 @@ public class Vec2 implements Serializable {
 | 
			
		||||
        this.x = x;
 | 
			
		||||
        this.y = y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object obj) {
 | 
			
		||||
        if (obj instanceof Vec2) {
 | 
			
		||||
            Vec2 vec = (Vec2) obj;
 | 
			
		||||
            return this.x == vec.x && this.y == vec.y;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Vec2 add(Vec2 o){
 | 
			
		||||
        return new Vec2(x + o.x, y + o.y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "("+x+","+y+")";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 237 KiB  | 
@ -1,11 +0,0 @@
 | 
			
		||||
.BorderPane{
 | 
			
		||||
    -fx-background-image: url("BackGround-menu.jpg");
 | 
			
		||||
    -fx-background-position:center;
 | 
			
		||||
}
 | 
			
		||||
.GridPane{
 | 
			
		||||
    -fx-background-image: url("Background-select-level.jpg");
 | 
			
		||||
    -fx-background-position:right;
 | 
			
		||||
}
 | 
			
		||||
.StackPane{
 | 
			
		||||
    -fx-background-image: url("BackGround-LvlFinish.jpg");
 | 
			
		||||
}
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<03><13>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<04><>"<22>"<22>"p1<70>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>3<><33>"<22>"<22>"p"<22><11>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>"<22>1<EFBFBD><13>2<EFBFBD>"p3<70><33>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS?<3F><><EFBFBD><EFBFBD><13>"<22>3<EFBFBD><33><13>"<22>2<EFBFBD>3<EFBFBD><33>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMSf<><66><EFBFBD><	1<>"<22>"p<11>&<26><>"<22>"<22>"<22><13>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD>"<22>1<EFBFBD><11>"p#<23><12>!<21>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>"<22><13><11>"p3<70><33>3o<33>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<06><><EFBFBD><EFBFBD><EFBFBD>3<><33>3<EFBFBD><33>1<EFBFBD>1<EFBFBD>#<23>#<23>SME
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1 +0,0 @@
 | 
			
		||||
SMS<06><><EFBFBD><EFBFBD><EFBFBD><13>3<EFBFBD><33>3o<33>4<34>"<22>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<01>1<>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD><12>3<EFBFBD><33>"<22>2<EFBFBD>3<EFBFBD><33>SME
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>"p<13><12>"<22>#<23>#<23>#<23>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>2<><13>"<22>#<23>#<23>BSME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMSv<><76><EFBFBD>#<23><11><11>#<23>#<23>BSME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<06><><EFBFBD><EFBFBD><EFBFBD>#<23>#|!<21>#\#<23>2<EFBFBD>2<EFBFBD>BSME
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1 +0,0 @@
 | 
			
		||||
SMS<06><><EFBFBD><EFBFBD><EFBFBD>#<23>#<23>!<21>!<21>#<23>4<34>3o<33>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<07><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<>B#|3?<3F>3<EFBFBD><33>#<23>&<26><>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMSy<><79>y<EFBFBD>B<>!<21>B<EFBFBD>$<24>#<23>#<23>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<03><>#<23><13>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<07><><EFBFBD>}<7D>߀$<24>3ۀ2<DB80><11><11>"<22>2x"p2<70>"<22>2<EFBFBD>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<04><>#<23>#<23><11>1<EFBFBD>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<>p<11><11>1<EFBFBD>#<23>#<23>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<>3<><33><13>1<EFBFBD>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS3<>2<><13>"<22>SME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><><EFBFBD><EFBFBD>2<>"<22>"<22>"p1<70><11>1<EFBFBD>"pSME
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
SMS<05><>߀1<>1<EFBFBD>3<EFBFBD><33>#<23>"<22>SME
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 3.8 KiB  | 
@ -1,26 +0,0 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.*;
 | 
			
		||||
 | 
			
		||||
class MapGeneratorTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void generate() {
 | 
			
		||||
        Map[] maps = new Map[] {
 | 
			
		||||
            MapGenerator.generate(MapGenerator.Difficulty.Easy),
 | 
			
		||||
            MapGenerator.generate(MapGenerator.Difficulty.Medium),
 | 
			
		||||
            MapGenerator.generate(MapGenerator.Difficulty.Difficult),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        for(Map m: maps){
 | 
			
		||||
            System.out.println("==========");
 | 
			
		||||
            System.out.println(m);
 | 
			
		||||
            System.out.println("++++++++++++++++++++");
 | 
			
		||||
            for (Piece p: m.getPieces()){
 | 
			
		||||
                System.out.println(p);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,177 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import school_project.Piece;
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.*;
 | 
			
		||||
 | 
			
		||||
class BinaryParserTest {
 | 
			
		||||
 | 
			
		||||
    static byte[] file_data = {
 | 
			
		||||
            'S', 'M', 'S',
 | 
			
		||||
            6, 5, (byte) 0x31, (byte) 0xEC, (byte) 0xF3, (byte) 0xFC,
 | 
			
		||||
            4,
 | 
			
		||||
            (byte) 0x22, (byte) 0x70,
 | 
			
		||||
            (byte) 0x33, (byte) 0x99, (byte) 0x80,
 | 
			
		||||
            (byte) 0x32, (byte) 0x7C,
 | 
			
		||||
            (byte) 0x33, (byte) 0xDB, (byte) 0x80,
 | 
			
		||||
            'S', 'M', 'E'
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void getByteSizeForMap() {
 | 
			
		||||
        boolean[][] map_shape = {
 | 
			
		||||
                { true, true, true },
 | 
			
		||||
                { true, false, true },
 | 
			
		||||
                { true, true, true },
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece1_shape = {
 | 
			
		||||
                { true, true },
 | 
			
		||||
                { true, false },
 | 
			
		||||
                { true, true },
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece2_shape = {
 | 
			
		||||
                { true },
 | 
			
		||||
                { true },
 | 
			
		||||
                { true },
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
        Map map = new Map(map_shape);
 | 
			
		||||
        Piece piece1 = new Piece(piece1_shape);
 | 
			
		||||
        Piece piece2 = new Piece(piece2_shape);
 | 
			
		||||
 | 
			
		||||
        map.addPiece(new Piece[]{piece1, piece2});
 | 
			
		||||
        piece2.setPosition(new Vec2(0, 2));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        assertEquals(15, BinaryParser.getByteSizeForMap(map, false));
 | 
			
		||||
        assertEquals(19, BinaryParser.getByteSizeForMap(map, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildByteFromMatrix(){
 | 
			
		||||
        byte[] map_data = Arrays.copyOfRange(file_data, 5, 9);
 | 
			
		||||
        boolean[][] map_shape = {
 | 
			
		||||
                {false, false, true, true, false, false},
 | 
			
		||||
                {false, true, true, true, true, false},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, true, true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(map_data, BinaryParser.BuildByteFromMatrix(map_shape));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildMatrixFromByte_map(){
 | 
			
		||||
        byte[] map_data = Arrays.copyOfRange(file_data, 5, 9);
 | 
			
		||||
        boolean[][] map_shape = {
 | 
			
		||||
                {false, false, true, true, false, false},
 | 
			
		||||
                {false, true, true, true, true, false},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, true, true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(map_shape, BinaryParser.BuildMatrixFromBytes(6, 5, map_data));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildMatrixFromByte_piece1(){
 | 
			
		||||
        byte[] piece1_data = Arrays.copyOfRange(file_data, 11, 12);
 | 
			
		||||
        boolean[][] piece1_shape = {
 | 
			
		||||
                {false, true},
 | 
			
		||||
                {true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(piece1_shape, BinaryParser.BuildMatrixFromBytes(2, 2, piece1_data));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildMatrixFromByte_piece2(){
 | 
			
		||||
        byte[] piece2_data = Arrays.copyOfRange(file_data, 13, 15);
 | 
			
		||||
        boolean[][] piece2_shape = {
 | 
			
		||||
                {true, false, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(piece2_shape, BinaryParser.BuildMatrixFromBytes(3, 3, piece2_data));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildMatrixFromByte_piece3(){
 | 
			
		||||
        byte[] piece3_data = Arrays.copyOfRange(file_data, 16, 17);
 | 
			
		||||
        boolean[][] piece3_shape = {
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(piece3_shape, BinaryParser.BuildMatrixFromBytes(3, 2, piece3_data));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void BuildMatrixFromByte_piece4(){
 | 
			
		||||
        byte[] piece4_data = Arrays.copyOfRange(file_data, 18, 20);
 | 
			
		||||
        boolean[][] piece4_shape = {
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertArrayEquals(piece4_shape, BinaryParser.BuildMatrixFromBytes(3, 3, piece4_data));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void ExtractLevelData() throws IOException {
 | 
			
		||||
        boolean[][] expected_map_shape = {
 | 
			
		||||
                {false, false, true, true, false, false},
 | 
			
		||||
                {false, true, true, true, true, false},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, true, true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        byte[] level_data = BinaryParser.ExtractLevelData(new ByteArrayInputStream(file_data));
 | 
			
		||||
        boolean[][] map = BinaryParser.ExtractMapFromLevelData(level_data);
 | 
			
		||||
 | 
			
		||||
        assertArrayEquals(expected_map_shape, map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void ExtractPiecesFronLevelDataTest() throws IOException {
 | 
			
		||||
        boolean[][] piece1_shape = {
 | 
			
		||||
                {false, true},
 | 
			
		||||
                {true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece2_shape = {
 | 
			
		||||
                {true, false, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece3_shape = {
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece4_shape = {
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][][] pieces_shapes = {
 | 
			
		||||
                piece1_shape,
 | 
			
		||||
                piece2_shape,
 | 
			
		||||
                piece3_shape,
 | 
			
		||||
                piece4_shape
 | 
			
		||||
        };
 | 
			
		||||
        byte[] level_data = BinaryParser.ExtractLevelData(new ByteArrayInputStream(file_data));
 | 
			
		||||
        Piece[] pieces = BinaryParser.ExtractPiecesFromLevelData(level_data, false);
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < pieces_shapes.length; i++) {
 | 
			
		||||
            assertArrayEquals(pieces_shapes[i], pieces[i].getShape());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,103 +0,0 @@
 | 
			
		||||
package school_project.Parsers;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.*;
 | 
			
		||||
import org.junit.jupiter.api.io.TempDir;
 | 
			
		||||
import school_project.Map;
 | 
			
		||||
import school_project.Piece;
 | 
			
		||||
import school_project.Vec2;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.*;
 | 
			
		||||
 | 
			
		||||
class FileParserFactoryTest {
 | 
			
		||||
 | 
			
		||||
    static Map generateMapTest(){
 | 
			
		||||
        boolean[][] map_shape = {
 | 
			
		||||
                {false, false, true, true, false, false},
 | 
			
		||||
                {false, true, true, true, true, false},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, false, false, true, true},
 | 
			
		||||
                {true, true, true, true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece1_shape = {
 | 
			
		||||
                {false, true},
 | 
			
		||||
                {true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece2_shape = {
 | 
			
		||||
                {true, false, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece3_shape = {
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] piece4_shape = {
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
        };
 | 
			
		||||
        Piece[] pieces = { new Piece(piece1_shape), new Piece(piece2_shape), new Piece(piece3_shape), new Piece(piece4_shape) };
 | 
			
		||||
        Map map = new Map(map_shape);
 | 
			
		||||
        map.addPiece(pieces);
 | 
			
		||||
 | 
			
		||||
        pieces[0].setPosition(new Vec2(1, 0));
 | 
			
		||||
        pieces[1].setPosition(new Vec2(3, 0));
 | 
			
		||||
        pieces[2].setPosition(new Vec2(3, 3));
 | 
			
		||||
        pieces[3].setPosition(new Vec2(0, 2));
 | 
			
		||||
        return map;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void saveLoadFileFromMap_Binary(@TempDir Path tmpFolder) throws IOException {
 | 
			
		||||
        Map map = generateMapTest();
 | 
			
		||||
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestBinaryLevel.level").toFile(), map);
 | 
			
		||||
 | 
			
		||||
        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestBinaryLevel.level").toFile());
 | 
			
		||||
        assertArrayEquals(map.getCleanedMap().getShape(), testMap.getShape());
 | 
			
		||||
        for (int i = 0; i < map.getPieces().size(); i++) {
 | 
			
		||||
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void saveLoadFileFromMap_save_Binary(@TempDir Path tmpFolder) throws IOException {
 | 
			
		||||
        Map map = generateMapTest();
 | 
			
		||||
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestBinarySave.slevel").toFile(), map);
 | 
			
		||||
 | 
			
		||||
        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestBinarySave.slevel").toFile());
 | 
			
		||||
        assertArrayEquals(map.getShape(), testMap.getShape());
 | 
			
		||||
        for (int i = 0; i < map.getPieces().size(); i++) {
 | 
			
		||||
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
 | 
			
		||||
            assertEquals(map.getPieces().get(i).getPosition(), testMap.getPieces().get(i).getPosition());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    @Test
 | 
			
		||||
    void saveLoadFileFromMap_Serialized(@TempDir Path tmpFolder) throws IOException {
 | 
			
		||||
        Map map = generateMapTest();
 | 
			
		||||
        FileParserFactory.saveFileFromMap( tmpFolder.resolve("TestSerializedLevel.serialized").toFile(), map);
 | 
			
		||||
 | 
			
		||||
        Map testMap = FileParserFactory.loadMapFromFile( tmpFolder.resolve("TestSerializedLevel.serialized").toFile());
 | 
			
		||||
        assertArrayEquals(map.getShape(), testMap.getShape());
 | 
			
		||||
        for (int i = 0; i < map.getPieces().size(); i++) {
 | 
			
		||||
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void saveLoadFileFromMap_save_Serialized(@TempDir Path tmpFolder) throws IOException{
 | 
			
		||||
        Map map = generateMapTest();
 | 
			
		||||
        FileParserFactory.saveFileFromMap(tmpFolder.resolve("TestSerializedSave.sserialized").toFile(), map);
 | 
			
		||||
 | 
			
		||||
        Map testMap = FileParserFactory.loadMapFromFile(tmpFolder.resolve("TestSerializedSave.sserialized").toFile());
 | 
			
		||||
        assertArrayEquals(map.getShape(), testMap.getShape());
 | 
			
		||||
        for (int i = 0; i < map.getPieces().size(); i++) {
 | 
			
		||||
            assertArrayEquals(map.getPieces().get(i).getShape(), testMap.getPieces().get(i).getShape());
 | 
			
		||||
            assertEquals(map.getPieces().get(i).getPosition(), testMap.getPieces().get(i).getPosition());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -17,6 +17,7 @@ class PieceTest {
 | 
			
		||||
        boolean[][] piece1_matrix_result = {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {true, true, false},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] piece2_matrix = {
 | 
			
		||||
@ -30,11 +31,12 @@ class PieceTest {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] piece3_matrix_result = {
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {false, true, true},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Piece piece1 = new Piece(piece2_matrix);
 | 
			
		||||
        Piece piece1 = new Piece();
 | 
			
		||||
        piece1.setShape(piece1_matrix);
 | 
			
		||||
 | 
			
		||||
        Piece piece2 = new Piece(piece2_matrix);
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,6 @@
 | 
			
		||||
package school_project;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import school_project.Utils.Array;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.*;
 | 
			
		||||
 | 
			
		||||
@ -32,30 +29,6 @@ class ShapeTest {
 | 
			
		||||
                {true}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] matrix_shape5 = {
 | 
			
		||||
                {false, false, false, false, false},
 | 
			
		||||
                {false, false, false, false, false},
 | 
			
		||||
                {false, true, true, true, false},
 | 
			
		||||
                {false, true, false, true, false},
 | 
			
		||||
                {false, false, false, false, false},
 | 
			
		||||
                {false, false, false, false, false},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] matrix_shape5_result = {
 | 
			
		||||
                {true, true, true},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] matrix_shape6 = {
 | 
			
		||||
                {true, false},
 | 
			
		||||
                {false, false}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] matrix_shape6_result = {
 | 
			
		||||
                {true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        System.out.println(Array.isRowOnlyFalse(matrix_shape1, 0));
 | 
			
		||||
        Shape shape1 = new Shape();
 | 
			
		||||
        shape1.setShape(matrix_shape1);
 | 
			
		||||
        assertEquals(3, shape1.getHeight());
 | 
			
		||||
@ -71,11 +44,5 @@ class ShapeTest {
 | 
			
		||||
        assertEquals(3, shape4.getHeight());
 | 
			
		||||
        assertEquals(1, shape4.getWidth());
 | 
			
		||||
 | 
			
		||||
        Shape shape5 = new Shape(matrix_shape5);
 | 
			
		||||
        assertArrayEquals(matrix_shape5_result, shape5.getShape());
 | 
			
		||||
 | 
			
		||||
        Shape shape6 = new Shape(matrix_shape6);
 | 
			
		||||
        assertArrayEquals(matrix_shape6_result, shape6.getShape());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,81 +0,0 @@
 | 
			
		||||
package school_project.Utils;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.*;
 | 
			
		||||
 | 
			
		||||
class ArrayTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void matrixCopyOf() {
 | 
			
		||||
        boolean[][] a = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] b = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] c = Array.MatrixCopyOf(a);
 | 
			
		||||
        assertArrayEquals(a, c);
 | 
			
		||||
        a[1][1] = true;
 | 
			
		||||
        assertArrayEquals(b, c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void matrixRemoveRow() {
 | 
			
		||||
        boolean[][] a = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] b = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] result = Array.MatrixRemoveRow(a, 1);
 | 
			
		||||
        assertArrayEquals(b, result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void matrixRemoveColumn() {
 | 
			
		||||
        boolean[][] a = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        boolean[][] b = new boolean[][] {
 | 
			
		||||
                {true, true},
 | 
			
		||||
                {false, false},
 | 
			
		||||
                {true, true},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        boolean[][] result = Array.MatrixRemoveColumn(a, 1);
 | 
			
		||||
        assertArrayEquals(b, result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void isRowOnlyFalse() {
 | 
			
		||||
        boolean[][] a = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertTrue(Array.isRowOnlyFalse(a, 1));
 | 
			
		||||
        assertFalse(Array.isRowOnlyFalse(a, 0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    void isColumnOnlyFalse() {
 | 
			
		||||
        boolean[][] a = new boolean[][] {
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
                {false, false, false},
 | 
			
		||||
                {true, false, true},
 | 
			
		||||
        };
 | 
			
		||||
        assertTrue(Array.isColumnOnlyFalse(a, 1));
 | 
			
		||||
        assertFalse(Array.isColumnOnlyFalse(a, 0));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								prototypes/demo/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								prototypes/demo/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
.gradle
 | 
			
		||||
build/
 | 
			
		||||
!gradle/wrapper/gradle-wrapper.jar
 | 
			
		||||
!**/src/main/**/build/
 | 
			
		||||
!**/src/test/**/build/
 | 
			
		||||
 | 
			
		||||
### IntelliJ IDEA ###
 | 
			
		||||
.idea/modules.xml
 | 
			
		||||
.idea/jarRepositories.xml
 | 
			
		||||
.idea/compiler.xml
 | 
			
		||||
.idea/libraries/
 | 
			
		||||
*.iws
 | 
			
		||||
*.iml
 | 
			
		||||
*.ipr
 | 
			
		||||
out/
 | 
			
		||||
!**/src/main/**/out/
 | 
			
		||||
!**/src/test/**/out/
 | 
			
		||||
 | 
			
		||||
### Eclipse ###
 | 
			
		||||
.apt_generated
 | 
			
		||||
.classpath
 | 
			
		||||
.factorypath
 | 
			
		||||
.project
 | 
			
		||||
.settings
 | 
			
		||||
.springBeans
 | 
			
		||||
.sts4-cache
 | 
			
		||||
bin/
 | 
			
		||||
!**/src/main/**/bin/
 | 
			
		||||
!**/src/test/**/bin/
 | 
			
		||||
 | 
			
		||||
### NetBeans ###
 | 
			
		||||
/nbproject/private/
 | 
			
		||||
/nbbuild/
 | 
			
		||||
/dist/
 | 
			
		||||
/nbdist/
 | 
			
		||||
/.nb-gradle/
 | 
			
		||||
 | 
			
		||||
### VS Code ###
 | 
			
		||||
.vscode/
 | 
			
		||||
 | 
			
		||||
### Mac OS ###
 | 
			
		||||
.DS_Store
 | 
			
		||||
							
								
								
									
										57
									
								
								prototypes/demo/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								prototypes/demo/build.gradle
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
plugins {
 | 
			
		||||
    id 'java'
 | 
			
		||||
    id 'application'
 | 
			
		||||
    id 'org.javamodularity.moduleplugin' version '1.8.12'
 | 
			
		||||
    id 'org.openjfx.javafxplugin' version '0.0.13'
 | 
			
		||||
    id 'org.beryx.jlink' version '2.25.0'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
group 'com.example'
 | 
			
		||||
version '1.0-SNAPSHOT'
 | 
			
		||||
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ext {
 | 
			
		||||
    junitVersion = '5.9.1'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = '17'
 | 
			
		||||
targetCompatibility = '17'
 | 
			
		||||
 | 
			
		||||
tasks.withType(JavaCompile) {
 | 
			
		||||
    options.encoding = 'UTF-8'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
application {
 | 
			
		||||
    mainModule = 'com.example.demo'
 | 
			
		||||
    mainClass = 'com.example.demo.HelloApplication'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
javafx {
 | 
			
		||||
    version = '17.0.2'
 | 
			
		||||
    modules = ['javafx.controls', 'javafx.fxml']
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
 | 
			
		||||
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test {
 | 
			
		||||
    useJUnitPlatform()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jlink {
 | 
			
		||||
    imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip")
 | 
			
		||||
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
 | 
			
		||||
    launcher {
 | 
			
		||||
        name = 'app'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jlinkZip {
 | 
			
		||||
    group = 'distribution'
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								prototypes/demo/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								prototypes/demo/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								prototypes/demo/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								prototypes/demo/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
distributionBase=GRADLE_USER_HOME
 | 
			
		||||
distributionPath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
 | 
			
		||||
zipStoreBase=GRADLE_USER_HOME
 | 
			
		||||
zipStorePath=wrapper/dists
 | 
			
		||||
							
								
								
									
										234
									
								
								prototypes/demo/gradlew
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								prototypes/demo/gradlew
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,234 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Copyright © 2015-2021 the original authors.
 | 
			
		||||
#
 | 
			
		||||
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
# you may not use this file except in compliance with the License.
 | 
			
		||||
# You may obtain a copy of the License at
 | 
			
		||||
#
 | 
			
		||||
#      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
#
 | 
			
		||||
# Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
# See the License for the specific language governing permissions and
 | 
			
		||||
# limitations under the License.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
##############################################################################
 | 
			
		||||
#
 | 
			
		||||
#   Gradle start up script for POSIX generated by Gradle.
 | 
			
		||||
#
 | 
			
		||||
#   Important for running:
 | 
			
		||||
#
 | 
			
		||||
#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
 | 
			
		||||
#       noncompliant, but you have some other compliant shell such as ksh or
 | 
			
		||||
#       bash, then to run this script, type that shell name before the whole
 | 
			
		||||
#       command line, like:
 | 
			
		||||
#
 | 
			
		||||
#           ksh Gradle
 | 
			
		||||
#
 | 
			
		||||
#       Busybox and similar reduced shells will NOT work, because this script
 | 
			
		||||
#       requires all of these POSIX shell features:
 | 
			
		||||
#         * functions;
 | 
			
		||||
#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
 | 
			
		||||
#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
 | 
			
		||||
#         * compound commands having a testable exit status, especially «case»;
 | 
			
		||||
#         * various built-in commands including «command», «set», and «ulimit».
 | 
			
		||||
#
 | 
			
		||||
#   Important for patching:
 | 
			
		||||
#
 | 
			
		||||
#   (2) This script targets any POSIX shell, so it avoids extensions provided
 | 
			
		||||
#       by Bash, Ksh, etc; in particular arrays are avoided.
 | 
			
		||||
#
 | 
			
		||||
#       The "traditional" practice of packing multiple parameters into a
 | 
			
		||||
#       space-separated string is a well documented source of bugs and security
 | 
			
		||||
#       problems, so this is (mostly) avoided, by progressively accumulating
 | 
			
		||||
#       options in "$@", and eventually passing that to Java.
 | 
			
		||||
#
 | 
			
		||||
#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
 | 
			
		||||
#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
 | 
			
		||||
#       see the in-line comments for details.
 | 
			
		||||
#
 | 
			
		||||
#       There are tweaks for specific operating systems such as AIX, CygWin,
 | 
			
		||||
#       Darwin, MinGW, and NonStop.
 | 
			
		||||
#
 | 
			
		||||
#   (3) This script is generated from the Groovy template
 | 
			
		||||
#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 | 
			
		||||
#       within the Gradle project.
 | 
			
		||||
#
 | 
			
		||||
#       You can find Gradle at https://github.com/gradle/gradle/.
 | 
			
		||||
#
 | 
			
		||||
##############################################################################
 | 
			
		||||
 | 
			
		||||
# Attempt to set APP_HOME
 | 
			
		||||
 | 
			
		||||
# Resolve links: $0 may be a link
 | 
			
		||||
app_path=$0
 | 
			
		||||
 | 
			
		||||
# Need this for daisy-chained symlinks.
 | 
			
		||||
while
 | 
			
		||||
    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
 | 
			
		||||
    [ -h "$app_path" ]
 | 
			
		||||
do
 | 
			
		||||
    ls=$( ls -ld "$app_path" )
 | 
			
		||||
    link=${ls#*' -> '}
 | 
			
		||||
    case $link in             #(
 | 
			
		||||
      /*)   app_path=$link ;; #(
 | 
			
		||||
      *)    app_path=$APP_HOME$link ;;
 | 
			
		||||
    esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
 | 
			
		||||
 | 
			
		||||
APP_NAME="Gradle"
 | 
			
		||||
APP_BASE_NAME=${0##*/}
 | 
			
		||||
 | 
			
		||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
			
		||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 | 
			
		||||
 | 
			
		||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
 | 
			
		||||
MAX_FD=maximum
 | 
			
		||||
 | 
			
		||||
warn () {
 | 
			
		||||
    echo "$*"
 | 
			
		||||
} >&2
 | 
			
		||||
 | 
			
		||||
die () {
 | 
			
		||||
    echo
 | 
			
		||||
    echo "$*"
 | 
			
		||||
    echo
 | 
			
		||||
    exit 1
 | 
			
		||||
} >&2
 | 
			
		||||
 | 
			
		||||
# OS specific support (must be 'true' or 'false').
 | 
			
		||||
cygwin=false
 | 
			
		||||
msys=false
 | 
			
		||||
darwin=false
 | 
			
		||||
nonstop=false
 | 
			
		||||
case "$( uname )" in                #(
 | 
			
		||||
  CYGWIN* )         cygwin=true  ;; #(
 | 
			
		||||
  Darwin* )         darwin=true  ;; #(
 | 
			
		||||
  MSYS* | MINGW* )  msys=true    ;; #(
 | 
			
		||||
  NONSTOP* )        nonstop=true ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Determine the Java command to use to start the JVM.
 | 
			
		||||
if [ -n "$JAVA_HOME" ] ; then
 | 
			
		||||
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 | 
			
		||||
        # IBM's JDK on AIX uses strange locations for the executables
 | 
			
		||||
        JAVACMD=$JAVA_HOME/jre/sh/java
 | 
			
		||||
    else
 | 
			
		||||
        JAVACMD=$JAVA_HOME/bin/java
 | 
			
		||||
    fi
 | 
			
		||||
    if [ ! -x "$JAVACMD" ] ; then
 | 
			
		||||
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 | 
			
		||||
 | 
			
		||||
Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
location of your Java installation."
 | 
			
		||||
    fi
 | 
			
		||||
else
 | 
			
		||||
    JAVACMD=java
 | 
			
		||||
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 | 
			
		||||
 | 
			
		||||
Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
location of your Java installation."
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Increase the maximum file descriptors if we can.
 | 
			
		||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
 | 
			
		||||
    case $MAX_FD in #(
 | 
			
		||||
      max*)
 | 
			
		||||
        MAX_FD=$( ulimit -H -n ) ||
 | 
			
		||||
            warn "Could not query maximum file descriptor limit"
 | 
			
		||||
    esac
 | 
			
		||||
    case $MAX_FD in  #(
 | 
			
		||||
      '' | soft) :;; #(
 | 
			
		||||
      *)
 | 
			
		||||
        ulimit -n "$MAX_FD" ||
 | 
			
		||||
            warn "Could not set maximum file descriptor limit to $MAX_FD"
 | 
			
		||||
    esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Collect all arguments for the java command, stacking in reverse order:
 | 
			
		||||
#   * args from the command line
 | 
			
		||||
#   * the main class name
 | 
			
		||||
#   * -classpath
 | 
			
		||||
#   * -D...appname settings
 | 
			
		||||
#   * --module-path (only if needed)
 | 
			
		||||
#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
 | 
			
		||||
 | 
			
		||||
# For Cygwin or MSYS, switch paths to Windows format before running java
 | 
			
		||||
if "$cygwin" || "$msys" ; then
 | 
			
		||||
    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
 | 
			
		||||
    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
 | 
			
		||||
 | 
			
		||||
    JAVACMD=$( cygpath --unix "$JAVACMD" )
 | 
			
		||||
 | 
			
		||||
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
 | 
			
		||||
    for arg do
 | 
			
		||||
        if
 | 
			
		||||
            case $arg in                                #(
 | 
			
		||||
              -*)   false ;;                            # don't mess with options #(
 | 
			
		||||
              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
 | 
			
		||||
                    [ -e "$t" ] ;;                      #(
 | 
			
		||||
              *)    false ;;
 | 
			
		||||
            esac
 | 
			
		||||
        then
 | 
			
		||||
            arg=$( cygpath --path --ignore --mixed "$arg" )
 | 
			
		||||
        fi
 | 
			
		||||
        # Roll the args list around exactly as many times as the number of
 | 
			
		||||
        # args, so each arg winds up back in the position where it started, but
 | 
			
		||||
        # possibly modified.
 | 
			
		||||
        #
 | 
			
		||||
        # NB: a `for` loop captures its iteration list before it begins, so
 | 
			
		||||
        # changing the positional parameters here affects neither the number of
 | 
			
		||||
        # iterations, nor the values presented in `arg`.
 | 
			
		||||
        shift                   # remove old arg
 | 
			
		||||
        set -- "$@" "$arg"      # push replacement arg
 | 
			
		||||
    done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Collect all arguments for the java command;
 | 
			
		||||
#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
 | 
			
		||||
#     shell script including quotes and variable substitutions, so put them in
 | 
			
		||||
#     double quotes to make sure that they get re-expanded; and
 | 
			
		||||
#   * put everything else in single quotes, so that it's not re-expanded.
 | 
			
		||||
 | 
			
		||||
set -- \
 | 
			
		||||
        "-Dorg.gradle.appname=$APP_BASE_NAME" \
 | 
			
		||||
        -classpath "$CLASSPATH" \
 | 
			
		||||
        org.gradle.wrapper.GradleWrapperMain \
 | 
			
		||||
        "$@"
 | 
			
		||||
 | 
			
		||||
# Use "xargs" to parse quoted args.
 | 
			
		||||
#
 | 
			
		||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
 | 
			
		||||
#
 | 
			
		||||
# In Bash we could simply go:
 | 
			
		||||
#
 | 
			
		||||
#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
 | 
			
		||||
#   set -- "${ARGS[@]}" "$@"
 | 
			
		||||
#
 | 
			
		||||
# but POSIX shell has neither arrays nor command substitution, so instead we
 | 
			
		||||
# post-process each arg (as a line of input to sed) to backslash-escape any
 | 
			
		||||
# character that might be a shell metacharacter, then use eval to reverse
 | 
			
		||||
# that process (while maintaining the separation between arguments), and wrap
 | 
			
		||||
# the whole thing up as a single "set" statement.
 | 
			
		||||
#
 | 
			
		||||
# This will of course break if any of these variables contains a newline or
 | 
			
		||||
# an unmatched quote.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
eval "set -- $(
 | 
			
		||||
        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
 | 
			
		||||
        xargs -n1 |
 | 
			
		||||
        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
 | 
			
		||||
        tr '\n' ' '
 | 
			
		||||
    )" '"$@"'
 | 
			
		||||
 | 
			
		||||
exec "$JAVACMD" "$@"
 | 
			
		||||
							
								
								
									
										89
									
								
								prototypes/demo/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								prototypes/demo/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
@rem
 | 
			
		||||
@rem Copyright 2015 the original author or authors.
 | 
			
		||||
@rem
 | 
			
		||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
@rem you may not use this file except in compliance with the License.
 | 
			
		||||
@rem You may obtain a copy of the License at
 | 
			
		||||
@rem
 | 
			
		||||
@rem      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
@rem
 | 
			
		||||
@rem Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
@rem See the License for the specific language governing permissions and
 | 
			
		||||
@rem limitations under the License.
 | 
			
		||||
@rem
 | 
			
		||||
 | 
			
		||||
@if "%DEBUG%" == "" @echo off
 | 
			
		||||
@rem ##########################################################################
 | 
			
		||||
@rem
 | 
			
		||||
@rem  Gradle startup script for Windows
 | 
			
		||||
@rem
 | 
			
		||||
@rem ##########################################################################
 | 
			
		||||
 | 
			
		||||
@rem Set local scope for the variables with windows NT shell
 | 
			
		||||
if "%OS%"=="Windows_NT" setlocal
 | 
			
		||||
 | 
			
		||||
set DIRNAME=%~dp0
 | 
			
		||||
if "%DIRNAME%" == "" set DIRNAME=.
 | 
			
		||||
set APP_BASE_NAME=%~n0
 | 
			
		||||
set APP_HOME=%DIRNAME%
 | 
			
		||||
 | 
			
		||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
 | 
			
		||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
 | 
			
		||||
 | 
			
		||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
			
		||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 | 
			
		||||
 | 
			
		||||
@rem Find java.exe
 | 
			
		||||
if defined JAVA_HOME goto findJavaFromJavaHome
 | 
			
		||||
 | 
			
		||||
set JAVA_EXE=java.exe
 | 
			
		||||
%JAVA_EXE% -version >NUL 2>&1
 | 
			
		||||
if "%ERRORLEVEL%" == "0" goto execute
 | 
			
		||||
 | 
			
		||||
echo.
 | 
			
		||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 | 
			
		||||
echo.
 | 
			
		||||
echo Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
echo location of your Java installation.
 | 
			
		||||
 | 
			
		||||
goto fail
 | 
			
		||||
 | 
			
		||||
:findJavaFromJavaHome
 | 
			
		||||
set JAVA_HOME=%JAVA_HOME:"=%
 | 
			
		||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 | 
			
		||||
 | 
			
		||||
if exist "%JAVA_EXE%" goto execute
 | 
			
		||||
 | 
			
		||||
echo.
 | 
			
		||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
 | 
			
		||||
echo.
 | 
			
		||||
echo Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
echo location of your Java installation.
 | 
			
		||||
 | 
			
		||||
goto fail
 | 
			
		||||
 | 
			
		||||
:execute
 | 
			
		||||
@rem Setup the command line
 | 
			
		||||
 | 
			
		||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@rem Execute Gradle
 | 
			
		||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 | 
			
		||||
 | 
			
		||||
:end
 | 
			
		||||
@rem End local scope for the variables with windows NT shell
 | 
			
		||||
if "%ERRORLEVEL%"=="0" goto mainEnd
 | 
			
		||||
 | 
			
		||||
:fail
 | 
			
		||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
 | 
			
		||||
rem the _cmd.exe /c_ return code!
 | 
			
		||||
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
 | 
			
		||||
exit /b 1
 | 
			
		||||
 | 
			
		||||
:mainEnd
 | 
			
		||||
if "%OS%"=="Windows_NT" endlocal
 | 
			
		||||
 | 
			
		||||
:omega
 | 
			
		||||
							
								
								
									
										1
									
								
								prototypes/demo/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								prototypes/demo/settings.gradle
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
rootProject.name = "demo"
 | 
			
		||||
							
								
								
									
										0
									
								
								prototypes/demo/src/StyleMenu.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								prototypes/demo/src/StyleMenu.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,184 @@
 | 
			
		||||
package com.example.demo;
 | 
			
		||||
 | 
			
		||||
import javafx.application.Application;
 | 
			
		||||
import javafx.geometry.HPos;
 | 
			
		||||
import javafx.geometry.Insets;
 | 
			
		||||
import javafx.geometry.Pos;
 | 
			
		||||
import javafx.scene.Scene;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.control.Label;
 | 
			
		||||
import javafx.scene.control.MenuButton;
 | 
			
		||||
import javafx.scene.layout.BorderPane;
 | 
			
		||||
import javafx.scene.layout.ColumnConstraints;
 | 
			
		||||
import javafx.scene.layout.GridPane;
 | 
			
		||||
import javafx.scene.layout.RowConstraints;
 | 
			
		||||
import javafx.scene.paint.Color;
 | 
			
		||||
import javafx.scene.text.Font;
 | 
			
		||||
import javafx.stage.Stage;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class HelloApplication extends Application {
 | 
			
		||||
    private Stage stage;
 | 
			
		||||
    //set up scene one
 | 
			
		||||
    private Scene Menu;
 | 
			
		||||
    private BorderPane BdP;
 | 
			
		||||
 | 
			
		||||
    private Label title;
 | 
			
		||||
    private Button Play;
 | 
			
		||||
    private Button Select_level;
 | 
			
		||||
    private Button Trophy;
 | 
			
		||||
    //set up scene 2
 | 
			
		||||
    private Scene Level_menu;
 | 
			
		||||
    private GridPane GdP;
 | 
			
		||||
    private Button bck_menu;
 | 
			
		||||
    //button for levele
 | 
			
		||||
    private MenuButton select_day;
 | 
			
		||||
    private Button _1;
 | 
			
		||||
    private Button _2;
 | 
			
		||||
    private Button _3;
 | 
			
		||||
    private Button _4;
 | 
			
		||||
    private Button _5;
 | 
			
		||||
    private Button _6;
 | 
			
		||||
    private Button _7;
 | 
			
		||||
    private Button _8;
 | 
			
		||||
    private Button _9;
 | 
			
		||||
    private Button _10;
 | 
			
		||||
 | 
			
		||||
    public void start(Stage primaryStage) {
 | 
			
		||||
        //set up the page
 | 
			
		||||
        stage = primaryStage;
 | 
			
		||||
        stage.setTitle("ROAD TO MASTER YOU");
 | 
			
		||||
        Menu = createMenu();
 | 
			
		||||
        Level_menu = createLevel_menu();
 | 
			
		||||
 | 
			
		||||
        stage.setScene(Menu);
 | 
			
		||||
        stage.show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    private Scene createMenu(){
 | 
			
		||||
        Play = new Button("Play");
 | 
			
		||||
        Trophy = new Button("Trophy");
 | 
			
		||||
        Select_level = new Button("Select Level");
 | 
			
		||||
        Select_level.setOnAction(event -> switchScenes(Level_menu));
 | 
			
		||||
        title = new Label("Welcome to road to master you");
 | 
			
		||||
        title.setFont(Font.font(20));
 | 
			
		||||
        title.setTextFill(Color.GOLD);
 | 
			
		||||
        BdP = new BorderPane(null,title,Select_level,Trophy,Play);
 | 
			
		||||
        Menu = new Scene(BdP,700,400);
 | 
			
		||||
        BorderPane.setAlignment(title,Pos.CENTER);
 | 
			
		||||
        BorderPane.setAlignment(Play,Pos.CENTER);
 | 
			
		||||
        BorderPane.setAlignment(Select_level,Pos.CENTER);
 | 
			
		||||
        BorderPane.setAlignment(Trophy,Pos.CENTER);
 | 
			
		||||
        Menu.getStylesheets().add("style.css");
 | 
			
		||||
        BdP.setPadding(new Insets(20,60,20,60));
 | 
			
		||||
 | 
			
		||||
        return Menu;
 | 
			
		||||
    }
 | 
			
		||||
    private Scene createLevel_menu(){
 | 
			
		||||
        bck_menu = new Button("Back to the menu");
 | 
			
		||||
        bck_menu.setOnAction(event -> switchScenes(Menu));
 | 
			
		||||
        GdP = new GridPane();
 | 
			
		||||
        Level_menu = new Scene(GdP,700,400);
 | 
			
		||||
        _1 = new Button("1");
 | 
			
		||||
        _2 = new Button("2");
 | 
			
		||||
        _3 = new Button("3");
 | 
			
		||||
        _4 = new Button("4");
 | 
			
		||||
        _5 = new Button("5");
 | 
			
		||||
        _6 = new Button("6");
 | 
			
		||||
        _7 = new Button("7");
 | 
			
		||||
        _8 = new Button("8");
 | 
			
		||||
        _9 = new Button("9");
 | 
			
		||||
        _10 = new Button("10");
 | 
			
		||||
        select_day = new MenuButton("Select day");
 | 
			
		||||
 | 
			
		||||
        //set up of the button
 | 
			
		||||
        GdP.add(select_day,1,0);
 | 
			
		||||
        GdP.add(_1,0,1);
 | 
			
		||||
        GdP.add(_2,1,1);
 | 
			
		||||
        GdP.add(_3,2,1);
 | 
			
		||||
        GdP.add(_4,0,2);
 | 
			
		||||
        GdP.add(_5,1,2);
 | 
			
		||||
        GdP.add(_6,2,2);
 | 
			
		||||
        GdP.add(_7,0,3);
 | 
			
		||||
        GdP.add(_8,1,3);
 | 
			
		||||
        GdP.add(_9,2,3);
 | 
			
		||||
        GdP.add(_10,1,4);
 | 
			
		||||
        GdP.add(bck_menu,2,4);
 | 
			
		||||
        //set up gap and padding and everything else
 | 
			
		||||
        GdP.setHgap(20);
 | 
			
		||||
        GdP.setVgap(20);
 | 
			
		||||
        GdP.setPadding(new Insets(40,20,20,40));
 | 
			
		||||
        ColumnConstraints col_1 = new ColumnConstraints();
 | 
			
		||||
        col_1.setPercentWidth(33);
 | 
			
		||||
        ColumnConstraints col_2 = new ColumnConstraints();
 | 
			
		||||
        col_2.setPercentWidth(33);
 | 
			
		||||
        ColumnConstraints col_3 = new ColumnConstraints();
 | 
			
		||||
        col_3.setPercentWidth(34);
 | 
			
		||||
        GdP.getColumnConstraints().addAll(col_1,col_2,col_3);
 | 
			
		||||
        //GdP.setGridLinesVisible(true);
 | 
			
		||||
        GridPane.setHalignment(_1, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_2, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_3, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_4, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_5, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_6, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_7, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_8, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_9, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(_10, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(select_day, HPos.CENTER);
 | 
			
		||||
        GridPane.setHalignment(bck_menu, HPos.CENTER);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return Level_menu;
 | 
			
		||||
    }
 | 
			
		||||
    public void switchScenes(Scene scene){
 | 
			
		||||
        stage.setScene(scene);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        launch(args);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***@Override
 | 
			
		||||
public void start(Stage primaryStage) {
 | 
			
		||||
    //set up the page
 | 
			
		||||
    primaryStage.setTitle("Road to Master You");
 | 
			
		||||
    BorderPane root = new BorderPane();
 | 
			
		||||
    Scene scene = new Scene(root,400,300);
 | 
			
		||||
    primaryStage.setScene(scene);
 | 
			
		||||
    primaryStage.show();
 | 
			
		||||
 | 
			
		||||
    //set up all the object needed for the menu
 | 
			
		||||
    Label title = new Label("Welcome to Road to Master You");
 | 
			
		||||
    Button Play = new Button("Play");
 | 
			
		||||
    Button Select_level = new Button("Select Level");
 | 
			
		||||
    Button Trophy = new Button("Trophy");
 | 
			
		||||
 | 
			
		||||
    //put all the object on the page
 | 
			
		||||
    root.setTop(title);
 | 
			
		||||
    root.setBottom(Trophy);
 | 
			
		||||
    root.setRight(Select_level);
 | 
			
		||||
    root.setLeft(Play);
 | 
			
		||||
 | 
			
		||||
    //adjust everything as I want (position,color)
 | 
			
		||||
    title.setTextFill(Color.GOLD);
 | 
			
		||||
    BorderPane.setAlignment(title,Pos.CENTER);
 | 
			
		||||
    BorderPane.setAlignment(Play,Pos.CENTER);
 | 
			
		||||
    BorderPane.setAlignment(Select_level,Pos.CENTER);
 | 
			
		||||
    BorderPane.setAlignment(Trophy,Pos.CENTER);
 | 
			
		||||
    scene.getStylesheets().add("style.css"); //todo found why there is no link btw file
 | 
			
		||||
 | 
			
		||||
    //Switch scene
 | 
			
		||||
    Select_level.setOnAction(event -> {
 | 
			
		||||
        SelectLevel secondWindow = new SelectLevel();
 | 
			
		||||
        secondWindow.show();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
package com.example.demo;
 | 
			
		||||
 | 
			
		||||
import javafx.fxml.FXML;
 | 
			
		||||
import javafx.scene.control.Label;
 | 
			
		||||
 | 
			
		||||
public class HelloController {
 | 
			
		||||
    @FXML
 | 
			
		||||
    private Label welcomeText;
 | 
			
		||||
 | 
			
		||||
    @FXML
 | 
			
		||||
    protected void onHelloButtonClick() {
 | 
			
		||||
        welcomeText.setText("Welcome to JavaFX Application!");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,65 @@
 | 
			
		||||
/***package com.example.demo;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.Group;
 | 
			
		||||
import javafx.scene.Scene;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.control.Label;
 | 
			
		||||
import javafx.scene.layout.BorderPane;
 | 
			
		||||
import javafx.scene.layout.GridPane;
 | 
			
		||||
import javafx.stage.Stage;
 | 
			
		||||
 | 
			
		||||
import static javafx.application.Application.launch;
 | 
			
		||||
 | 
			
		||||
public class SelectLevel extends Stage {
 | 
			
		||||
    private Stage stage;
 | 
			
		||||
    //set up scene one
 | 
			
		||||
    private Scene Menu;
 | 
			
		||||
    private BorderPane BdP;
 | 
			
		||||
 | 
			
		||||
    private Label title;
 | 
			
		||||
    private Button Play;
 | 
			
		||||
    private Button Select_level;
 | 
			
		||||
    private Button Trophy;
 | 
			
		||||
    //set up scene 2
 | 
			
		||||
    private Scene Level_menu;
 | 
			
		||||
    private GridPane GdP;
 | 
			
		||||
    private Button bck_menu;
 | 
			
		||||
 | 
			
		||||
    public void start(Stage primaryStage) {
 | 
			
		||||
        //set up the page
 | 
			
		||||
        primaryStage.setTitle("Select your Level");
 | 
			
		||||
        Menu = createMenu();
 | 
			
		||||
        Level_menu = createLevel_menu();
 | 
			
		||||
 | 
			
		||||
        primaryStage.setScene(Menu);
 | 
			
		||||
        primaryStage.show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    private Scene createMenu(){
 | 
			
		||||
        Play = new Button("Play");
 | 
			
		||||
        Trophy = new Button("Trophy");
 | 
			
		||||
        Select_level = new Button("Select Level");
 | 
			
		||||
        Select_level.setOnAction(event -> switchScenes(Level_menu));
 | 
			
		||||
        title = new Label("Welcome to road to master you");
 | 
			
		||||
        BdP = new BorderPane(null,title,Select_level,Trophy,Play);
 | 
			
		||||
        Menu = new Scene(BdP,700,400);
 | 
			
		||||
 | 
			
		||||
        return Menu;
 | 
			
		||||
    }
 | 
			
		||||
    private Scene createLevel_menu(){
 | 
			
		||||
        bck_menu = new Button("Back to the menu");
 | 
			
		||||
        bck_menu.setOnAction(event -> switchScenes(Menu));
 | 
			
		||||
        GdP = new GridPane();
 | 
			
		||||
        Level_menu = new Scene(GdP,700,400);
 | 
			
		||||
 | 
			
		||||
        return Level_menu;
 | 
			
		||||
    }
 | 
			
		||||
    public void switchScenes(Scene scene){
 | 
			
		||||
        stage.setScene(scene);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        launch(args);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
***/
 | 
			
		||||
							
								
								
									
										8
									
								
								prototypes/demo/src/main/java/module-info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								prototypes/demo/src/main/java/module-info.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
module com.example.demo {
 | 
			
		||||
    requires javafx.controls;
 | 
			
		||||
    requires javafx.fxml;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    opens com.example.demo to javafx.fxml;
 | 
			
		||||
    exports com.example.demo;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,16 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<?import javafx.geometry.Insets?>
 | 
			
		||||
<?import javafx.scene.control.Label?>
 | 
			
		||||
<?import javafx.scene.layout.VBox?>
 | 
			
		||||
 | 
			
		||||
<?import javafx.scene.control.Button?>
 | 
			
		||||
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
 | 
			
		||||
      fx:controller="com.example.demo.HelloController">
 | 
			
		||||
    <padding>
 | 
			
		||||
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
 | 
			
		||||
    </padding>
 | 
			
		||||
 | 
			
		||||
    <Label fx:id="welcomeText"/>
 | 
			
		||||
    <Button text="Hello!" onAction="#onHelloButtonClick"/>
 | 
			
		||||
</VBox>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 423 KiB After Width: | Height: | Size: 423 KiB  | 
@ -0,0 +1,48 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<?import javafx.scene.control.Button?>
 | 
			
		||||
<?import javafx.scene.control.Label?>
 | 
			
		||||
<?import javafx.scene.control.MenuButton?>
 | 
			
		||||
<?import javafx.scene.control.MenuItem?>
 | 
			
		||||
<?import javafx.scene.layout.ColumnConstraints?>
 | 
			
		||||
<?import javafx.scene.layout.GridPane?>
 | 
			
		||||
<?import javafx.scene.layout.RowConstraints?>
 | 
			
		||||
 | 
			
		||||
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/19">
 | 
			
		||||
  <columnConstraints>
 | 
			
		||||
    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
 | 
			
		||||
    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
 | 
			
		||||
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
 | 
			
		||||
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
 | 
			
		||||
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
 | 
			
		||||
  </columnConstraints>
 | 
			
		||||
  <rowConstraints>
 | 
			
		||||
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
 | 
			
		||||
  </rowConstraints>
 | 
			
		||||
   <children>
 | 
			
		||||
      <Label prefHeight="108.0" prefWidth="200.0" style="-fx-alignment: center;" text="Select Level" GridPane.columnIndex="2" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="1" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="2" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="3" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="2" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="5" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="6" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="7" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="8" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="4" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="3" />
 | 
			
		||||
      <Button mnemonicParsing="false" stylesheets="@SelectLevel.css" text="9" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="4" />
 | 
			
		||||
      <Button mnemonicParsing="false" text="10" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
 | 
			
		||||
      <MenuButton mnemonicParsing="false" text="Select day " GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1">
 | 
			
		||||
        <items>
 | 
			
		||||
          <MenuItem mnemonicParsing="false" text="Action 1" />
 | 
			
		||||
          <MenuItem mnemonicParsing="false" text="Action 2" />
 | 
			
		||||
        </items>
 | 
			
		||||
      </MenuButton>
 | 
			
		||||
      <Button mnemonicParsing="false" text="Back to menu" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="6" />
 | 
			
		||||
   </children>
 | 
			
		||||
</GridPane>
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
.root {
 | 
			
		||||
    -fx-background-image: url("Background-select-level.jpg");
 | 
			
		||||
    -fx-background-position: center
 | 
			
		||||
}
 | 
			
		||||
.button{
 | 
			
		||||
    -fx-alignment: center;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,35 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<?import javafx.geometry.Insets?>
 | 
			
		||||
<?import javafx.scene.control.Button?>
 | 
			
		||||
<?import javafx.scene.control.Label?>
 | 
			
		||||
<?import javafx.scene.layout.BorderPane?>
 | 
			
		||||
<?import javafx.scene.text.Font?>
 | 
			
		||||
 | 
			
		||||
<BorderPane centerShape="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1">
 | 
			
		||||
   <top>
 | 
			
		||||
      <Label prefHeight="116.0" prefWidth="600.0" style="-fx-alignment: center; -fx-padding: 10;" text="Road to MasterU" textAlignment="CENTER" textFill="GOLD" underline="true" wrapText="true" BorderPane.alignment="CENTER">
 | 
			
		||||
         <font>
 | 
			
		||||
            <Font size="26.0" />
 | 
			
		||||
         </font>
 | 
			
		||||
      </Label>
 | 
			
		||||
   </top>
 | 
			
		||||
   <bottom>
 | 
			
		||||
      <Button mnemonicParsing="false" style="-fx-alignment: center;" text="Trophy" textAlignment="CENTER" BorderPane.alignment="CENTER">
 | 
			
		||||
         <BorderPane.margin>
 | 
			
		||||
            <Insets bottom="100.0" />
 | 
			
		||||
         </BorderPane.margin></Button>
 | 
			
		||||
   </bottom>
 | 
			
		||||
   <right>
 | 
			
		||||
      <Button mnemonicParsing="false" prefHeight="0.0" prefWidth="153.0" style="-fx-alignment: center;" text="Select Level" BorderPane.alignment="CENTER">
 | 
			
		||||
         <BorderPane.margin>
 | 
			
		||||
            <Insets right="100.0" />
 | 
			
		||||
         </BorderPane.margin></Button>
 | 
			
		||||
   </right>
 | 
			
		||||
   <left>
 | 
			
		||||
      <Button mnemonicParsing="false" prefHeight="10.0" prefWidth="90.0" style="-fx-alignment: center;" text="Play" textAlignment="CENTER" BorderPane.alignment="CENTER">
 | 
			
		||||
         <BorderPane.margin>
 | 
			
		||||
            <Insets left="110.0" />
 | 
			
		||||
         </BorderPane.margin></Button>
 | 
			
		||||
   </left>
 | 
			
		||||
</BorderPane>
 | 
			
		||||
@ -0,0 +1,12 @@
 | 
			
		||||
.root{
 | 
			
		||||
    -fx-background-image:url("BackGround-menu.jpg");
 | 
			
		||||
    -fx-background-position:center;
 | 
			
		||||
}
 | 
			
		||||
.label{
 | 
			
		||||
    -fx-font-size: 75;
 | 
			
		||||
}
 | 
			
		||||
.button {
 | 
			
		||||
    -fx-start-margin: 20;
 | 
			
		||||
    -fx-text-alignment: center;
 | 
			
		||||
    -fx-padding: 10;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user