五子棋1.0(Java单机版)

简介

这个程序实现了单机版五子棋,目前无法联机,只能自己跟自己下。
棋盘是20*20的。
主要功能:下棋、认输、悔棋、重新开始、退出等功能
PS:目前设置只有显示游戏规则。

截图

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

完整代码

package Gobang;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
//import java.applet.*;
//import java.net.*;
//import java.io.*;
//import javax.imageio.*;
public class Frame  extends JFrame implements MouseListener,ActionListener{//JFrame的扩展类

	private static final long serialVersionUID = 1L;
	JPanel panel1;//用于安放按钮;
	JButton RestartButton,SetButton,AdmitDefeatButton,RegretButton,ExitButton;//五个按钮,各有其功能。
	Graphics g;//画笔
	BufferedImage buf;
	int x;//鼠标的坐标
	int y;
	int[][] Chess = new int[20][20];   // 保存棋子,1表示黑子,2表示白子
	boolean IsBlack = true;   //表示当前要下的是黑子还是白子,true表示黑子,false表示白子
	boolean IsFinish = false;   //表示当前游戏是否结束
	int xRange;
	int yRange;
	int[] chessX = new int[400];//用来保存从开始到当前的所有棋子,用于悔棋;
	int[] chessY = new int[400];
	int countX = 0;
	int countY = 0;
	/*本来想用于播放背景音乐,但是没有成功,,,先暂时放弃
	//File f;
	//URI uri;
	//URL url;
	//@SuppressWarnings("deprecation")
	*/
	//
	public Frame() {
		//设置标题、大小、排列方式等
		this.setTitle("五子棋");
		this.setSize(500,550);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		this.setLayout(null);
		//五个按钮:重新开始、设置、认输、悔棋、退出。
		RestartButton = new JButton("重新开始");
		RestartButton.setSize(20,40);
		SetButton = new JButton("设置");
		SetButton.setSize(20,40);
		AdmitDefeatButton = new JButton("认输");
		AdmitDefeatButton.setSize(20,40);
		RegretButton = new JButton("悔棋" );
		RegretButton.setSize(20,40);
		ExitButton = new JButton("退出");
		ExitButton.setSize(20,40);
		//五个按钮添加到中间容器;
		panel1 = new JPanel();
		panel1.setBorder(BorderFactory.createLoweredBevelBorder()); //设置边框
		panel1.setLayout(new GridLayout(1,5));
		panel1.add(RestartButton);
		panel1.add(SetButton);
		panel1.add(AdmitDefeatButton);
		panel1.add(RegretButton);
		panel1.add(ExitButton);
		this.add(panel1);
		panel1.setSize(460,20);
		panel1.setLocation(0, 460);
		
		this.repaint();//表示重新绘制画布,可以自动调用paint函数;
		//本类作为监听类,包括鼠标监听和按钮动作监听;
		this.addMouseListener(this);
		RestartButton.addActionListener(this);
		SetButton.addActionListener(this);
		AdmitDefeatButton.addActionListener(this);
		RegretButton.addActionListener(this);
		ExitButton.addActionListener(this);
		/*音频播放部分
		try {
			f = new File("");
			uri = f.toURI();
			url = uri.toURL();
			AudioClip aau; 
			aau = Applet.newAudioClip(url);
			aau.loop();  //循环播放
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		*/
	}
	//画布绘制
	public void paint(Graphics g)
	{
		if(g == null)//如果第一次绘制,新建一个图片,并且创建画布。
		{
			buf = new BufferedImage(450, 450, BufferedImage.TYPE_INT_RGB);
			g =  buf.createGraphics();
		}
		if(g != null)//
		{
			super.paint(g);//表示在原来图像的基础上,再画图
			g.setColor(new Color(249,205,173));//画笔颜色调成褐色;
			g.fill3DRect(20, 40, 400, 400,true);//用画笔画一个边长为400的正方形;边距为20,40
			for(int i = 0; i <= 20; i++)//用画笔横竖各画19条线
			{
				g.setColor(Color.BLACK);//画笔颜色调为黑色;
				g.drawLine(20,40+i*20,420,40+i*20);
				g.drawLine(20+i*20,40,20+i*20,440);
			}
		}
		 for(int i=0; i<20; i++){
				for (int j = 0; j < 20; j++) {
					//画实心黑子,直径16
					if(Chess[i][j] == 1){    
						int tempX = i*20+12;
						int tempY = j*20+32;
						g.setColor(Color.BLACK);
						g.fillOval(tempX, tempY, 16, 16);
						g.setColor(Color.BLACK);
						g.drawOval(tempX, tempY, 16, 16);
					}
					
					//画实心白子,直径16
					if(Chess[i][j] == 2){
						int tempX = i*20+12;
						int tempY = j*20+32;
						g.setColor(Color.WHITE);
						g.fillOval(tempX, tempY, 16, 16);
						g.setColor(Color.WHITE);
						g.drawOval(tempX, tempY, 16, 16);
					}
				}
			}
		g.drawImage(buf, 0, 0,this);
		
	}		

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
		if(!IsFinish)	//判断棋局是否结束
		{
			x = e.getX();	//获取当前鼠标点击位置
			y = e.getY();
			if(x >= 20 && x < 420 && y >= 40 && y<= 440)//判断鼠标是否在棋局内
			{
				xRange = (x-20)%20;
				if(xRange > 10 && xRange < 20)	//如果在交叉点的边长为10的范围内,就把棋子下在这;
				{
					x = (x - 20) / 20 + 1;
				}
				else
				{
					x = (x - 20) / 20;
				}
				yRange = (y-40)%20;
				if(yRange > 10 && yRange < 20)
				{
					y = (y - 40) / 20 + 1;
				}
				else
				{
					y = (y - 40) / 20;
				}
				
				if(Chess[x][y] == 0)	//如果该交叉点没有被下过;
				{
					chessX[countX++] = x;	//存储当前棋子的位置;
					chessY[countY++] = y;
					if(IsBlack)			//如果是黑子
					{
						Chess[x][y] = 1;
						IsBlack = false;
					}
					else
					{
						Chess[x][y] = 2;
						IsBlack = true;
					}
					this.repaint();//重新绘制画布
				}
				
				if(this.isWin())//如果下棋之后赢了,弹出对话框
				{
					if(Chess[x][y] == 1)
					{
						JOptionPane.showMessageDialog(this, "黑方胜利");
					}
					else 
					{
						JOptionPane.showMessageDialog(this, "白方胜利");
					}
					this.IsFinish = true;  //游戏结束
				}
				
			}
			

		}
	}
	
	public boolean isWin(){
		boolean flag = false;
		int count = 1; 
		int color = Chess[x][y];  
		//判断横向是否有5个棋子相连
		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;
	}
	 // 检查棋盘中的五子棋是否连成五子,xChange,yChange为相对于当前棋子位置的变化量
	public int checkCount(int xChange , int yChange ,int color){
		int count = 1;//统计总共有几个连着的棋子;
		int tempX = xChange;
		int tempy = yChange;  
		//判断棋子右边有没有相同颜色的棋子;
		while(x + xChange >=0 && x+xChange <20  && y+yChange >=0 && 
				y+yChange < 20 && color == Chess[x+xChange][y+yChange])
		{
			count++;						//如果有,棋子数加一
			if(xChange != 0)  
				xChange++;    				//如果横向方向变化,x相对位置加一
			if(yChange != 0 )				
			{      
				if(yChange != 0)			
				{
					if(yChange > 0)			//如果纵向方向增加,y相对位置加一
					{   
						yChange++;		
					}
					else 					//如果纵向方向减小,y相对位置减一
					{
						yChange--;		
					}
				}
			}
			
		}
		xChange = tempX;
		yChange = tempy;  
		//判断棋子左边有没有相同颜色的棋子;
		while(x-xChange >=0 && x-xChange <20 && y-yChange >=0 &&
				y-yChange <20 && color == Chess[x-xChange][y-yChange])
		{		
			count++;
			if(xChange != 0)
			{
				xChange++;
			}
			if(yChange != 0)
			{
				if (yChange > 0) 
				{
					yChange++;			
				}
				else 
				{
					yChange--;			
				}
			}
		}
		return count;
	}
	//监听动作函数
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource() == RestartButton)//如果点击的按钮是RestartButton,清空画板,还原设置
		{
			if(JOptionPane.showConfirmDialog(this, "Do you want to restart the game?") == 0)
			{
				for (int i = 0; i < 15; i++) 
				{
					for (int j = 0; j < 15; j++) 
					{
						Chess[i][j] = 0;  //清空棋盘的棋子
					}
					
				}
				
				//清空下棋棋子坐标的记录
				for (int i = 0; i < 15; i++)
				{
					chessX[i] = 0;
					chessY[i] = 0;
				}
				countX =0;
				countY =0;
				IsBlack = true;
				IsFinish = false;
				this.repaint();
			}
		}
		if(e.getSource() == AdmitDefeatButton)//如果点击的按钮是AdmitDefeatButton,结束游戏,并提示
		{
			if(!IsFinish)	//判断棋局是否结束
			{
				if(JOptionPane.showConfirmDialog(this, "Are you sure you want to give up?") == 0)
				{
					if(IsBlack == true)
					{
						JOptionPane.showMessageDialog(this,"白方获胜");
					}
					else
					{
						JOptionPane.showMessageDialog(this,"黑方获胜");
					}
					IsFinish = true;
				}
			}
		}
		if(e.getSource() == ExitButton)//如果点击的按钮是ExitButton,退出程序
		{
			if(JOptionPane.showConfirmDialog(this, "Do you want to exit?") == 0)
			{
				System.exit(0);
			}
		}
		if(e.getSource() == RegretButton)///如果点击的按钮是RegretButton,悔棋一步
		{
			if(!IsFinish)	//判断棋局是否结束
			{
			if(IsBlack == true)	//如果现在是黑子要下,表示悔棋的是白子
			{
				if(JOptionPane.showConfirmDialog(this, "The white want to regret,do you agree?") == 0)
				{
					int tempX = chessX[--countX];	//获取上一步白子下的位置;
					int tempY = chessY[--countY];
					Chess[tempX][tempY] = 0;	//撤回白子
					IsBlack = false;	//当前要下的变为白方
				}
			}
			else
			{
				if(JOptionPane.showConfirmDialog(this, "The black want to regret,do you agree?") == 0)
				{
					int tempX = chessX[--countX];
					int tempY = chessY[--countY];
					Chess[tempX][tempY] = 0;
					IsBlack = true;
				}
			}
			this.repaint();	//重新绘制画布
			}
		}
		if(e.getSource() == SetButton)	//设置按钮,现在只显示游戏规则
		{
				 JDialog frame1 = new JDialog();//新建对话框
				 frame1.setBounds(			//设置对话框边界
			                new Rectangle(
			                        0,
			                        260, 
			                        600, 
			                        200
			                )
			            );
				 JTextField tf = new JTextField();//新建文本框
				 frame1.setTitle("Play Rule");
			     frame1.getContentPane().add(tf);	//添加文本框
			     tf.setText("The two sides use black and white pieces respectively.\n At the intersection of the straight line and horizontal line of the chessboard, \nthe one who forms a five piece line first wins.");
			     frame1.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);    // 设置模式类型
			     frame1.setVisible(true);
		 }        
	}
	public static void main(String[] args) {
		new Frame();
}
	@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
		
	}
}



  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值