뭔가 어설프긴 하지만 완성은 했다 ㅋㅋㅋ 그래픽적으로 더 신경을 쓰고 싶지만 귀찮아서 안하구 있다 애플릿은 크기가 동적으로 변하지 않는 것 같다 난이도에 따라 크기가 변해야 되는데 어떻게 해결할지 고민중이다 [http://zeropage.org/~darkduck/mine.html 실행] {{{~cpp import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; public class Mine extends JApplet { private int row, col, numMines; private Vector mines = new Vector(); //private Point firstClick = new Point(); private int map[][]; private int numClick; // 왼쪽 버튼 누른 수 // numClick + numMines == row * col => 겜종료 private int numFlags; // 깃발 꼿은 수 // numMines - numFlags = 남은 폭탄 수 private boolean gameOver = false; Timer t = new Timer(); JPanel top = new JPanel(), center = new JPanel(); JTextField numLeftMines = new JTextField(3), useTime = new JTextField(6); JButton action = new JButton("^ _ ^"); private Kan kan[][]; public void init() { Container cp = getContentPane(); action.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mines.clear(); setMapSize(row, col, numMines); setMines(); setFigures(); center.removeAll(); setKans(); gameOver = false; action.setText("^ _ ^"); numLeftMines.setText(String.valueOf(numMines)); useTime.setText("0"); center.validate(); t.reset(); } }); top.add(numLeftMines, BorderLayout.WEST); top.add(action, BorderLayout.CENTER); top.add(useTime, BorderLayout.EAST); cp.add(top, BorderLayout.NORTH); setMapSize(9, 9, 10); setMines(); setFigures(); setKans(); numLeftMines.setText(String.valueOf(numMines)); useTime.setText("0"); center.setLayout(new GridLayout(row, col)); cp.add(center); //cp.setSize(20 * col, 20 * row); t.start(); } public void setMapSize(int r, int c, int nm) { row = r; col = c; numMines = nm; map = new int[row][col]; } public void setMines() { Random rand = new Random(); int r, c; boolean samePos; int i = 0; while (i < numMines) { r = Math.abs(rand.nextInt()) % row; c = Math.abs(rand.nextInt()) % col; samePos = false; for (int j = 0; j < mines.size(); j++) if ((((Point)mines.get(j)).y == r && ((Point)mines.get(j)).x == c)/* || (firstClick.y == r && firstClick.x == c)*/) { samePos = true; break; } if (samePos == true) continue; mines.add(new Point(c, r)); i++; } } public void setFigures() { int figure; for (int i = 0; i < numMines; i++) map[((Point)mines.get(i)).y][((Point)mines.get(i)).x] = -1; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { if (map[i][j] == -1) continue; figure = 0; if (j > 0 && map[i][j - 1] == -1) figure++; if (j < col - 1 && map[i][j + 1] == -1) figure++; if (i > 0) { if (map[i - 1][j] == -1) figure++; if (j > 0 && map[i - 1][j - 1] == -1) figure++; if (j < col - 1 && map[i - 1][j + 1] == -1) figure++; } if (i < row - 1) { if (map[i + 1][j] == -1) figure++; if (j > 0 && map[i + 1][j - 1] == -1) figure++; if (j < col - 1 && map[i + 1][j + 1] == -1) figure++; } map[i][j] = figure; } numFlags = 0; numClick = 0; } public void setKans() { kan = new Kan[row][col]; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) { kan[i][j] = new Kan(map[i][j], j, i); kan[i][j].setBorder(BorderFactory.createRaisedBevelBorder()); center.add(kan[i][j]); } } class Kan extends JLabel { private boolean state = false; // false 숨겨진 상태 // true 드러난 상태 private int numAroundMines; // 0~8 // -1 폭탄 private int x, y; public Kan(int nam, int x, int y) { numAroundMines = nam; setHorizontalAlignment(JLabel.CENTER); this.x = x; this.y = y; addMouseListener(new MouseListener() { public void mouseClicked(MouseEvent e) { if (!gameOver && e.getButton() == MouseEvent.BUTTON1 && !getText().equals("X")) clicked(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (!gameOver && e.getButton() == MouseEvent.BUTTON3 && state == false) { if (getText().equals("X")) { setText("?"); numFlags--; numLeftMines.setText(String.valueOf(numMines - numFlags)); } else if (getText().equals("?")) { setText(""); } else if (getText().equals("")) { setText("X"); numFlags++; numLeftMines.setText(String.valueOf(numMines - numFlags)); } } if (!gameOver && e.getButton() == MouseEvent.BUTTON1 && state == false) action.setText("^ o ^"); } public void mouseReleased(MouseEvent e) { if (!gameOver && e.getButton() == MouseEvent.BUTTON1 && state == false) { action.setText("^ _ ^"); } } }); } public void clicked() { if (state == false) { state = true; numClick++; setBorder(BorderFactory.createLoweredBevelBorder()); if (numAroundMines == -1) { setText("O"); boom(); return; } else if (numAroundMines == 0) { setText(""); if (x > 0 && map[y][x - 1] != -1) kan[y][x - 1].clicked(); if (x < col - 1 && map[y][x + 1] != -1) kan[y][x + 1].clicked(); if (y > 0) { if (map[y - 1][x] != -1) kan[y - 1][x].clicked(); if (x > 0 && map[y - 1][x - 1] != -1) kan[y - 1][x - 1].clicked(); if (x < col - 1 && map[y - 1][x + 1] != -1) kan[y - 1][x + 1].clicked(); } if (y < row - 1) { if (map[y + 1][x] != -1) kan[y + 1][x].clicked(); if (x > 0 && map[y + 1][x - 1] != -1) kan[y + 1][x - 1].clicked(); if (x < col - 1 && map[y + 1][x + 1] != -1) kan[y + 1][x + 1].clicked(); } } else setText(String.valueOf(numAroundMines)); if (row * col == numClick + numMines) success(); } } public void success() { gameOver = true; action.setText("^ . ^ V"); } public void boom() { gameOver = true; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) if (map[i][j] == -1) { if (!kan[i][j].getText().equals("X")) { kan[i][j].setText("O"); kan[i][j].setBorder(BorderFactory.createLoweredBevelBorder()); } } action.setText("ㅡ . ㅡ"); } } class Timer extends Thread { int t = 0; public Timer() { } public void run() { while (true) { try { sleep(10); } catch (InterruptedException e) { } if (!gameOver) { t++; useTime.setText(t / (100 * 60 * 60) + ":" + (t % (100 * 60 * 60)) / (100 * 60) + ":" + (t % (100 * 60)) / 100 + "." + t % 100); } } } public void reset() { t = 0; } } } }}}