Java实现单机版五子棋游戏的示例代码

目录
  • 前言
  • 主要需求
  • 主要设计
  • 功能截图
  • 代码实现
  • 总结

前言

五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏,是世界智力运动会竞技项目之一,通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成5子连线者获胜。

棋具与围棋通用,起源于中国上古时代的传统黑白棋种之一。主要流行于华人和汉字文化圈的国家以及欧美一些地区,是世界上最古老的棋。

容易上手,老少皆宜,而且趣味横生,引人入胜;不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。

用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

1、对局双方各执一色棋子。

2、空棋盘开局。

3、玩家(黑棋)先、AI(红棋)后,交替下子,每次只能下一子。

4、棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。

5、黑方的第一枚棋子可下在棋盘任意交叉点上。

6、轮流下子是双方的权利,但允许任何一方放弃下子权,先形成5子连线者获胜。

主要设计

1、由于是单机的游戏,启动游戏后,可直接开始游戏。

2、游戏规则:

  • 对局双方各执一色棋子。
  • 空棋盘开局。
  • 黑先、红后,交替下子,每次只能下一子。
  • 棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。
  • 黑方的第一枚棋子可下在棋盘任意交叉点上。
  • 轮流下子是双方的权利,但允许任何一方放弃下子权,先形成5子连线者获胜。

3、设计排行榜功能

统计局数,步数和结果

4、更换棋盘

可以切换不同的棋盘,下棋更加赏心悦目。

5、更换棋子

可以芀不同的棋子颜色。

功能截图

启动游戏:

对战效果

切换棋盘:

代码实现

主界面:

package wuziqi;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class Wumain extends JFrame{
	Pan p = null;
	JMenuBar menuber = new JMenuBar();
	JMenu jm1 = new JMenu("选项");
	JMenu jm2 = new JMenu("设置");
	JMenu jm3 = new JMenu("帮助");
	JMenuItem jm1_1 = new JMenuItem("重新开始");
	JMenuItem jm1_2 = new JMenuItem(" 排行榜");
	JMenuItem jm1_3 = new JMenuItem("退出游戏");
	JMenuItem jm2_1 = new JMenuItem("更换棋盘");
	JMenuItem jm2_2 = new JMenuItem("更换棋子");
	JMenuItem jm3_1 = new JMenuItem("关于我们");
	public Wumain()
	{
		   p =new Pan();
		   this.setSize(585,600);
		   this.setLocation(200,100);
		   this.add(p);
		   this.setResizable(false);
		   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		   jm1.add(jm1_1);
		   jm1.add(jm1_2);
		   jm1.add(jm1_3);
		   jm2.add(jm2_1);
		   jm2.add(jm2_2);
		   jm3.add(jm3_1);
		   menuber.add(jm1);
		   menuber.add(jm2);
		   menuber.add(jm3);
		   this.setJMenuBar(menuber);
		   this.addMouseListener(p);
		   jm1_3.addActionListener(new ActionListener() {
//			匿名虚构类
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);

			}
		});
		   jm1_1.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				for(int i=0;i<p.row;i++){
					for(int j=0;j<p.col;j++){
						p.num[i][j] = 0;
					}
				}
				p.canSetqizi = true;
				p.qizi_num = 0;
				repaint();
			}
		});
		   jm2_1.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				Random r = new Random();
				int n = r.nextInt(8);
				String qipan_name = "qipan"+n+".jpg";
				p.qipan_name = qipan_name;
				repaint();
			}
		});
		   jm2_2.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				Random r = new Random();
				int n = r.nextInt(8);
				String qizi1_name = "c"+n+".png";
				String qizi2_name = "c"+(n+1)+".png";
				p.qizi1_name = qizi1_name;
				p.qizi2_name = qizi2_name;
				repaint();
			}
		});
		   jm3_1.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String msg ="关于我们\n" +
						"1、玩家先落子;\n" +
						"2、形成5颗同色连子即为赢;\n\n\n" +
						"  ";
				JOptionPane.showMessageDialog(null, msg);

			}
		});
		   jm1_2.addActionListener(new ActionListener() {

			   public void actionPerformed(ActionEvent e) {
			String msg ="排行榜\n" +
					"局数      步数      结果\n";
			for(int i=0;i<p.paihanglist.size();i++)
			{
				PaiHangBang ph = p.paihanglist.get(i);
			      msg = msg+"   "+ph.getJushu()
			    		  +"          "+ph.getBushu()
			    		  +"          "+ph.getJieguo()+"\n";
			}
				JOptionPane.showMessageDialog(null, msg);
			   }
		});
		   this.setVisible(true);
	}
	public static void main(String[] args){
		Wumain w = new Wumain();
	}
}

