扫雷中雷数为0的怎样递归的去实现周围有0的一起显示?

cjh_tostring 2012-07-26 05:26:40

public class ShaoLei extends JFrame implements ActionListener {
public JButton[][] jbu = new JButton[15][20];
public static int[][] number = new int[15][20];// 有雷 的坐标保存为1,无雷为0
public static int[][] numberL = new int[15][20];// 对应坐标为周围雷的数量,如果该坐标是雷,保存为9
public int[][] xy = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 },
{ 1, 0 }, { 1, -1 }, { 0, -1 } };// 该数组对应了相应坐标周围的8个坐标的加减

public ShaoLei() {
setTitle("一個簡單的掃雷實現");
setBounds(100, 100, 1000, 800);
init();
setVisible(true);
setLayout(new GridLayout(15, 20));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void init() {
printQP();// 生成按钮
initNumber();// 随机生成50个雷
countL();// 该方法用来计算对应坐标周围雷的数量,并保存到numberL 数组
}

// 随机生成50个雷
public void initNumber() {
int x = (int) (Math.random() * 15);
int y = (int) (Math.random() * 20);
int i = 0;
while (i < 50) {
if (i == 0) {
number[x][y] = 1;
} else {
while (number[x][y] == 1) {// 如果该位置已经有雷则重新生成x和y,则到没有和前面的重复
x = (int) (Math.random() * 15);
y = (int) (Math.random() * 20);
}
number[x][y] = 1;
}
i++;
}
}

// 生成按钮
public void printQP() {
for (int i = 0; i < jbu.length; i++) {
for (int j = 0; j < jbu[i].length; j++) {
jbu[i][j] = new JButton();
jbu[i][j].addActionListener(this);
add(jbu[i][j]);
}
}
}

// 该方法用来计算雷的数量
public void countL() {
for (int i = 0; i < number.length; i++) {
for (int j = 0; j < number[i].length; j++) {
int sumT = 0;//计数每个坐标周围的雷数
if (number[i][j] == 0) {// 如果不是雷则对该坐标周围的8个按钮进行判断
for (int k = 0; k < xy.length; k++) {// 循环8次
int[] tempXY = xy[k];
int TX = i + tempXY[0];// 每次循环的X坐标
int TY = j + tempXY[1];// 每次循环的Y坐标
if (TX >= 0 && TY >= 0 && TX <= 14 && TY <= 19) {// 如果越界就不计算在内
if (number[TX][TY] == 1) {// 如果该坐标是雷则sumT加 1
sumT++;
}
}
}
numberL[i][j] = sumT;// 将计算出的改坐标的累的数量保存到numberL数组
} else if (number[i][j] == 1) {//如果该坐标有雷,则将该数组的该处保存为9
numberL[i][j] = 9;
}

}
}
}

@Override
public void actionPerformed(ActionEvent e) {
JButton jb = (JButton) e.getSource();
int x = 0, y = 0;
for (int i = 0; i < jbu.length; i++)
for (int j = 0; j < jbu[i].length; j++) {
if (jbu[i][j].equals(jb)) {// 找到对于的按钮
x = i;
y = j;
}
}
if (number[x][y] == 1) {
for (int i = 0; i < number.length; i++)
for (int j = 0; j < number[i].length; j++) {
if (number[i][j] == 1) {
x = i;
y = j;
jbu[x][y].setText("雷");
jbu[x][y].setBackground(Color.red);// 有雷就将该按钮设置为红色
}
}
} else {
if (numberL[x][y] == 0) {//如果该坐标的雷数量为0,则将周围的8个按钮一起显示
space(x, y);
}
jbu[x][y].setText("" + numberL[x][y]);// 设置按钮的文本为周围雷的数量
jbu[x][y].setBackground(Color.blue);// 无雷就将按钮设置为蓝色
}
}

//设置显示对应的x,y坐标周围的8个按钮
public void space(int x, int y) {
for (int i = 0; i < xy.length; i++) {
int[] tempXY = xy[i];
int TX = x + tempXY[0];// 每次循环的X坐标
int TY = y + tempXY[1];// 每次循环的Y坐标
if (TX >= 0 && TY >= 0 && TX <= 14 && TY <= 19) {
/*if (numberL[TX][TY] == 0) {
space(TX, TY);此处想用递归去处理8个坐标中是否有雷数为0的
}*/
jbu[TX][TY].setText("" + numberL[TX][TY]);// 设置按钮的文本为周围雷的数量
jbu[TX][TY].setBackground(Color.blue);// 无雷就将按钮设置为蓝色
}
}
}

public static void main(String args[]) {
new ShaoLei();
System.out.println("-------------有雷的坐标为1-------------------");
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 20; j++) {
System.out.print(number[i][j] + " ");
}
System.out.println();
}
System.out.println("----------对应坐标周围雷的数量-------------------");

