连连看  一个buttonExp数组g[12][12]存储120个按钮,中每个按钮有两个成员变量 imageID 和 isClear 数组边上一圈留白,中间的根据随即的数字(1-36)设置对应的Icon,并加入网格中显示出来,问题是 加载的Icon和按钮的imageID不一致。事件触发时再次根据imageID加载Icon依旧不一致 我现在的程序是只要两个按钮imageID一样,就可以消去,但是就是因为Icon,imageID不一致,所以会有显示图标一致 但是依旧消不去   求解另外消去 我的算法复杂度是n^2 非递归  急等解决此问题啊请各位指点啊 以下是程序。。import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import javax.swing.*;/*
 * 连连看
 */public class LLK
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run() 
{
LLKFrame frame = new LLKFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}class LLKFrame extends JFrame
{
/**
 * 
 */
private static final long serialVersionUID = -2838734276836949965L; public LLKFrame()
{
setTitle("连连看");
setSize(600, 600);
LLKPanel panel = new LLKPanel();
add(panel);
}
}class LLKPanel extends JPanel
{
/**
 * 
 */
private static final long serialVersionUID = 830308310004194846L;
//面板初始化
private JPanel confirmPanel;
private buttonpanel panel;//重写这个panel 背景
private JButton display;
private JButton quit;

/*有待添加
private JButton suggest;//提示<----------------------------------------
private JLabel ;//累计分数<----------------------------------------
private JLabel time;//倒计时<----------------------------------------
private JPanel x;//自选大小<-------------------------------------
//消去后图像变化
//无解的策略 每步遍历 纪律一组listA 相应的listB 遍历求解 若遍历后无解则死局 随即相同子数重部
*/

//数据域
private int digRightCount;//标志正确的点数
private buttonExp preButton;//前一个按下的按钮 初始化为空 消去后为空 空后点击为该按钮
private ImageIcon background;//背景图片
private List<ImageIcon> imageList;//用于存储未选择图片对象
private List<ImageIcon> imageListB;//用于存储被选择图片对象

private buttonExp [][] g;//存储100个图标

//轻度包装的Button
class buttonExp extends JButton
{
/**
 * 
 */
private static final long serialVersionUID = -805416125906085267L;
public int imageID;//边框内点为图片编号 [1,36]的随机数  边框上为 -1
public boolean isCleared;

public buttonExp()
{
super();
imageID = 0;
isCleared = false;
}
}

//初始化有背景的面板
class buttonpanel extends JPanel
{
/**
 * 
 */
private static final long serialVersionUID = -8449729785897799869L;
private ImageIcon background;

public buttonpanel(ImageIcon background)
{
this.background = background;
}

protected void paintComponent(Graphics graphics)

setOpaque(true);
super.paintComponent(graphics);
Dimension d = getSize();
for (int x = 0; x < d.width; x += background.getIconWidth())
for (int y = 0; y < d.height; y += background.getIconHeight())
graphics.drawImage(background.getImage(), x, y, null, null);
}
}

public LLKPanel()
{
//数据域初始化
digRightCount = 0;

preButton = null;

//载入背景图片
java.net.URL imgURL1 = LLK.class.getResource("/background.gif"); 
background = new ImageIcon(imgURL1); 

//导入图像
imageList = new LinkedList<ImageIcon>();
for (int i = 0; i < 36; i++)
{
String add = "/" + Integer.toString(i + 1, 10) + ".gif"; 
java.net.URL imgURL = LLK.class.getResource(add); 
ImageIcon imageIcon = new ImageIcon(imgURL);
imageList.add(imageIcon);
}

imageListB = new LinkedList<ImageIcon>();
for (int i = 0; i < 36; i++)
{
String add = "/" + Integer.toString(i + 1, 10) + "B.gif"; 
java.net.URL imgURL = LLK.class.getResource(add); 
ImageIcon imageIcon = new ImageIcon(imgURL);
imageListB.add(imageIcon);
}

setLayout(new BorderLayout());

//添加一个panel 上面有重新开始按钮
confirmPanel = new JPanel();

display = new JButton("重新开始");
display.addActionListener(new choiceAction(1));
confirmPanel.add(display);

quit = new JButton(" 退出 ");
quit.addActionListener(new choiceAction(2));
confirmPanel.add(quit);

add(confirmPanel, BorderLayout.NORTH);


//12*12的方格
panel = new buttonpanel(background);
panel.setLayout(new GridLayout(10, 10));

g = new buttonExp[12][12];

//初始化为白板
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
g[i][j] = new buttonExp();
}
}

//框内加入面板 添加事件响应 改变图标
for (int i = 1; i < 11; i++)
{
for (int j = 1; j < 11; j++)
{
buttonAction listener = new buttonAction(i, j);
g[i][j].addActionListener(listener);
panel.add(g[i][j]);
}
}
add(panel,BorderLayout.CENTER);


//开始成对撒图片
List<buttonExp> addedButtom = new LinkedList<buttonExp>();

