Dateien nach "visualizationElements" hochladen

This commit is contained in:
Jonathan-Kalmbach 2024-07-10 05:57:22 +00:00
parent 90a0bb07ec
commit d27d48f734
5 changed files with 627 additions and 0 deletions

View File

@ -0,0 +1,327 @@
package visualizationElements;
import java.awt.Graphics;
import java.util.Stack;
import java.util.Vector;
/**
* Represents a maze to visualize.
* @author MSchaefer
*
*/
public class Maze extends VisualizationElement{
private static final int CELL_WIDTH = 30;
private static final int CELL_HEIGTH = 30;
private static final int START_X_POS = 20;
private static final int START_Y_POS = 20;
private Cell[][] maze;
private Cell currentCell;
private int heigth;
private int width;
private int xpos;
private int ypos;
private Stack<Cell> cellStack;
/**
* Creates a new Maze.
* @param heigth Height of the Maze.
* @param width Width of the Maze.
*/
public Maze(int heigth, int width){
super();
this.setHeigth(heigth);
this.setWidth(width);
this.cellStack = new Stack<Cell>();
this.maze = new Cell[width][heigth];
initMaze();
}
@Override
public void draw(Graphics g) {
xpos = START_X_POS;
ypos = START_Y_POS;
for(int column = 0; column < width; column++){
for(int row = 0; row < heigth; row++){
Cell currentCell = maze[column][row];
if(currentCell.hasNorthWall()){
g.drawLine(xpos, ypos, xpos + CELL_WIDTH, ypos);
}
if(currentCell.hasSouthWall()){
g.drawLine(xpos, ypos + CELL_HEIGTH, xpos + CELL_WIDTH, ypos + CELL_HEIGTH);
}
if(currentCell.hasWestWall()){
g.drawLine(xpos, ypos, xpos, ypos + CELL_HEIGTH);
}
if(currentCell.hasEastWall()){
g.drawLine(xpos + CELL_WIDTH, ypos, xpos + CELL_WIDTH, ypos + CELL_HEIGTH);
}
ypos = ypos + CELL_HEIGTH;
}
ypos = START_Y_POS;
xpos = xpos + CELL_WIDTH;
}
}
/**
* @param maze the maze to set
*/
public void setMaze(Cell[][] maze) {
this.maze = maze;
}
/**
* @return the maze
*/
public Cell[][] getMaze() {
return maze;
}
/**
* @param heigth the heigth to set
*/
public void setHeigth(int heigth) {
this.heigth = heigth;
}
/**
* @return the heigth
*/
public int getHeigth() {
return heigth;
}
/**
* @param width the width to set
*/
public void setWidth(int width) {
this.width = width;
}
/**
* @return the width
*/
public int getWidth() {
return width;
}
/**
* Initializes the maze.
*/
private void initMaze() {
initMazeWithAllWalls();
generateWays();
}
/**
* Initializes a Maze full of walls.
*/
private void initMazeWithAllWalls() {
xpos = START_X_POS;
ypos = START_Y_POS;
for(int column = 0; column < width; column++){
for(int row = 0; row < heigth; row++){
maze[column][row] = new Cell(column, row);
ypos = ypos + CELL_HEIGTH;
}
xpos = xpos + CELL_WIDTH;
}
}
/**
* Generates ways through a maze full of walls.
*/
private void generateWays(){
/*
-Pick a room randomly, and push it onto the stack. This is the starting room.
-Pick a room adjacent to the first room, and open a door between them. This room is the current room.
-Push the starting room onto the stack.
-While there's at least one room left on the stack, repeat the following steps:
-If there are any unconnected rooms next to the current room,
-Pick one randomly, and open a door between it and the current room.
-Push the current room onto the stack; the new room becomes the current room.
-Go back to the top of the loop.
-If there are no unconnected rooms next to the current room,
-Pop a room off of the stack; it becomes the current room.
-Go back to the top of the loop.
-When the stack is empty, the maze is complete.*/
boolean goalMarked = false;
currentCell = maze[0][0];
currentCell.setAsStart();
currentCell.removeNorthWall();
cellStack.push(currentCell);
while(cellStack.size() > 0){
currentCell.markAsVisited();
if(!goalMarked){
if(currentCell.getRow() == maze.length - 1){
currentCell.setAsGoal();
currentCell.removeSouthWall();
goalMarked = true;
}
else if(currentCell.getColumn() == maze[0].length - 1){
currentCell.setAsGoal();
currentCell.removeEastWall();
goalMarked = true;
}
}
Vector<Cell> unvisitedNeighbours = getUnvisitedCellNeighbors(currentCell);
if(unvisitedNeighbours.size() != 0){
int randomUnvisitedNeighbourIndex = (int) (Math.random() * unvisitedNeighbours.size());
Cell randomUnvisitedNeighbour = unvisitedNeighbours.get(randomUnvisitedNeighbourIndex);
removeWallBetweenCurrentCellAndNeighbour(currentCell, randomUnvisitedNeighbour);
cellStack.push(currentCell);
currentCell = randomUnvisitedNeighbour;
}
else{
currentCell = cellStack.pop();
}
}
}
/**
* Removes a cell's south wall.
* @param column Column of the cell.
* @param row Row of the cell.
*/
private void removeCellsSouthWall(int column, int row){
maze[column][row].removeSouthWall();
// removes WestWall of neighbor
if(row < maze[column].length && maze[column][row + 1].hasNorthWall()){
removeCellsNorthWall(column, row + 1);
}
}
/**
* Removes a cell's north wall.
* @param column Column of the cell.
* @param row Row of the cell.
*/
private void removeCellsNorthWall(int column, int row){
maze[column][row].removeNorthWall();
// removes WestWall of neighbor
if(row < maze[column].length && maze[column][row - 1].hasSouthWall()){
removeCellsSouthWall(column, row - 1);
}
}
/**
* Removes a cell's east wall.
* @param column Column of the cell.
* @param row Row of the cell.
*/
private void removeCellsEastWall(int column, int row) {
maze[column][row].removeEastWall();
// removes WestWall of neighbor
if(column < maze.length - 1 && maze[column + 1][row].hasWestWall()){
removeCellsWestWall(column + 1, row);
}
}
/**
* Removes a cell's west wall.
* @param column Column of the cell.
* @param row Row of the cell.
*/
private void removeCellsWestWall(int column, int row){
maze[column][row].removeWestWall();
// removes WestWall of neighbor
if(column < maze.length - 1 && maze[column - 1][row].hasEastWall()){
removeCellsEastWall(column - 1, row);
}
}
/**
* Removes the wall between two cells.
* @param cell Cell to remove a wall.
* @param neighbor The Cell's neighbour to remove the corresponding wall.
*/
private void removeWallBetweenCurrentCellAndNeighbour(Cell cell, Cell neighbor) {
if(neighbor.getRow() == cell.getRow()){
if(neighbor.getColumn() < cell.getColumn()){
removeCellsWestWall(cell.getColumn(), cell.getRow());
}
else{
removeCellsEastWall(cell.getColumn(), cell.getRow());
}
}
else if(neighbor.getRow() < cell.getRow()){
removeCellsNorthWall(cell.getColumn(), cell.getRow());
}
else{
removeCellsSouthWall(cell.getColumn(), cell.getRow());
}
}
/**
* Gets all unvisited neighbors of a cell.
* @param currentCell The cell to get the neighbors.
* @return The cell's unvisited neighbors.
*/
private Vector<Cell> getUnvisitedCellNeighbors(Cell currentCell) {
Vector<Cell> neighbours = getAllCellNeighbours(currentCell);
Vector<Cell> unvisitedNeighbours = new Vector<Cell>();
for(Cell neighbour : neighbours){
if(!neighbour.isVisited()){
unvisitedNeighbours.add(neighbour);
}
}
return unvisitedNeighbours;
}
/**
* Gets all neighbors of a cell.
* @param currentCell The cell to get the neighbors.
* @return The cell's neighbors.
*/
private Vector<Cell> getAllCellNeighbours(Cell currentCell) {
Vector<Cell> neighbours = new Vector<Cell>();
int currentCellRow = currentCell.getRow();
int currentCellColumn = currentCell.getColumn();
if(currentCellRow < heigth-1){
neighbours.add(maze[currentCellColumn][currentCellRow+1]);
}
if(currentCellRow != 0){
neighbours.add(maze[currentCellColumn][currentCellRow-1]);
}
if(currentCellColumn < width-1){
neighbours.add(maze[currentCellColumn+1][currentCellRow]);
}
if(currentCellColumn != 0){
neighbours.add(maze[currentCellColumn-1][currentCellRow]);
}
return neighbours;
}
}