排行榜

package wuziqi;

public class PaiHangBang {

	private int jushu;
	private int bushu;
	private String jieguo;
	public int getJushu() {
		return jushu;
	}
	public void setJushu(int jushu) {
		if(jushu<1){
			this.jushu = 1;
		}
		this.jushu = jushu;
	}
	public int getBushu() {
		return bushu;
	}
	public void setBushu(int bushu) {
		this.bushu = bushu;
	}
	public String getJieguo() {
		return jieguo;
	}
	public void setJieguo(String jieguo) {
		this.jieguo = jieguo;
	}
}

棋盘

package wuziqi;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Pan extends JPanel implements MouseListener{
	int i=0,j=0;
	int row = 15;
//	数组下标
	int col = 15;
//	数组上标
	String qipan_name = "qipan1.jpg";
	String qizi1_name = "c1.png";
	String qizi2_name = "c2.png";
	int num[][] = new int[row][col];
//	0:标示该位置为空,1:标示红棋子,2:标示黑棋子
	boolean canSetqizi = true;
//	定义boolean值,用来判断该位置是否有子
	int qizi_num = 0;
//	定义记录落子数
	List<PaiHangBang> paihanglist = new ArrayList();
//	定义集合,用来存储排行榜
	public void paint(Graphics g){
		super.paint(g);
		Image img= new ImageIcon("img/"+qipan_name).getImage();
//		调入棋盘图片
		g.drawImage(img, 0, 0, 567, 567, this);
//		绘制棋盘
		Image c1= new ImageIcon("img/"+qizi1_name).getImage();
		Image c2= new ImageIcon("img/"+qizi2_name).getImage();
		for(int i = 0;i<num.length;i++){
			for(int j = 0;j<num[i].length;j++){
				if(num[i][j] == 1)
				{
					g.drawImage(c1, i*35+20, j*35+20, 35, 35, this);
				}
				else if(num[i][j] == 2)
				{
					g.drawImage(c2, i*35+20, j*35+20, 35, 35, this);
				}
			}
//			重绘棋子
		}
//		重载整个界面(防止最小化后原内容丢失)
	}
	public int[] getLoc(int x,int y) {
		int count = 1;
//		定义计数器,用于计算棋子数
		int[] wz1 = null;
		int[] wz2 = null;
//		定义数组,用来存储危险位置
		for(int i =x-1;i>=0;i--){
			if(num[i][y] == num[x][y])
			{
				count++;
			}
			else
			{
				if(num[i][y] == 0){
					wz1 = new int[]{i,y};
//					获取左边的危险位置坐标
				}
				break;
			}
		}
//		左
		for(int i =x+1;i<row;i++){
			if(num[i][y] == num[x][y])
			{
				count++;
			}else{
				if(num[i][y] == 0){
					wz2 = new int[]{i,y};
//					获取有变位置危险坐标
				}
				break;
			}
		}
//		右
		if(count>=3)
		{
			if(wz1 != null){
				return wz1;
//				判断返回左边危险位置
			}else if(wz2 != null){
				return wz2;
//				判断返回右边危险位置
			}else{
				return null;
			}
		}
//		左右
		count = 1;
		wz1 = null;
		wz2 = null;
//		初始化所有参数
		for(int j =y-1;j>=0;j--){
			if(num[x][j] == num[x][y])
			{
				count++;
			}
			else
			{
				if(num[x][j] == 0){
					wz1 = new int[]{x,j};
				}
				break;
			}
		}
//		上
		for(int j =y+1;j<col;j++){
			if(num[x][j] == num[x][y])
			{
				count++;
			}else{
				if(num[x][j] == 0){
					wz2 = new int[]{x,j};
				}
				break;
			}
		}
//		下
		if(count>=3)
		{
			if(wz1 != null){
				return wz1;
			}else if(wz2 != null){
				return wz2;
			}else{
				return null;
			}
		}
//		上下
		count = 1;
		wz1 = null;
		wz2 = null;
		for(int i =x-1,j =y-1;i>=0&&j>=0;i--,j--){
			if(num[i][j] == num[x][y])
			{
				count++;
			}
			else
			{
				if(num[i][j] == 0){
					wz1 = new int[]{i,j};
				}
				break;
			}
		}
//		左上
		for(int i =x+1,j =y+1;i<row&&j<col;i++,j++){
			if(num[i][j] == num[x][y])
			{
				count++;
			}else{
				if(num[i][j] == 0){
					wz2 = new int[]{i,j};
				}
				break;
			}
		}
//		右下
		if(count>=3)
		{
			if(wz1 != null){
				return wz1;
			}else if(wz2 != null){
				return wz2;
			}else{
				return null;
			}
		}
//		左上右下
		count = 1;
		wz1 = null;
		wz2 = null;
		for(int i =x-1,j =y+1;i>=0&&j<col;i--,j++){
			if(num[i][j] == num[x][y])
			{
				count++;
			}
			else
			{
				if(num[i][j] == 0){
					wz1 = new int[]{i,j};
				}
				break;
			}
		}
//		左下
		for(int i =x+1,j =y-1;i<row&&j>=0;i++,j--){
			if(num[i][j] == num[x][y])
			{
				count++;
			}else{
				if(num[i][j] == 0){
					wz2 = new int[]{i,j};
				}
				break;
			}
		}
//		右上
		if(count>=3)
		{
			if(wz1 != null){
				return wz1;
			}else if(wz2 != null){
				return wz2;
			}else{
				return null;
			}
		}
//		左下右上
		return null;
	}
	public boolean iswin(int x,int y){
		int count = 1;
		for(int i =x-1;i>=0;i--){
			if(num[i][y] == num[x][y])
			{
				count++;
			}
			else
			{
				break;
			}
		}
//		左
		for(int i =x+1;i<row;i++){
			if(num[i][y] == num[x][y])
			{
				count++;
			}else{
				break;
			}
		}
//		右
		if(count>=5)
		{
			return true;
		}
//		左右
		count = 1;
		for(int j =y-1;j>=0;j--){
			if(num[x][j] == num[x][y])
			{
				count++;
			}
			else
			{
				break;
			}
		}
//		上
		for(int j =y+1;j<col;j++){
			if(num[x][j] == num[x][y])
			{
				count++;
			}else{
				break;
			}
		}
//		下
		if(count>=5)
		{
			return true;
		}
//		上下
		count = 1;
		for(int i =x-1,j =y-1;i>=0&&j>=0;i--,j--){
			if(num[i][j] == num[x][y])
			{
				count++;
			}
			else
			{
				break;
			}
		}
//		左上
		for(int i =x+1,j =y+1;i<row&&j<col;i++,j++){
			if(num[i][j] == num[x][y])
			{
				count++;
			}else{
				break;
			}
		}
//		右下
		if(count>=5)
		{
			return true;
		}
//		左上右下
		count = 1;
		for(int i =x-1,j =y+1;i>=0&&j<col;i--,j++){
			if(num[i][j] == num[x][y])
			{
				count++;
			}
			else
			{
				break;
			}
		}
//		左下
		for(int i =x+1,j =y-1;i<row&&j>=0;i++,j--){
			if(num[i][j] == num[x][y])
			{
				count++;
			}else{
				break;
			}
		}
//		右上
		if(count>=5)
		{
			return true;
		}
//		左下右上
		return false;
	}
//	判断输赢
	@Override
	public void mouseClicked(MouseEvent e) {
		if(canSetqizi){
			Graphics g = this.getGraphics();
			int checkusersuccess = 0;
//			标示是否落子成功
			int x = e.getX();
			int y = e.getY();
//			获取鼠标点击的位置
			Image c1= new ImageIcon("img/"+qizi1_name).getImage();
			int i = (x-25)/35;
			int j = (y-75)/35;
			if(num[i][j] != 0){
	             JOptionPane.showMessageDialog(null, "该位置有旗子,请重新落子");
	             return;
//	             判断有子,终止本次事件,进行下次事件触发
			}else{
				g.drawImage(c1, i*35+20, j*35+20, 35, 35, this);
//				画出玩家落子
				num[i][j] = 1;
//				给数组付一个只值,表示该位置有旗子
				checkusersuccess = 1;
//				标示量标示
				qizi_num++;
//				记录玩家落子步数
			}
			boolean b=iswin(i,j);
			if(b){
				JOptionPane.showMessageDialog(null, "你赢了!");
				canSetqizi = false;
				PaiHangBang ph = new PaiHangBang();
				ph.setJushu(paihanglist.size()+1);
				ph.setBushu(qizi_num);
				ph.setJieguo("win");
				paihanglist.add(ph);
				return;
			}
//			调用boolean判断方法
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
//			时间间隔:玩家落子后的等待
			Random r = new Random();
			Image c2 = new ImageIcon("img/"+qizi2_name).getImage();
//			调入黑棋子图片
			do{
				int[] wz =getLoc(i, j);
				if(wz == null){
			i = r.nextInt(15);
			j = r.nextInt(15);
				}else{
					i=wz[0];
					j=wz[1];
				}
//			设置随机的坐标
			}while(num[i][j] != 0);
			g.drawImage(c2, i*35+20, j*35+20, 35, 35, this);
			num[i][j] = 2;
			boolean d=iswin(i,j);
			if(d){
				JOptionPane.showMessageDialog(null, "你输了!");
				canSetqizi = false;
				PaiHangBang ph = new PaiHangBang();
				ph.setJushu(paihanglist.size()+1);
				ph.setBushu(qizi_num);
				ph.setJieguo("fail");
				paihanglist.add(ph);
				return;
			}
//			随机电脑落子位置;
		}
	}

	@Override
	public void mousePressed(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

	}

}

