其中,代码中所定义的常量是为代码修改容易而设。为了界面美观,稍稍修改一下CBboard的border属性,打开该属性框,然后在“可用边框”里选择“BevelBorder”。
注意:现在还无法看到所设计的棋盘,原因是JPanel不是顶层容器,所以还要为它建一个顶层容器,而这个容器在2中已经建好了。可以在Chessboard里预览一下效果(需要注释掉Chessboard里的一些代码),预览效果如图1。

棋盘实现了,就可以在上面添加棋子了。为了实现下棋,采取的措施是预先在棋盘上15*15个下棋点处分别放置一个透明的无边框的按钮,玩棋时再根据落子方的不同分别加载上黑子或白子图片。具体实现分为如下四步:
第一步:创建15*15个按钮。代码如下:
private JButton[][] jb=new JButton[Model.MaxlineY][Model.MaxlineX];//预先放在棋盘上的棋子
其中,Model.MaxlineY与Model.MaxlineX在3.1中已定义。
第二步:设置按钮的属性为透明和无边框。代码如下:
private void initJB(){
//初始化棋子属性
for(int i=0;i<Model.MaxlineY;i++)
for(int j=0;j<Model.MaxlineX;j++){
jb[i][j]=new JButton();
jb[i][j].setBorder(null); //无边框
jb[i][j].setContentAreaFilled(false); //透明
}
}
第三步:把棋子放入棋盘。代码如下:
private void putJB(){
//把棋子放在cbBoard里
for(int i=0;i<Model.MaxlineY;i++)
for(int j=0;j<Model.MaxlineX;j++)
add(jb[i][j]);
}
第四步:移动棋子到落子点。代码如下:
private void setLocationJB(){
//把jb放在适当的位置
int locationI=0,locationJ=0;
for(int i=0;i<Model.MaxlineY;i++,locationI+=30){
locationJ=0;
for(int j=0;j<Model.MaxlineX;j++,locationJ+=30){
jb[i][j].setBounds(locationI,locationJ,30,30);
jb[i][j].addActionListener(this); //给按钮注册事件监听器(后面会用到)
}
}
}
到此为止,棋盘的基本布局就完成了。还需要建一个二维数组,用于存储当前棋局。代码如下:
private int[][] chess=new int[Model.MaxlineY][Model.MaxlineX]; //存储当前棋局
然后,对它进行初始化,赋初值为0。代码如下:
private void initChess(){
//初始化棋局
for(int i=0;i<Model.MaxlineY;i++)
for(int j=0;j<Model.MaxlineX;j++)
chess[i][j]=0;
}
为了让上面所做的工作在CBboard面板被加载时就能够进行,把上述函数加在初始化函数里。代码如下:
public CBboard() {
initComponents();
initChess();
initJB();
putJB();
setLocationJB();
//选项设置,供读者参考
}
接下来要做的是,为棋盘上的按钮添加事件,使它能够响应鼠标点击,实现落子。分三步实现:
(1) 使CBboard类实现ActionListener接口。实现如下:
把”public class CBboard extends javax.swing.JPanel”代码改为” public class CBboard extends javax.swing.JPanel implements ActionListener”。
(2) 注册监听器。在3“第四步”处已经实现。
(3) 监听事件,实现落子。实现代码如下:
public void actionPerformed(ActionEvent ae){
int i,j; //纪录被点击棋子的位置
for(i=0;i<Model.MaxlineY;i++)
for(j=0;j<Model.MaxlineX;j++)
if(ae.getSource()==jb[i][j]){ //找到玩家点击的位置
setChess(i,j,2); //玩家落子
if(suanf.isWin(2)) //如果玩家赢,下同
afterWin(2);
else{ //玩家未赢
suanf.countchessLocation(sij); //电脑找到落子的最佳位置
setChess(sij[0],sij[1],1); //电脑落子
if(suanf.isWin(1)) //如果电脑赢
afterWin(1);
}
}
}
private suanfa suanf=new suanfa();//定义算法类,suanfa类后面会讲到
private int[] sij=new int[2];//纪录最佳位置
读者可能注意到,在上面的代码中有两个函数setChess与afterWin尚未定义。就来定义它们。
|