java五子棋人机对战

先上图看看界面和功能,如果满意,可继续看下面的代码

图片在这里插入图片描述在这里插入图片描述

Core类里面有落棋的基本功能,有判断胜负,悔棋,重新开始,以及AI落子的算法等

package 五子棋test;

import java.util.*;
import java.util.Stack;

public class Core {
    private int [][]core;//棋盘
    private int x;
    private int y;
    class Chess{//下棋
    	int x;
    	int y;
    	public Chess(int x,int y)
    	{
    		this.x=x;
    		this.y=y;
    	}
    }
    Stack<Chess> stack;//用于悔棋和最新落子图标
    public Core(int x,int y)//构造
    {
    	stack = new Stack<>();
    	core = new int[x][y];
    	this.x=x;
    	this.y=y;
    }
    //判断是否为空
    private int IsEmpty(int x,int y)
    {
    	int ok=0;
    	if(core[x][y]==0)
    	{
    		ok=1;
    	}
    	return ok;
    }
  //下棋
    public int ChessIt(int x,int y,int var)
    {
    	if(IsEmpty(x,y)==1)
    	{
    		core[x][y]=var;
    		Chess chess = new Chess(x,y);
    		stack.push(chess);
    		return IsVictory(x,y,var);
    	}
    	else
    		return -1;
    }
  //获取棋盘状态
    public int[][] getCore()
    {
    	return this.core;
    }
    //判断是否胜利
    private int IsVictory(int x,int y,int var)
    {
    	int i,j,s1=0,s2=0,s3=0,s4=0;
    	//横向判断
    	for(i=y-4;i<=y+4;++i)
    	{
    		if(i<0||i>=this.y) continue;
    		if(core[x][i]==var)
    		{
    			s1++;
    		}
    		else
    		{
    			s1=0;
    		}
    		if(s1==5)
    			return var;
    	}
    	//纵向判断
    	for(i=x-4;i<=x+4;++i)
    	{
    		if(i<0||i>=this.x) continue;
    		if(core[i][y]==var)
    		{
    			s2++;
    		}
    		else
    		{
    			s2=0;
    		}
    		if(s2==5)
    			return var;
    	}
    	//左上到右
    	for(i=x-4,j=y-4;i<=x+4&&j<=y+4;++i,++j)
    	{
    		if(i<0||i>=this.x||j<0||j>=this.y) continue;
    		if(core[i][j]==var)
    		{
    			s3++;
    		}
    		else
    		{
    			s3=0;
    		}
    		if(s3==5)
    			return var;
    	}
    	//左下到右
    	for(i=x-4,j=y+4;i<=x+4&&j>=y-4;++i,--j)
    	{
    		if(i<0||i>=this.x||j<0||j>=this.y) continue;
    		if(core[i][j]==var)
    		{
    			s4++;
    		}
    		else
    		{
    			s4=0;
    		}
    		if(s4==5)
    			return var;
    	}
    	return 0;
    }