for (int i = 0; i < 15; i++) {
for (int j = 0; j < 20; j++) {
System.out.print(numberL[i][j] + " ");
}
System.out.println();
}
}

}


注释的地方为我想用递归去判断的地方,这个我不知道能不能算是递归,如果不能用递归的话,用什么办法能解决呢。
...全文
635 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
shangzhihaohao 2012-07-28
  • 打赏
  • 举报
回复
三楼是个死循环。
shangzhihaohao 2012-07-28
  • 打赏
  • 举报
回复
用洗牌算法随机生成雷会好点
程序员一灯 2012-07-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

真怀念啊,当年似乎是高三就写过这个东西。

递归调用即可。
[/Quote]

大神。你高中就。。。。
还有你几年。。。工作经验?
cjh_tostring 2012-07-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

用洗牌算法随机生成雷会好点
[/Quote]
能给个例子吗算法
cjh_tostring 2012-07-27
  • 打赏
  • 举报
回复
感谢2楼,感谢5楼
2楼的循环 for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++)这个当初没想到,就直接用数组来代替了,特别感谢5楼!顺便仰望下4楼。
chenjihong1989 2012-07-27
  • 打赏
  • 举报
回复

public class ShaoLei extends JFrame implements ActionListener {
public JButton[][] jbu = new JButton[15][20];
public static int[][] number = new int[15][20];// 有雷 的坐标保存为1,无雷为0
int[][] numberTemp=new int[15][20];//增加一个数组来对应坐标为周围雷的数量
public static int[][] numberL = new int[15][20];// 对应坐标为周围雷的数量,如果该坐标是雷,保存为9
public int[][] xy = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 },
{ 1, 0 }, { 1, -1 }, { 0, -1 } };// 该数组对应了相应坐标周围的8个坐标的加减

public ShaoLei() {
setTitle("一個簡單的掃雷實現");
setBounds(100, 100, 1000, 800);
printQP();// 生成按钮
initNumber();// 随机生成50个雷
countL();// 该方法用来计算对于坐标雷的数量
setVisible(true);
setLayout(new GridLayout(15, 20));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

// 随机生成50个雷
public void initNumber() {
int x = (int) (Math.random() * 15);
int y = (int) (Math.random() * 20);
int i = 0;
while (i < 70) {
if (i == 0) {
number[x][y] = 1;
} else {
while (number[x][y] == 1) {// 如果该位置已经有雷则重新生成x和y,则到没有和前面的重复
x = (int) (Math.random() * 15);
y = (int) (Math.random() * 20);
}
number[x][y] = 1;
}
i++;
}
}
// 生成按钮
public void printQP() {
for (int i = 0; i < jbu.length; i++) {
for (int j = 0; j < jbu[i].length; j++) {
jbu[i][j] = new JButton();
jbu[i][j].addActionListener(this);
add(jbu[i][j]);
}
}
}
// 该方法用来计算雷的数量
public void countL() {
for (int i = 0; i < number.length; i++) {
for (int j = 0; j < number[i].length; j++) {
int sumT = 0;// 计数每个坐标周围的雷数
if (number[i][j] == 0) {// 如果不是雷则对该坐标周围的8个按钮进行判断
for (int k = 0; k < xy.length; k++) {// 循环8次
int[] tempXY = xy[k];
int TX = i + tempXY[0];// 每次循环的X坐标
int TY = j + tempXY[1];// 每次循环的Y坐标
if (TX >= 0 && TY >= 0 && TX <= 14 && TY <= 19) {// 如果越界就不计算在内
if (number[TX][TY] == 1) {// 如果该坐标是雷则sumT加 1
sumT++;
}
}
}
numberL[i][j] = sumT;// 将计算出的改坐标的累的数量保存到numberL数组
numberTemp[i][j]=sumT;
} else if (number[i][j] == 1) {// 如果该坐标有雷,则将该数组的该处保存为9
numberL[i][j] = 9;
}
}
}
}

@Override
public void actionPerformed(ActionEvent e) {
JButton jb = (JButton) e.getSource();
int x = 0, y = 0;
for (int i = 0; i < jbu.length; i++)
for (int j = 0; j < jbu[i].length; j++) {
if (jbu[i][j].equals(jb)) {// 找到对应的按钮
x = i;
y = j;
}
}
if (number[x][y] == 1) {
for (int i = 0; i < number.length; i++)
for (int j = 0; j < number[i].length; j++) {
if (number[i][j] == 1) {
x = i;
y = j;
jbu[x][y].setText("雷");
jbu[x][y].setBackground(Color.gray);// 有雷就将该按钮设置为红色
}
}
} else {
if (numberTemp[x][y] == 0) {// 如果该坐标的雷数量为0,则将周围的8个按钮一起显示
numberTemp[x][y]=-1;//每次将该位置标记为-1,让其不参加下次循环
space(x, y);
}
jbu[x][y].setText("" + numberL[x][y]);// 设置按钮的文本为周围雷的数量
jbu[x][y].setBackground(Color.white);// 无雷就将按钮设置为蓝色
}
}

// 设置显示对应的x,y坐标周围的8个按钮
public void space(int x, int y) {
for (int i = 0; i < xy.length; i++) {
int[] tempXY = xy[i];
int TX = x + tempXY[0];// 每次循环的X坐标
int TY = y + tempXY[1];// 每次循环的Y坐标
if (TX >= 0 && TY >= 0 && TX <= 14 && TY <= 19) {
if (numberTemp[TX][TY] == 0) {
numberTemp[TX][TY]=-1;//每次将该位置标记为-1,让其不参加下次循环
space(TX, TY);//此处想用递归去处理8个坐标中是否有雷数为0的
}
jbu[TX][TY].setText("" + numberL[TX][TY]);// 设置按钮的文本为周围雷的数量
jbu[TX][TY].setBackground(Color.white);// 无雷就将按钮设置为蓝色
}
}

}

public static void main(String args[]) {
new ShaoLei();
}
}