总结

通过此次的《五子棋单机版》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

以上就是Java实现单机版五子棋游戏的示例代码的详细内容,更多关于Java五子棋的资料请关注我们其它相关文章!

时间: 2022-09-17

java实现单机版五子棋小游戏

简单的java小游戏–单机版五子棋 学了java有一段时间了,今天就来搞一个简单的单机版五子棋游戏. 实现功能:那必须能进行基础的输赢判断.还有重新开始的功能,悔棋的功能,先手设置的功能和退出的功能.在右上角能够显示目前轮到哪个棋种下棋.右下角还有一个记录信息框,记录行为,当信息量过多时,可以清除信息内容. 成果: 初始界面: 游戏(获胜)界面: 附上代码: Chessframe.java package firstgobang; import javax.swing.JFrame; impor

Java实现五子棋游戏单机版(1.0)

本文实例为大家分享了Java实现五子棋游戏单机版的具体代码,供大家参考,具体内容如下 简介 这个程序实现了单机版五子棋,目前无法联机,只能自己跟自己下.棋盘是20*20的.主要功能:下棋.认输.悔棋.重新开始.退出等功能 PS:目前设置只有显示游戏规则. 截图 完整代码 package Gobang; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; //impor

Java实现五子棋单机版

本文实例为大家分享了Java实现五子棋单机版的具体代码,供大家参考,具体内容如下 Java五子棋设计流程: 1.创建窗口和设计一个棋盘界面 2.实现鼠标点击,棋子出现,黑白棋轮流下 3.能够判断输赢 4.添加按钮功能 实现结果图: import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Graphics; imp

