Hallo java-forum,
ich würde gerne meinen Quellcode in verschieden Klassen refaktorieren, sprich aufräumen. Komme jedoch nicht wirklich weiter. Der Code soll aus drei Teilen bestehen.
1.Sokoban
In diesem Part möchte ich die main-Methode einbringen. Dieser soll auf 2.Player und 3.Level zugreifen können.
2.Player
Hier möchte ich mit einer move-Methode alle auf den Spieler bezogenen Informationen unterbringen.
3.Level
Hier soll das Level (.txt Datei) geladen werden.
Mein Ansatz:
Ich habe den Quellcode mit den jeweils relevanten Bereichen in eigene Klassen geteilt, ohne was am Quellcode zu verändern. Habe es aber nicht geschafft, dass die main-Methode auf die anderen Klassen zugreifen kann.
Würde mich über jeden Ansatz freuen.
MfG
Quellcode
ich würde gerne meinen Quellcode in verschieden Klassen refaktorieren, sprich aufräumen. Komme jedoch nicht wirklich weiter. Der Code soll aus drei Teilen bestehen.
1.Sokoban
In diesem Part möchte ich die main-Methode einbringen. Dieser soll auf 2.Player und 3.Level zugreifen können.
2.Player
Hier möchte ich mit einer move-Methode alle auf den Spieler bezogenen Informationen unterbringen.
3.Level
Hier soll das Level (.txt Datei) geladen werden.
Mein Ansatz:
Ich habe den Quellcode mit den jeweils relevanten Bereichen in eigene Klassen geteilt, ohne was am Quellcode zu verändern. Habe es aber nicht geschafft, dass die main-Methode auf die anderen Klassen zugreifen kann.
Würde mich über jeden Ansatz freuen.
MfG
Quellcode
Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
/**
* This class is the second part for the Sokoban game
*
* @author Jane Doe 1234567 Group 42h
* @author John Doe 1234567 Group 42h
*/
class Sokoban {
private final static int X = 0;
private final static int Y = 1;
private final static char WALL = '#';
private final static char PLAYER = '@';
private final static char BOX = '$';
private final static char GOAL = '.';
private final static char PLAYER_ON_GOAL = '+';
private final static char BOX_ON_GOAL = '*';
private final static char FREE = ' ';
private final static int[] UP = {0, -1};
private final static int[] DOWN = {0, 1};
private final static int[] LEFT = {-1, 0};
private final static int[] RIGHT = {1, 0};
private static char[][] room;
private static int freeBox;
private static int emptyGoal;
private static int[] size = {-1, 0};
private static int[] player;
/**
* Loads the level from the "file" and validate it
*
* @param file path to the file
* @return false iff an error occurs or the level is invalid, true otherwise
*/
private static boolean loadLevel(String file) {
BufferedReader bufferedReader;
try {
bufferedReader = Files.newBufferedReader(Paths.get(file));
bufferedReader.mark(100 * 100);
String line;
while ((line = bufferedReader.readLine()) != null) {
size[Y]++;
if (size[X] > -1 && size[X] != line.length()) {
return false;
} else {
size[X] = line.length();
}
}
bufferedReader.reset();
room = new char[size[Y]][];
int i = 0;
while ((line = bufferedReader.readLine()) != null) {
room[i] = new char[line.length()];
for (int j = 0; j < line.length(); j++) {
room[i][j] = line.charAt(j);
}
i++;
// oder room[i++] = line.toCharArray();
}
bufferedReader.close();
} catch (IOException e) {
return false;
}
for (int i = 0; i < room.length; i++) {
for (int j = 0; j < room[i].length; j++) {
switch (room[i][j]) {
case FREE:
case BOX_ON_GOAL:
case WALL:
break;
case PLAYER_ON_GOAL:
emptyGoal++;
case PLAYER:
if (player != null) {
return false;
} else {
player = new int[]{j, i};
}
break;
case BOX:
freeBox++;
break;
case GOAL:
emptyGoal++;
break;
default:
return false;
}
}
}
return !(player == null || emptyGoal != freeBox);
}
/**
* Prints the level to the output stream
*/
private static void printLevel() {
for (char[] row : room) {
System.out.println(row);
}
}
/**
* Function for vector addition
*
* @param first first vector
* @param second second vector
* @return new vector = first + second
*/
private static int[] add(int[] first, int[] second) {
return new int[]{first[X] + second[X], first[Y] + second[Y]};
}
/**
* Game logic for Sokoban
*
* @return true if the level was solved, otherwise false
*/
private static boolean game() {
// create new Scanner that reads from console
Scanner input = new Scanner(System.in);
// flag if we quit the program
boolean run = true;
int[] direction;
do {
printLevel();
System.out.println("Do you want to go up, down, left, right or exit the program?");
// check which command was chosen and execute it
switch (input.next()) {
case "w":
case "up":
direction = UP;
break;
case "s":
case "down":
direction = DOWN;
break;
case "a":
case "left":
direction = LEFT;
break;
case "d":
case "right":
direction = RIGHT;
break;
case "exit":
run = false;
continue;
default: // if the user input is not one of our commands print help
System.out.println("Command unknown! Please type up, down, left or right to move or exit to quit this program");
continue;
}
if (!move(direction)) {
System.out.println("You can not go there!");
}
} while (run && emptyGoal != 0 && freeBox != 0);
return run;
}
/**
* Makes a move
*
* @param direction as a vector
* @return true iff it was successful, otherwise false
*/
private static boolean move(int[] direction) {
int[] next = add(player, direction);
switch (room[next[Y]][next[X]]) {
case BOX_ON_GOAL:
case BOX:
int[] behind = add(next, direction);
if (!(room[behind[Y]][behind[X]] == FREE || room[behind[Y]][behind[X]] == GOAL)) {
return false;
}
if (room[next[Y]][next[X]] == BOX_ON_GOAL) {
emptyGoal++;
freeBox++;
}
if (room[behind[Y]][behind[X]] == GOAL) {
room[behind[Y]][behind[X]] = BOX_ON_GOAL;
emptyGoal--;
freeBox--;
} else {
room[behind[Y]][behind[X]] = BOX;
}
if (room[next[Y]][next[X]] == BOX_ON_GOAL) {
room[next[Y]][next[X]] = GOAL;
} else {
room[next[Y]][next[X]] = FREE;
}
case GOAL:
case FREE:
if (room[player[Y]][player[X]] == PLAYER_ON_GOAL) {
room[player[Y]][player[X]] = GOAL;
} else {
room[player[Y]][player[X]] = FREE;
}
player = next;
if (room[player[Y]][player[X]] == FREE) {
room[player[Y]][player[X]] = PLAYER;
} else {
room[player[Y]][player[X]] = PLAYER_ON_GOAL;
}
return true;
default:
return false;
}
}
/**
* The Main method for the Sokoban game with contains all of the game logic
*
* @param args args[0] the path to the level
*/
public static void main(String[] args) {
String file = "sokoban.txt";
if (args.length > 0) {
file = args[0];
}
if (!loadLevel(file)) {
System.err.println("Level has an invalid format");
return;
}
if (game()) {
System.out.println("Yeah you have solved the level :)");
} else {
System.out.println("You have not solved the level :(");
}
printLevel();
System.out.println("Goodbye");
}
}