其实五子棋呢主要包括三部分:五子棋棋盘和下棋子等关于Swing界面的应用;然后就是计算输赢的算法;最后就是人机对战的人工智能。刚刚开始做的时候是老老实实的画的棋盘,通过后来的学习知道了其实棋盘是可以找合适的棋盘图片粘贴的,目前还没找到想要的。。。。。。画棋盘就是一个循环画线的过程:
//画格子的方法
private void drawchessbosrd(java.awt.Graphics g){
//设置线条颜色
g.setColor(java.awt.Color.BLACK);
//循环画横线
for(int i=0;i<Config.H_LINE;i++){
g.drawLine(Config.X, Config.Y+i*Config.SIZE, Config.X+(Config.S_LINE-1)*Config.SIZE, Config.Y+i*Config.SIZE);
}
//循环画竖线
for(int i=0;i<Config.S_LINE;i++){
g.drawLine(Config.X+i*Config.SIZE, Config.Y, Config.X+i*Config.SIZE, Config.Y+(Config.S_LINE-1)*Config.SIZE);
}
}
现在呢,棋盘有了,我们就需要在鼠标点击的格子交叉处下棋子,刚开始的棋子也是在窗体上得到一个画板然后画一个实心圆......后来学会了在那交叉点上画一个棋子的图片,图片怎么看上去也比一个平面圆有立体感啊!画图片的之前当然的计算出交叉点的坐标,这样才能在离点击的最近的地方画图片:
//点击鼠标得到坐标
int x1=e.getX();
int y1=e.getY();
//计算离鼠标点击地点最近的一个交叉点
if((x1-Config.X)%Config.SIZE<Config.SIZE/2){
j=(x1-Config.X)/Config.SIZE;
}else if((x1-Config.X)%Config.SIZE>Config.SIZE/2){
j=(x1-Config.X)/Config.SIZE+1;
}else{
j=(x1-Config.X-Config.SIZE/2)/Config.SIZE;
}
if((y1-Config.Y)%Config.SIZE<Config.SIZE/2){
i=(y1-Config.Y)/Config.SIZE;
}else if((y1-Config.Y)%Config.SIZE>Config.SIZE/2){
i=(y1-Config.Y)/Config.SIZE+1;
}else{
i=(y1-Config.Y-Config.SIZE/2)/Config.SIZE;
}
//开始下棋子,只能在没有下棋子的地方下
if(data[i][j]==0){
if(count==1){//在交叉点下黑子
//在交叉点画一个圆
URL url=this.getClass().getResource("b.png");
//根据url创建图片对象
ImageIcon imageb=new ImageIcon(url);
g.drawImage(imageb.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2,
Config.CHESS, Config.CHESS,back); count++;
}
}else{//在交叉点下白子 //在交叉点画一个圆
URL url=this.getClass().getResource("w.png");
//根据url创建图片对象
ImageIcon imagew=new ImageIcon(url);
g.drawImage(imagew.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2,
Config.CHESS, Config.CHESS,back);
count--;
}
}
}
现在呢,棋子画上去了,我们就要判断一下输赢了。判断输赢的条件就是五子连珠,一颗棋子周围大家都知道有八个方向,所以呢就要向八个方向判断一下是否有相同的棋子,如果有就继续判断,一直到某个方向上有五颗相同的棋子,让程序输出一下输赢了就ok咯。判断输赢的方法大致都是一样的:
public boolean horizontalWin(int r,int c) {
//定义一个计数器,默认等于,当前下的棋子
int count = 1;
boolean state = false;
//循环遍历数组,此处是遍历当前行的每一个单元格,现在是往右边判断
for(int j=c+1;j<chesses[r].length;j++){
//判断当前数组中的元素是否想等
if(chesses[r][j] == chesses[r][c])
//相等计数器加1
count++;
//不相等,则退出循环
else
break;
}
//循环遍历数组,此处是遍历当前行的每一个单元格,现在是往左边判断
for(int j=c-1;j>0;j--){
//判断当前数组中的元素是否想等
if(chesses[r][j] == chesses[r][c])
//相等计数器加1
count++;
//不相等,则退出循环
else
break;
}
//如果统计的数据大于4,就表示已经五颗相同颜色的棋子连在一起了,表示已经赢了
if(count > 4)
//状态修改为true.
state = true;
//}
//返回状态
return state;
}
不同的是每个方向的循环方式不一样而已,当有五颗棋子连珠的时候,就可以显示输赢了,显示之后当然要清空棋盘:
if(win.erectWin(i,j)||win.horizontalWin(i, j)||win.leftObliqueWin(i, j)||win.rightObliqueWin(i, j)){
javax.swing.JOptionPane.showMessageDialog(null,
"黑子赢了(*^__^*) " );
for(int i=0;i<data.length;i++){
for(int j=0;j<data[i].length;j++){
data[i][j]=0;
}
}
paint(g);
}
然而这时的五子棋还有很多不完善,比如:重绘等等,所以我们在下棋子的时候一定要用一个东西来保存当前棋子的信息,这个东西可以是二维数组,也可以是自定义队列,有了保存棋子的东西,那么重绘也就很简单了。如果我们想保存某一局棋局的时候,就需要用到文件保存了,吧当前棋局的所有信息存入一个文件中,读取的按照信息进行重绘:
public void savefile(int[][] data) {
//保存的文件名
String filename="src\\cn\\tan\\lesson6\\chess";
try {
//新建输出流对象
FileWriter fw = new FileWriter(filename);
//循环输出数据
for(int i=0;i<data.length;i++){
for(int j=0;j<data[i].length;j++){
fw.write(data[i][j]+"\t");
}
fw.write("\r\n");
}
//强制写入并关闭流对象
fw.flush();
fw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
打开文件时的方法:
open.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String command=e.getActionCommand();
if(command.equals("打开文件")){
String s = "";
//读取文件文件名
String fielname="src\\cn\\tan\\lesson6\\chess";
try {
//新建输入流对象
FileReader fr=new FileReader(fielname);
BufferedReader br=new BufferedReader(fr);
int [][] set=new int[12][12];
for(int i=0;i<set.length;i++){
s=br.readLine();
String value[]=s.split("\t");
// paint(g);
for(int j=0;j<set.length;j++){
//得到第i行j列的元素值
int m=Integer.parseInt(value[j]);
data[i][j]=m;
if(m==1){
//设置颜色
g.setColor(java.awt.Color.WHITE);
//画棋子
URL url=this.getClass().getResource("w.png");
//根据url创建图片对象
ImageIcon imagew=new ImageIcon(url);
g.drawImage(imagew.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2,
Config.CHESS, Config.CHESS,back);
}
if(m==2){
//设置颜色
// g.setColor(java.awt.Color.BLACK);
//画棋子
URL url=this.getClass().getResource("b.png");
//根据url创建图片对象
ImageIcon imageb=new ImageIcon(url);
g.drawImage(imageb.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2,
Config.CHESS, Config.CHESS,back); }
}
}
fr.close();
br.close();
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
当然还有其他的比如重新开始、悔棋等功能就不再一一列举代码咯......至于人机对战仍在思索ing