项目设计-----五子棋

一、团队成员

组长:郭瀚文 202203010057
组员:关乾春 202203010058 邓国岩 202203010059

二、主要内容

项目完整代码:https://gitee.com/memoryee/gobang

一个简易的五子棋游戏,能够实现离线和联网对战。
离线模式能够支持本地双人对战。
联网模式需要用户登录并等待服务器匹配对手

三、简介

1、设计目标

通过socket编程,GUI设计,mysql等技术的学习,来实现一个联网的多人五子棋小游戏

2、实现技术

socket编程,GUI设计,mysql

3、开发环境

java

4、功能特点

能够在本地实现双人对战
同时也能通过服务器联网实现异地对战

四、功能介绍

1、离线模式

(1)落子

通过二维数组存储棋子在棋盘上的位置,在绘制棋盘,实现落子的功能
代码如下:

//在Mouse类中,通过重写mosueclicked方法来获取鼠标点击位置与棋盘格子的关系
public void mouseClicked(MouseEvent e) {
		int x = e.getX();// 鼠标点击处获取x、y坐标
		int y = e.getY();
		// 获取落子坐标,此处进行判断让获取的坐标位于棋盘线交点处
		if ((x - x0) % size > size / 2) {
			x1 = (x - x0) / size + 1;
		} 
		else if ((x - x0) % size <= size / 2) {
			x1 = (x - x0) / size;
		}
		if ((y - y0) % size > size / 2) {
			y1 = (y - y0) / size + 1;
		} 
		else if ((y - y0) % size <= size / 2) {
			y1 = (y - y0) / size;
		}
		
//		System.out.println(y1 + " " + x1);
//		System.out.println(chessArr[y1][x1]);
 
		
		//判断本地游戏是否开始
		if (start) {
			// 判断棋子是否会越出棋盘界
			if (0 <= x1 && x1 <= 14 && 0 <= y1 && y1 <= 14) {
				// 判断只有空位置才能下棋
				if (chessArr[y1][x1] == 0) {
						if (count % 2 == 0) {
							//static1.black.paintIcon(chessPanel, g, x1 * size - 25 + x0, y1 * size - 25 + y0);
							chessArr[y1][x1] = 1;// 记录棋盘上每颗棋子的颜色,黑色记1,白色记-1
							chesses[count++] = new Chess(x1, y1, 1);
	 
						} 
						else {
							//static1.white.paintIcon(chessPanel, g, x1 * size - 25 + x0, y1 * size - 25 + y0);
							chessArr[y1][x1] = -1;
							chesses[count++] = new Chess(x1, y1, -1);
						}
						historyArea.refresh(y1, x1, chessArr[y1][x1]);
						chessPanel.repaint();
				} 
			}
			else {
					System.out.print("超出棋盘边界");
			}
			int winner = win.checkWin(x1, y1);//获得谁是赢家
			if(winner != 0) {
				winner(winner);
			}
		}
	}

(2)悔棋

定义chess类来存储一个棋子的坐标及颜色,定义一个chess的一位数组,用于表示第几步的棋
子是什么颜色以及坐标是多少,悔棋的时候按倒序依次取出棋子然后重新绘制棋盘,从而实现
悔棋的效果
代码如下:

//Mouse类中的方法
public void regret() {
		if(start && count >= 1) {
			-- count;
			int x = chesses[count].getX();
			int y = chesses[count].getY();
			chessArr[y][x] = 0;
			historyArea.setText("");
			for(int i = 0; i < count; i ++ ) {
				x = chesses[i].getX();
				y = chesses[i].getY();
				int color = chesses[i].getColor();
				historyArea.refresh(y, x, color);
			}
			chessPanel.repaint();
		}
	}

(3)复盘

原理同(2),按照顺序依次取出棋子,然后按顺序绘制在棋盘上。
为了实现复盘的效果,同时新建一个计时器类,设定固定的时间间隔来实现依次下棋的效果。
代码如下:

public void repeat() {
		timer = new Timer();
		timer.schedule(new TimerTask() {
			int x, y, color, idx = 0;
			
			@Override
			public void run() {
				if(idx < count) {
					Chess thisChess = chesses[idx];
					x = thisChess.getX();
					y = thisChess.getY();
					color = thisChess.getColor();
					chessArr[y][x] = color;
					historyArea.refresh(y, x, color);
					chessPanel.repaint();
					++ idx;
				}
				else {
					timer.cancel();
				}
			}
		}, 1000, 1000);
		//复盘后要禁止下棋,不用清零count因为开始时count一定为0
		start = false;
	}

(4)获胜

当某一方下棋后,判断该棋子各个方向的同色棋子是否达到五个
每个方向单独计数
某个方向的同色棋子数达到五个,判定游戏结束,禁止下棋
public class Win {
	private int[][] chessArr = new int[15][15];
	private int count = 0;
	
	public Win(int[][] chessArr) {
		this.chessArr = chessArr;
	}
	
	//判断四个方向是否连成五个的判断函数
	//水平
	public int countchessX(int x1, int y1) {
		count = 1;
		for (int i = x1 + 1; i < chessArr.length; i++) {
			if (chessArr[y1][x1] == chessArr[y1][i]) {
				count++;
 
			} 
			else {
				break;
			}
		}
		for (int i = x1 - 1; i >= 0; i--) {
			if (chessArr[y1][x1] == chessArr[y1][i]) {
				count++;
 
			} 
			else {
				break;
			}
		}
 
//		System.out.println("X" + count);
		return count;
	}
 