View File

@ -0,0 +1,61 @@
/**
*
*/
package visualizationElements;
import java.awt.Graphics;
import java.util.Vector;
/**
* Represents a queue to visualize.
* @author MSchaefer
*
*/
public class Queue extends List {
/**
* Creates a new Queue.
* @param values The values to of the queue.
*/
public Queue(Vector<?> values){
super(values);
}
/**
* Creates a new Queue.
* @param values The values to of the queue.
*/
public Queue(Object[] values){
super(values);
}
@Override
public void draw(Graphics g) {
numberOfRows = valueTable.length;
numberOfColumns = valueTable[0].length;
int xpos = START_X_POS;
int ypos = START_Y_POS;
for(int j = 0; j < numberOfColumns; j++){
xpos = xpos + CELL_WIDTH;
ypos = START_Y_POS;
for(int i = 0; i < numberOfRows; i++){
ypos = ypos + CELL_HEIGHT;
g.drawRect(xpos, ypos, CELL_WIDTH, CELL_HEIGHT);
if(valueTable[i][j] != null){
g.drawString(valueTable[numberOfRows-(i+1)][numberOfColumns-(j+1)].toString(), xpos + CELL_HEIGHT, ypos + 15);
}
}
}
g.drawLine(START_X_POS, ypos - 3, xpos + CELL_WIDTH, ypos - 3);
g.drawLine(START_X_POS, ypos + CELL_HEIGHT + 3, xpos + CELL_WIDTH, ypos + CELL_HEIGHT + 3);
g.drawLine(START_X_POS, ypos - 4, xpos + CELL_WIDTH, ypos - 4);
g.drawLine(START_X_POS, ypos + CELL_HEIGHT + 4, xpos + CELL_WIDTH, ypos + CELL_HEIGHT + 4);
}
}

