import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* @author 管超
* 2009年8月26日
* tips:算法并非尽善尽美,有待改进的地方还有很多
*/
public class Test090826 extends Applet implements ActionListener,MouseListener
{
String str="人机对弈的五子棋游戏";
Dimension currentPos=new Dimension();//用于后来计算x、y的值
int chessBoard[][]=new int[15][15];//存储棋局的数组以0、1、2分别别代表空格、我方棋子、敌方棋子
int x=20,y=20;//由鼠标监视器返回值计算得到的坐标
int valueOfPresent[][]=new int[15][15];//保存每个点的当前值,再在其中选取最大值落点
int presentStatus[][][][]=new int[15][15][4][2];//当前状态记录 4 个方向 同色棋子的数目及是否被堵死
int locationX, locationY;//下一步落点的坐标
boolean finish1=false,finish2=false;//判断是否结束
int numOfLeft , leftBarrier , leftBlank;
int numOfRight , rightBarrier , rightBlank;
int numOfUp , upBarrier , upBlank;
int numOfDown , downBarrier , downBlank;
int numOfLu , luBarrier , luBlank;
int numOfLd , ruBarrier , ruBlank;
int numOfRu , ldBarrier , ldBlank;
int numOfRd , rdBarrier , rdBlank;
public void init()
{
addMouseListener(this);
for(int i=0;i<=14;i++)
{
for(int j=0;j<=14;j++)
chessBoard[i][j]=0;
}
}
public static void main(String[] args)
{
JFrame frame=new JFrame("人机对弈的五子棋游戏");
Test090826 applet=new Test090826();
frame.getContentPane().add(applet,BorderLayout.CENTER);
applet.init();
applet.start();
frame.setVisible(true);
}
public void paint(Graphics g)
{
int x0=30,y0=50,dx=30,dy=30,N=14,M=14;
int x1,y1,x2,y2;
g.setColor(Color.black);
y1=y0;
y2=y0+M*dy;
for(int i=0;i<=N;i++)
{
x1=x0+i*dx;
g.drawLine(x1,y1,x1,y2);
}
g.setColor(Color.black);
x1=x0;
x2=x0+N*dx;
for(int j=0;j<=M;j++)
{
y1=y0+j*dy;
g.drawLine(x1,y1,x2,y1);
}
g.setColor(Color.black);
g.setFont(new Font("TimesRoman",Font.BOLD,25));
g.drawString(str,120,30);
g.setColor(Color.red);
g.fillOval(600,60,20,20); g.drawString(" : 我棋子的颜色",610,80);
g.setColor(Color.blue);
g.fillOval(600,100,20,20); g.drawString(" : 您棋子的颜色",610,120);
if(finish2)
{
if(!finish1)
{
g.setColor(Color.red);
g.drawString("你赢了!恭喜你!",150,550);
}
}
if(finish1)
{
g.setColor(Color.red);
g.drawString("你输了,再接再厉吧",150,550);
}
for(int i=0;i<=14;i++)
for(int j=0;j<=14;j++)
{
if(chessBoard[i][j]==1)
{
g.setColor(Color.red);
g.fillOval(20+i*30,40+j*30,20,20);
}
if(chessBoard[i][j]==2)
{
g.setColor(Color.blue);
g.fillOval(20+i*30,40+j*30,20,20);
}
}
}
public void actionPerformed(ActionEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
currentPos.width=e.getX();
currentPos.height=e.getY();
if(currentPos.width>15¤tPos.width<485¤tPos.height>35¤tPos.height<485) //15*15的画布中
{
x=y=20;
for(int i=0;i<=14;i++)
{
for(int j=0;j<=14;j++)
{
if(currentPos.width<=(45+i*30)¤tPos.width>=(15+i*30))
x=i;
if(currentPos.height<=(65+j*30)¤tPos.height>=(35+j*30))
y=j;
}
}
if(x!=20&&y!=20)
if(chessBoard[x][y]==0)
chessBoard[x][y]=2;
repaint();
preset();
getStatus(1);//我方搜索
getStatus(2);//对手搜索
getLoc();
repaint();
}
}
public void mousePressed(MouseEvent e)
{ }
public void mouseReleased(MouseEvent e)
{ }
public void mouseEntered(MouseEvent e)
{ }
public void mouseExited(MouseEvent e)
{ }
//每一次搜索执行前均需初始化数组
public void preset()
{
for (int i=0;i<15;i++)
{
for (int j=0;j<15;j++)
valueOfPresent[i][j]=0;
}
}
//逐点搜索,并且确定该点的权值
public void getStatus(int side)
{
int sum=0;
for (int i=0;i<15;i++)
{
for (int j=0;j<15;j++)
{
numOfLeft=0; leftBarrier=0; leftBlank=0;
numOfRight=0; rightBarrier=0; rightBlank=0;
numOfUp=0; upBarrier=0; upBlank=0;
numOfDown=0; downBarrier=0; downBlank=0;
numOfLu=0; luBarrier=0; luBlank=0;
numOfLd=0; ldBarrier=0; ldBlank=0;
numOfRu=0; ruBarrier=0;ruBlank=0;
numOfRd=0; rdBarrier=0; rdBlank=0;
sum=0;
if ( chessBoard[i][j]==0)
{
for (int k=1;k<5;k++)
{
//横向检查
if ( (leftBarrier==0) && (leftBlank==0))
{
if( (j-k)>=0 )
{
if (chessBoard[i][j-k]==side) numOfLeft++;
else if (chessBoard[i][j-k]==0)leftBlank=1;
else leftBarrier=1;
}
else leftBarrier=1;
}
if ( (rightBlank==0) && (rightBarrier==0))
{
if ((j+k)<15)
{
if (chessBoard[i][j+k]==side ) numOfRight ++;
else if (chessBoard[i][j+k]==0) rightBlank=1;
else rightBarrier=1;
}
else rightBarrier =1;
}
//斜向检查
if ( (luBlank==0) && (luBarrier==0) )
{
if ((i-k)>=0 && (j-k)>=0)
{
if ( chessBoard[i-k][j-k]==side) numOfLu++;
else if ( chessBoard[i-k][j-k]==0) luBlank=1;
else luBarrier=1;
}else luBarrier=1;
}
if ( (rdBlank==0) && (rdBarrier==0))
{
if ((i+k)<15 && (j+k)<15)
{
if (chessBoard[i+k][j+k]==side ) numOfRd++;
else if ( chessBoard[i+k][j+k]==0) rdBlank=1;
else rdBarrier=1;
}
else rdBarrier =1;
}
// 竖直方向检查
if ( (upBlank==0) && (upBarrier==0))
{
if ((i-k)>=0)
{
if (chessBoard[i-k][j]==side) numOfUp++;
else if ( chessBoard[i-k][j]==0) upBlank=1;
else upBarrier=1;
}
else upBarrier =1;
}
if ( ( downBlank==0)&& (downBarrier==0) )
{
if ((i+k)<15)
{
if (chessBoard[i+k][j]==side)numOfDown++;
else if ( chessBoard[i+k][j]==0) downBlank=1;
else downBarrier=1;
}
else downBarrier =1;
}
//斜向检查
if ( ( ldBlank==0)&& (ldBarrier==0))
{
if ((i+k)<15 && (j-k)>=0)
{
if (chessBoard[i+k][j-k]==side) numOfLd++;
else if ( chessBoard[i+k][j-k]==0) ldBlank=1;
else ldBarrier =1;
}
else ldBarrier=1;
}
if ( (ruBlank==0)&& (ruBarrier==0))
{
if ( (i-k)>=0 && (j+k)<15 )
{
if (chessBoard[i-k][j+k]==side) numOfLd++;
else if (chessBoard[i-k][j+k]==0) ruBlank=1;
else ruBarrier=1;
}
else ruBarrier =1;
}
}//end for (k)
/*以下为估值部分*/
presentStatus[i][j][0][0]=numOfLeft+numOfRight;
presentStatus[i][j][0][1]=leftBarrier+rightBarrier;
presentStatus[i][j][1][0]=numOfLu+numOfRd;
presentStatus[i][j][1][1]=luBarrier+rdBarrier;
presentStatus[i][j][2][0]=numOfUp+numOfDown;
presentStatus[i][j][2][1]=upBarrier+downBarrier;
presentStatus[i][j][3][0]=numOfRu+numOfLd;
presentStatus[i][j][3][1]=ruBarrier+ldBarrier;
for ( int k=0;k<4;k++)
{
switch (presentStatus[i][j][k][0])//以一个方向上的棋子数目来判定
{
case 1:
{
if (presentStatus[i][j][k][1]==1)
{
if (side==2)valueOfPresent[i][j]=1+valueOfPresent[i][j];
else valueOfPresent[i][j]=5+valueOfPresent[i][j];
}
else if(presentStatus[i][j][k][1]==0)
{
if ( side==2)valueOfPresent[i][j]=21+valueOfPresent[i][j];
else valueOfPresent[i][j]=23+valueOfPresent[i][j];
}
break;
}//case 1
case 2:
{
if (presentStatus[i][j][k][1]==1)
{
if (side==2)valueOfPresent[i][j]=93+valueOfPresent[i][j];
else valueOfPresent[i][j]=valueOfPresent[i][j]+138;
}
else if(presentStatus[i][j][k][1]==0)
{
if ( side==2)valueOfPresent[i][j]=valueOfPresent[i][j]+553;
else valueOfPresent[i][j]=valueOfPresent[i][j]+555;
}break;
}//case 2
case 3:
{
if (presentStatus[i][j][k][1]==1)
{
if (side==2)valueOfPresent[i][j]=valueOfPresent[i][j]+580;
else valueOfPresent[i][j]=valueOfPresent[i][j]+600;
}
else if(presentStatus[i][j][k][1]==0)
{
if ( side==2)valueOfPresent[i][j]=valueOfPresent[i][j]+2221;
else valueOfPresent[i][j]=valueOfPresent[i][j]+5000;
}break;
}//case 3
case 4:
{
sum++;
if (side==1)finish1=true;
else if (sum>=2) finish2=true;
if (side==2) valueOfPresent[i][j]=valueOfPresent[i][j]+30000;
else valueOfPresent[i][j]=valueOfPresent[i][j]+40000;break;
}//case 4
} //end swtich
}//end for (k)
}// end if
}// end for (j)
}//end for(i)
}
/*获取计算机的落子点*/
public void getLoc()
{
int temp=-1;
for (int i=0; i<15;i++)
{
for (int j=0;j<15;j++)
{
if (valueOfPresent[i][j]>=temp)
{
temp = valueOfPresent[i][j];
locationX=j;
locationY=i;
}
}
}
if (temp==0)
{
locationX=6;
locationY=7;
}
chessBoard[locationY][locationX]=1;
}
}