  //悔棋
    public boolean RetChess()
    {
    	if(stack.isEmpty())
    	{
    		return false;
    	}
    	Chess chess = stack.pop();
    	core[chess.x][chess.y]=0;
    	return true;
    }
    public int returnX()//返回最新落子的x坐标
    {
		Chess chess = stack.peek();
		return chess.x;
    }
    public int returnY()//返回最新落子的y坐标
    {
		Chess chess = stack.peek();
		return chess.y;
    }
    //重新开始
    public void reSatrt()
    {
    	for(int i=0;i<this.x;++i)
    	{
    		for(int j=0;j<this.y;++j)
    		{
    			core[i][j]=0;
    		}
    	}
    	
    	this.stack.clear();
    }
    public void st()//ai先
    {
    	core[9][9]=2;
    }
    //Ai落子
    public int csAI(int var)
    {
    	int i,j,max=0,t,a=0,b=0;
    	for(i=0;i<this.x;++i)
    	{
    		for(j=0;j<this.y;++j)
    		{
    			if(core[i][j]==0)
    			{
	    			t=getScore(i,j);
	    			if(t>max)
	    			{
	    				max=t;
	    				a=i;
	    				b=j;
	    			}
    			}
    		}
    	}
    	core[a][b]=var;
    	//System.out.println(max);
    	Chess chess = new Chess(a,b);
		stack.push(chess);
    	return IsVictory(a,b,var);
    }
  //总得分情况
    public int getScore(int x, int y)
    {
    	int xscore = getXScore(x,y,1)+getXScore(x,y,2);
    	int yscore = getYScore(x,y,1)+getYScore(x,y,2);
    	int kscore1 = getKScore1(x,y,1)+getKScore1(x,y,2);
    	int kscore2 = getKScore2(x,y,1)+getKScore2(x,y,2);
    	return xscore+yscore+kscore1+kscore2;
    }
    private int getScoreAll(int cout, int leftnum, int rightnum)
    {//得分规则
    	int score=0;
    	if(cout>=5)//5子情况
    	{
    		score += 99999;
    	}
    	if(cout==4)//4子情况
    	{
    		if(leftnum==1&&rightnum==1)//1为空2为堵
    		{
    			score += 5000;
    			//System.out.print(4+":"+1+" ");
    		}
    		if(leftnum==2&&rightnum==1||leftnum==1&&rightnum==2)
    		{
    			score += 3000;
    			//System.out.print(4+":"+2+" ");
    		}
    		if(leftnum==2&&rightnum==2)
    		{
    			score += 1000; //?
    			//System.out.print(4+":"+3+" ");
    		}
    	}
    	if(cout==3)
    	{
    		if(leftnum==1&&rightnum==1)//1为空2为堵
    		{
    			score += 3000;
    			//System.out.print(3+":"+1+" ");
    		}
    		if(leftnum==2&&rightnum==1||leftnum==1&&rightnum==2)
    		{
    			score += 1000;
    			//System.out.print(3+":"+2+" ");
    		}
    		if(leftnum==2&&rightnum==2)
    		{
    			score += 500; //?
    			//System.out.print(3+":"+3+" ");
    		}
    	}
    	if(cout==2)
    	{
    		if(leftnum==1&&rightnum==1)//1为空2为堵
    		{
    			score += 500;
    			//System.out.print(2+":"+1+" ");
    		}
    		if(leftnum==2&&rightnum==1||leftnum==1&&rightnum==2)
    		{
    			score += 200;
    			//System.out.print(2+":"+2+" ");
    		}
    		if(leftnum==2&&rightnum==2)
    		{
    			score += 100; //?
    			//System.out.print(2+":"+3+" ");
    		}
    	}
    	if(cout==1)
    	{
    		if(leftnum==1&&rightnum==1)//1为空2为堵
    		{
    			score += 100;
    			//System.out.print(1+":"+1+" ");
    		}
    		if(leftnum==2&&rightnum==1||leftnum==1&&rightnum==2)
    		{
    			score += 50;
    			//System.out.print(1+":"+2+" ");
    		}
    		if(leftnum==2&&rightnum==2)
    		{
    			score += 30; //?
    			//System.out.print(1+":"+3+" ");
    		}
    	}
    	return score;
    }
	public int getXScore(int x, int y, int var)
	{//横向
		int she=1;
		if(var==1) she=2;
		core[x][y]=var;//
		int leftnum=0,rightnum=0,i,cont=0;
		for(i=y;i<this.y;++i)
		{
			if(core[x][i]==var)
				cont++;
			else
			{
				if(core[x][i]==0)
					rightnum=1;//空
				if(core[x][i]==she)
					rightnum=2;//无位置
				break;
			}
		}
		for(i=y-1;i>=0;--i)
		{
			if(core[x][i]==var)
				cont++;
			else
			{
				if(core[x][i]==0)
					leftnum=1;//空
				if(core[x][i]==she)
					leftnum=2;
				break;
			}
		}
		core[x][y]=0;
		return getScoreAll(cont, leftnum,rightnum);
		
	}
	public int getYScore(int x, int y, int var)
	{//纵向得分
		int she=1;
		if(var==1) she=2;
		core[x][y]=var;//
		int leftnum=0,rightnum=0,i,cont=0;
		for(i=x;i<this.x;++i)
		{
			if(core[i][y]==var)
				cont++;
			else
			{
				if(core[i][y]==0)
					rightnum=1;//空
				if(core[i][y]==she)
					rightnum=2;
				break;
			}
		}
		for(i=x-1;i>=0;--i)
		{
			if(core[i][y]==var)
				cont++;
			else
			{
				if(core[i][y]==0)
					leftnum=1;//空
				if(core[i][y]==she)
					leftnum=2;
				break;
			}
		}
		core[x][y]=0;
		return getScoreAll(cont, leftnum,rightnum);
	}
	public int getKScore1(int x, int y, int var)
	{//左上到右下
		int she=1;
		if(var==1) she=2;
		core[x][y]=var;//
		int j,leftnum=0,rightnum=0,i,cont=0;
		for(i=x,j=y;i<this.x&&j<this.y;++i,++j)
		{
			if(core[i][j]==var)
				cont++;
			else
			{
				if(core[i][j]==0)
					rightnum=1;//空
				if(core[i][j]==she)
					rightnum=2;
				break;
			}
		}
		for(i=x-1,j=y-1;i>=0&&j>=0;--i,--j)
		{
			if(core[i][j]==var)
				cont++;
			else
			{
				if(core[i][j]==0)
					leftnum=1;//空
				if(core[i][j]==she)
					leftnum=2;
				break;
			}
		}
		core[x][y]=0;
		return getScoreAll(cont, leftnum,rightnum);
	}
	public int getKScore2(int x, int y, int var)
	{//左下到右上
		int she=1;
		if(var==1) she=2;
		core[x][y]=var;//
		int j,leftnum=0,rightnum=0,i,cont=0;
		for(i=x,j=y;i<this.x&&j>=0;++i,--j)
		{
			if(core[i][j]==var)
				cont++;
			else
			{
				if(core[i][j]==0)
					rightnum=1;//空
				if(core[i][j]==she)
					rightnum=2;
				break;
			}
		}
		for(i=x-1,j=y+1;i>=0&&j<this.y;--i,++j)
		{
			if(core[i][j]==var)
				cont++;
			else
			{
				if(core[i][j]==0)
					leftnum=1;//空
				if(core[i][j]==she)
					leftnum=2;
				break;
			}
		}
		core[x][y]=0;
		return getScoreAll(cont, leftnum,rightnum);
		
	}
}

