Java
Ich habe mich nie über GolfScript oder CJam beschwert, aber hier ist trotzdem eine Java-Antwort für Sie. Dies war eine wirklich erfreuliche Herausforderung. ;)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.geom.Ellipse2D;
import java.util.*;
import javax.swing.*;
public class MazeMaker {
int row, col, exitRow, exitCol, numCells, score, array[][];
final int SQWIDTH = 20;
boolean gameOver = true;
Ellipse2D.Double ellipse;
JFrame frame;
JPanel mazePanel;
JLabel scoreLabel;
public MazeMaker() {
frame = new JFrame("Maze");
frame.setLayout(new BorderLayout());
JPanel topPanel = createTopPanel();
frame.add(topPanel,BorderLayout.NORTH);
createMazePanel();
frame.add(new JScrollPane(mazePanel),BorderLayout.CENTER);
setKeyActions();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private void constructArray(int seed, int rows, int cols) {
array = new int[rows*2-1][cols*2-1];
for (int[] a : array)
Arrays.fill(a,-1);
numCells = (array.length / 2 + 1) * (array[0].length / 2 + 1);
Random rand = new Random(seed);
int row = rand.nextInt(array.length / 2 + 1) * 2;
int col = rand.nextInt(array[0].length / 2 + 1) * 2;
array[row][col] = 0;
boolean first = true, a = false, exitFound = false;
while (true) {
if (first) {
int direction = rand.nextInt(4);
if (direction == 0 && row != 0) {
array[row-1][col] = 0;
array[row-2][col] = 0;
row -= 2;
first = false;
}
else if (direction == 1 && col != array[0].length - 1) {
array[row][col+1] = 0;
array[row][col+2] = 0;
col += 2;
first = false;
}
else if (direction == 2 && row != array.length - 1) {
array[row+1][col] = 0;
array[row+2][col] = 0;
row += 2;
first = false;
}
else if (direction == 3 && col != 0) {
array[row][col-1] = 0;
array[row][col-2] = 0;
col -= 2;
first = false;
}
}
else {
int availableCells = 0;
boolean up = false, down = false, left = false, right = false;
if (row != 0 && array[row-2][col] == -1) {
availableCells++;
up = true;
}
if (col != array[0].length-1 && array[row][col+2] == -1) {
availableCells++;
right = true;
}
if (row != array.length-1 && array[row+2][col] == -1) {
availableCells++;
down = true;
}
if (col != 0 && array[row][col-2] == -1) {
availableCells++;
left = true;
}
if (availableCells != 0) {
a = true;
while (true) {
boolean[] b = {up,right,down,left};
int i = rand.nextInt(4);
if (b[i]) {
if (i == 0) {
array[row-1][col] = 0;
array[row-2][col] = 0;
row -= 2;
}
else if (i == 1) {
array[row][col+1] = 0;
array[row][col+2] = 0;
col += 2;
}
else if (i == 2) {
array[row+1][col] = 0;
array[row+2][col] = 0;
row += 2;
}
else if (i == 3) {
array[row][col-1] = 0;
array[row][col-2] = 0;
col -= 2;
}
break;
}
}
}
else {
array[row][col] = 1;
if (!exitFound && a) {
if (new Random().nextInt(5) == 0) {
exitFound = true;
exitRow = row;
exitCol = col;
}
}
a = false;
if (row != 0 && array[row-1][col] == 0 && (array[row-2][col] == 0 || array[row-2][col] == 1)) {
array[row-1][col] = 1;
array[row-2][col] = 1;
row -= 2;
}
else if (col != array[0].length-1 && array[row][col+1] == 0 && (array[row][col+2] == 0 || array[row][col+2] == 1)) {
array[row][col+1] = 1;
array[row][col+2] = 1;
col += 2;
}
else if (row != array.length-1 && array[row+1][col] == 0 && (array[row+2][col] == 0 || array[row+2][col] == 1)) {
array[row+1][col] = 1;
array[row+2][col] = 1;
row += 2;
}
else if (col != 0 && array[row][col-1] == 0 && (array[row][col-2] == 0 || array[row][col-2] == 1)) {
array[row][col-1] = 1;
array[row][col-2] = 1;
col -= 2;
}
}
if (checkDone()) {
if (!exitFound) {
exitRow = row;
exitCol = col;
}
break;
}
}
}
}
private boolean checkDone() {
int count = 0;
for (int k = 0; k < array.length; k+=2) {
for (int l = 0; l < array[0].length; l+=2) {
if (array[k][l] == 0 || array[k][l] == 1)
count++;
}
}
return count == numCells;
}
private JPanel createTopPanel() {
GridBagLayout l = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
JPanel panel = new JPanel(l);
JLabel inputLabel = new JLabel("ID:");
c.gridwidth = 1;
l.setConstraints(inputLabel,c);
panel.add(inputLabel);
JTextField inputField = new JTextField(5);
l.setConstraints(inputField,c);
panel.add(inputField);
JLabel rowLabel = new JLabel("Rows:");
l.setConstraints(rowLabel,c);
panel.add(rowLabel);
JTextField rowField = new JTextField(3);
l.setConstraints(rowField,c);
panel.add(rowField);
JLabel colLabel = new JLabel("Columns:");
l.setConstraints(colLabel,c);
panel.add(colLabel);
JTextField colField = new JTextField(3);
l.setConstraints(colField,c);
panel.add(colField);
JButton applyButton = new JButton("Apply");
applyButton.addActionListener(ev -> {
try {
int seed = Integer.parseInt(inputField.getText()),
rows = Integer.parseInt(rowField.getText()),
cols = Integer.parseInt(colField.getText());
if (seed >= 0 && rows >= 3 && cols >= 3) {
gameOver = false;
scoreLabel.setText("Score: " + (score = 0));
constructArray(seed,rows,cols);
row = (int) (Math.random() * (array.length / 2 + 1)) * 2;
col = (int) (Math.random() * (array[0].length / 2 + 1)) * 2;
frame.setSize((1+SQWIDTH * array[0].length)/2 > 750 ? (1+SQWIDTH * array[0].length)/2 : 750,
75+(1+SQWIDTH * array.length)/2);
mazePanel.setPreferredSize(new Dimension(
(1+SQWIDTH * array[0].length)/2 > 750 ? (1+SQWIDTH * array[0].length)/2 - 15 : 750,
15+(1+SQWIDTH * array.length)/2));
ellipse = new Ellipse2D.Double(col*SQWIDTH/2+3,row*SQWIDTH/2+3,10,10);
setItems();
mazePanel.repaint();
}
} catch (NumberFormatException ignore) {}
});
l.setConstraints(applyButton,c);
panel.add(applyButton);
scoreLabel = new JLabel("Score: ");
c.gridwidth = GridBagConstraints.REMAINDER;
l.setConstraints(scoreLabel,c);
panel.add(scoreLabel);
return panel;
}
private void createMazePanel() {
mazePanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 0, y = 0;
if (!gameOver) {
for (int k = 0; k < array.length; k+=2) {
for (int l = 0; l < array[0].length; l+=2) {
int n = array[k][l];
if (n == 0 || n == 1 || n == 4 || n == 5 || n == 6)
g.setColor(Color.white);
else if (n == 2)
g.setColor(Color.green);
else if (n == 3)
g.setColor(Color.red);
g.fillRect(x, y, SQWIDTH, SQWIDTH);
if (n == 4) {
g.setColor(new Color(245,209,34));
g.fillOval(x+3, y+3, 10, 10);
}
else if (n == 5) {
g.setColor(new Color(255,223,55));
g.fillPolygon(new int[]{x,x+3,x+8,x+13,x+16,x+14,x+2},new int[]{y+2,y+6,y+2,y+6,y+2,y+16,y+16},7);
g.setColor(new Color(12,234,44));
g.fillOval(x+7,y+6,4,7);
}
else if (n == 6) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
g2.setColor(new Color(108,225,119));
g2.drawOval(x+5, y+1, 8, 8);
g2.drawLine(x+5, y+3, x+5, y+11);
g2.drawArc(x+5, y+8, 7, 7, 180, 180);
}
g.setColor(Color.black);
if (k != array.length-1 && array[k+1][l] == -1)
g.fillRect(x-3, y+SQWIDTH-3, SQWIDTH+3, 3);
if (l != array[0].length-1 && array[k][l+1] == -1)
g.fillRect(x+SQWIDTH-3,y,3,SQWIDTH);
x += SQWIDTH;
}
x = 0;
y += SQWIDTH;
}
g.setColor(Color.red);
((Graphics2D) g).fill(ellipse);
}
}
};
}
private void setKeyActions() {
InputMap im = mazePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = mazePanel.getActionMap();
im.put(KeyStroke.getKeyStroke("pressed UP"), "up");
am.put("up", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
if (row != 0 && array[row-1][col] != -1 && array[row-2][col] != 3 && !gameOver) {
int n = array[row][col];
array[row][col] = n == 0 || n == 1 || n == 4 || n == 5 ? 2 : 3;
row -= 2;
n = array[row][col];
if (n == 4)
scoreLabel.setText("Score: " + (score += 20));
else if (n == 5)
scoreLabel.setText("Score: " + (score += 50));
else if (n == 2)
scoreLabel.setText("Score: " + (score -= 1));
ellipse.y = row * SQWIDTH/2 + 3;
mazePanel.repaint();
}
if (!gameOver && array[row][col] == 6) {
JOptionPane.showMessageDialog(frame, "Huzzah! You found the exit! ", "Finish", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
else if (!gameOver && checkGameOver()) {
JOptionPane.showMessageDialog(frame, "You got trapped! Try again!", "Game over", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
}
});
im.put(KeyStroke.getKeyStroke("pressed RIGHT"), "right");
am.put("right",new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
if (col != array[0].length-1 && array[row][col+1] != -1 && array[row][col+2] != 3 && !gameOver) {
int n = array[row][col];
array[row][col] = n == 0 || n == 1 || n == 4 || n == 5 ? 2 : 3;
col += 2;
n = array[row][col];
if (n == 4)
scoreLabel.setText("Score: " + (score += 20));
else if (n == 5)
scoreLabel.setText("Score: " + (score += 50));
else if (n == 2)
scoreLabel.setText("Score: " + (score -= 1));
ellipse.x = col * SQWIDTH/2 + 3;
mazePanel.repaint();
}
if (!gameOver && array[row][col] == 6) {
JOptionPane.showMessageDialog(frame, "Huzzah! You found the exit! ", "Finish", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
else if (!gameOver && checkGameOver()) {
JOptionPane.showMessageDialog(frame, "You got trapped! Try again!", "Game over", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
}
});
im.put(KeyStroke.getKeyStroke("pressed DOWN"), "down");
am.put("down", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
if (row != array.length-1 && array[row+1][col] != -1 && array[row+2][col] != 3 && !gameOver) {
int n = array[row][col];
array[row][col] = n == 0 || n == 1 || n == 4 || n == 5 ? 2 : 3;
row += 2;
n = array[row][col];
if (n == 4)
scoreLabel.setText("Score: " + (score += 20));
else if (n == 5)
scoreLabel.setText("Score: " + (score += 50));
else if (n == 2)
scoreLabel.setText("Score: " + (score -= 1));
ellipse.y = row * SQWIDTH/2 + 3;
mazePanel.repaint();
}
if (!gameOver && array[row][col] == 6) {
JOptionPane.showMessageDialog(frame, "Huzzah! You found the exit! ", "Finish", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
else if (!gameOver && checkGameOver()) {
JOptionPane.showMessageDialog(frame, "You got trapped! Try again!", "Game over", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
}
});
im.put(KeyStroke.getKeyStroke("pressed LEFT"), "left");
am.put("left",new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ev) {
if (col != 0 && array[row][col-1] != -1 && array[row][col-2] != -1 && !gameOver) {
int n = array[row][col];
array[row][col] = n == 0 || n == 1 || n == 4 || n == 5 ? 2 : 3;
col -= 2;
n = array[row][col];
if (n == 4)
scoreLabel.setText("Score: " + (score += 20));
else if (n == 5)
scoreLabel.setText("Score: " + (score += 50));
else if (n == 2)
scoreLabel.setText("Score: " + (score -= 1));
ellipse.x = col * SQWIDTH/2 + 3;
mazePanel.repaint();
}
if (!gameOver && array[row][col] == 6) {
JOptionPane.showMessageDialog(frame, "Huzzah! You found the exit! ", "Finish", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
else if (!gameOver && checkGameOver()) {
JOptionPane.showMessageDialog(frame, "You got trapped! Try again!", "Game over", JOptionPane.PLAIN_MESSAGE);
gameOver = true;
}
}
});
}
private void setItems() {
array[exitRow][exitCol] = 6;
Random r = new Random();
for (int k = 1; k < (array.length * array[0].length) / 20; k++) {
int row = r.nextInt(array.length / 2 + 1) * 2,
col = r.nextInt(array[0].length / 2 + 1) * 2;
if ((row == this.row && col == this.col) || array[row][col] == 4 || array[row][col] == 5 || array[row][col] == 6)
k--;
else
array[row][col] = r.nextInt(2) + 4;
}
}
private boolean checkGameOver() {
if (row == 0 && col == 0)
return (array[row+2][col] == 3 && array[row][col+2] == 3) ||
(array[row+1][col] == -1 && array[row][col+2] == 3) ||
(array[row+2][col] == 3 && array[row][col+1] == -1);
else if (row == 0 && col == array[0].length-1)
return (array[row+2][col] == 3 && array[row][col-2] == 3) ||
(array[row+1][col] == -1 && array[row][col-2] == 3) ||
(array[row+2][col] == 3 && array[row][col-1] == -1);
else if (row == array.length-1 && col == 0)
return (array[row-2][col] == 3 && array[row][col+2] == 3) ||
(array[row-1][col] == -1 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row][col+1] == -1);
else if (row == array.length-1 && col == array[0].length-1)
return (array[row-2][col] == 3 && array[row][col-2] == 3) ||
(array[row-1][col] == -1 && array[row][col-2] == 3) ||
(array[row-2][col] == 3 && array[row][col-1] == -1);
else if (row == 0)
return (array[row+2][col] == 3 && array[row][col-1] == -1 && array[row][col+1] == -1) ||
(array[row+1][col] == -1 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row+1][col] == -1 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row+1][col] == -1 && array[row][col-2] == 3 && array[row][col+2] == 3) ||
(array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row+2][col] == 3 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+2] == 3);
else if (col == 0)
return (array[row][col+2] == 3 && array[row-1][col] == -1 && array[row+1][col] == -1) ||
(array[row][col+1] == -1 && array[row-2][col] == 3 && array[row+1][col] == -1) ||
(array[row][col+1] == -1 && array[row-1][col] == -1 && array[row+2][col] == 3) ||
(array[row][col+1] == -1 && array[row-2][col] == 3 && array[row+2][col] == 3) ||
(array[row][col+2] == 3 && array[row-2][col] == 3 && array[row+1][col] == -1) ||
(array[row][col+2] == 3 && array[row-1][col] == -1 && array[row+2][col] == 3) ||
(array[row][col+2] == 3 && array[row-2][col] == 3 && array[row+2][col] == 3);
else if (row == array.length-1)
return (array[row-2][col] == 3 && array[row][col-1] == -1 && array[row][col+1] == -1) ||
(array[row-1][col] == -1 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row-1][col] == -1 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row-1][col] == -1 && array[row][col-2] == 3 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row-2][col] == 3 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row][col-2] == 3 && array[row][col+2] == 3);
else if (col == array[0].length-1)
return (array[row][col-2] == 3 && array[row-1][col] == -1 && array[row+1][col] == -1) ||
(array[row][col-1] == -1 && array[row-2][col] == 3 && array[row+1][col] == -1) ||
(array[row][col-1] == -1 && array[row-1][col] == -1 && array[row+2][col] == 3) ||
(array[row][col-1] == -1 && array[row-2][col] == 3 && array[row+2][col] == 3) ||
(array[row][col-2] == 3 && array[row-2][col] == 3 && array[row+1][col] == -1) ||
(array[row][col-2] == 3 && array[row-1][col] == -1 && array[row+2][col] == 3) ||
(array[row][col-2] == 3 && array[row-2][col] == 3 && array[row+2][col] == 3);
else
return (array[row-2][col] == 3 && array[row][col+1] == -1 && array[row+1][col] == -1 && array[row][col-1] == -1) ||
(array[row-1][col] == -1 && array[row][col+2] == 3 && array[row+1][col] == -1 && array[row][col-1] == -1) ||
(array[row-1][col] == -1 && array[row][col+1] == -1 && array[row+2][col] == 3 && array[row][col-1] == -1) ||
(array[row-1][col] == -1 && array[row][col+1] == -1 && array[row+1][col] == -1 && array[row][col-2] == 3) ||
(array[row-1][col] == -1 && array[row+1][col] == -1 && array[row][col-2] == 3 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row+2][col] == 3 && array[row][col-1] == -1 && array[row][col+1] == -1) ||
(array[row-2][col] == 3 && array[row+1][col] == -1 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row-1][col] == -1 && array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row-1][col] == -1 && array[row+2][col] == 3 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row+1][col] == -1 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row-1][col] == -1 && array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row+1][col] == -1 && array[row][col-2] == 3 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row+2][col] == 3 && array[row][col-1] == -1 && array[row][col+2] == 3) ||
(array[row-2][col] == 3 && array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+1] == -1) ||
(array[row-2][col] == 3 && array[row+2][col] == 3 && array[row][col-2] == 3 && array[row][col+2] == 3);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MazeMaker::new);
}
}
Der Prozess der Erstellung des eigentlichen Labyrinths nutzt die Tiefensuchalgorithmus verwendet , jedoch mit einem iterativen Ansatz. So funktioniert das.
Wir beginnen mit einem 2D-Array von int
Werten, wobei jedes Element ein -1 ist. Ein zufälliges Element mit geraden Indizes wird ausgewählt und sein Wert wird zu 0:
-1 -1 -1 -1 -1 -1 0 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1
Dann tritt das Programm in eine Schleife ein und prüft auf verfügbare Zellen, bis es einen Zustand erreicht, in dem keine verfügbaren Zellen mehr vorhanden sind. Dies kann mehrmals vorkommen und ist der Zeitpunkt, an dem das Zurückverfolgen beginnt. Zu diesem Zeitpunkt werden alle Nullen, auf die es stößt, zu Einsen. Auch in dieser Zeit wird festgelegt, ob an dieser Stelle ein Ausgang platziert werden soll. Am Ende könnte das Array also so aussehen:
0 0 0 0 0 0 1 1 1
0 -1 -1 -1 -1 -1 0 -1 1
0 0 0 0 0 -1 0 -1 1
-1 -1 -1 -1 -1 -1 0 -1 1
0 0 0 0 0 0 0 -1 1
0 -1 -1 -1 -1 -1 -1 -1 1
0 -1 1 1 1 1 1 -1 1
0 -1 1 -1 1 -1 -1 -1 1
0 -1 1 -1 1 1 1 1 1
Wenn an bestimmten Stellen im Array eine vorgegebene Anzahl von Einsen oder Nullen vorliegt, wird die Schleife beendet. Mit dem Array wird dann das resultierende Labyrinth gezeichnet:
Es ist leicht zu erkennen, dass die -1s im Array Wände darstellen und die 0s und 1s Korridore sind. Gegenstände werden zufällig im Labyrinth verteilt. Die rote Ellipse ist der "Spieler", den Sie steuern.
Das Labyrinth ist zur Vereinfachung in ein Bildlauffenster eingebettet. Wenn die Größe des Rahmens die maximale Größe überschreitet, können Sie einen Bildlauf durchführen, um den Rest des Labyrinths anzuzeigen.
Ich würde sagen, das einzige Problem dabei ist, wie der Spielende-Check durchgeführt wird. Ich dachte über mehrere Möglichkeiten nach, um das zu tun, aber schließlich habe ich alles hart programmiert. Ich bin offen für Vorschläge, wie es gemacht werden kann.