java实现单机版五子棋

这个小游戏是我和我姐们儿的JAVA课程设计,也是我做的第一个JAVA项目,适合初学者,希望能帮到那些被JAVA课设所困扰的孩纸们~~~ 一.该游戏需要实现 1.设计主框架,界面. 2.利用ActionListener接口实现按钮事件的监听. 3.重新开始功能的实现. 4.悔棋功能的实现. 5.退出功能的实现. 6.棋盘中棋子点类的定义. 7.利用MouseListener接口实现事件监听,并实现接口里的所有方法. 8.当鼠标移动到棋盘上的交点上,且该点上无棋子时能够变成小手形状. 9.点击棋盘时

Java五子棋单机版源码分享

初学JavaGUI编程,就写了一个小游戏–五子棋. 目前只实现了单机版,任何事情都是从简制作的,有问题请大牛们不吝指教啊. 此处的棋盘和棋子都未用图片,全部都是使用Java中的Graphics画出来的. 源码已提交至GitHub,点击此处GitHub源码 以下列出其中的五子棋类: import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; imp

Java棋类游戏实践之单机版五子棋

本文实例讲述了java实现的五子棋游戏代码,分享给大家供大家参考,具体代码如下 一.实践目标        1.掌握JavaGUI界面设计        2.掌握鼠标事件的监听(MouseListener,MouseMotionListener) 二.实践内容       设计一个简单的五子棋程序,能够实现五子棋下棋过程.如下图所示 1.五子棋棋盘类 package cn.edu.ouc.fiveChess; import java.awt.Color; import java.awt.Curs