楼上好强大,我高三的时候还在天天玩,赌博,喝酒,打架呢,现才到了一个坑爹的大学啊,真后悔啊。
MiceRice 2012-07-27
  • 打赏
  • 举报
回复
真怀念啊,当年似乎是高三就写过这个东西。

递归调用即可。
wangdong20 2012-07-27
  • 打赏
  • 举报
回复
写错了,笔误了
这里应该再加一个方法,判断一个按钮周围8个是不是都没有雷
boolean isSpace(int x, int y){ // lz同样要注意越界问题
for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++){
if(jbu[x + i][y + j] == 1){
return false;
}
}
}
return true;
}



void countL(int x, int y){
for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++){
if(x + i > jbu.length || x + i < 0 // lz要注意越界问题
|| y +j > jbu.length || y + j < 0){
break;
}
if(isSpace(x + i, y + j)){ // 如果无雷就继续递归,
scanner(x + i, y + j);
countL(x + i, y + j); // 再次调用countL()方法
}
}
}
}
raistlic 2012-07-27
  • 打赏
  • 举报
回复
跟围棋提子问题差不多,可以用 Set<Point>
wangdong20 2012-07-27
  • 打赏
  • 举报
回复
lz可以这样,写一个函数实现总体递归,再写一个函数实现扫描8个方法

void scanner(int x, int y){ // 扫描周围8个按钮的方法
for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++ ){
if(i != 0 && j != 0){
if(jbu[x + i][y + j] == 0){
jbu[x + i][y + j].setText("" + numberL[TX][TY]);// 设置按钮的文本为周围雷的数量
jbu[x + i][y + j].setBackground(Color.blue);// 无雷就将按钮设置为蓝色
}
else{
jbu[x + i][y + j].setText("雷");
jbu[x + i][y + j].setBackground(Color.red);// 有雷就将该按钮设置为红色
}
}
}
}
}

再来就是递归了
void countL(int x, int y){
for(int i = -1; i <= 1; i++){
for(int j = -1; j <= 1; j++){
if(x + i > jbu.length || x + i < 0 // lz要注意越界问题
|| y +j > jbu.length || y + j < 0){
break;
}
if(jbu[x + i][y + j] == 0){ // 如果无雷就继续递归,
scanner(x + i, y + j);
}
}
}
}

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