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

2022-10-07,,,,

前言

五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏,是世界智力运动会竞技项目之一,通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成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五子棋的资料请关注其它相关文章!

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

下载本文的Word格式文档,以方便收藏与打印。