Java
Je ne me suis jamais plaint de GolfScript ou CJam, mais voici quand même une réponse Java pour vous. Ce fut un défi vraiment agréable. ;)
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);
}
}
Le processus de création du labyrinthe réel utilise le algorithme de recherche en profondeur d'abord , mais avec une approche itérative. Voici comment cela fonctionne.
Nous commençons avec un tableau 2D de int
valeurs, chaque élément étant un -1. Un élément aléatoire avec des indices pairs est choisi et sa valeur devient 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
Ensuite, le programme entre dans une boucle, vérifiant les cellules disponibles jusqu'à ce qu'il atteigne un état où il n'y a pas de cellules disponibles. Cela peut se produire plusieurs fois et c'est à ce moment qu'il commence à revenir en arrière. À ce moment, tous les 0 qu'il rencontre deviennent des 1. C'est également à cette période qu'il détermine si une sortie doit être placée à cet endroit. Donc, à la fin de tout cela, le tableau pourrait ressembler à ceci:
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
Lorsqu'il y a un nombre prédéterminé de 1 ou de 0 à certains endroits de la matrice, la boucle se termine. Ensuite, en utilisant le tableau, le labyrinthe résultant est dessiné:
Il est facile de voir que les -1 dans le tableau représentent des murs et que les 0 et les 1 sont des couloirs. Les objets sont distribués au hasard dans le labyrinthe. L'ellipse rouge est le "joueur" que vous contrôlez.
Le labyrinthe est enveloppé dans un volet de défilement pour plus de commodité, de sorte que si la taille dépasse la taille maximale du cadre, vous pouvez faire défiler pour voir le reste du labyrinthe.
Je dirais que le seul problème avec cela est de savoir comment la vérification de fin de partie est effectuée. J'ai réfléchi à plusieurs façons de procéder, mais j'ai fini par recourir à tout coder en dur. Je suis ouvert aux suggestions sur la façon dont cela peut être fait.