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; } }