View File

@ -0,0 +1,92 @@
package visualizationElements;
import java.awt.Graphics;
import java.util.Vector;
/**
* Represents a Stack to visualize.
* @author MSchaefer
*
*/
public class Stack extends Table {
/**
* Creates a new Stack.
* @param values The values of the stack.
*/
public Stack(Vector<?> values){
super(null, values.size(), 1);
Object[][] tableArray = createTableArray(values);
super.setValues(tableArray);
}
/**
* Creates a new Stack.
* @param values The values of the stack.
*/
public Stack(Object[] values){
super(null, values.length, 1);
Object[][] tableArray = new Object[values.length][1];
int i = 0;
for(Object o : values){
tableArray[i][0] = o;
i++;
}
super.setValues(tableArray);
}
@Override
public void draw(Graphics g) {
numberOfRows = valueTable.length;
numberOfColumns = valueTable[0].length;
int xpos = START_X_POS;
int ypos = START_Y_POS;
for(int j = 0; j < numberOfColumns; j++){
xpos = xpos + CELL_WIDTH;
ypos = START_Y_POS;
for(int i = 0; i < numberOfRows; i++){
ypos = ypos + CELL_HEIGHT;
g.drawRect(xpos, ypos, CELL_WIDTH, CELL_HEIGHT);
if(valueTable[i][j] != null){
g.drawString(valueTable[numberOfRows-(i+1)][numberOfColumns-(j+1)].toString(), xpos + CELL_HEIGHT, ypos + 15);
}
}
}
g.drawLine(START_X_POS + CELL_WIDTH - 3, START_Y_POS, START_X_POS + CELL_WIDTH - 3, ypos + CELL_HEIGHT + 3);
g.drawLine(xpos + CELL_WIDTH + 3, START_Y_POS, xpos + CELL_WIDTH + 3, ypos + CELL_HEIGHT + 3);
g.drawLine(START_X_POS + CELL_WIDTH - 3, ypos + CELL_HEIGHT + 3, xpos + CELL_WIDTH + 3, ypos + CELL_HEIGHT + 3);
g.drawLine(START_X_POS + CELL_WIDTH - 4, START_Y_POS, START_X_POS + CELL_WIDTH - 4, ypos + CELL_HEIGHT + 4);
g.drawLine(xpos + CELL_WIDTH + 4, START_Y_POS, xpos + CELL_WIDTH + 4, ypos + CELL_HEIGHT + 4);
g.drawLine(START_X_POS + CELL_WIDTH - 4, ypos + CELL_HEIGHT + 4, xpos + CELL_WIDTH + 4, ypos + CELL_HEIGHT + 4);
}
/**
* Creates the array to visualize as stack out from the vector.
* @param values Vector to convert.
* @return Array with values to visualizes as list.
*/
private Object[][] createTableArray(Vector<?> values) {
Object[][] tableArray = new Object[values.size()][1];
for (int i = 0; i<values.size(); i++) {
tableArray[i][0] = values.get(i).toString();
}
return tableArray;
}
}