	//竖直
	public int countchessY(int x1, int y1) {
		count = 1;
 
		for (int i = y1 + 1; i < chessArr.length; i++) {
			if (chessArr[y1][x1] == chessArr[i][x1]) {
				count++;
 
			} 
			else {
				break;
			}
		}
		for (int i = y1 - 1; i >= 0; i--) {
			if (chessArr[y1][x1] == chessArr[i][x1]) {
				count++;
 
			} 
			else {
				break;
			}
		}
//		System.out.println("Y" + count);
		return count;
	}
	
	//y = x
	public int countchessM(int x1, int y1) {
		count = 1;
		for (int i = x1 + 1, j = y1 + 1; i < chessArr.length && j < chessArr.length; i++, j++) {
			if (chessArr[y1][x1] == chessArr[j][i]) {
				count++;
			} 
			else {
				break;
			}
		}
		for (int i = x1 - 1, j = y1 - 1; i >= 0 && j >= 0; i--, j--) {
			if (chessArr[y1][x1] == chessArr[j][i]) {
				count++;
			} 
			else {
				break;
			}
 
		}
//		System.out.println("M" + count);
		return count;
	}
 
	
	//y = -x
	public int countchessN(int x1, int y1) {
		count = 1;
		for (int i = x1 + 1, j = y1 - 1; i < chessArr.length && j >= 0; i++, j--) {
			if (chessArr[y1][x1] == chessArr[j][i]) {
				count++;
			} 
			else {
				break;
			}
		}
		for (int i = x1 - 1, j = y1 + 1; i >= 0 && j < chessArr.length; i--, j++) {
			if (chessArr[y1][x1] == chessArr[j][i]) {
				count++;
			} 
			else {
				break;
			}
		}
		return count;
	}
	
	//判断输赢的函数,返回哪个颜色获胜
	public int checkWin(int x1, int y1) {
		int ret = 0;
		if (countchessX(x1, y1) >= 5 || countchessY(x1, y1) >= 5 || countchessM(x1, y1) >= 5 || countchessN(x1, y1) >= 5) {
			if (chessArr[y1][x1] == 1) {  //最后下黑棋
				ret = 1;
			} 
			else if (chessArr[y1][x1] == -1) {  //最后下白棋
				ret = -1;
			}
		}
		return ret;
	}

}

2、在线模式

(1)用户登录

当用户点击联网对战按钮的时候,会弹出一个登陆界面,如果账号第一次登录则需要注册
如果,已经注册过,则会显示登陆成功,并显示当前用户的用户名
客户端及服务端的代码,请移步git仓库
https://gitee.com/memoryee/gobang

(2)联网匹配

当用户登录成功后,就会于服务端去连接,当服务端的连接人数位两人时,游戏就会开始,就
可以开始下棋了,最先链接进入服务端的用户为先手,也就是黑棋
同上
客户端及服务端的代码,请移步git仓库
https://gitee.com/memoryee/gobang

五、主要功能截图

1、主界面
主界面
2、游戏界面
游戏界面
3、用户登录界面
用户登录界面

六、技术难点

网络通信:实现网络通信是五子棋联网游戏的关键难点。需要在客户端和服务器端之间建立可靠的通信
连接,以保证双方可以实时传递游戏状态和数据信息。

游戏同步:在对弈双方进行游戏时,需要将游戏状态同步给对方,确保对弈双方看到的游戏状态是一致
且同步的。若游戏状态出现了不一致的情况,则会影响游戏的公平性和可玩性。

网络延迟:由于网络的延迟,可能会出现客户端和服务器端的数据不同步,或是造成游戏时间的卡顿。
为了减轻这种情况的影响,需要对网络延迟进行优化,采用更稳定的网络协议和传输方式进行数据传输。

算法优化:五子棋的算法较为复杂,需要进行深度优化,以避免游戏卡顿和影响游戏操作。此外,还需
要处理好游戏结束后的胜负判断、计分等问题。

安全性:网络游戏涉及到用户的个人信息和账号信息,需要考虑网络安全问题,防止信息被篡改或者泄
露。

总之,五子棋联网游戏,在实现过程中需要结合以上难点,采用合适的技术手段进行实现。同时,也需
要不断对游戏性能和用户体验进行优化,以提升游戏体验和用户满意度。

七、启示

代码结构和可读性:实现五子棋联网游戏需要编写复杂的代码,对代码结构和可读性的要求十分高。
一个好的代码结构可以使代码更易于维护和修改,同时提高代码质量和可靠性。在编写代码时应尽量
避免重复代码和冗余代码,同时注重代码的格式和注释,让代码更加易懂。

网络通信:网络通信是现代软件设计中一个必不可少的重要模块。在实现五子棋联网游戏时,需要使
用网络通信技术实现客户端和服务器之间的数据传输。理解网络通信原理和技术可以为实现其他类型
的网络应用提供帮助。

算法优化:五子棋算法的优化需要经过多次实践和不断调整才能达到最佳效果,能够通过学习不同算
法和技巧来提高算法的效率。算法的优化对于软件设计和实现来说都是非常重要的一步,可以提高软
件的性能、稳定性和可靠性。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值