基于Alphabet剪枝的五子棋AI

之前无聊写的,代码在附件里,仅供参考- -   AB剪枝只有2层,所以AI战斗力很渣。。

AB.java

class AB {
	static int round=1;
	static int n=Jframe.n;
	static int G[][]=new int[20][20];
	static int INF=10000;
	static void copy(int a[][],int b[][]){
		for(int i=0;i<=n;i++){
			for(int j=0;j<=n;j++){
				b[i][j]=a[i][j];
			}
		}
	}
	static int checkVictory(int G[][]){   //黑方胜利返回1,白方胜利返回-1,还没分出胜负返回0
		for(int i=0;i<=n;i++){
			int sum=0,now=0;   //对于每行,从左向右扫
			for(int j=0;j<=n;j++){   
				if(G[i][j]!=now){
					now=G[i][j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
			sum=0;now=0;   //对于每列,从右向左扫
			for(int j=0;j<=n;j++){
				if(G[j][i]!=now){
					now=G[j][i];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[i+j][j]!=now){
					now=G[i+j][j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[j][i+j]!=now){
					now=G[j][i+j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
			sum=0;now=0;
			for(int j=0;i-j>=0;j++){
				if(G[j][i-j]!=now){
					now=G[j][i-j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[i+j][n-j]!=now){
					now=G[i+j][n-j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==5){
					return now;
				}
			}
		}
		return 0;
	}
	static int max(int a,int b){
		if(a>b)return a;
		return b;
	}
	static int min(int a,int b){
		if(a=0&&j+1<=n)
						if(G[i][j-sum]==0&&G[i][j+1]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(j-sum>=0&&j+1<=n)
						if(G[i][j-sum]==0&&G[i][j+1]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(j-sum>=0&&j+1<=n)
						if(G[i][j-sum]==0&&G[i][j+1]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
			sum=0;now=0;   //对于每列,从右向左扫
			for(int j=0;j<=n;j++){
				if(G[j][i]!=now){
					now=G[j][i];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==2){
					if(j-sum>=0&&j+1<=n)
						if(G[j-sum][i]==0&&G[j+1][i]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(j-sum>=0&&j+1<=n)
						if(G[j-sum][i]==0&&G[j+1][i]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(j-sum>=0&&j+1<=n)
						if(G[j-sum][i]==0&&G[j+1][i]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[i+j][j]!=now){
					now=G[i+j][j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==2){
					if(j-sum>=0&&j+1<=n)
						if(G[i+j-sum][j-sum]==0&&G[i+j+1][j+1]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(j-sum>=0&&j+1<=n)
						if(G[i+j-sum][j-sum]==0&&G[i+j+1][j+1]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(j-sum>=0&&j+1<=n)
						if(G[i+j-sum][j-sum]==0&&G[i+j+1][j+1]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[j][i+j]!=now){
					now=G[j][i+j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==2){
					if(j-sum>=0&&i+j+1<=n)
						if(G[j-sum][i+j-sum]==0&&G[j+1][i+j+1]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(j-sum>=0&&j+1<=n)
						if(G[j-sum][i+j-sum]==0&&G[j+1][i+j+1]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(j-sum>=0&&j+1<=n)
						if(G[j-sum][i+j-sum]==0&&G[j+1][i+j+1]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
			sum=0;now=0;
			for(int j=0;i-j>=0;j++){
				if(G[j][i-j]!=now){
					now=G[j][i-j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==2){
					if(j-sum>=0&&i-j-1>=0)
						if(G[j-sum][i-j+sum]==0&&G[j+1][i-j-1]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(j-sum>=0&&i-j-1>=0)
						if(G[j-sum][i-j+sum]==0&&G[j+1][i-j-1]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(j-sum>=0&&i-j-1>=0)
						if(G[j-sum][i-j+sum]==0&&G[j+1][i-j-1]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
			sum=0;now=0;
			for(int j=0;i+j<=n;j++){
				if(G[i+j][n-j]!=now){
					now=G[i+j][n-j];
					sum=1;
				}else{
					if(now!=0)
					sum++;
				}
				if(sum==2){
					if(i+j+1<=n&&n-j+sum<=n)
						if(G[i+j-sum][n-j+sum]==0&&G[i+j+1][n-j-1]==0)
					        h2[now+1]++;
				}else if(sum==3){
					if(i+j+1<=n&&n-j+sum<=n)
						if(G[i+j-sum][n-j+sum]==0&&G[i+j+1][n-j-1]==0)
					        h3[now+1]++;
					s3[now+1]++;
				}else if(sum==4){
					if(i+j+1<=n&&n-j+sum<=n)
						if(G[i+j-sum][n-j+sum]==0&&G[i+j+1][n-j-1]==0)
					        h4[now+1]++;
					s4[now+1]++;
				}else if(sum==5){
					hs5[now+1]++;
				}
			}
		}
		score=h2[0]*10-h2[2]*8+h3[0]*100-h3[2]*100+s3[0]*20-s3[2]*20;
		score+=h4[0]*1000-h4[2]*1500;
		score+=s4[0]*30-s4[2]*30;
		score+=hs5[0]*5000-hs5[2]*5000;
		return score;
	}
}


begin.java

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;


public class begin { 
	static Jframe local;
	static int clicknum=0;
	static int over=0;
public static void main (String args[]) { 
	local=new Jframe(); 
    
    while(true){  
    	int last=clicknum;
        Point point = MouseInfo.getPointerInfo().getLocation();  
        if(clicknum>last)
        Jframe.turnPC();
       // System.out.println(point);  
      //  try { Thread.sleep(100); } catch (InterruptedException e) { }  
    
    }  
 } 
}


Jframe.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

class Jframe extends JFrame{ 
static int width=800,height=800,n=15,r=23;
static int  w=width/n,h=height/n,beg=60;
ArrayList points = null;
public Jframe(){ 
   points = new ArrayList();
   this.setTitle("老西五子棋v1.0(电脑弱智版)");
   this.setSize(width+100,height+100); 
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
   setVisible(true); 
   this.addMouseListener(new MyMouseListener());
   this.addWindowListener(new WindowAdapter(){
	   public void windowClosing(WindowEvent e)
	   {
	    setVisible(false);
	    System.exit(0);
	   }
	  });
   this.setBackground(Color.GREEN);
} 
@Override 
public void paint(Graphics g) { 
       super.paint(g); 
       //画边界
       g.setColor(Color.GRAY);
       for(int i=0;i<=n;i++){
    	   g.drawLine(beg+i*w, beg, beg+i*w, beg+n*h);
       }
       for(int i=0;i<=n;i++){
    	   g.drawLine(beg, beg+i*h, beg+n*w, beg+i*h);
       }
       // 画棋子
       
       Iterator it = points.iterator();
       Color c = g.getColor();
       while(it.hasNext())
       {
        qi p = (qi)it.next();
        if(p.color==1)
        	g.setColor(Color.black);
        else
        	g.setColor(Color.yellow);
        g.fillOval(p.x-r,p.y-r,2*r,2*r);
        if(it.hasNext()==false){
        	g.setColor(Color.red);
        	g.fillOval(p.x-4,p.y-4,8,8);
        }
       }
       g.setColor(Color.black);
       if(AB.round%2==1)
       g.drawString("轮到黑方", beg, beg+n*h+20);
       else
       g.drawString("轮到白方", beg, beg+n*h+20);
       System.out.println();
       for(int i=0;i<=n;i++){
    	   for(int j=0;j<=n;j++){
    		   System.out.print(AB.G[i][j]+" ");
    	   }System.out.println();
       }
       int ans=AB.checkVictory(AB.G);
       if(ans==1){
    	   JOptionPane.showMessageDialog(null, "黑方获胜!"); 
    	 
       }else if(ans==-1){
    	   JOptionPane.showMessageDialog(null, "白方获胜!"); 
    	   
       }
       if(ans!=0){
    	   points.clear();
    	   for(int i=0;i<=n;i++){
    		   for(int j=0;j<=n;j++){
    			   AB.G[i][j]=0;
    		   }
    	   }
    	   AB.round=1;
    	   begin.clicknum=0;
       }
} 
public double dis(double x1,double y1,double  x2,double y2){
	return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

public void addPoint(Point p)
{
 int flag=0;
 for(int i=0;i<=n;i++){
	 for(int j=0;j<=n;j++){
		 if(dis(beg+i*w,beg+j*h,p.x,p.y)<25){
			 flag=1;
			 p.x=beg+i*w;p.y=beg+j*h;
			 break;
		 }
	 }
	 if(flag==1) break;
 }
 if(flag==0)return ;
 Iterator i = points.iterator();
 while(i.hasNext())
 {
  qi k = (qi)i.next();
  if(k.x==p.x&&k.y==p.y){
	  JOptionPane.showMessageDialog(null, "该区域已经有子,请您重放~"); 
	  return ;
  }
 }
 
 qi temp= new qi(p.x,p.y);
 if(AB.round%2==1){
	 temp.color=1;
 }else{
	 temp.color=-1;
 }
 AB.G[(temp.y-beg)/h][(temp.x-beg)/w]=temp.color;
 AB.round++;
 points.add(temp);
}
  
  static void turnPC(){
	  if(AB.checkVictory(AB.G)!=0)return ;
	  Jframe mf=begin.local;
	  Point ansp = new Point(AB.round/2%(AB.n+1),AB.round/2/(AB.n+1));
	     int maxx=-AB.INF;
	     for(int i=0;i<=AB.n;i++){
	    	 for(int j=0;j<=AB.n;j++){
	    		 if(AB.G[i][j]!=0)continue;
	    		 //下子范围
	    		 if(AB.round<=4){
	    			 int flag=1;
		    		 if(i>=1&&i<=n-1&&j>=1&&j<=n-1){
		    			 for(int k=i-1;k<=i+1;k++){
		    				 for(int l=j-1;l<=j+1;l++){
		    					 if(AB.G[k][l]==-1||AB.G[k][l]==1)
		    						 flag=0;
		    				 }if(flag==0) break;
		    			 }
		    		 }
		    		 if(flag==1)continue;
	    		 }
	    		 int curG[][]=new int[20][20];
	    		 AB.copy(AB.G, curG);
	    		 curG[i][j]=-1;
	    	     int k=AB.alphabeta(curG,1,-AB.INF,AB.INF,1);
	    	   //  System.out.print(k+" ");
	    		 if(k>maxx){
	    			 maxx=k;ansp.x=j;ansp.y=i;
	    		 }
	    	 }
	     }
	     ansp.x*=Jframe.w;ansp.x+=Jframe.beg;
	     ansp.y*=Jframe.h;ansp.y+=Jframe.beg;
	     mf.addPoint(ansp);
	     mf.repaint();
  }

} 
class MyMouseListener extends MouseAdapter
{
 public void mouseClicked(MouseEvent e)
 {
	 if(AB.round%2==0)return ;
	 Jframe mf = (Jframe)e.getSource();
	 int before=AB.round;
     mf.addPoint((new Point(e.getX(),e.getY())));
     mf.repaint();
     if(before==AB.round)return ;
     begin.clicknum++;
 }
 
}


qi.java

import java.awt.Point;


class qi extends Point{
	int color;
	qi(int a,int b){
		super(a,b);
	}
}



你可能感兴趣的:(Java,项目作品,五子棋,ai,alphabeta剪枝)