精华内容
下载资源
问答
  • java小游戏五子棋

    2018-08-24 16:32:33
    利用java写的五子棋小游戏,里面的jar文件是可执行的jar文件
  • java 小游戏 五子棋

    2011-11-17 15:29:15
    Java 五子棋小游戏 完整的class文件
  • java 小游戏五子棋

    2012-09-25 19:56:41
    一款java小游戏五子棋制作简单易懂方便学习
  • Java小游戏——五子棋

    2020-11-18 00:53:13
    Java小游戏——五子棋详细解析

    Java小游戏——五子棋详细解析
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • JAVA五子棋小游戏

    万次阅读 多人点赞 2018-08-10 18:05:20
    学完Java基础书时总想着要自己编写出小游戏,事情并非如自己所愿,每次鼓起勇气来编写时,总是不知道该怎么写,写到一半就开始放弃。因为自己习惯跟着视屏去看和编写,思路和方法都是老师教,自己根本无法去考虑那么...

     

    学完Java基础书时总想着要自己编写出小游戏,事情并非如自己所愿,每次鼓起勇气来编写时,总是不知道该怎么写,写到一半就开始放弃。因为自己习惯跟着视屏去看和编写,思路和方法都是老师教,自己根本无法去考虑那么的多,所以一直写不出属于自己的东西。今天通过这篇文章来分享一下Java五子棋的编写思路。

    需要知道五子棋的简单内容,如有棋盘、棋子、输赢规则等需要实现。

    为了一步一步讲解,下面的代码将会进行拆分,方便讲解。    完整代码将会在最下方。

    1.那么我们先来简单的实现一个五子棋的棋盘布局。

    package 模拟练习.五子棋;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Toolkit;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    
    public class FI extends JFrame {
    		//设置游戏界面
    		/*	屏幕分辨率求法:
    				int w = f.getToolkit().getScreenSize().width;//宽度
    				int h = f.getToolkit().getScreenSize().height;//高度
    		Toolkit.getDefaultToolkit().getScreenSize().width   与上面等同
    		都是用来获取屏幕的宽高,
    		this.setLocation((width - 500) / 2 , (height - 500) / 2 );
    		这是使你的窗口能够居中显示,这样看起来美观。
    	*/
    		int width = Toolkit.getDefaultToolkit().getScreenSize().width;
    		int height = Toolkit.getDefaultToolkit().getScreenSize().height;	
    		int[][] allChess = new int[15][15];   // 用数组来保存棋子,0表示无子,1表示黑子,2表示白子
    		boolean isblack = true;   //用来表示黑子还是白子, true表示黑子   false表示白子
    		boolean canPlay = true;   // 用来表示当前游戏是否结束
    		String message = "黑方先行";
    		String blackMessage = "无限制";
    		String whiteMessage = "无限制";	
    		public FI(){
    			this.setTitle("五子棋1.0");
    			this.setSize(500,500);
    			this.setLocation((width - 500) / 2 , (height - 500) / 2 );
    			this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    			this.setResizable(false);  //设置窗口不可改变,固定窗口大小
    			this.setVisible(true);			
    			this.repaint();  //java里repaint()是重绘component的方法;	
                                //它会直接调用下面的方法对界面进行重行绘画				
    		}
    
    		//画棋盘界面
    		public void paint(Graphics g){
    			//双缓冲技术
    			BufferedImage buf = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
            // 这个bufferedImage 可以在网上查找相关用法,它是对图像的一种处理。
    			Graphics g1 =  buf.createGraphics();  // 创建画笔
    			g1.setColor(new Color(0,169,158));
    			g1.fill3DRect(43, 60, 375, 375, true);
    			
    				for (int i = 0; i <= 15; i++) {
    					g1.setColor(Color.WHITE);
    					g1.drawLine(43, 60+i*25, 375+43, 60+i*25);  //画棋盘横线
    					g1.drawLine(43+i*25, 60, 43+i*25, 375+60);  //画棋盘竖线
    				}
    				
    				g1.setFont(new Font("黑体",Font.BOLD,20));
    				g1.drawString("游戏信息:"+message,50,50);
    				
    				g1.drawRect(30, 440, 180, 40);
    				g1.drawRect(250, 440, 180, 40);   //画黑方时间与白方时间字符串的边框
    				g1.setFont(new Font("宋体",0,12));
    				
    				    g1.drawString("黑方时间: "+blackMessage,40,465);
    			        g1.drawString("白方时间: "+whiteMessage,260,465);
    			         
    			        g1.drawRect(430,66,55,20);
    			        g1.drawString("重新开始",432,80); //重新开始按钮
    			         
    			        g1.drawRect(430,106,55,20);
    			        g1.drawString("游戏设置",432,120); //游戏设置按钮
    			         
    			        g1.drawRect(430,146, 55, 20);
    			        g1.drawString("游戏说明", 432, 160); // 游戏说明按钮
    			  
    			        g1.drawRect(430, 186, 55, 20);
    			        g1.drawString("退出游戏", 432, 200);  // 退出游戏按钮
    			  
    			        g1.drawRect(430, 246, 55, 20);
    			        g1.drawString("悔棋", 442, 260);  // 悔棋
    			  
    			        g1.drawRect(430, 286, 55, 20);
    			        g1.drawString("认输", 442, 300);  // 认输			
    				
    				 g.drawImage(buf, 0, 0,this);	
    		}
    		
    	public static void main(String[] args) {
    		new FI();
    	}
    }

     这里就简单的实现的窗口和棋盘的布局。(以上实现方法可以用另一种方法进行实现,不用一个一个的画出来,2.0的版本会进行更新   )

    效果图      :五子棋

     2.接下来就开始实现下棋功能,既然要下棋那就要画出棋子。

    	     for(int i=0; i<15; i++){
    				for (int j = 0; j < 15; j++) {
    					//画实心黑子
    					if(allChess[i][j] == 1){    
    						int tempX = i*25+47;
    						int tempY = j*25+64;
    						g1.setColor(Color.BLACK);
    						g1.fillOval(tempX, tempY, 16, 16);
    						g1.setColor(Color.BLACK);
    						g1.drawOval(tempX, tempY, 16, 16);
    					}
    					
    					//画实心白子
    					if(allChess[i][j] == 2){
    						int tempX = i*25+47;
    						int tempY = j*25+64;
    						g1.setColor(Color.WHITE);
    						g1.fillOval(tempX, tempY, 16, 16);
    						g1.setColor(Color.WHITE);
    						g1.drawOval(tempX, tempY, 16, 16);
    					}
    				}
    			}

              allChess[i][j]是你下棋的位置, 对这个数组进行判断  如果为1 那就代表是黑棋
               2就是白棋     

               tempX,tempY  是用来确定棋子所在的位置区域的顶点坐标。
               因为一个方格是25*25的大小     所以我们定义一个16*16方格的内切圆,并涂上相应的颜色
                这样就达到我们在棋盘上的地方进行下棋

    3.接下来是对鼠标进行添加监听器,这样才能做到你点的时候做出相应的反应。

    public void mousePressed(MouseEvent e){
    		if(canPlay){
    			x=e.getX();
    			y=e.getY();  // 用来获取鼠标坐标
    			if(x>55 && x<= 405  && y>=72 && y<=420){
    				//让鼠标在棋盘范围内
    				if((x-55)%25>12){
    					x=(x-55)/25 + 1;
    				}else {
    					x = (x-55)/25;
    				}
    				if((y-72)%25>12){
    					y=(y-72)/25 + 1;
    				}else {
    					y=(y-72)/25;
    				}
    				
                /**  (405-55)/25=14格  而棋盘是15*15所以这里需要进行一个判断 12可以进行改动
                                            不能超过14就行。
                               这里用的是整形变量,精确度不准,容易造成所点的区域下不了棋
                        2.0版本会升级到把棋子放在交点上,不会在方格内下
                  */
    
    
    
    
    				//落子
                            /**  x,y代表棋子的位置所在
                                  chessX,chessY用来记录下棋的位置以便悔棋时需要
                                  如  chessX[0] = 3;
                                      chessY[0] = 4;
                                    即 第一步棋子下在  (3,4)位置
                                */
    				if(allChess[x][y] == 0){
    					chessX[countX++] = x;
    					chessY[countY++] = y;
    					if(isblack){
    						allChess[x][y] = 1;
    						isblack = false;
    						message = "白方下子";
    					}else {
    						allChess[x][y] = 2;
    						isblack = true;
    						message = "黑方下子";
    					}
    					this.repaint();   
             //调用方法进行绘制,如果allChess[x][y] = 1;  则画出黑棋
    					
    
    
                           //  下一个棋就进行输赢判断 
    					if(this.isWin()){
    						if(allChess[x][y] == 1){
    							JOptionPane.showMessageDialog(this, "游戏结束,黑方胜利");
    						}else {
    							JOptionPane.showMessageDialog(this, "游戏结束,白方胜利");
    						}
    						this.canPlay = false;  //表示游戏结束
    					}
    					
    					
    				}
    			}
    		}
    		
    
    	}
    	

          这里是对鼠标的动作所做出的反应,当然重行开始游戏和悔棋等功能也会在这里实现。

    4.接下来是实现对五子棋的输赢做出判断,这个也是比较难的。

              其实思路很简单,就是怎样使得效率提高就有些麻烦了,最容易的方法就是当你下一个棋子时我就开始依次横向和纵向做出判断是否连城五子,以五子棋的颜色为判断基础 ,例如: 横着一排有五个一样的颜色就代表胜利。如果横向和纵向都不符合要求,开始进行斜着判断,直到发现五子相同为止,如果都不成立就代表没有连城五子,不做出任何判断。

    	/**
    	 * 判断输赢规则
    	 * @return
    	 */
    	public boolean isWin(){
    		boolean flag = false;
    		int count = 1;  //用来保存共有相同颜色多少棋子相连,初始值为1
    		int color = allChess[x][y];  //color = 1 (黑子) color = 2(白子)
    		
    		//判断横向是否有5个棋子相连,特点:纵坐标是相同,即allChess[x][y] 中y值是相同
    		count = this.checkCount(1,0,color);
    		if(count >= 5){
    			flag = true;
    		}else {
    			//判断纵向
    			count = this.checkCount(0,1,color);
    			if(count >= 5){
    				flag = true;
    			}else {
    				 //判断右上,左下
    				count = this.checkCount(1,-1,color);
    				if(count >= 5){
    					flag = true;
    				}else {
    					//判断右下,左上
    					count = this.checkCount(1,1,color);
    					if(count >= 5){
    						flag =  true;
    					}
    				}
    			}
    		}
    		
    		return flag;
    	}
    	/**
    	 * 检查棋盘中的五子棋是否连城五子
    	 * @param xChange
    	 * @param yChenge
    	 * @param color
    	 * @return
    	 */
    	public int checkCount(int xChange , int yChenge ,int color){
    		int count = 1;
    		int tempX = xChange;
    		int tempy = yChenge;  //保存初始值
    		
    		//全局变量x,y最初为鼠标点击的坐标,
    		//经下棋方法已经将x,y的范围变成0-15(遍历整个棋盘,寻找相同颜色的棋子)
    		while(x + xChange >=0 && x+xChange <15  && y+yChenge >=0 && 
    				y+yChenge < 15 && color == allChess[x+xChange][y+yChenge]){
    			// allChess[x+xChange][y+yChenge] 表示移动一个坐标来进行判断是否为同一颜色
    			//例如横向判断checkCount(1,0,color); 传入xchange = 1,ychange = 0;
    			//   即每次向右移动一次,如果满足同一颜色就继续判断,不满足则返回
    			
    			
    			count++;
    			if(xChange != 0)  xChange++;     // 满足条件继续向右判断
    			if(yChenge != 0 ){      //  横向判断ychange = 0 不满足条件不执行
    				if(yChenge != 0){
    					if(yChenge > 0) {   
    						yChenge++;		//使棋子沿着右下一条线移动,进行判断	
    					}else {
    						yChenge--;		// 使棋子沿着右上一条线移动,进行判断
    					}
    				}
    			}
    			
    		}
    		
    		//  经过以上判断  xchange和ychange可能发生改变,所以最开始设置初始值以便接下来使用
    		xChange = tempX;
    		yChenge = tempy;   // 恢复初始值
    		
    		//以棋子为中心,横向判断为例,分为两个方向,上面是右边判断,下面是进行左边
    		while(x-xChange >=0 && x-xChange <15 && y-yChenge >=0 &&
    				y-yChenge <15 && color == allChess[x-xChange][y-yChenge]){
    			
    			//(x-xChange >=0 && x-xChange <15 && y-yChenge >=0 &&
    		//  	y-yChenge <15)    始终保持棋子在移动时保持在规定的区域内
    			
    			count++;
    			if(xChange != 0){
    				xChange++;
    			}
    			if(yChenge != 0){
    				if (yChenge > 0) {
    					yChenge++;			//使棋子沿着左上一条线移动,进行判断
    				}else {
    					yChenge--;			//使棋子沿着左下一条线移动,进行判断
    				}
    			}
    		}
    		
    		return count;
    	}

        对于横向判断,以你下的棋子为中心,依次向左移动和向右移动一格进行判断,count = this.checkCount(1,0,color);  1表示是横坐标,0表示纵坐标,因为只是横向判断所以只需改变横坐标即可。(例如所下棋子位置为(5,5)  只需判断右边(6,5)的颜色是否一致,如若一致继续向右判断,不一致就向左(4,5)依次做出判断)

        纵向判断与横向判断同理,但是需要改变纵坐标位置。count = this.checkCount(0,1,color);

        以上横纵判断完后如若没有五子相连则继续以棋子为中心右上和左下进行判断,这里的坐标需要进行改动。如对于右上进行判断为count = this.checkCount(1,-1,color);    横坐标+1  纵坐标-1。

    以上代码需要你自己多体会,画一个自己一个一个试试,能加深你的理解能力。

    5.做到以上几点就算完成了,接下来实现的是棋盘右边的功能

    //重新开始游戏
    		if(e.getX() >=430 && e.getY() <= (428+55)  && e.getY() >= 66
    			&&	e.getY() <= (66+20) ){
    			int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?"); 
    			if(result == 0){
    				restarGame();
    			}
    		}
    
    
    		public void restarGame(){
    			for (int i = 0; i < 15; i++) {
    				for (int j = 0; j < 15; j++) {
    					allChess[i][j] = 0;  //清空棋盘的棋子
    				}
    				
    			}
    			
    			//清空下棋棋子坐标的记录
    			for (int i = 0; i < 15; i++) {
    				chessX[i] = 0;
    				chessY[i] = 0;
    				
    			}
    			
    			countX =0;
    			countY =0;
    			message = "黑方先行";
    			blackMessage = "无限制";
    			whiteMessage = "无限制";
    			blackTime = maxTime;
    			whileTime = maxTime;
    			isblack = true;
    			canPlay = true;
    			this.repaint();
    			
    		}
    	

    这个就是简单的清空棋盘棋子方法,达到重新开局的效果。

    6.还有一个比较不容易理解的是悔棋功能

    	//悔棋
    		if(e.getX() >= 430 && e.getX() <= (430+55) && e.getY() >= 246 
    				&&  e.getY() <= (246+20)){
    			int result = JOptionPane.showConfirmDialog(this, 
    					(isblack == true ? "白方悔棋,黑方是否同意?" :"黑方悔棋,白方是否同意?"));
    			// result = 0为悔棋
    			if(result == 0){
    				allChess[chessX[--countX]][chessY[--countY]]=0;
    				if(isblack == true ){
    					isblack = false;
    				}else {
    					isblack = true;
    				}
    				
    				this.repaint();  //重绘棋盘
    			}
    		}

    (e.getX() >= 430 && e.getX() <= (430+55) && e.getY() >= 246 &&  e.getY() <= (246+20)  表示鼠标所点击的位置在这个范围表示悔棋。  这里其实可以用  button按钮来代替的

    先进行判断是否愿意悔棋,当确定实现悔棋时,即实现allChess[chessX[--countX]][chessY[--countY]]=0;这个功能,因为chessx[]和chessY[]用来记录你所下的步数,例如:你下到第11步时想要悔棋,这时将allChess[][]将其置0并消除第11步数字,表示没有下棋;这时轮到你下棋。这就是悔棋的原理。

    总结:以上就是对五子棋的简单实现,由于还没有接触到多线程,所以对功能进行了部分删减,这只是V1.0版本,后续将会继续增加一些新的功能。其次这个代码也并不是我原创的,只能说照着编一下吧,拿来供自己琢磨。对于学习Java有一些小小的建议,希望大家学习的时候不要总是直接复制粘贴,这样对你没多少提升,就算你原原本本照着编一下也会对你有所提升。写这篇文章也只是想分享一下自己学习,提升自己的逻辑思维。

    完整代码:

    package 模拟练习.五子棋;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.image.BufferedImage;
    public  class FiveGame extends JFrame implements MouseListener{
    	
    	private static final long serialVersionUID = 1L;
    	//设置游戏界面
    	//	屏幕分辨率求法:
    	//		int w = f.getToolkit().getScreenSize().width;//宽度
    	//		int h = f.getToolkit().getScreenSize().height;//高度
    	int width = Toolkit.getDefaultToolkit().getScreenSize().width;
    	int height = Toolkit.getDefaultToolkit().getScreenSize().height;
    	
    	int x,y;  // 定义鼠标的坐标
    	int[][] allChess = new int[15][15];   // 用数组来保存棋子,0表示无子,1表示黑子,2表示白子
    	boolean isblack = true;   //用来表示黑子还是白子, true表示黑子   false表示白子
    	boolean canPlay = true;   // 用来表示当前游戏是否结束
    	String message = "黑方先行";
    	String blackMessage = "无限制";
    	String whiteMessage = "无限制";
    	
    	//保存棋谱,记录双方每一步落子的位置
    	int[] chessX = new int[255];
    	int[] chessY = new int[255];
    	int countX,countY;
    	
    	//默认设置无时间限制
    	int maxTime = 0;   //保存最大时间
    	int blackTime = 0;
    	int whileTime = 0;   //保存黑白方所剩余的时间
    
    	public FiveGame(){
    		this.setTitle("五子棋1.0");
    		this.setSize(500,500);
    		this.setLocation((width - 500) / 2 , (height - 500) / 2 );
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setResizable(false);  //设置窗口不可改变,固定窗口大小
    		this.setVisible(true);
    		
    		this.repaint();  //java里repaint()是重绘component的方法;
    		this.addMouseListener(this);
    
    		
    	}
    	
    	//画棋盘界面
    	public void paint(Graphics g){
    		//双缓冲技术
    		BufferedImage buf = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
    		Graphics g1 =  buf.createGraphics();  // 创建画笔
    		g1.setColor(new Color(0,169,158));
    		g1.fill3DRect(43, 60, 375, 375, true);
    		
    			for (int i = 0; i <= 15; i++) {
    				g1.setColor(Color.WHITE);
    				g1.drawLine(43, 60+i*25, 375+43, 60+i*25);  //画棋盘横线
    				g1.drawLine(43+i*25, 60, 43+i*25, 375+60);  //画棋盘竖线
    			}
    			
    			g1.setFont(new Font("黑体",Font.BOLD,20));
    			g1.drawString("游戏信息:"+message,50,50);
    			
    			g1.drawRect(30, 440, 180, 40);
    			g1.drawRect(250, 440, 180, 40);   //画黑方时间与白方时间字符串的边框
    			g1.setFont(new Font("宋体",0,12));
    			
    			    g1.drawString("黑方时间: "+blackMessage,40,465);
    		        g1.drawString("白方时间: "+whiteMessage,260,465);
    		         
    		        g1.drawRect(430,66,55,20);
    		        g1.drawString("重新开始",432,80); //重新开始按钮
    		         
    		        g1.drawRect(430,106,55,20);
    		        g1.drawString("游戏设置",432,120); //游戏设置按钮
    		         
    		        g1.drawRect(430,146, 55, 20);
    		        g1.drawString("游戏说明", 432, 160); // 游戏说明按钮
    		  
    		        g1.drawRect(430, 186, 55, 20);
    		        g1.drawString("退出游戏", 432, 200);  // 退出游戏按钮
    		  
    		        g1.drawRect(430, 246, 55, 20);
    		        g1.drawString("悔棋", 442, 260);  // 悔棋
    		  
    		        g1.drawRect(430, 286, 55, 20);
    		        g1.drawString("认输", 442, 300);  // 认输
    		
    		        
    		     for(int i=0; i<15; i++){
    				for (int j = 0; j < 15; j++) {
    					//画实心黑子
    					if(allChess[i][j] == 1){    
    						int tempX = i*25+47;
    						int tempY = j*25+64;
    						g1.setColor(Color.BLACK);
    						g1.fillOval(tempX, tempY, 16, 16);
    						g1.setColor(Color.BLACK);
    						g1.drawOval(tempX, tempY, 16, 16);
    					}
    					
    					//画实心白子
    					if(allChess[i][j] == 2){
    						int tempX = i*25+47;
    						int tempY = j*25+64;
    						g1.setColor(Color.WHITE);
    						g1.fillOval(tempX, tempY, 16, 16);
    						g1.setColor(Color.WHITE);
    						g1.drawOval(tempX, tempY, 16, 16);
    					}
    				}
    			}
    		
    			
    			 g.drawImage(buf, 0, 0,this);	
    	}
    	
    	
    	
    	public void mousePressed(MouseEvent e){
    		if(canPlay){
    			x=e.getX();
    			y=e.getY();  // 用来获取鼠标坐标
    			if(x>55 && x<= 405  && y>=72 && y<=420){
    				//让鼠标在棋盘范围内
    				if((x-55)%25>12){
    					x=(x-55)/25 + 1;
    				}else {
    					x = (x-55)/25;
    				}
    				if((y-72)%25>12){
    					y=(y-72)/25 + 1;
    				}else {
    					y=(y-72)/25;
    				}
    				
    				//落子
    				if(allChess[x][y] == 0){
    					chessX[countX++] = x;
    					chessY[countY++] = y;
    					if(isblack){
    						allChess[x][y] = 1;
    						isblack = false;
    						message = "白方下子";
    					}else {
    						allChess[x][y] = 2;
    						isblack = true;
    						message = "黑方下子";
    					}
    					this.repaint();
    					
    					if(this.isWin()){
    						if(allChess[x][y] == 1){
    							JOptionPane.showMessageDialog(this, "游戏结束,黑方胜利");
    						}else {
    							JOptionPane.showMessageDialog(this, "游戏结束,白方胜利");
    						}
    						this.canPlay = false;  //表示游戏结束
    					}
    					
    					
    				}
    			}
    		}
    		
    		//重新开始游戏
    		if(e.getX() >=430 && e.getY() <= (428+55)  && e.getY() >= 66
    			&&	e.getY() <= (66+20) ){
    			int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?"); 
    			if(result == 0){
    				restarGame();
    			}
    		}
    		
    		
    		//游戏说明
    		if(e.getX() >= 430 && e.getY() <= (430+55)  && e.getY() >=146
    			&&	e.getY() <= (146+20) ){
    			JOptionPane.showMessageDialog(this, "规则:横竖斜先连成五子者获胜!");
    		}
    		
    		//退出游戏
    		if(e.getX() >=430 && e.getX() <= (430+55)  && e.getY() >=186 
    				&&  e.getY() <= (186+20)){
    			int result = JOptionPane.showConfirmDialog(this, "是否退出游戏?");
    			if(result == 0){
    				System.exit(0);
    			}
    		}
    		
    		//悔棋
    		if(e.getX() >= 430 && e.getX() <= (430+55) && e.getY() >= 246 
    				&&  e.getY() <= (246+20)){
    			int result = JOptionPane.showConfirmDialog(this, 
    					(isblack == true ? "白方悔棋,黑方是否同意?" :"黑方悔棋,白方是否同意?"));
    			// result = 0为悔棋
    			if(result == 0){
    				allChess[chessX[--countX]][chessY[--countY]]=0;
    				if(isblack == true ){
    					isblack = false;
    				}else {
    					isblack = true;
    				}
    				
    				this.repaint();  //重绘棋盘
    			}
    		}
    		
    		 //认输
            if(e.getX()>=430 && e.getX()<=(428+55) && e.getY()>=286 
            		&& e.getY()<=(286+20)){
                int result=JOptionPane.showConfirmDialog(this, "是否认输?");
                if(result==0){
                    JOptionPane.showMessageDialog(this,
                    	"游戏结束,"+(isblack==true ? "黑方认输,白方获胜!" : "白方认输,黑方获胜!"));
                }
            }
    
    	}
    	
    		public void restarGame(){
    			for (int i = 0; i < 15; i++) {
    				for (int j = 0; j < 15; j++) {
    					allChess[i][j] = 0;  //清空棋盘的棋子
    				}
    				
    			}
    			
    			//清空下棋棋子坐标的记录
    			for (int i = 0; i < 15; i++) {
    				chessX[i] = 0;
    				chessY[i] = 0;
    				
    			}
    			
    			countX =0;
    			countY =0;
    			message = "黑方先行";
    			blackMessage = "无限制";
    			whiteMessage = "无限制";
    			blackTime = maxTime;
    			whileTime = maxTime;
    			isblack = true;
    			canPlay = true;
    			this.repaint();
    			
    		}
    	
    	
    
    	/**
    	 * 判断输赢规则
    	 * @return
    	 */
    	public boolean isWin(){
    		boolean flag = false;
    		int count = 1;  //用来保存共有相同颜色多少棋子相连,初始值为1
    		int color = allChess[x][y];  //color = 1 (黑子) color = 2(白子)
    		
    		//判断横向是否有5个棋子相连,特点:纵坐标是相同,即allChess[x][y] 中y值是相同
    		count = this.checkCount(1,0,color);
    		if(count >= 5){
    			flag = true;
    		}else {
    			//判断纵向
    			count = this.checkCount(0,1,color);
    			if(count >= 5){
    				flag = true;
    			}else {
    				 //判断右上,左下
    				count = this.checkCount(1,-1,color);
    				if(count >= 5){
    					flag = true;
    				}else {
    					//判断右下,左上
    					count = this.checkCount(1,1,color);
    					if(count >= 5){
    						flag =  true;
    					}
    				}
    			}
    		}
    		
    		return flag;
    	}
    	/**
    	 * 检查棋盘中的五子棋是否连城五子
    	 * @param xChange
    	 * @param yChenge
    	 * @param color
    	 * @return
    	 */
    	public int checkCount(int xChange , int yChenge ,int color){
    		int count = 1;
    		int tempX = xChange;
    		int tempy = yChenge;  //保存初始值
    		
    		//全局变量x,y最初为鼠标点击的坐标,
    		//经下棋方法已经将x,y的范围变成0-15(遍历整个棋盘,寻找相同颜色的棋子)
    		while(x + xChange >=0 && x+xChange <15  && y+yChenge >=0 && 
    				y+yChenge < 15 && color == allChess[x+xChange][y+yChenge]){
    	
    			count++;
    			if(xChange != 0)  xChange++;    
    			if(yChenge != 0 ){      
    				if(yChenge != 0){
    					if(yChenge > 0) {   
    						yChenge++;		
    					}else {
    						yChenge--;		
    					}
    				}
    			}
    			
    		}
    		
    		
    		xChange = tempX;
    		yChenge = tempy;   // 恢复初始值
    		
    		
    		while(x-xChange >=0 && x-xChange <15 && y-yChenge >=0 &&
    				y-yChenge <15 && color == allChess[x-xChange][y-yChenge]){		
    			count++;
    			if(xChange != 0){
    				xChange++;
    			}
    			if(yChenge != 0){
    				if (yChenge > 0) {
    					yChenge++;			
    				}else {
    					yChenge--;			
    				}
    			}
    		}
    		
    		return count;
    	}
    	
    	
    
    	public void mouseClicked(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	public void mouseReleased(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	public void mouseEntered(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	public void mouseExited(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    	
    	public static void main(String[] args) {
    		new FiveGame();
    	}
    
    	
    }
    

    里面可能存在一些瑕疵,不过后续版本会进行修改。

    如若存在什么问题请联系我进行修改,你的建议将会是我最大的动力

     

    展开全文
  • 主要为大家详细介绍了Java项目实现五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • java开发的五子棋小游戏java开发的五子棋小游戏java开发的五子棋小游戏
  • java小游戏五子棋

    2011-04-29 17:56:46
    java初学者练习项目之五子棋! 人机对战! java 练习项目 五子棋 初学者 人机对战 java 练习项目 五子棋 初学者 人机对战
  • java实现五子棋小游戏

    2020-09-03 20:51:24
    主要介绍了java实现五子棋小游戏的相关资料,十分简单实用,推荐给大家,需要的朋友可以参考下
  • JAVA代码开发的五子棋小游戏,代码较小,用于初学者练手。
  • java五子棋小游戏

    2017-06-22 11:23:05
    java 五子棋 游戏
  • java 五子棋小游戏

    2017-03-03 16:02:34
    java 小游戏,供java初学者学习使用
  • Java小游戏网络五子棋

    2014-09-14 15:06:07
    Java代码编写的小游戏,已经可以在eclipse上运行成功。
  • 大学JAVA程序设计大作业 该作业是我大学时做的,以小游戏五子棋为例
  • java写的五子棋小游戏

    2020-11-04 21:01:47
    java写的五子棋,支持人机对战,双人对战. 五子棋系统应该具有选择玩家先落子还是电脑先落子的功能,应该具有开始游戏和重新开始的功能,当然了,必须具有在玩家指定位置落子的功能。以上描述,用用例图在图1中做...
  • Java小游戏网络五子棋Java实用源码整理learns.
  • JAVA小游戏五子棋

    2019-04-12 14:55:50
    一、编写五子棋的基本思路 1、游戏界面开发; 2、绘制棋盘,棋子,提示信息; 3、鼠标监听,需要保证棋子下在交叉线上; 4、胜负判定 5、按钮功能实现 6、计时器功能实现 二、以下是程序源代码: 1、游戏界面开发 ...

    一、编写五子棋的基本思路

    1、游戏界面开发;
    2、绘制棋盘,棋子,提示信息;
    3、鼠标监听,需要保证棋子下在交叉线上;
    4、胜负判定
    5、按钮功能实现
    6、计时器功能实现

    二、以下是程序源代码:

    1、游戏界面开发

    //界面开发
    public FiveChessFrame() {
    		//设置界面标题和大小
    		this.setTitle("五子棋");
    		this.setSize(1280, 760);
    		//保证游戏界面在桌面中心
    		this.setLocation((width - 1280) / 2, (height - 720) / 2);
    		// 窗体不可伸缩的
    		this.setResizable(false);
    		//界面关闭方式
    		this.setDefaultCloseOperation(3);
    		//添加鼠标监听
    		this.addMouseListener(this);
    		//用ImageIO读取背景图片文件
    		try {
    			bgImage = ImageIO.read(new File("beijing2.jpg"));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		//窗体可视
    		this.setVisible(true);
    		// 线程启动
    		t.start();
    		// 线程挂起
    		t.suspend();
    		// 刷新屏幕,防止开始游戏时无法显示(黑屏)
    		this.repaint();
    	}
    

    2、绘制棋盘,棋子,提示信息

    在这一模块中,主要使用了画笔(Graphics g)对棋盘、棋子绘制和运用双缓冲技术防止屏幕闪烁。在这一部分的主要难点在于对棋子的保存,让每下一个棋子都保留在棋盘上;而解决的思路是:用一个数组来保存棋盘上每个交点的数据,每下一棋,则改变此棋子为位置在数组中的数据;最后只需要每下一棋,就通过遍历数组就可以画出之前下过的棋子了,由此达到保存棋子的功能。
    而双缓冲技术尚是初次接触,其核心思想是:把之前棋盘上的棋局合成一张图像,每次落子时调用paint方法只需要把图像画出就可以了,这样做可以避免当棋子多时,因为一个一个地画棋子形成的延时,在视觉上看就像是屏幕闪烁一样的问题。

    //使用画笔绘制棋盘,棋子等
    	// 鼠标点击坐标
    	int x = 0;
    	int y = 0;
    	// 用二维数组保存下过的棋子数据(0没有棋子,1是黑子,2是白子)
    	int[][] allchess = new int[29][17];
    	// 提示当前下棋的是黑还是白
    	String message = "黑方先行";
    	// 保存双方剩余时间
    	String blackMessage = "无限制";
    	String whiteMessage = "无限制";
    	//画笔
    	public void paint(Graphics g) {
    	
    		// 双缓冲技术防止屏幕闪烁(大致原理为:把之前的面板当做一张图片画出,避免了工作量大时棋子画不过来)
    		BufferedImage bufferedImage = new BufferedImage(1280, 760, BufferedImage.TYPE_INT_RGB);
    		Graphics g1 = bufferedImage.createGraphics();
    
    		// 画背景,
    		g1.drawImage(bgImage, 0, 35, this);
    		g1.setFont(new Font("微软雅黑", Font.BOLD, 30));
    		g1.drawString("欢乐五子棋", 485, 70);
    		g1.setFont(new Font("宋体", Font.BOLD, 40));
    		//提示该谁落子了
    		g1.drawOval(435, 680, 200, 65);
    		g1.drawString(message, 450, 725);
    		//倒计时提示款
    		g1.setFont(new Font("黑体", Font.BOLD, 25));
    		g1.drawString("黑方时间:" + blackMessage, 95, 725);
    		g1.drawString("白方时间:" + whiteMessage, 710, 725);
    
    		// 画棋盘
    		// 画横线
    		for (int i = 0; i < 17; i++) {
    			g1.drawLine(20, 90 + 35 * i, 1002, 90 + 35 * i);
    		}
    		// 画竖线
    		for (int j = 0; j < 29; j++) {
    			g1.drawLine(20 + 35 * j, 90, 20 + 35 * j, 650);
    		}
    		// 标注四个点
    		g1.fillOval(157, 192, 7, 7);
    		g1.fillOval(857, 192, 7, 7);
    		g1.fillOval(157, 542, 7, 7);
    		g1.fillOval(857, 542, 7, 7);
    		// 中心点
    		g1.fillOval(507, 367, 7, 7);
    		// 四条边的中点
    		g1.fillOval(507, 193, 7, 7);
    		g1.fillOval(507, 542, 7, 7);
    		g1.fillOval(157, 367, 7, 7);
    		g1.fillOval(857, 367, 7, 7);
    
    		// 绘制全部棋子
    		for (int i = 0; i < 29; i++) {
    			for (int j = 0; j < 17; j++) {
    				// 下过的黑子一一画出
    				if (allchess[i][j] == 1) {
    					int tempx = i * 35 + 20;
    					int tempy = j * 35 + 90;
    					g1.fillOval(tempx - 10, tempy - 10, 20, 20);
    				}
    				// 下过的白子一一画出
    				if (allchess[i][j] == 2) {
    					int tempx = i * 35 + 20;
    					int tempy = j * 35 + 90;
    					g1.setColor(Color.WHITE);
    					g1.fillOval(tempx - 10, tempy - 10, 20, 20);
    					g1.setColor(Color.BLACK);
    					g1.drawOval(tempx - 10, tempy - 10, 20, 20);
    
    				}
    			}
    		}
    		//把面板内容当初一张图片画出
    		 g.drawImage(bufferedImage, 0, 0, this);
    	}
    
    

    3、鼠标监听,按键功能实现

    在这一模块中,因为背景的原因,没有使用JButton来构建按钮,而是通过感应鼠标点击在背景中按钮的区域来达到类似按钮的功能。其中的难点在于悔棋功能的实现,而思路是:通过每下一个棋子就记录下棋子的位置,而悔棋只需要把之前数组中棋子位置的数据改为0(0是没棋子),把先行提示改回来,再调用repaint()重绘就可以了。

    
    	// 标识当前棋子的颜色
    	boolean isBlack = true;
    	// 标识当前游戏是否可以继续
    	boolean canplay = true;
    	// 记录每一个棋子的位置
    	int chessX;
    	int chessY;
    	// 保存最多拥有多少时间(秒)
    	int maxtime = 0;
    	// 做倒计时的线程
    	Thread t = new Thread(this);
    	// 保存黑方和白方剩余时间
    	int blacktime = 0;
    	int whitetime = 0;
    	
    @Override
    	public void mousePressed(MouseEvent e) {
    		if (canplay == true) {
    			// 获取点击位置
    			x = e.getX();
    			y = e.getY();
    			// 判断鼠标是否点在棋盘上
    			if (x >= 20 && x <= 1005 && y >= 90 && y <= 655) {
    				// 保证输出的棋子在点上(说实话,这种方法下的棋子落点不够准确)
    				x = (x - 20) / 35;
    				y = (y - 90) / 35;
    
    				// 判断位置是否可以下棋(空的)
    				if (allchess[x][y] == 0) {
    					// 判断当前下的是什么棋子
    					if (isBlack == true) {
    						// 保存棋子
    						allchess[x][y] = 1;
    						//保存刚下棋子的位置
    						chessX = x;
    						chessY = y;
    						isBlack = false;
    						message = "白方先行";
    
    					} else {
    						allchess[x][y] = 2;
    						chessX = x;
    						chessY = y;
    						isBlack = true;
    						message = "黑方先行";
    					}
    					
    				} else {
    					return;
    				}
    				// 每下一棋都重新画棋盘
    				this.repaint();
    				// 每一步都判断胜负
    				boolean winFlag = this.checkWin();
    				if (winFlag == true) {
    					JOptionPane.showMessageDialog(this, "游戏结束," + (allchess[x][y] == 1 ? "黑方" : "白方") + "获胜!");
    					//锁棋盘,不再允许落子
    					canplay = false;
    				}
    			}
    		}
    		
    		// 开始游戏按钮
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 95 && e.getY() <= 135) {
    		    //提示弹框
    			int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");
    			//点击是
    			if (result == 0) {
    				JOptionPane.showMessageDialog(this, "重新开始游戏");
    				canplay = true;
    				// 清空棋盘(即把allchess数据清0,游戏信息改正,标识改正)
    				allchess = new int[29][17];
    				message = "黑方先行";
    				isBlack = true;
    				if (maxtime > 0) {
    					blackMessage = maxtime / 3600 + ":" + (maxtime / 60 - maxtime / 3600 * 60) + ":"
    							+ (maxtime - maxtime / 60 * 60);
    					whiteMessage = maxtime / 3600 + ":" + (maxtime / 60 - maxtime / 3600 * 60) + ":"
    							+ (maxtime - maxtime / 60 * 60);
    					// 重新启动线程
    					t.resume();
    				} else {
    					blackMessage = "无限制";
    					whiteMessage = "无限制";
    				}
    				this.repaint();
    
    			}
    		}
    		// 游戏设置(时间)
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 170 && e.getY() <= 210) {
    			String input = JOptionPane.showInputDialog("请输入游戏的最大时间(分钟)");
    			try {
    				maxtime = Integer.parseInt(input) * 60;
    				if (maxtime < 0) {
    					JOptionPane.showMessageDialog(this, "请输入正数");
    				}
    				if (maxtime == 0) {
    					int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");
    					if (result == 0) {
    						allchess = new int[29][17];
    						message = "黑方先行";
    						isBlack = true;
    						blacktime = maxtime;
    						whitetime = maxtime;
    						blackMessage = "无限制";
    						whiteMessage = "无限制";
    						this.repaint();
    					}
    				}
    				if (maxtime > 0) {
    					int result = JOptionPane.showConfirmDialog(this, "设置完成,是否重新开始游戏?");
    					if (result == 0) {
    						allchess = new int[29][17];
    						message = "黑方先行";
    						isBlack = true;
    						//把剩余的时间赋给二者
    						blacktime = maxtime;
    						whitetime = maxtime;
    						blackMessage = maxtime / 3600 + ":" + (maxtime / 60 - maxtime / 3600 * 60) + ":"
    								+ (maxtime - maxtime / 60 * 60);
    						whiteMessage = maxtime / 3600 + ":" + (maxtime / 60 - maxtime / 3600 * 60) + ":"
    								+ (maxtime - maxtime / 60 * 60);
    						t.resume();
    						this.repaint();
    					}
    				}
    			} catch (NumberFormatException e1) {
    				JOptionPane.showMessageDialog(this, "请规范输入时间!");
    			}
    		}
    		// 游戏说明
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 255 && e.getY() <= 295) {
    			JOptionPane.showMessageDialog(this, "此处没有说明。");
    		}
    		// 认输
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 395 && e.getY() <= 435) {
    			int result = JOptionPane.showConfirmDialog(this, "是否确认认输?");
    			if (result == 0) {
    				if (isBlack) {
    					JOptionPane.showMessageDialog(this, "黑方认输,游戏结束");
    				} else {
    					JOptionPane.showMessageDialog(this, "白方认输,游戏结束");
    				}
    				canplay = false;
    			}
    
    		}
    		// 悔棋
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 470 && e.getY() <= 515) {
    			int result = JOptionPane.showConfirmDialog(this, (isBlack == true ? "白方悔棋,黑方是否同意?" : "黑方悔棋,白方是否同意?"));
    			if (result == 0) {
    				JOptionPane.showMessageDialog(this, "对方允许悔棋,请重新落子。");
    				//把刚下的棋子数据清0
    				allchess[chessX][chessY] = 0;
    				//改变先行提示
    				if (isBlack == true) {
    					isBlack = false;
    					message = "白方先行";
    				} else {
    					isBlack = true;
    					message = "黑方先行";
    				}
    				//重画棋局
    				this.repaint();
    			}
    			if (result == 1) {
    				JOptionPane.showMessageDialog(this, "对方不允许你悔棋,请继续游戏。");
    			}
    		}
    		// 退出
    		if (e.getX() >= 1080 && e.getX() <= 1240 && e.getY() >= 555 && e.getY() <= 600) {
    			JOptionPane.showMessageDialog(this, "游戏结束");
    			//直接退出
    			System.exit(0);
    		}
    	}
    

    4、胜负判定

    在此模块中,通过五子棋的规则(横、竖、左斜、右斜任一方向上5个棋子连成一线)来判断胜负;而计数不仅要往右计数,还要往左计算,通过横纵坐标的加减来判断右边后,根据保存刚下棋子的坐标来重新向左边计数。

    	// 胜负判定(四个方向)
    	private boolean checkWin() {
    		boolean flag = false;
    		// 保存共有相同颜色相连棋子的个数
    		int count = 1;
    		// 棋子用颜色标识,1是黑子,2是白子
    		int color = allchess[x][y];
    
    		// 判断横向
    		count = this.checkCount(1, 0, color);
    		if (count >= 5) {
    			flag = true;
    		} else {
    		// 判断纵向
    		count = this.checkCount(0, 1, color);
    		if (count >= 5) {
    			flag = true;
    		} else {
    		// 判断45°
    		count = this.checkCount(1, -1, color);
    		if (count >= 5) {
    			flag = true;
    		} else {
    		// 判断135°
    		count = this.checkCount(1, 1, color);
    		if (count >= 5) {
    			flag = true;
    					}
    				}
    			}
    		}
    		return flag;
    	}
    
    	// 判定是否有5个棋子相连
    	public int checkCount(int xChange, int yChange, int color) {
    		int count = 1;
    		// 保存刚下的棋子坐标
    		int tempx = xChange;
    		int tempy = yChange;
    		//从刚下的棋子坐标开始往右边判断
    		// 每次向前移动一次,遇到同一颜色就继续判断
    		while (x + xChange >= 0 && x + xChange < 29 && y + yChange >= 0 && y + yChange < 17
    				&& color == allchess[x + xChange][y + yChange]) {
    
    			count++;
    			if (xChange != 0)
    				xChange++;
    			if (yChange != 0) {
    				if (yChange > 0) {
    					// 使棋子沿着右下一条线移动,进行判断
    					yChange++;
    				} else {
    					// 使棋子沿着右上一条线移动,进行判断
    					yChange--;
    				}
    			}
    		}
    		//从刚下的棋子坐标开始往左边判断
    		xChange = tempx;
    		yChange = tempy; 
    
    		while (x - xChange >= 0 && x - xChange < 29 && y - yChange >= 0 && y - yChange < 17
    				&& color == allchess[x - xChange][y - yChange]) {
    
    			count++;
    			if (xChange != 0) {
    				xChange++;
    			}
    			if (yChange != 0) {
    				if (yChange > 0) {
    					// 使棋子沿着左上一条线移动,进行判断
    					yChange++;
    				} else {
    					// 使棋子沿着左下一条线移动,进行判断
    					yChange--;
    				}
    			}
    		}
    
    		return count;
    	}
    

    5、计时器功能实现

    @Override
    	public void run() {
    	    //还有剩余时间,则开始计时
    		if (maxtime > 0) {
    			while (true) {
    			
    				if (isBlack) {
    					blacktime--;
    					if (blacktime == 0) {
    						JOptionPane.showMessageDialog(this, "黑方超时,游戏结束!");
    						canplay = false;
    						//线程挂起,停止计时
    						t.suspend();
    					}
    				} else {
    					whitetime--;
    					if (whitetime == 0) {
    						JOptionPane.showMessageDialog(this, "白方超时,游戏结束!");
    						canplay = false;
    						t.suspend();
    					}
    				}
    
    				// 睡眠1秒
    				try {
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				// 通过线程的运行、睡眠来间断显示blackMessage或whiteMessage来达到时间跳动的效果
    				blackMessage = blacktime / 3600 + ":" + (blacktime / 60 - blacktime / 3600 * 60) + ":"
    						+ (blacktime - blacktime / 60 * 60);
    				whiteMessage = whitetime / 3600 + ":" + (whitetime / 60 - whitetime / 3600 * 60) + ":"
    						+ (whitetime - whitetime / 60 * 60);
    				this.repaint();
    			}
    
    		}
    	}
    

    项目总结:

    在整个五子棋项目中,最让我印象深刻的是悔棋功能的事现;尽管我的思路是对的,但是老是没有找准棋子的坐标位置,甚至一度把我上一次鼠标点击的位置(x,y)当成了棋子的坐标,实际上上一次点击的位置是悔棋按钮,因此老是出现数组越界,更是揪着数组越界这个错误,又改成棋子数组的下标((x - 20) / 35, (y - 90) / 35);一番周折后才意识到问题的所在,才重新定义变量来保持棋子位置,悔棋功能得以实现。此外,在整个项目中,我对于通过JOptionPane设置弹框,通过 BufferedImage.createGraphics()实现双缓冲,通过线程的start()和suspend()、sleep()来达到计时的效果,通过标识的运用来减小代码量等等也有所收获。
    此外,在这个项目里,我也遇到了一些问题,比如使用了双缓冲技术后,我发现我的棋盘,时间计时,先行提示信息等一些通过双缓冲后的画笔画的东西都由黑色变成了白色,而且一开始下的几个黑棋也变白了;对于这个问题,不知所以然。

    展开全文
  • JAVA代码的五子棋小游戏源码整理
  • JAVA代码的五子棋小游戏Java实用源码整理learns
  • java制作五子棋小游戏。功能简单,具有悔棋、判断输赢的基本功能
  • 这是我自己写的java小游戏五子棋,没有添加什么图片,都是最基础的功能的实现,有兴趣的可以自己添加图片。
  • Java实现五子棋小游戏

    2014-04-13 19:37:53
    利用Java实现五子棋小游戏 代码80多行
  • java小游戏五子棋

    2011-04-27 11:49:28
    这是一个用java开发的手机小游戏五子棋》。
  • java五子棋游戏

    2017-08-16 21:09:20
    java五子棋小游戏,swing开发

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,903
精华内容 1,161
关键字:

java小游戏五子棋

java 订阅