Java棋类游戏实践之中国象棋

本文实例讲述了java实现的中国象棋游戏代码,分享给大家供大家参考,具体代码如下 一.实践目的: 1.鼠标点击.拖动等事件的应用与区别 2.棋谱文件的保存与读取 3.完善象棋的规则. 二.实践内容: 中国象棋历史悠久,吸引了无数的人研究,现对中国象棋的对战和实现棋谱的制作做如下的设计和说明,供大家参考学习. 1.机机对弈,红方先手.在符合规则的情况下拖动棋子到目的地,松鼠标落子. 人人对弈图 2.制作棋谱,选择制作棋谱菜单后,对弈开始,并记录了下棋过程. 选择"制作棋谱"菜单 棋谱制作

Java基于享元模式实现五子棋游戏功能实例详解

本文实例讲述了Java基于享元模式实现五子棋游戏功能.分享给大家供大家参考,具体如下: 一.模式定义 享元模式,以共享的方式高效地支持大量的细粒度对象.通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗.享元的英文是Flyweight,表示特别小的对象,即细粒度对象. 二.模式举例 1. 模式分析 我们借用五子棋游戏来说明这一模式. 2. 享元模式静态类图 3. 代码示例 3.1 创建抽象棋子一AbstractChessman package com.demo.flyweight.obj

10个微妙的Java编码最佳实践

这是一个比Josh Bloch的Effective Java规则更精妙的10条Java编码实践的列表.和Josh Bloch的列表容易学习并且关注日常情况相比,这个列表将包含涉及API/SPI设计中不常见的情况,可能有很大影响. 我在编写和维护jOOQ(Java中内部DSL建模的SQL)时遇到过这些.作为一个内部DSL,jOOQ最大限度的挑战了Java的编译器和泛型,把泛型,可变参数和重载结合在一起,Josh Bloch可能不会推荐的这种太宽泛的API. 让我与你分享10个微妙的Java编码最佳

java数独游戏完整版分享

本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 自己写的数独游戏,共9关,代码如下: 1.DoShudu类用于产生数独数组 import java.util.Random; public class DoShudu { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] cells=newshudu(); //ce

简单实现java数独游戏

本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

详解Java异常处理最佳实践及陷阱防范

前言 不管在我们的工作还是生活中,总会出现各种"错误",各种突发的"异常".无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现.所以我们要时刻注意这些陷阱以及需要一套"最佳实践"来建立起一个完善的异常处理机制. 异常分类 首先,这里我画了一个异常分类的结构图. 在JDK中,Throwable是所有异常的父类,其下分为"Error"和"Exception&

java连连看游戏菜单设计

本文实例为大家分享了java连连看游戏菜单的具体实现代码,供大家参考,具体内容如下 先写GUI. 首先初始化框架,菜单,按钮,需要把菜单和按钮都添加在框架中.注意添加的顺序,首先要设置菜单,再设置框架,再设置按钮,如果交换了设置菜单和框架的顺序,会导致菜单显示不出,被框架挡住.对菜单设置了三个选项,第一个选项有五个下拉按键,用循环添加,第二个和第三个选项的下拉按键直接添加. GUI代码如下: package gui; import java.awt.Font; import javax.swin

Java 小游戏开发之俄罗斯方块

Java项目 俄罗斯方块 一.心得 二.游戏实例 游戏截图 目录结构 三.代码 1.主界面 Tetris.java package com.fry.tetris; import java.util.Arrays; import java.util.Random; /** * 4格方块 */ public class Tetromino { protected Cell[] cells = new Cell[4]; /** 保存旋转的相对于轴位置状态 */ protected State[] st