View File

@ -0,0 +1,146 @@
/**
*
*/
package visualizationElements;
import java.awt.Font;
import java.awt.Graphics;
/**
* Represents a table to visualize.
* @author MSchaefer
*
*/
public class Table extends VisualizationElement {
protected static final int START_Y_POS = 20;
protected static final int START_X_POS = 20;
protected static final int CELL_HEIGHT = 20;
protected static final int CELL_WIDTH = 80;
protected int numberOfRows;
protected int numberOfColumns;
private int height;
private int width;
protected Object[][] valueTable;
private String[] columnCaptions;
/**
* Creates a new Table.
* @param values The values of the table.
* @param columnCaptions The captions of the table columns.
* @param width Width of the table.
* @param height Height of the table.
*
*/
public Table(Object[][] values, String[] columnCaptions, int width, int height) {
super();
if(columnCaptions.length != values[0].length){
throw new IllegalArgumentException("Not all columns have got a caption!");
}
this.setValues(values);
this.setColumnCaptions(columnCaptions);
}
/**
* Creates a new Table.
* @param values The values of the table.
* @param width Width of the table.
* @param height Height of the table.
*
*/
public Table(Object[][] values, int width, int height) {
super();
this.setValues(values);
this.setColumnCaptions(null);
}
/* (non-Javadoc)
* @see visualizationElements.VisualizationElement#draw()
*/
@Override
public void draw(Graphics g) {
numberOfRows = valueTable.length;
numberOfColumns = valueTable[0].length;
int xpos = START_X_POS;
int ypos = START_Y_POS;
for(int j = 0; j < numberOfColumns; j++){
xpos = xpos + CELL_WIDTH;
ypos = START_Y_POS;
if(columnCaptions != null){
g.setFont(new Font("Arial", Font.BOLD, 13));
g.drawRect(xpos, ypos, CELL_WIDTH, CELL_HEIGHT);
g.drawRect(xpos+1, ypos + 1, CELL_WIDTH-2, CELL_HEIGHT-2);
g.drawString(columnCaptions[j].toString(), xpos + 5, ypos + 15);
g.setFont(new Font("Arial", Font.PLAIN, 13));
}
for(int i = 0; i < numberOfRows; i++){
ypos = ypos + CELL_HEIGHT;
g.drawRect(xpos, ypos, CELL_WIDTH, CELL_HEIGHT);
if(valueTable[i][j] != null){
g.drawString(valueTable[i][j].toString(), xpos + CELL_HEIGHT, ypos + 15);
}
}
}
}
/**
* @param width the width to set
*/
public void setWidth(int width) {
this.width = width;
}
/**
* @return the width
*/
public int getWidth() {
return width;
}
/**
* @param height the height to set
*/
public void setHeight(int height) {
this.height = height;
}
/**
* @return the height
*/
public int getHeight() {
return height;
}
public void setColumnCaptions(String[] columnCaptions) {
this.columnCaptions = columnCaptions;
}
public String[] getColumnCaptions(){
return this.columnCaptions;
}
/**
* @param values the values to set
*/
public void setValues(Object[][] values) {
this.valueTable = values;
}
/**
* @return the values
*/
public Object[][] getValues() {
return valueTable;
}
}

View File

@ -0,0 +1 @@
<body>Provides all classes to visualize algorithms, and abstract data types with predefined visualization elements.</body>