Show类只要是绘制界面以及监听事件

package 五子棋test;

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.awt.*;

/**
 * 
 * @author GodofOrange
 * @see 图形界面
 */
public class Show extends JFrame implements MouseListener {
	static int ok=0;
    public Core core;
    private static final long serialVersionUID = 1L;
    private int var = 1;
    //设置一些颜色
    Color bgColor=new Color(246,214,159);
    Color aColor=new Color(255,255,255);
    Color bColor=new Color(155,125,25);
    Color cColor=new Color(55,125,25);
    Color lineColor=new Color(164,135,81);
    Color pointColor=new Color(116,88,49);
    public Show(String title) {
        super(title);
        core = new Core(19, 19);
        this.setSize(800, 650);
        this.setLocation(200, 30);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setResizable(false);
        this.addMouseListener(this);
    }
    public void drawBord(Graphics g1) {//棋盘背景颜色
        g1.setColor(bgColor);
        g1.fillRect(30, 60, 540, 540);
    }
    public void drawImage(Graphics g2) {//插入图片
        Graphics2D g4d = (Graphics2D) g2.create();
             //从本地读取一张图片
        String filepath = "a.jpg";
        Image image = Toolkit.getDefaultToolkit().getImage(filepath);
             //绘制图片(如果宽高传的不是图片原本的宽高, 则图片将会适当缩放绘制)
        g4d.drawImage(image, 575, 430, 215, 173, this);
    }
    public void drawDian(Graphics g3)//ai最新落子位置
    {
    	if(!core.stack.isEmpty())
    	{
    		int a=core.returnX(),b=core.returnY();
    		//Chess chess = core.stack.peek();
	    	g3.setColor(Color.red);
	    	g3.drawRect(26+30*a,54+30*b,10,10);
	    	g3.fillRect(26+30*a,54+30*b,10,10);
    	}
    }
    public void drawChess(Graphics g)//画棋子棋盘以及显示棋子
    {//这里两线相距30
    	g.setColor(lineColor);
        // 横
        for (int i = 0; i < 20; i++)//第一条显示不出来
            g.drawLine(30, 30 + i * 30, 570, 30 + i * 30);
        // 竖线
        for (int i = 0; i < 19; i++)
            g.drawLine(30 + i * 30, 60, 30 + i * 30, 600);
        g.setColor(pointColor);
        int[][] board = core.getCore();//获取棋盘状态
        for (int i = 0; i < 19; i++) {//遍历棋盘显示棋子
            for (int j = 0; j < 19; j++) {
            	if(i==9&&j==9||i==4&&j==4||i==4&&j==14||i==14&&j==14||i==14&&j==4)
                {
                    g.setColor(pointColor);
                    g.fillOval(22 + i * 30, 52 + j * 30, 15, 15);
                
                }
                if (board[i][j] == 1)
                {
                	g.setColor(aColor);
                    g.fillOval(15 + i * 30, 45 + j * 30, 30, 30);
                    
                }
                if(board[i][j]==2)
                {
                	g.setColor(Color.black);
                    g.fillOval(15 + i*30, 45+j*30, 30, 30);
                
                }
            }
        }
    }
    public void drawOther(Graphics g)//按钮和其他
    {
    	 Graphics2D g2d = (Graphics2D) g.create();
         Graphics2D g3d = (Graphics2D) g.create();
         BasicStroke bs1 = new BasicStroke(15);// 笔画的轮廓(画笔宽度/线宽为15px)
         g2d.setStroke(bs1);
         g3d.setFont(new Font("null", Font.BOLD|Font.ITALIC, 18));//设置字体
         g2d.setColor(lineColor);
         g2d.drawRect(630,60, 100, 50);
         g3d.setColor(cColor);
         g3d.drawString("悔棋",660,90);
         g3d.setColor(Color.red);
         g2d.drawRect(630,150,100, 50);
         g3d.drawString("开始",660,180);
         g3d.setColor(bColor);
         g2d.drawRect(630,240,100, 50);
         g3d.drawString("设置",660,270);
         g3d.setColor(Color.black);
         g3d.drawString("清歌与墨", 640,360);
         g3d.setFont(new Font("TimesRoman", Font.BOLD, 20));
         g3d.drawString("人生如棋,棋如人生,落好每个棋,走好每一步。",100,630);
    }
    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
    	super.paint(g);
    	drawBord(g);
    	drawImage(g);
    	drawChess(g);
        drawOther(g);
        drawDian(g);
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {//监听落子
        // TODO Auto-generated method stub
        if (e.getX()>=20&&e.getX() < 570 && e.getY()>=50&&e.getY() < 600) {
            int a = core.ChessIt(_getX(e.getX()), (_getY(e.getY())), var);
            if(a!=-1)//判断是否落子有效
            {
	            this.repaint();
	            if (a == 1) {
	                JOptionPane.showMessageDialog(null,"你赢了", "恭喜", JOptionPane.DEFAULT_OPTION);;
	            }
	            if(a==2) {
	                JOptionPane.showMessageDialog(null,"AI赢了", "加油", JOptionPane.DEFAULT_OPTION);;
	            }
	            if(a!=-1) {
	                if(var==1) var=2;
	                else if(var==2) var=1;
	            }
	            int b = core.csAI(var);//AI落子
	            this.repaint();
	            if (b == 1) {
	                JOptionPane.showMessageDialog(null,"你赢了", "恭喜", JOptionPane.DEFAULT_OPTION);;
	            }
	            if(b==2) {
	                JOptionPane.showMessageDialog(null,"AI赢了", "加油", JOptionPane.DEFAULT_OPTION);;
	            }
	            if(b!=-1) {
	                if(var==1) var=2;
	                else if(var==2) var=1;
	            }
            }
        }
        else if(e.getX()>630&&e.getX()<730&&e.getY()>60&&e.getY()<110) {
        //悔棋,这里只悔玩家的棋,故一下悔两步
           core.RetChess();
           core.RetChess();
            this.repaint();
        }
        if(e.getX()>630&&e.getX()<730&&e.getY()>150&&e.getY()<200) {//重新开始
            core.reSatrt();
            if(ok==1)
            {
            	core.st();
            }
            this.repaint();
        }
        if(e.getX()>630&&e.getX()<730&&e.getY()>240&&e.getY()<290) {//设置
            Object[] options = {"人先","AI先"};
            int n = JOptionPane.showOptionDialog(null,"人先还是AI先?","游戏设置",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE, null,options,options[0]);
            
            this.core.reSatrt();
            if(n==0) 
            	{this.var=1;
            		ok=0;
            	}
            if(n==1) {
            	this.var=1;
            	core.st();
            	ok=1;
            }
            this.repaint();
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    private int _getX(int x) {//转换坐标
        x -= 30;
        if (x % 15 <= 7)
            return x / 30;
        else
            return x / 30 + 1;
    }

    private int _getY(int y) {
        y -= 60;
        if (y % 15 <= 7)
            return y / 30;
        else
            return y / 30 + 1;
    }
}

Test启动测试

public class Test {
	public static void main(String[] args) {
        new Show("五子棋");
    }
}

  • 29
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值