Java
GolfScript veya CJam'dan hiç şikayet etmedim, ama işte yine de bir Java cevabı. Bu gerçekten eğlenceli bir mücadele oldu. ;)
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);
}
}
Gerçek labirent oluşturma işlemi derinlemesine ilk arama algoritmasını kullanır , ancak yinelemeli bir yaklaşımla. İşte nasıl çalışıyor.
int
Her öğe -1 olan bir 2D değer dizisi ile başlarız . Hatta endeksleri olan rastgele bir öğe seçilir ve değeri 0 olur:
-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
Ardından, program mevcut hücrelerin olmadığı bir duruma ulaşana kadar mevcut hücreleri kontrol ederek bir döngüye girer. Bu birkaç kez olabilir ve geriye dönmeye başladığında da olur. Şu anda karşılaştığı tüm 0'lar 1'di. Ayrıca bu süre zarfında bir çıkış o konuma yerleştirilmesi gerekip gerekmediğini belirler. Sonuç olarak, dizi şöyle görünebilir:
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
Dizideki belirli noktalarda önceden belirlenmiş bir 1s veya 0s sayısı olduğunda, döngü çıkar. Ardından diziyi kullanarak, ortaya çıkan labirent çizilir:
Dizideki -1 öğelerinin duvarları temsil ettiği ve 0 ve 1 lerin koridor olduğunu görmek kolaydır. Öğeler rastgele labirent boyunca dağıtılır. Kırmızı elips, kontrol ettiğiniz "oyuncu" dur.
Labirent, kolaylık sağlamak için bir kaydırma paneline sarılmıştır, böylece boyut çerçevenin maksimum boyutunu aşarsa, labirentin geri kalanını görmek için kaydırma yapabilirsiniz.
Bununla ilgili tek sorun, oyun kontrolünün nasıl biteceğidir. Bunu yapmanın birkaç yolunu düşündüm, ama hepsini kodlamak için başvurdum. Bunun nasıl yapılabileceği ile ilgili önerilere açığım.