不知該取什麼名字
2007-01-15 18:44:53 UTC
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
class riavnc
public static void main(String[] args){
private byte[] map; // 以一維陣列來取代二維,以減少物件的使用
private int[] x, y;
private Frame f;
private int[] directions;
// 前四個bits用來記錄此格的資料, 後面四個bits用來記錄旁邊的地雷數
private static final byte BOMB = 0x10; // 用以紀錄本格有地雷
private static final byte VISIT = 0x20; // 用以紀錄已按左鍵
private static final byte MARK = 0x40; // 用以紀錄已按右鍵
private static final byte NEB = 0x0f; // 用以取出旁邊的地雷數
void checkWin() {
int width = x + 2;
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
if ((((map[tt] & MARK) > 0) && ((map[tt] & BOMB) == 0)) || (((map[tt] & MARK) == 0) && ((map[tt] & BOMB) > 0))) {
return;
}
}
}
showAll();
showWin();
}
void showAll() {
int width = x + 2;
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i*width;
for (int j=1; j<=y; j++) { // 由左而右
int tt = tmp + j;
if ((map[tt] & BOMB) != 0) { // 畫上標示
map[tt] |= MARK;
} else {
map[tt] = (byte)((map[tt] | VISIT) & ~MARK); // 設為按過, 再把標示拿掉
}
}
}
repaint();
}
void showWin() {
Dialog d;
(d = new Dialog(f, true)).addWindowListener(new CloseWindow(d));
((Button)d.add(new Button("恭喜過關"))).addActionListener(new CloseWindow(d));
d.pack();
d.show();
}
public Dimension getPreferredSize() {
return new Dimension(22*x,22*y);
}
void reset() {
map = new byte[(x+2)*(y+2)];
int width = x + 2;
for (int i = 0; i <= y + 1; i++) { // 由上而下
int tmp = i * width;
for (int j = 0; j <= x + 1; j++) { // 由左而右
int tt = tmp + j;
if (i==0 || i == (x + 1) || j == 0 || j == (y + 1)) {
map[tt] = VISIT; // boundary
} else {
map[tt] = 0; // normal position
}
}
}
// 15%為地雷
for (int i = 0, bombNumber = (int)(x*y*0.15); i < bombNumber;) { // setup bombs
int row = (int)(Math.random()*y)+1;
int col = (int)(Math.random()*x)+1;
int tt = row * width + col;
if ((map[tt] & BOMB) == 0) { // has no bomb yet
i++;
map[tt] |= BOMB;
}
}
// 計算旁邊的地雷數
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
for (int k = 0; k < 8; k++) {
if ((map[tt + directions[k]] & BOMB) != 0) { // 旁有地雷
map[tt]++; // 後面四個bit用來記錄旁邊的地雷數
}
}
}
}
repaint();
}
// 畫出盤面
public void paint(Graphics g) {
g.setColor(Color.red);
for (int i = 1; i <= x; i++) { // 畫縱線
g.drawLine(i*20, 0, i*20, 200);
}
for (int j = 1; j <= y; j++) { // 畫橫線
g.drawLine(0, j*20, 200, j*20);
}
int width = x + 2;
// 畫出每一格目前的狀態
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
if ((map[tt] & VISIT) != 0) { // 已經翻過來了
g.setColor(Color.blue);
if ((map[tt] & NEB) != 0) { // 旁有地雷, show出地雷數
g.drawString(Integer.toString(map[tt] & NEB), j * 20 - 15, i * 20 - 5);
} else { // 沒有地雷, 填空白
g.fillRect((j - 1) * 20, (i - 1) * 20, 20, 20);
}
} else if ((map[tt] & MARK) != 0) { // 已用右鍵做記號
g.setColor(Color.green);
g.fillOval((j - 1) * 20, (i - 1) * 20, 20, 20);
}
}
}
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Exit")) {
System.exit(0);
} else if (command.equals("New Game")) {
reset();
} else {
System.out.println("Unknown Command");
}
}
public Mine2(int x, int y) {
MenuBar mb;
Menu m;
this.x = x;
this.y = y;
int width = y + 2;
directions = new int[8];
directions[0] = 1;
directions[1] = -1;
directions[2] = width;
directions[3] = -width;
directions[4] = -width - 1;
directions[5] = -width + 1;
directions[6] = width - 1;
directions[7] = width + 1;
(f = new Frame("踩地雷")).add(this).addMouseListener(this);
f.addWindowListener(new CloseWindow(f,true));
f.setMenuBar(mb=new MenuBar());
mb.add(m = new Menu("File"));
m.add(new MenuItem("New Game")).addActionListener(this);
m.add(new MenuItem("Exit")).addActionListener(this);
reset();
f.pack();
f.show();
}
void setTouched(int tt) {
map[tt] |= VISIT;
if ((map[tt] & NEB) == 0) { // no bomb around, auto flip
for (int i = 0; i < 8; i++) {
if ((map[tt + directions[i]] & VISIT) == 0) { // 已翻開就不用再做了
setTouched(tt + directions[i]);
}
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
int row = e.getY()/20 + 1;
int col = e.getX()/20 + 1;
int tt = row*(y + 2) + col;
if (row > x || col > y || (map[tt] & VISIT) != 0) { // 超出邊界或已經翻過就不必處理
return;
}
if (e.isMetaDown()) { // 按右鍵, 作個標記就好了
map[tt] ^= MARK;
} else if ((map[tt] & BOMB) != 0) { // 按到地雷了
showAll();
return;
} else {
setTouched(tt);
}
checkWin();
repaint();
}
public static void main(String[] args) {
new Mine2(10,10);
}
}
不管我怎麼改、除錯。 GEL顯示的錯誤都是第五行的:
public static void main(String args[]) {
及 最後一個 } 問遍了同學們 也沒人可以解答QQ
第一次挑戰這麼長的程式(踩地雷) 請問有那位朋友
可以教教我那裡寫錯了?
--
* Origin: 中山大學-美麗之島BBS * From: 59.113.143.144
import java.awt.event.*;
import java.util.Random;
class riavnc
public static void main(String[] args){
private byte[] map; // 以一維陣列來取代二維,以減少物件的使用
private int[] x, y;
private Frame f;
private int[] directions;
// 前四個bits用來記錄此格的資料, 後面四個bits用來記錄旁邊的地雷數
private static final byte BOMB = 0x10; // 用以紀錄本格有地雷
private static final byte VISIT = 0x20; // 用以紀錄已按左鍵
private static final byte MARK = 0x40; // 用以紀錄已按右鍵
private static final byte NEB = 0x0f; // 用以取出旁邊的地雷數
void checkWin() {
int width = x + 2;
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
if ((((map[tt] & MARK) > 0) && ((map[tt] & BOMB) == 0)) || (((map[tt] & MARK) == 0) && ((map[tt] & BOMB) > 0))) {
return;
}
}
}
showAll();
showWin();
}
void showAll() {
int width = x + 2;
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i*width;
for (int j=1; j<=y; j++) { // 由左而右
int tt = tmp + j;
if ((map[tt] & BOMB) != 0) { // 畫上標示
map[tt] |= MARK;
} else {
map[tt] = (byte)((map[tt] | VISIT) & ~MARK); // 設為按過, 再把標示拿掉
}
}
}
repaint();
}
void showWin() {
Dialog d;
(d = new Dialog(f, true)).addWindowListener(new CloseWindow(d));
((Button)d.add(new Button("恭喜過關"))).addActionListener(new CloseWindow(d));
d.pack();
d.show();
}
public Dimension getPreferredSize() {
return new Dimension(22*x,22*y);
}
void reset() {
map = new byte[(x+2)*(y+2)];
int width = x + 2;
for (int i = 0; i <= y + 1; i++) { // 由上而下
int tmp = i * width;
for (int j = 0; j <= x + 1; j++) { // 由左而右
int tt = tmp + j;
if (i==0 || i == (x + 1) || j == 0 || j == (y + 1)) {
map[tt] = VISIT; // boundary
} else {
map[tt] = 0; // normal position
}
}
}
// 15%為地雷
for (int i = 0, bombNumber = (int)(x*y*0.15); i < bombNumber;) { // setup bombs
int row = (int)(Math.random()*y)+1;
int col = (int)(Math.random()*x)+1;
int tt = row * width + col;
if ((map[tt] & BOMB) == 0) { // has no bomb yet
i++;
map[tt] |= BOMB;
}
}
// 計算旁邊的地雷數
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
for (int k = 0; k < 8; k++) {
if ((map[tt + directions[k]] & BOMB) != 0) { // 旁有地雷
map[tt]++; // 後面四個bit用來記錄旁邊的地雷數
}
}
}
}
repaint();
}
// 畫出盤面
public void paint(Graphics g) {
g.setColor(Color.red);
for (int i = 1; i <= x; i++) { // 畫縱線
g.drawLine(i*20, 0, i*20, 200);
}
for (int j = 1; j <= y; j++) { // 畫橫線
g.drawLine(0, j*20, 200, j*20);
}
int width = x + 2;
// 畫出每一格目前的狀態
for (int i = 1; i <= y; i++) { // 由上而下
int tmp = i * width;
for (int j = 1; j <= x; j++) { // 由左而右
int tt = tmp + j;
if ((map[tt] & VISIT) != 0) { // 已經翻過來了
g.setColor(Color.blue);
if ((map[tt] & NEB) != 0) { // 旁有地雷, show出地雷數
g.drawString(Integer.toString(map[tt] & NEB), j * 20 - 15, i * 20 - 5);
} else { // 沒有地雷, 填空白
g.fillRect((j - 1) * 20, (i - 1) * 20, 20, 20);
}
} else if ((map[tt] & MARK) != 0) { // 已用右鍵做記號
g.setColor(Color.green);
g.fillOval((j - 1) * 20, (i - 1) * 20, 20, 20);
}
}
}
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Exit")) {
System.exit(0);
} else if (command.equals("New Game")) {
reset();
} else {
System.out.println("Unknown Command");
}
}
public Mine2(int x, int y) {
MenuBar mb;
Menu m;
this.x = x;
this.y = y;
int width = y + 2;
directions = new int[8];
directions[0] = 1;
directions[1] = -1;
directions[2] = width;
directions[3] = -width;
directions[4] = -width - 1;
directions[5] = -width + 1;
directions[6] = width - 1;
directions[7] = width + 1;
(f = new Frame("踩地雷")).add(this).addMouseListener(this);
f.addWindowListener(new CloseWindow(f,true));
f.setMenuBar(mb=new MenuBar());
mb.add(m = new Menu("File"));
m.add(new MenuItem("New Game")).addActionListener(this);
m.add(new MenuItem("Exit")).addActionListener(this);
reset();
f.pack();
f.show();
}
void setTouched(int tt) {
map[tt] |= VISIT;
if ((map[tt] & NEB) == 0) { // no bomb around, auto flip
for (int i = 0; i < 8; i++) {
if ((map[tt + directions[i]] & VISIT) == 0) { // 已翻開就不用再做了
setTouched(tt + directions[i]);
}
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
int row = e.getY()/20 + 1;
int col = e.getX()/20 + 1;
int tt = row*(y + 2) + col;
if (row > x || col > y || (map[tt] & VISIT) != 0) { // 超出邊界或已經翻過就不必處理
return;
}
if (e.isMetaDown()) { // 按右鍵, 作個標記就好了
map[tt] ^= MARK;
} else if ((map[tt] & BOMB) != 0) { // 按到地雷了
showAll();
return;
} else {
setTouched(tt);
}
checkWin();
repaint();
}
public static void main(String[] args) {
new Mine2(10,10);
}
}
不管我怎麼改、除錯。 GEL顯示的錯誤都是第五行的:
public static void main(String args[]) {
及 最後一個 } 問遍了同學們 也沒人可以解答QQ
第一次挑戰這麼長的程式(踩地雷) 請問有那位朋友
可以教教我那裡寫錯了?
--
* Origin: 中山大學-美麗之島BBS * From: 59.113.143.144