`
yanglei998
  • 浏览: 1242 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

300行代码实现的智能五子棋人机对战

阅读更多

这款五子棋小游戏是我五六年前在培训的时候花了一整个下午时间即兴写出来的,功能很简单,实现了五子棋的电脑对战,主要就是为了研究下电脑下棋算法,所以其他的功能和细节都没考虑,比如电脑最后的落子点我是直接用图片标示出来的,最好是另建一个线程来闪烁最后落子点,还有智能等级也是可以调节的,偏重于防守和进攻都可以修改代码中权值的设定来实现的,有兴趣的朋友可以在此基础上扩展一下。因为没有写谁先下棋的功能,可以模拟下电脑先下子,只需要你在边角上先下一子就可以了,相比下来,电脑先下的话,电脑赢的几率更大点,一共用到了三张图片,都在附件中。

 

 


下面是全部的代码,写了一些注释,希望能对你阅读代码起到一点帮助

 

import java.awt.*;
import java.awt.event.*;
import java.net.URL;

import javax.swing.*;
public class GobangGame {
    public static void main(String[] args) {
        GameF game = new GameF();
        game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        game.show();
    }
}
class GameF extends JFrame {
    public GameF() {
        Container contentPane = getContentPane();
        final Panel panel = new Panel();
        panel.setBackground(new Color(255, 182, 147));
        contentPane.setBackground(new Color(255, 182, 147));
        contentPane.add(panel);
        setSize(560, 560);
        setTitle("杨雷的五子棋游戏 版本1.0");
        setResizable(false);
        panel.setCursor(new Cursor(Cursor.HAND_CURSOR));
        JMenuBar menuBar=new JMenuBar();
        JMenu menu=new JMenu("选项");
        JMenuItem menuStart=new JMenuItem("开始游戏");
        menuStart.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e){
           	  panel.ResetGame();
           	  panel.repaint();
           }
        });
        JMenuItem menuExit =new JMenuItem("退出");
        menuExit.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            	  System.exit(0);
            }
         });
        menuBar.add(menu);
        menu.add(menuStart);
        menu.add(menuExit);
        this.setJMenuBar(menuBar);
      }
}
class Panel extends JPanel {
    private URL blackImgURL = GobangGame.class.getResource("black.gif");
	private ImageIcon black=new ImageIcon(blackImgURL);
	private URL whiteImgURL = GobangGame.class.getResource("white.gif");
	private ImageIcon white=new ImageIcon(whiteImgURL);
	private URL currentImgURL = GobangGame.class.getResource("current.gif");
	private ImageIcon current=new ImageIcon(currentImgURL);
	private int i, j, k, m, n, icount;
	private int[][] board = new int [16][16];
	private boolean[][][] ptable = new boolean[16][16][672];
	private boolean[][][] ctable = new boolean[16][16][672];
	private int[][] cgrades = new int[16][16];
	private int[][] pgrades = new int[16][16];
	private int cgrade,pgrade;
	private int[][] win = new int[2][672];
	private int oldx,oldy;
	private int bout=1;
	private int pcount,ccount;
	private boolean player,computer,over,pwin,cwin,tie,start;
	private int mat,nat,mde,nde;
	public Panel(){
	 	addMouseListener(new Xiazi());
	 	this.ResetGame();
	 }
	 public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < 16; i++)
            for (int j = 0; j < 16; j++){
                g.drawLine(50, 50 + j * 30, 500, 50 + j * 30);
            }
        for (int i = 0; i < 16; i++)
            for (int j = 0; j < 16; j++){
                g.drawLine(50 + j * 30, 50, 50 + j * 30, 500);
            }
        for (int i = 0; i < 16; i++){
            String number = Integer.toString(i);
            g.drawString(number, 46 + 30 * i, 45);
        }
        for (int i = 1; i < 16; i++){
            String number = Integer.toString(i);
            g.drawString(number, 33, 53 + 30 * i);
        }
       updatePaint(g);
    }
	class Xiazi extends MouseAdapter{
	 	public void mouseClicked(MouseEvent e){
	 		if(!over)
	 		{
	 			oldx = e.getX();
			    oldy = e.getY(); 
	 	        mouseClick();
	 	        repaint();
	 		}
	 	}
	 }
//      游戏初始化
        public void ResetGame()
		{ 
			//初始化棋盘
			for(i=0;i<16;i++)
				for(j=0;j<16;j++)
				{
					this.pgrades[i][j] = 0;
					this.cgrades[i][j] = 0;
					this.board[i][j] = 2;
				}
			//遍历所有的五连子可能情况的权值
			//横
			for(i=0;i<16;i++)
				for(j=0;j<12;j++){
					for(k=0;k<5;k++){
						this.ptable[j+k][i][icount] = true;
						this.ctable[j+k][i][icount] = true;
					}
					icount++;
				}
			//竖
			for(i=0;i<16;i++)
				for(j=0;j<12;j++){
					for(k=0;k<5;k++){
						this.ptable[i][j+k][icount] = true;
						this.ctable[i][j+k][icount] = true;
					}
					icount++;
				}
			//右斜
			for(i=0;i<12;i++)
				for(j=0;j<12;j++){
					for(k=0;k<5;k++){
						this.ptable[j+k][i+k][icount] = true;
						this.ctable[j+k][i+k][icount] = true;
					}
					icount++;
				}
			//左斜
			for(i=0;i<12;i++)
				for(j=15;j>=4;j--){
					for(k=0;k<5;k++){
						this.ptable[j-k][i+k][icount] = true;
						this.ctable[j-k][i+k][icount] = true;
					}
					icount++;
				}
			for(i=0;i<=1;i++)  //初始化黑子白子上的每个权值上的连子数
				for(j=0;j<672;j++)
					this.win[i][j] = 0;
            this.player = true;
			this.icount = 0;
			this.ccount = 0;
			this.pcount = 0;
			this.start = true;
			this.over = false;
			this.pwin = false;
			this.cwin = false;
			this.tie = false;
			this.bout=1;
		}
    public void ComTurn(){     //找出电脑(白子)最佳落子点
		   for(i=0;i<=15;i++)     //遍历棋盘上的所有坐标
				for(j=0;j<=15;j++){   
					this.pgrades[i][j]=0;  //该坐标的黑子奖励积分清零
					if(this.board[i][j] == 2)  //在还没下棋子的地方遍历
						for(k=0;k<672;k++)    //遍历该棋盘可落子点上的黑子所有权值的连子情况,并给该落子点加上相应奖励分
							if(this.ptable[i][j][k]){
								switch(this.win[0][k]){   
								    case 1: //一连子
										this.pgrades[i][j]+=5;
										break;
									case 2: //两连子
										this.pgrades[i][j]+=50;
										break;
									case 3: //三连子
										this.pgrades[i][j]+=180;
										break;
									case 4: //四连子
										this.pgrades[i][j]+=400;
										break;
								}
							}
					this.cgrades[i][j]=0;//该坐标的白子的奖励积分清零
					if(this.board[i][j] == 2)  //在还没下棋子的地方遍历
						for(k=0;k<672;k++)     //遍历该棋盘可落子点上的白子所有权值的连子情况,并给该落子点加上相应奖励分
							if(this.ctable[i][j][k]){
								switch(this.win[1][k]){  
									case 1:  //一连子
										this.cgrades[i][j]+=5;
										break;
									case 2:  //两连子
										this.cgrades[i][j]+=52;
										break;
									case 3: //三连子
										this.cgrades[i][j]+=100;
										break;
									case 4:  //四连子
										this.cgrades[i][j]+=400;
										break;
								}
							}
				}
			if(this.start){      //开始时白子落子坐标
				if(this.board[4][4]==2){
					m = 4;
					n = 4;
				}else{
					m = 5;
					n = 5;
				}
				this.start = false;
			}else{
				for(i=0;i<16;i++)
					for(j=0;j<16;j++)
						if(this.board[i][j] == 2){  //找出棋盘上可落子点的黑子白子的各自最大权值,找出各自的最佳落子点
							if(this.cgrades[i][j]>=this.cgrade){
								this.cgrade = this.cgrades[i][j];   
								this.mat = i;
								this.nat = j;
							}
							if(this.pgrades[i][j]>=this.pgrade){
								this.pgrade = this.pgrades[i][j];   
								this.mde = i;
								this.nde = j;
							}
						}
				if(this.cgrade>=this.pgrade){   //如果白子的最佳落子点的权值比黑子的最佳落子点权值大,则电脑的最佳落子点为白子的最佳落子点,否则相反
					m = mat;
					n = nat;
				}else{
					m = mde;
					n = nde;
				}
			}
			this.cgrade = 0;		
			this.pgrade = 0;
			this.board[m][n] = 1;  //电脑下子位置   
			ccount++;
			if((ccount == 50) && (pcount == 50))  //平局判断
			{
				this.tie = true;
				this.over = true;
			}
			for(i=0;i<672;i++){
				if(this.ctable[m][n][i] && this.win[1][i] != 7)
					this.win[1][i]++;     //给白子的所有五连子可能的加载当前连子数
				if(this.ptable[m][n][i]){
					this.ptable[m][n][i] = false;
					this.win[0][i]=7;
				}
			}
			this.player = true;     //该人落子
			this.computer = false;  //电脑落子结束
		} 
	public void mouseClick(){
	    if(!this.over)
			if(this.player){
				if(this.oldx<520 && this.oldy<520) {
					int m1=m,n1=n;
                    m = (oldx-33)/30;
					n = (oldy-33)/30;
				    if(this.board[m][n] == 2){   
				    	this.bout++;
						this.board[m][n] = 0;	
						pcount++;
						if((ccount == 50) && (pcount == 50)){
							this.tie = true;
							this.over = true;
						}
						for(i=0;i<672;i++){
							if(this.ptable[m][n][i] && this.win[0][i] != 7)
								this.win[0][i]++;     //给黑子的所有五连子可能的加载当前连子数
							if(this.ctable[m][n][i]){
								this.ctable[m][n][i] = false;
								this.win[1][i]=7;
							}
						}
						this.player = false;      
						this.computer = true;
					}else{
                         m=m1;n=n1;
					}
				}
			}
	  }
	 public void updatePaint(Graphics g){
	 	if(!this.over){   //如果是轮到电脑下 
	 		if(this.computer)
				this.ComTurn();  //得到最佳下子点     
			//遍历当前棋盘上的五连子情况,判断输赢
			for(i=0;i<=1;i++)
				for(j=0;j<672;j++){   
					if(this.win[i][j] == 5)
						if(i==0){                //人赢
							this.pwin = true;
							this.over = true;    //游戏结束
							break;
						}else{
							this.cwin = true;    //电脑赢
							this.over = true;
							break;
						}
					if(this.over)               //一遇到五连子退出棋盘遍历
						break;
				}
             g.setFont(new Font("华文行楷",0,20));
             g.setColor(Color.RED);
			//画出当前棋盘所有棋子
			for(i=0;i<=15;i++)
				for(j=0;j<=15;j++){   //如果board元素值为0,则该坐标处为黑子
					if(this.board[i][j] == 0){
						 g.drawImage(black.getImage(),i*30+31,j*30+31,black.getImage().getWidth(black.getImageObserver())-3,black.getImage().getHeight(black.getImageObserver())-3, black.getImageObserver());
					}
					//如果board元素值为1,则该坐标处为白子
					if(this.board[i][j] == 1){
						 g.drawImage(white.getImage(),i*30+31,j*30+31,white.getImage().getWidth(white.getImageObserver())-3,white.getImage().getHeight(white.getImageObserver())-3, white.getImageObserver());
					}
				}
			//画出白子(电脑)当前所下子,便于辨认
			if(this.board[m][n]!=2)
    			g.drawImage(current.getImage(),m*30+31,n*30+31,current.getImage().getWidth(current.getImageObserver())-4,current.getImage().getHeight(current.getImageObserver())-4, current.getImageObserver());
	        //判断输赢情况
			//人赢
			if(this.pwin)
			    g.drawString("您太厉害了!再来一次请重新开始游戏..",20,200);
			//电脑赢
			if(this.cwin)
			    g.drawString("很遗憾,你输了!再来一次请重新开始游戏..",84,190);
			//平局
			if(this.tie)
				g.drawString("不分胜负!再来一次请重新开始游戏..",80,200);
		g.dispose();
	 }
  } 
}

 

如果有兴趣的朋友可以和我一起交流下技术, 我QQ号码: 249930610, MSN: yangsharp@hotmail.com

 

 

  • 大小: 56 KB
分享到:
评论

相关推荐

    五子棋人机对战,matlab语言编写的源码.zip

    【标题】"五子棋人机对战,matlab语言编写的源码.zip" 提供的是一个使用MATLAB编程语言实现的五子棋游戏,它包含了一套完整的五子棋人机对战系统。MATLAB通常被用作科学计算、数据分析和算法开发的工具,但也可以...

    五子棋人机对战源码(vc++)

    本篇文章将深入解析基于VC++实现的五子棋人机对战源码,帮助读者理解其中的关键技术和思路。 首先,我们来看标题中的“五子棋人机对战”。在人机对战模式下,系统需要同时具备模拟人类玩家思考的能力和提供用户交互...

    QT五子棋人机对战人人对战

    人机对战模式涉及到了人工智能(AI)的设计。在QT五子棋中,AI可能采用了基于搜索算法的方法,如Minimax算法或Alpha-Beta剪枝,这些算法能模拟对手的可能走法,预测未来的棋局,从而帮助计算机做出最优决策。AI的...

    五子棋人机对战源码

    总的来说,五子棋人机对战源码的分析不仅涉及到编程语言的应用,还涵盖了人工智能和博弈策略的实现。通过深入研究,不仅可以提升编程技能,还能对游戏设计和AI算法有更深入的理解。对于有兴趣的开发者来说,这是一个...

    matlab五子棋程序(人机对战)

    本程序是用MATLAB编写的五子棋游戏,支持人机对战模式。它采用了一种较为简单的AI算法来实现计算机下棋,适合初学者学习和理解。 #### 二、程序结构 程序主要分为三个部分: 1. **主函数`functionfive()`**:负责...

    Python五子棋人机对战游戏源码

    #最后决定就写个五子棋人机对战吧! #这个源码我在多年前曾用VB6写过,当时毕业设计拿了优秀,之后经过了几次修改计算机Ai还不算太差,想投机赢是没机会的。 #由于本人初学Python(第一个完整的Python程序),有些技巧...

    javascript五子棋人机对战

    【javascript五子棋人机对战】项目是一个利用JavaScript实现的在线五子棋游戏,它包含人工智能(AI)模块,让玩家可以与计算机进行对战。这个项目可能是一个半成品,开发者试图通过不同的计算策略来优化游戏性能,...

    C++五子棋人机对战代码

    在本文中,我们将深入探讨基于C++实现的五子棋人机对战代码。五子棋,又称为连珠,是一种两人对弈的策略性棋类游戏,目标是在棋盘上形成连续的五个同色棋子,无论是横、竖还是斜线。C++是一种广泛应用的编程语言,...

    Python五子棋小游戏源代码,支持人机对战和局域网对战两模式

    在人机对战模式中,程序需要实现一个AI(人工智能)对手。这通常涉及到搜索算法,如Minimax算法或Alpha-Beta剪枝。这些算法用于模拟对手的思考过程,寻找最佳落子位置。在五子棋中,由于游戏相对简单,可能采用更...

    一个C++.net实现的智能五子棋人机对战游戏

    在这个C#.NET实现的智能五子棋人机对战游戏中,开发者使用了C#编程语言,结合.NET框架,创建了一个互动的对弈平台,玩家可以与计算机进行对战。五子棋是一种策略型两人棋类游戏,目标是在棋盘上先连成五子的玩家获胜...

    五子棋人机对战C++程序

    总的来说,"五子棋人机对战C++程序"是一个综合性的项目,它涉及到游戏规则的模拟、人工智能的实现、用户界面设计以及文件操作等多个方面。通过分析和理解这个程序,我们可以提升对C++编程、算法设计以及软件工程实践...

    五子棋人机对战C++源码

    【五子棋人机对战C++源码】是一个基于Microsoft Visual C++(VC)的MFC(Microsoft Foundation Classes)框架开发的项目,用于实现玩家与计算机之间的五子棋游戏。MFC是微软提供的一套面向对象的类库,它简化了...

    JAVA 五子棋人机对战

    【JAVA五子棋人机对战】是一种基于JAVA编程实现的智力游戏,它结合了基本的计算机算法与玩家之间的互动,让玩家可以与计算机进行五子棋比赛。在这个项目中,开发者采用了一些简单的人工智能策略,通过分析棋盘上不同...

    五子棋人机对战源代码

    根据给定的信息,我们可以分析并总结出以下与“五子棋人机对战源代码”相关的知识点: ### 一、程序结构与基本定义 #### 1. 基本头文件引入 - `&lt;stdio.h&gt;`:标准输入输出库,用于处理输入输出操作。 - `&lt;string.h&gt;...

    python 五子棋人机对战

    总的来说,【Python五子棋人机对战】项目涵盖了Python编程、图形界面设计、游戏逻辑实现、AI策略以及可能的机器学习应用等多个方面,是学习和实践Python技术的宝贵资源。通过研究和改进这个项目,开发者不仅可以提升...

    javascript实现的五子棋人机对战游戏源码

    在本项目中,我们讨论的是一个使用JavaScript实现的五子棋人机对战游戏源码。这个源码提供了实现一个基本的在线五子棋游戏所需的所有功能,包括棋盘渲染、用户交互、人工智能算法以及游戏逻辑。让我们深入探讨其中...

    java五子棋人机对战

    【Java五子棋人机对战】是一款基于Java编程语言实现的桌面游戏,它允许玩家与计算机进行对弈,提供了一种娱乐与学习相结合的方式。在这个项目中,开发者利用Java的强大功能,创建了一个直观且互动性强的五子棋界面,...

    Android 五子棋人机对战

    【Android五子棋人机对战】是一款基于Eclipse Android SDK开发的移动平台游戏,它为玩家提供了与人工智能对弈的娱乐体验。在这款游戏中,玩家可以选择与电脑进行一场智慧的较量,体验五子棋的独特魅力。五子棋是一种...

Global site tag (gtag.js) - Google Analytics