游戏棋 闲暇空余和朋友、陪自己玩耍的居家出行利器

释放双眼,带上耳机,听听看~!
首先,我们要做的就是打开你的(或者其他的java编译软件,当然这些都是废话),之后我们就要开始制作五子棋的第一步:制作一个界面,制作界面的方法相信不用我多说,还不会制作界面的朋友可以去看我以前的文章。

花了一个多星期才终于完善了我所有的五子棋。接下来给大家分享一款可以和朋友一起玩,闲暇时间陪你一起玩的居家旅行工具——五子棋。 (对了,我分享的不是游戏,而是游戏的制作方法)

一、制作接口

首先我们要做的就是打开你的(或者其他java编译软件,当然这些都是废话),然后我们开始制作五子棋的第一步:制作界面,制作方法接口相信没必要我多说,不知道怎么做接口的朋友可以看我之前的文章。代码直接附在这里:

public void showUI() {
		// 窗体对象,JFrame默认是边框布局
		JFrame jf = new JFrame();
		jf.setTitle("五子棋1.0");
		jf.setSize(800, 700);
		// 设置退出进程的方法
		jf.setDefaultCloseOperation(3);
		// 设置居中显示
		jf.setLocationRelativeTo(null);
		GamePanel gp = new GamePanel(chessArray);
		//设置棋盘背景色
		gp.setBackground(new Color(139,139,122));
		jf.add(gp,BorderLayout.CENTER);
		//设置东边的属性
		JPanel jp=new JPanel();
		jp.setBackground(new Color(245,245,245));
		jf.add(jp,BorderLayout.EAST);
		//设置东边流式布局的属性
		java.awt.FlowLayout fl=new java.awt.FlowLayout(5,5,60);
		jp.setLayout(fl);
		Dimension di=new Dimension(120,0);
		jp.setPreferredSize(di);
		//设置东边的按钮及按钮的属性
		javax.swing.JButton jbu1=new javax.swing.JButton("开始游戏");
		Dimension di1=new Dimension(100,60);
		jbu1.setPreferredSize(di1);
		jp.add(jbu1);
		javax.swing.JButton jbu2=new javax.swing.JButton("人人对战");
		Dimension di2=new Dimension(100,60);
		jbu2.setPreferredSize(di2);
		jp.add(jbu2);
		javax.swing.JButton jbu3=new javax.swing.JButton("人机对战");
		Dimension di3=new Dimension(100,60);
		jbu3.setPreferredSize(di3);
		jp.add(jbu3);
		javax.swing.JButton jbu4=new javax.swing.JButton("悔棋");
		Dimension di4=new Dimension(100,60);
		jbu4.setPreferredSize(di4);
		jp.add(jbu4);
		javax.swing.JButton jbu5=new javax.swing.JButton("重新开始");
		Dimension di5=new Dimension(100,60);
		jbu5.setPreferredSize(di5);
		jp.add(jbu5);
		jf.setVisible(true);

顺便说一句,我们这里使用的不再是我们之前使用的流式布局。这里使用的布局就是布局,(即边框布局)。我们通常使用的默认是边框布局。评论也写了。虽然不是流式布局,但是我们可以将边框布局的block设置成我们想要的布局。我这里设置的是流布局。详情见代码。

二、创建按钮和监听器

界面完成后,我们要做的就是创建我们需要的按钮和按钮的监听器:

//设置按钮的动作监听器
		jbu1.addActionListener(mouse);
		jbu2.addActionListener(mouse);
		jbu3.addActionListener(mouse);
		jbu4.addActionListener(mouse);
		jbu5.addActionListener(mouse);

然后在另一个类中创建一个监听方法:

public void mouseClicked(MouseEvent e) {
		x1 = e.getX();
		y1 = e.getY();
		if (z == 1) {
			rr();
		}
		if (z == 2) {
			rj();
			gameWin(xx, yy);
			try {
		    	  Thread.sleep(350);
		       }catch(Exception ef) {}
			a.ai();
			gameWin(a.getmaxi(), a.getmaxj());
			
		}
	}
	// 对设置的按钮进行功能实现
	public int z;
	public void actionPerformed(ActionEvent e) {
		System.out.println("str" + e.getActionCommand());
		if (e.getActionCommand().equals("开始游戏")) {
			j.addMouseListener(this);
		}
		if (e.getActionCommand().equals("人人对战")) {
			z = 1;
		}
		if (e.getActionCommand().equals("人机对战")) {
			a = new AI(g, chessArray, j);
			z = 2;
		}
		if (e.getActionCommand().equals("悔棋")) {
			System.out.println("2");
			for (int i = 0; i < LINE; i++) {
				for (int j = 0; j < LINE; j++) {
					chessArray[xx][yy] = 0;
					count = 0;
				}
			}
			j.repaint();
		}
		if (e.getActionCommand().equals("重新开始")) {
			System.out.println("1");
			// 调用repaint清空所有的棋子并使每个下过的点可以再下
			for (int i = 0; i < LINE; i++) {
				for (int j = 0; j < LINE; j++) {
					chessArray[i][j] = 0;
					count = 0;
				}
			}
			j.repaint();
		}
	}

这里可以清楚的看到我设置的按钮和按钮方法的实现。因为我比较懒,先一起贴吧。之后游戏棋,我们将讨论按钮的功能实现。现在我只是告诉你创建一个监听器。 .

三、所有人对所有人

完成按键的监控,接下来我们将实现五子棋中最简单的可以让人娱乐​​的部分,也就是大家部分(和自己下棋,或者和朋友在同一台电脑下棋)。要完成大家的部分,我们首先要考虑的是如何搭建棋盘,如何让棋子落在棋盘线的交点上,如何让黑白交替出现。要做到这一点,我们首先要确定棋盘的宽度、高度和棋盘之间的间隔以及棋子的大小都是由你自己设定的。当然,为了让棋盘更加匀称美观,这些数据都是我亲测过的,大家也可以试试:

棋盘:

for(int i=0;i<LINE;i++){
			g.drawLine(X, Y+i*SIZE, (LINE-1)*SIZE+X, Y+i*SIZE);
			g.drawLine(X+i*SIZE, Y, X+i*SIZE, (LINE-1)*SIZE+Y);
		}

控制棋盘的交点和黑白交替:

		if ((x1 - X) % SIZE > SIZE / 2) {
			xx = (x1 - X) / SIZE + 1;
		} else {
			xx = (x1 - X) / SIZE;
		}
		if ((y1 - Y) % SIZE > SIZE / 2) {
			yy = (y1 - Y) / SIZE + 1;
		} else {
			yy = (y1 - Y) / SIZE;
		}
		// 控制棋子的黑白色交替出现
		if (chessArray[xx][yy] == 0) {
			if (count == 1) {
				g.setColor(Color.WHITE);
				chessArray[xx][yy] = 1;
				count--;
			} else {
				g.setColor(Color.BLACK);
				chessArray[xx][yy] = -1;
				count++;
			}
			g.fillOval(xx * SIZE + X - CHESS / 2, yy * SIZE + Y - CHESS / 2,CHESS, CHESS);
		}

做完这件事后,还要考虑输赢的情况。这也是大家最复杂的部分,未来人类和机器也会用到。整个五子棋的思路和精髓其实在于五子的判断:

// 判断黑棋和白棋的获胜方式
	// 行
	public int checkrow(int x, int y) {
		int count1 = 0;// 存放连续的相同颜色的棋子数
		for (int i = x + 1; i < 15; i++) {
			if (chessArray[Math.abs(i)][y] == chessArray[x][y]) {
				count1++;
				System.out.println(count1);
			} else {
				break;
			}
		}
		for (int i = x; i >= 0; i--) {
			if (chessArray[Math.abs(i)][y] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		return count1;
	}
	// 列
	public int checkcolumn(int x, int y) {
		int count1 = 0;// 存放连续的相同颜色的棋子数
		for (int i = y + 1; i < 15; i++) {
			if (chessArray[x][Math.abs(i)] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		for (int i = y; i >= 0; i--) {
			if (chessArray[x][Math.abs(i)] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		return count1;
	}
	// 斜
	public int checkinclined1(int x, int y) {
		int count1 = 0;// 存放连续的相同颜色的棋子数
		for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {
			if (chessArray[i][j] == chessArray[x][y]) {
				count1++;
				System.out.println(count1);
			} else {
				break;
			}
		}
		for (int i = x + 1, j = y + 1; i < LINE && j < LINE; i++, j++) {
			if (chessArray[i][j] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		return count1;
		
	}
	public int checkinclined2(int x, int y) {
		int count1 = 0;
		for (int i = x - 1, j = y + 1; i >= 0 && j < LINE; i--, j++) {
			if (chessArray[i][j] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		for (int i = x + 1, j = y - 1; i < LINE && j >= 0; i++, j--) {
			if (chessArray[i][j] == chessArray[x][y]) {
				count1++;
			} else {
				break;
			}
		}
		return count1;
	}
	public void gameWin(int x,int y){
		if(checkinclined1(x, y)>=4||checkinclined2(x,y)>=4||checkcolumn(x,y)>=5||checkrow(x,y)>=5){
			if(chessArray[x][y] == -1){
				hwin();
			}else if(chessArray[x][y] == 1){
				bwin();
			}
		}
	}

这是判断五子棋胜负的一路。

完成大家判断走法、黑白交替、输赢的判断。相信大家已经对如何制作步步高供大家玩有一个基本的想法了。

四、人机大战

在完成了大家战斗的功能之后,接下来要做的就是我们简单的人工智能AI了。 AI在我们现在的生活中非常有名。相信大家一定对五子棋的AI很感兴趣吧,虽然五子棋的AI听起来很棒,但是并没有大家想象的那么复杂。我在这里没有使用任何特别强大的方法。我只是使用了一个哈希表并使用权重来让 AI 判断。达到我们简单人工智能的目的。首先我们需要创建一个权重表来存储不同棋子的权重,这里黑色是-1,白色是1:

HashMap<String, Integer> hm = new HashMap<String, Integer>();
	public AI(Graphics g, int[][] chessArray, JPanel j) {
		this.g = g;
		this.chessArray = chessArray;
		this.j = j; // 设置不同情况时的权值

		hm.put("-1", 20);
		hm.put("-1-1", 400);
		hm.put("-1-1-1", 420);
		hm.put("-1-1-1-1", 3000);
		hm.put("-11", 4);
		hm.put("-1-11", 40);
		hm.put("-1-1-11", 400);
		hm.put("-1-1-1-11", 10000);
		hm.put("1-1-1-1-1", 10000);
		hm.put("1", 8);
		hm.put("11", 80);
		hm.put("111", 1000);
		hm.put("1111", 5000);
		hm.put("1111-1", 5000);
		hm.put("1111-1-1", 5000);
		hm.put("1-1", 6);
		hm.put("11-1", 60);
		hm.put("111-1", 600);
		hm.put("-11-1", 5);
		hm.put("-111-1", 5);
		hm.put("1-1-11", 5);
		hm.put("1-11", 5);
	}

这样,一个简单的权重表就完成了。事实上,这个重量表并不是很准确。可能有很多数值没有设置好,但作为一个简单的AI,还是可以和普通人一起玩的。建立哈希表并设置权重后,我们需要将需要的值存储在权重中。这里我们需要int类型,所以我们有如下代码来存储哈希表需要的数据:

public void ai() {
		for (int i = 0; i < LINE; i++) {
			for (int j = 0; j < LINE; j++) {
				if (chessArray[i][j] == 0) {
					String code = "";
					int color = 0;
					// 向右
					for (int k = i + 1; k < 15; k++) {
						if (chessArray[Math.abs(k)][j] == 0) {
							break;
						} else {
							if (color == 0) { // 右边第一颗棋子
								color = chessArray[Math.abs(k)][j]; // 保存颜色
								code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况
							} else if (chessArray[Math.abs(k)][j] == color) {
								code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况
							} else {
								code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况
								break;
							}
						}
						if (chessArray[i][j] != 0) {
							chessValue[i][j] = 0;
						}
					}
					Integer value = hm.get(code);
					if (value != null) {
						chessValue[i][j] += value;
					}
					if (value != null) {

游戏棋 闲暇空余和朋友、陪自己玩耍的居家出行利器

游戏棋 闲暇空余和朋友、陪自己玩耍的居家出行利器

chessValue[i][j] += value; } // 向左 code = ""; color = 0; for (int k = i - 1; k >= 0; k--) { if (chessArray[Math.abs(k)][j] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[Math.abs(k)][j]; // 保存颜色 code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况 } else if (chessArray[Math.abs(k)][j] == color) { code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况 } else { code += chessArray[Math.abs(k)][j]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 向上 code = ""; color = 0; for (int k = j - 1; k >= 0; k--) { if (chessArray[i][Math.abs(k)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[i][Math.abs(k)]; // 保存颜色 code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 } else if (chessArray[i][Math.abs(k)] == color) { code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 } else { code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 向下 code = ""; color = 0; for (int k = j + 1; k < LINE; k++) { if (chessArray[i][Math.abs(k)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[i][Math.abs(k)]; // 保存颜色 code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 } else if (chessArray[i][Math.abs(k)] == color) { code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 } else { code += chessArray[i][Math.abs(k)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 右下 code = ""; color = 0; for (int k = i + 1, l = j + 1; k < LINE || l < LINE; k++, l++) { if (chessArray[Math.abs(k)][Math.abs(l)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[Math.abs(k)][Math.abs(l)]; // 保存颜色 code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else if (chessArray[Math.abs(k)][Math.abs(l)] == color) { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 右上 code = ""; color = 0; for (int k = i + 1, l = j - 1; k < LINE || l >= 0; k++, l--) { if (chessArray[Math.abs(k)][Math.abs(l)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[Math.abs(k)][Math.abs(l)]; // 保存颜色 code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else if (chessArray[Math.abs(k)][Math.abs(l)] == color) { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 左上 code = ""; color = 0; for (int k = i - 1, l = j - 1; k >= 0 || l >= 0; k--, l--) { if (chessArray[Math.abs(k)][Math.abs(l)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[Math.abs(k)][Math.abs(l)]; // 保存颜色 code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else if (chessArray[Math.abs(k)][Math.abs(l)] == color) { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } // 左下 code = ""; color = 0; for (int k = i - 1, l = j + 1; k >= 0 || l < LINE; k--, l++) { if (chessArray[Math.abs(k)][Math.abs(l)] == 0) { break; } else { if (color == 0) { // 左边第一颗棋子 color = chessArray[Math.abs(k)][Math.abs(l)]; // 保存颜色 code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else if (chessArray[Math.abs(k)][Math.abs(l)] == color) { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 } else { code += chessArray[Math.abs(k)][Math.abs(l)]; // 保存棋子相连情况 break; } } } value = hm.get(code); if (value != null) { chessValue[i][j] += value; } if (chessArray[i][j] != 0) { chessValue[i][j] = 0; } } } } for (int j = 0; j < LINE; j++) { for (int i = 0; i < LINE; i++) { System.out.print(chessValue[i][j] + " "); } System.out.println(); } for (int j = 0; j < LINE; j++) { for (int i = 0; i < LINE; i++) { System.out.print(chessArray[i][j] + " "); } System.out.println(); }

其实这个方法和之前判断五子连线的方法思路是一样的,所以我会说五子连线的思路其实就是五子棋的精髓。 (设置最后两个for循环,检查权重错误和颜色错误。)五子棋步法判断完成后,就要控制五子棋计算机的步法了。这里需要注意的是:每次我们下完棋和电脑下完棋后,都要判断输赢。这里我们需要用我上面写的语句来判断输赢,而且每走一步之后,我们都要将每一个点的权重清零。移动的点是彩色的,不能放在下面,代码如下:

// 判断权值最大的位置,并在该位置下棋。
		int maxv = 0;
		for (int i = 0; i < LINE; i++) {
			for (int j = 0; j < LINE; j++) {
				if (maxv < chessValue[i][j]) {
					maxv = chessValue[i][j];
					maxi = i;
					maxj = j;
				}
			}
		}
		//画白棋
		g.setColor(Color.WHITE);
		g.fillOval(maxi * SIZE + X - CHESS / 2, maxj * SIZE + Y - CHESS / 2,CHESS, CHESS);
		chessArray[maxi][maxj] = 1;
		System.out.println("x" + maxi + "y" + maxj);
		for (int i = 0; i < LINE; i++) {
			for (int j = 0; j < LINE; j++) {
				chessValue[i][j] = 0;
			}

完成这些方法后,我们只需要调用监听类中的方法就可以了。

五、完成所有按钮功能并重绘

完成以上所有步骤后,我们就来到了我们步步高的最后一步,也就是步步高按钮功能的实现。我的五子棋按钮不多游戏棋,只有五个,每个都有不同的功能。 ,如果要实现这5个按钮的功能,可以先看看有没有想法:

其实看起来并不难,对吧?我们来看看:其实我们在开始游戏的时候,是想让鼠标在我们的棋盘上停止工作,所以我把面板的监听器放在了按钮的监听器里面。这样就达到了效果。人和人机要调用不同的方法,但是需要注意的是,每次调用一个下棋的方法,都要判断一次胜负,然后后悔重新开始。事实上,原理是相似的。 ,就是调用()方法重绘棋盘中的棋子,从而达到完美忏悔重启的目的,代码:

public int z;
	public void actionPerformed(ActionEvent e) {
		System.out.println("str" + e.getActionCommand());
		if (e.getActionCommand().equals("开始游戏")) {
			j.addMouseListener(this);
		}
		if (e.getActionCommand().equals("人人对战")) {
			z = 1;
		}
		if (e.getActionCommand().equals("人机对战")) {
			a = new AI(g, chessArray, j);
			z = 2;
		}
		if (e.getActionCommand().equals("悔棋")) {
			System.out.println("2");
			for (int i = 0; i < LINE; i++) {
				for (int j = 0; j < LINE; j++) {
					chessArray[xx][yy] = 0;
					count = 0;
				}
			}
			j.repaint();
		}
		if (e.getActionCommand().equals("重新开始")) {
			System.out.println("1");
			// 调用repaint清空所有的棋子并使每个下过的点可以再下
			for (int i = 0; i < LINE; i++) {
				for (int j = 0; j < LINE; j++) {
					chessArray[i][j] = 0;
					count = 0;
				}
			}
			j.repaint();
		}

完成按钮功能的实现,然后重绘。其实之前我已经告诉过你,重绘其实就是调用paint方法,然后重绘我们要重绘的东西。这里我们要重绘的东西是棋盘和棋子,所以我们要重新创建一个类并在里面重绘:

public class GamePanel extends JPanel implements Config{
	private int[][] chessArray;
	
	public GamePanel(int[][] chessArray){
		this.chessArray = chessArray;
	}
	public void paint(Graphics g){
		super.paint(g);
		//重绘棋盘
		//硬编码
		for(int i=0;i<LINE;i++){
			g.drawLine(X, Y+i*SIZE, (LINE-1)*SIZE+X, Y+i*SIZE);
			g.drawLine(X+i*SIZE, Y, X+i*SIZE, (LINE-1)*SIZE+Y);
		}
		paintChess(g);
	}
	/**
	 * 重绘棋子
	 * @param g
	 */
	public void paintChess(Graphics g){
		for(int i=0;i<chessArray.length;i++){
			for(int j=0;j<chessArray[i].length;j++){
				if(chessArray[i][j] == 1){
					g.setColor(Color.WHITE);
					g.fillOval(i * SIZE + X - CHESS / 2, j * SIZE + Y - CHESS / 2, CHESS, CHESS);
				}else if(chessArray[i][j] == -1){
					g.setColor(Color.BLACK);
					g.fillOval(i * SIZE + X - CHESS / 2, j * SIZE + Y - CHESS / 2, CHESS, CHESS);
				}
			}
		}
	}
}

顺便说一句,你可能会很困惑。我在每个类中都调用了一些大写的常量,比如LINE、X、Y等。其实这在java编程中是很重要的东西,它让我们改变编码更容易,我们称之为“硬编码”,在其实硬编码就是重新定义一个接口,把我们要使用的数据存储在接口中,这样以后需要修改代码的时候,会减少很多。工作量很大,我这里为每个类都继承了这样一个接口:

public interface Config {
	public static final int X = 50;
	public static final int Y = 40;
	public static final int LINE = 15;
	public static final int SIZE = 40;
	public static final int CHESS = 30;
}

写到这里,我们的五子棋已经完成。相信大家已经了解了五子棋的制作方法,也有了自己制作一些小游戏的想法。如果您对我的五子棋有任何疑问或意见,可以评论与我讨论,我们下期再见! !

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索