1 Commits

Author SHA1 Message Date
Mat
114acc8126 first try for the menu in javafx
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-06 15:23:34 +02:00
43 changed files with 745 additions and 1676 deletions

View File

@ -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
...

View File

@ -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)

View File

@ -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.

View File

@ -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'

View File

@ -1,51 +1,32 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package school_project;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyCombination;
import javafx.stage.Screen;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import school_project.Menu.MenuAccueil;
import java.io.IOException;
public class Controller extends Application {
private static Stage stage;
Parent root;
public static Vec2 screen_size;
@Override
public void start(Stage primaryStage) throws IOException {
stage = primaryStage;
screen_size = new Vec2(
(int) Screen.getPrimary().getBounds().getWidth(),
(int) Screen.getPrimary().getBounds().getHeight()
);
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("test");
Button btn = new Button("test");
btn.setOnAction(event -> System.out.println("hey"));
stage.setTitle("ROAD TO MASTER YOU");
Group root = new Group();
root.getChildren().add(btn);
// Full Screen mode
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
Scene scene = new Scene(root, 300,300);
primaryStage.setScene(scene);
root = new MenuAccueil();
switchRoot(root);
stage.show();
primaryStage.show();
}
public static void switchRoot(Parent root){
Scene scene = new Scene(root);
stage.setScene(scene);
}
public static void main(String[] args) {
launch();
launch();
}
}

View File

@ -1,83 +0,0 @@
package school_project;
import javafx.scene.Group;
import javafx.scene.input.MouseButton;
import school_project.Menu.MenuAccueil;
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();
public GameUI(Map level) throws FileNotFoundException {
super();
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);
_piece.setLayoutX(piece_space.x);
_piece.setLayoutY(piece_space.y);
piece_space.y += _piece.boundary_size.y;
if(piece_space.y >= Controller.screen_size.y){
column++;
piece_space.y = SPACE_SIZE;
piece_space.x = (SEGMENT_SIZE*3 + SPACE_SIZE*4 )* column;
}
// 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;
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)
);
System.out.println(level.placePiece(p, piece_position_in_grid) + piece_position_in_grid.toString());
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 MenuAccueil());
}
}
});
getChildren().add(_piece);
}
}
}

View File

@ -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,22 +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);
}
}
}

View File

@ -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;
}
}

View File

@ -1,42 +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.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import school_project.Controller;
public class MenuAccueil extends BorderPane {
public MenuAccueil(){
super();
//create all the objet that i need
Button Play = new Button("Play");
Button SelectLevel= new Button("Select Level");
Button Trophy = new Button("Trophy");
Label Title = new Label("Welcome to Road to Master");
//set up all the Button where i need
setTop(Title);
setLeft(Play);
setRight(SelectLevel);
setBottom(Trophy);
Title.setFont(Font.font(20));
Title.setTextFill(Color.GOLD);
setAlignment(Title, Pos.CENTER);
setAlignment(Play,Pos.CENTER);
setAlignment(SelectLevel,Pos.CENTER);
setAlignment(Trophy,Pos.CENTER);
setPadding(new Insets(20,60,20,60));
SelectLevel.setOnAction(event -> Controller.switchRoot(new MenuLevel(1)));
getStyleClass().add("BorderPane");
getStylesheets().add(String.valueOf(getClass().getResource("StyleMenuAcceuil.css")));
}
}

View File

@ -1,110 +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;
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++) {
if(i==0){
Button Level = new Button("level "+(StartLevel));
StartLevel+=3;
add(Level,i,j);
setHalignment(Level,HPos.CENTER);
if(j==4){
StartLevel-=11;
}
}
else if(i==1&&j!=4) {
Button Level = new Button("level "+(StartLevel));
StartLevel += 3;
add(Level, i, j);
setHalignment(Level,HPos.CENTER);
if (j == 3) {
StartLevel -=8;
}
}
else if(i==2&&j!=4){
Button Level = new Button("level "+(StartLevel));
StartLevel+=3;
add(Level,i,j);
setHalignment(Level,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")));
}
}

View File

@ -1,220 +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 = 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;
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -1,14 +1,5 @@
package school_project;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import java.util.ArrayList;
import java.util.Random;
import static javafx.scene.paint.Color.WHITE;
import static javafx.scene.paint.Color.color;
/**
* Represent a Piece in the game.
* Every Piece should be contained in a Map Object.
@ -19,20 +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();
color = new Color((rand.nextDouble()%190), (rand.nextDouble()%190), (rand.nextDouble()%190), 1);
}
public void setColor(Paint p){
color = p;
}
public Paint getColor(){
return color;
}
public Vec2 getPosition() {
@ -40,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;
}
/**
@ -80,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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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: 423 KiB

View File

@ -1,8 +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;
}

View File

@ -1 +0,0 @@
SMS<05><><EFBFBD><EFBFBD>3<><33>"<22>"<22>"p"<22><11>SME

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -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);
}
}
}
}

View File

@ -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());
}
}
}

View File

@ -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());
}
}
}

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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));
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

View File

@ -0,0 +1,316 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
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
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

View File

@ -0,0 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. 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,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>menu_road_to_masterU</artifactId>
<version>1.0-SNAPSHOT</version>
<name>menu_road_to_masterU</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.9.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>
com.example.menu_road_to_masteru/com.example.menu_road_to_masteru.HelloApplication
</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
package com.example.menu_road_to_masteru;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load());
stage.setTitle("Welcome to Road to masterU");
scene.getStylesheets().add("menu.css");
stage.setHeight(700);
stage.setWidth((1000));
stage.setResizable(false);
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}

View File

@ -0,0 +1,14 @@
package com.example.menu_road_to_masteru;
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!");
}
}

View File

@ -0,0 +1,8 @@
module com.example.menu_road_to_masteru {
requires javafx.controls;
requires javafx.fxml;
opens com.example.menu_road_to_masteru to javafx.fxml;
exports com.example.menu_road_to_masteru;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane 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">
<children>
<Button fx:id="PlaySelect" layoutX="251.0" layoutY="200.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="94.0" text="Play" />
<Button fx:id="LevelSelect" layoutX="224.0" layoutY="263.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="147.0" text="Select level" />
<Label fx:id="titlegame" layoutY="88.0" prefHeight="30.0" prefWidth="600.0" text="Road to MasterU">
<font>
<Font size="20.0" />
</font>
</Label>
<Button fx:id="TrophyOption" layoutX="492.0" layoutY="361.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="94.0" text="Trophy" />
</children>
</AnchorPane>

View File

@ -0,0 +1,13 @@
.root{
-fx-background-image:url("BackGround-menu.jpg");
-fx-background-position:center;
}
.label{
-fx-font-size: 75;
-fx-text-fill: gold;
-fx-alignment: center;
-fx-underline: on;
}
.button{
-fx-start-margin: 20;
}