Random ran = new Random();
int count = 0;
while(true)
{
if (count == 50)
break;

int x1 = ran.nextInt(10) + 1;
int y1 = ran.nextInt(10) + 1;

int x2 = ran.nextInt(10) + 1;
int y2 = ran.nextInt(10) + 1;

//两个重合
if (x1 == x2 && y1 == y2)
continue;

//在这一轮前若已包含这个两个点
if (addedButtom.contains(g[x1][y1]) == true)
continue;
if (addedButtom.contains(g[x2][y2]) == true)
continue;

//随即获取图标编号
int imageRan = ran.nextInt(36);

g[x1][y1].imageID = imageRan;
g[x2][y2].imageID = imageRan;

g[x1][y1].setIcon(imageList.get(imageRan));
g[x2][y2].setIcon(imageList.get(imageRan));

//已经设置图片按钮入栈
addedButtom.add(g[x1][y1]);
addedButtom.add(g[x2][y2]);
count++;
}
}

class buttonAction implements ActionListener
{
private int row;
private int line;

public buttonAction(int r, int l)
{
row = r;
line = l;
}

public void actionPerformed(ActionEvent e)
{
buttonExp button = g[row][line];

//是否已经清除
if (button.isCleared == true)
return;

//之前是否有按钮被标记
if (preButton == null)
{
preButton = button;
button.setIcon(imageListB.get(button.imageID));
return;
}

//两次同一个按钮
if (preButton == button)
{
preButton.setIcon(imageList.get(preButton.imageID));
preButton = null;
return;
}

System.out.println("pre:" + preButton.imageID + " " + " post:" + button.imageID);

//两按钮是否图片相同
if (button.imageID != preButton.imageID)
{
preButton.setIcon(imageList.get(preButton.imageID));
preButton = null;
Toolkit.getDefaultToolkit().beep();
return;
}

//是否可消
if (isRight(preButton, button) == true)
{
//按钮enable 图标设空
preButton.setEnabled(false);
button.setEnabled(false);
preButton.setIcon(null);
button.setIcon(null);

button.setContentAreaFilled (false);
preButton.setContentAreaFilled (false);
button.setBorder(null);
preButton.setBorder(null);

preButton.isCleared = true;
button.isCleared = true;

preButton = null;
digRightCount++;

if (digRightCount == 50)
JOptionPane.showMessageDialog(null, "你赢了");
}
else
{
preButton.setIcon(imageList.get(preButton.imageID));
button.setIcon(imageListB.get(preButton.imageID));
preButton = null;
Toolkit.getDefaultToolkit().beep();
}
}
}

public boolean isRight(buttonExp Start, buttonExp End)
{
return true;
}


//处理那两个按钮重新开始和退出
class choiceAction implements ActionListener 
{
public int x;

public choiceAction(int i)
{
x = i;
}

public void actionPerformed(ActionEvent event)
{
if (x == 1)
{
//数据域初始化
digRightCount = 0; preButton = null; //初始化为白板
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
g[i][j].imageID = 0;
g[i][j].isCleared = false;
}
} //成对撒图片
List<buttonExp> addedButtom = new LinkedList<buttonExp>(); Random ran = new Random();
int count = 0;
while(true)
{
if (count == 50)
break;

int x1 = ran.nextInt(10) + 1;
int y1 = ran.nextInt(10) + 1;

int x2 = ran.nextInt(10) + 1;
int y2 = ran.nextInt(10) + 1;

//两个重合
if (x1 == x2 && y1 == y2)
continue;

//在这一轮前若已包含这个两个点
if (addedButtom.contains(g[x1][y1]) == true)
continue;
if (addedButtom.contains(g[x2][y2]) == true)
continue;

//随即获取图标编号
int imageRan = ran.nextInt(36);
g[x1][y1].setIcon(imageList.get(imageRan));
g[x2][y2].setIcon(imageList.get(imageRan));

g[x1][y1].imageID = imageRan;
g[x2][y2].imageID = imageRan;

g[x1][y1].setEnabled(true);
g[x2][y2].setEnabled(true);

//已经设置图片按钮入栈
addedButtom.add(g[x1][y1]);
addedButtom.add(g[x2][y2]);
count++;
}
}

if (x == 2)
System.exit(0);
}
}

}

解决方案 »

  1.   

    实际验证过之后,我认为,代码没有问题,可能是你导入的图片有重复的。所以你觉得是点击了相同的图片,但是实际上图片Image_ID不一致。建议你把你所有的图片都查对一下
      

  2.   


    开始学的是c/c++ 对for_each不感冒 写的老长。。  能用两句写的我一般不缩到一行 见笑见笑
      

  3.   


    查了图片没问题 在整个过程中 imageID没有变化 就是在g[row][line]设置icon的时候不对了 而且这个不对的地方还是随机的 在buttonExp消息响应的地方我再次根据imageID设置icon 依旧无法解决
    我用getsource的方法取得点击的对象button 再button.setIcon(imageList.get(button.imageId))这样依旧无法使button的icon成为imageId所代表的icon  求解
      

  4.   

    我把你程序裡的圖都拿掉,改用 imageId當文字顯示,執行起來一切正常。
      

  5.   

    还不错。我自己配了图片,感觉还行。
    一点意见:
    好像路径算法有问题,只要点的是一样的图片,不通的也能消另外,好像没有必要定义两个图标List吧,一个15.gif,一个15b.gif,我将它们改成同一个图片了。