zoukankan      html  css  js  c++  java
  • java swing 双人五子棋源代码

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Toolkit;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.image.BufferedImage;
    
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    
    public class FiveChessFrame extends JFrame implements Runnable,MouseListener{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	//游戏界面大小
    	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 whiteTime=0; //保存黑白方所剩余的时间
    	
    	Thread timer=new Thread(this); 
    	
    	public FiveChessFrame(){
    		this.setTitle("五子棋游戏");
    		this.setSize(500, 500);
    		this.setLocation((width - 500) / 2, (height - 500) / 2);
            this.setResizable(false);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);
            this.repaint();
            this.addMouseListener(this);
            
            timer.start();  //开启计时线程
            timer.suspend();
    	}
    	
    	//画棋盘界面
    	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(428,66,54,20);
    		g1.drawString("重新开始",432,80); //重新开始按钮
    		
    		g1.drawRect(428,106,54,20);
    		g1.drawString("游戏设置",432,120); //游戏设置按钮
    		
            g1.drawRect(428, 146, 54, 20);
            g1.drawString("游戏说明", 432, 160); // 游戏说明按钮
     
            g1.drawRect(428, 186, 54, 20);
            g1.drawString("退出游戏", 432, 200);  // 退出游戏按钮
     
            g1.drawRect(428, 246, 54, 20);
            g1.drawString("悔棋", 442, 260);  // 悔棋
     
            g1.drawRect(428, 286, 54, 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.BLACK);
    	        		g1.drawOval(tempX, tempY, 16, 16);
    	        	}
            	}
            }
    		g.drawImage(buf, 0, 0,this);
    	}
    	
    	
    	@Override
    	public void mousePressed(MouseEvent e){
    		if(canPlay){
    			x=e.getX();
    			y=e.getY(); //获得鼠标坐标
    			
    			if(x>=55 && x<=405 && y>=72 && y<=420){
    				//使x,y在0-15的范围
    				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()>=428 && e.getY()<=(428+54) && e.getY()>=66 && e.getY()<=(66+20)){
    			int result=JOptionPane.showConfirmDialog(this,"是否重新开始游戏?"); //0表示重新开始
    			if(result==0){
    				restartGame();
    			}
    		}
    		
    		//游戏倒计时设置
    		if (e.getX()>=428 && e.getX()<=(428+54) && e.getY()>= 106 && e.getY()<=(106+20)) {
    			String time=JOptionPane.showInputDialog("请输入游戏的最大时间(单位:分钟),如果输入0,表示没有时间限制:");
    			maxTime=Integer.parseInt(time)*60;  //将分钟转换为秒,以便后面计算
    			if(maxTime<0){
    				JOptionPane.showMessageDialog(this,"输入的游戏时间有误,请重新设置!");
    			}
    			else if(maxTime==0){
    				int result=JOptionPane.showConfirmDialog(this,"游戏时间设置成功,是否重新开始游戏?");
    				//重新开始
    				if(result==0){
    					restartGame();
    					timer.suspend(); //挂起线程,以便之后重新启动
    				}
    			}
    			else if(maxTime>0){
    				int result = JOptionPane.showConfirmDialog(this,"游戏时间设置成功,是否重新开始游戏?");
    				if(result==0){
    					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]=-1;
    						chessY[i]=-1;
    					}
    					countX=0;
    					countY=0;
    					message="黑方先行";
    					isblack=true;
    					
    					blackMessage=maxTime/3600+":"+(maxTime/60-maxTime/3600*60)+":"+(maxTime-maxTime/60*60);
    					whiteMessage = maxTime/3600 + ":" + (maxTime/60-maxTime/3600*60) + ":"+ (maxTime-maxTime/60*60);
    					
    					blackTime=maxTime;  
    					whiteTime=maxTime;
    					timer.resume();
    					this.canPlay=true; 
    					this.repaint();
    				}
    			}
    		
    		}
    		
    		
    		//游戏说明
    		if(e.getX()>=428 && e.getY()<=(428+54) && e.getY()>=146 && e.getY()<=(146+20)){
    			JOptionPane.showMessageDialog(this,"规则:横竖斜先连成五子者获胜!");
    		}
    		
    		//退出游戏
    		 if(e.getX()>=428 && e.getX()<=(428+54) && e.getY()>=186 && e.getY()<=(186+20)) {
    			 int result=JOptionPane.showConfirmDialog(this,"是否退出游戏?");
    			 if(result==0){
    				 System.exit(0);
    			 }
    		 }
    		 
    		 //悔棋
    		 if(e.getX()>=428 && e.getX()<=(428+54) && 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()>=428 && e.getX()<=(428+54) && e.getY()>=286 && e.getY()<=(286+20)){
    			 int result=JOptionPane.showConfirmDialog(this, "是否认输?");
    			 if(result==0){
    				 JOptionPane.showMessageDialog(this,"游戏结束,"+(isblack==true ? "黑方认输,白方获胜!" : "白方认输,黑方获胜!"));
    			 }
    		 }
    		 
    	}
    	
    	//计时
    	@Override
    	public void run() {
    		if(this.maxTime>0){
    			while(true){
    				if(isblack){
    					blackTime--;
    					if(blackTime==0){
    						JOptionPane.showMessageDialog(this,"黑方超时,游戏结束");
    						restartGame();
    						timer.suspend();
    					}
    				}
    				else{
    					whiteTime--;
    					if(whiteTime==0){
    						JOptionPane.showMessageDialog(this,"白方超时,游戏结束");
    						restartGame();
    						timer.suspend();
    					}
    				}
    				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();
    				try {
    					Thread.sleep(1000);  //设置与时钟同步,1秒钟记一次
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    	}
    	
    	@Override
    	public void mouseClicked(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void mouseReleased(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void mouseEntered(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void mouseExited(MouseEvent e) {
    		// TODO Auto-generated method stub
    		
    	}
    	
    	public void restartGame(){
    		for(int i=0;i<15;i++){
    			for(int j=0;j<15;j++){
    				allChess[i][j]=0;  //清空棋盘的棋子
    			}
    		}
    		//清空下棋棋子坐标(x,y)的记录
    		for(int i=0;i<15;i++){
    			chessX[i]=0;
    			chessY[i]=0;
    		}
    		
    		countX=0;
    		countY=0;
    		message="黑方先行";
    		blackMessage="无限制";
    		whiteMessage="无限制";
    		blackTime=maxTime;
    		whiteTime=maxTime;
    		isblack=true;
    		canPlay=true;
    		this.repaint();
    	}
    	
    	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;
    		
    	}
    	
    	public int checkCount(int xChange,int yChange,int color){
    		int count=1;
    		int tempX=xChange;
    		int tempY=yChange; //保存初始值
    		
    		//全局变量x,y最初为鼠标点击的坐标,经下棋方法已经将x,y的范围变成0-15(遍历整个棋盘,寻找相同颜色的棋子)
    		while(x+xChange>=0 && x+xChange<15 && y+yChange>=0 && y+yChange<15 && color==allChess[x+xChange][y+yChange]){
    			count++;
    			if(xChange!=0) xChange++;
    			if(yChange!=0){
    				if(yChange!=0){
    					if(yChange>0) yChange++;
    					else {
    						yChange--;
    					}
    				}
    			}
    		}
    		xChange=tempX;
    		yChange=tempY;
    		while(x-xChange>=0 && x-xChange<15 && y-yChange>=0 && y-yChange<15 && color==allChess[x-xChange][y-yChange]){
    			count++;
    			if(xChange!=0){
    				xChange++;
    			}
    			if(yChange!=0){
    				if(yChange>0) yChange++;
    				else{
    					yChange--;
    				}
    			}
    		}
    		return count;
    	}
    	
    
    	public static void main(String[] args) {
    		new FiveChessFrame();
    	}
    
    }
    
  • 相关阅读:
    博客是一种心情
    双显示器和双鼠标
    C++ Primer Plus 第六版 代码笔记
    Bug,昂首走进2005
    让万能五笔2004免费版改首页的功能见鬼去吧。
    Gmail提供POP3和SMTP已经老长时间了
    快过年回家了,发点实用的东西给大家
    关于博客园Post的时候排版的一点小建议
    在.Net下进行MicroStation(GG)的开发(一)
    验证域的另一方法
  • 原文地址:https://www.cnblogs.com/zhangming-blog/p/4133759.html
Copyright © 2011-2022 走看看