`
xiaoyjj
  • 浏览: 53158 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

java学习ing——五子棋的制作(人人对战)

阅读更多

 java学习ing——五子棋的制作(人人对战)

 

 

 

 

      自从上次完成了一次画图板,接下来的一个小项目的制作就是五子棋。包括了人人对战还有就是人机对战。这一片文章就先说一下人人对战,人机之后再来完善

#^_^

 

先附一张效果图哈~

 

 

      先来制定一个制作五子棋大体的一个思路吧:

          1.要先有个窗体,有棋盘。

          2.要能在上面画出棋子(也就是下棋),并且要完成黑白交替的下棋。

          3.要能够判断输赢,判断是否有某个颜色的棋子五个相连。

      人人的比较简单,基本的思路就是这样,然后再来一步步的完成。

 

制作前期的准备工作

      我们可以先定义一个存放五子棋他各个属性的一个接口,这样在创建棋盘等等的地方就可以通过直接调用这个接口中的静态属性来完成。这样的好处就是在修改某一参数的时候就能够直接通过修改这个接口中的属性的数值来完成。

/*
 * 五子棋相关属性的类
 */
public interface WZQ_config {

	/*
	 *设置棋盘网格行数列数为15
	 */
	public static final int Row = 15;
	public static final int Column = 15;
	
	/*
	 * 设置棋盘初始位置坐标
	 */
	public static final int X = 30;
	public static final int Y = 60;
	
	/*
	 * 设置棋子大小
	 */
	public static final int Chess_size = 40;
	
	/*
	 * 设置棋盘格子大小
	 */
	public static final int WZQ_JianJu = 40;
	
	
}

 

 

 

 

 

窗体界面的实现

      实现五子棋界面的方法可能也是蛮多的,我知道的呢有一种是在一个窗体上面分别在指定的位置使用循环绘制横竖15条线来形成一个棋盘的网格。第二种方法是直接在一个窗体上面添加一个棋盘完整的图片,这种比较简单省事儿吧。~~但。我自己用的是绘制网格线的方法。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class WZQ_Board extends JFrame {
	public Graphics g;
	public static WZQ_Board wzq;

	/*
	 * 重载构造方法
	 */
	public WZQ_Board() {
		this.initUI();
	}

	/*
	 * 初始化界面的方法
	 */
	void initUI() {
		/*
		 * 设置棋盘属性
		 */
		this.setTitle("吉吉的五子棋");
		this.setSize(new Dimension(650, 650));
		this.setResizable(false);
		this.setDefaultCloseOperation(3);
		this.setLocationRelativeTo(null);
		this.setLayout(null);

		/*
		 * 添加一块棋盘
		 */
		this.setLayout(null);
		JPanel jp = new JPanel() {
			/*
			 * (non-Javadoc)定义一个匿名内部类重写paint方法
			 * 
			 * @see javax.swing.JComponent#paint(java.awt.Graphics)
			 */
			public void paint(Graphics g) {
				g.setColor(Color.BLACK);
				super.paint(g);
				// 画15行
				for (int i = 0; i < 15; i++) {
					g.drawLine(20, 20 + i * WZQ_config.WZQ_JianJu, 20
							+ (WZQ_config.Column - 1) * WZQ_config.WZQ_JianJu,
							20 + i * WZQ_config.WZQ_JianJu);
				}
				// 画15列
				for (int i = 0; i < 15; i++) {
					g.drawLine(20 + i * WZQ_config.WZQ_JianJu, 20, 20 + i
							* WZQ_config.WZQ_JianJu, 20
							+ (WZQ_config.Column - 1) * WZQ_config.WZQ_JianJu);
				}
				g.setColor(Color.BLACK);
				g.fillOval(133, 133, 15, 15);
				g.fillOval(293, 133, 15, 15);
				g.fillOval(453, 133, 15, 15);
				g.fillOval(133, 293, 15, 15);
				g.fillOval(293, 293, 15, 15);
				g.fillOval(453, 293, 15, 15);
				g.fillOval(133, 453, 15, 15);
				g.fillOval(293, 453, 15, 15);
				g.fillOval(453, 453, 15, 15);

				// 重绘棋子
				for (int i = 0; i < 650; i++) {
					for (int j = 0; j < 650; j++) {
						if (WZQ_listener.array[i][j] == "black") {
							g.setColor(Color.BLACK);
							g.fillOval(i, j, WZQ_config.Chess_size,
									WZQ_config.Chess_size);
						} else if (WZQ_listener.array[i][j] == "white") {
							g.setColor(Color.WHITE);
							g.fillOval(i, j, WZQ_config.Chess_size,
									WZQ_config.Chess_size);
						}
					}
				}
			}
		};
		jp.setBackground(new Color(209, 167, 78));
		jp.setBounds(10, 10, 602, 602);
		this.add(jp);

		this.setVisible(true);
		g = jp.getGraphics();

		/*
		 * 添加监听器
		 */
		WZQ_listener lis = new WZQ_listener(g);
		jp.addMouseListener(lis);

	}

}

 

 

       这里绘制棋盘的方法是重写在他的重绘方法当中。在JFrame窗体上新建了一个带有颜色的JPanel,再在这个panel上面进行画线,这样呢就使得自己的棋盘变得~~美观些吧!

 

棋子的实现

      下棋功能的实现需要考虑的地方也蛮多的:

          1.首先想到下棋就是使用一个监听器来监听之前创建的panel棋盘,在鼠标释放的时候执行画园儿的操作。

          2.怎么完成黑白交替着下

          3.怎么使得棋子都下在正确的位置(网格线的相交点上)

          4.怎么使得一个位置上只能存在一个棋子

啊~~我们再来一条一条的完善。

      第一步很简单了,创建一个监听器来继承MouseAdapter这个抽象类。至于为什么不是实现MouseListener这个接口呢,原因很简单a~

因为实现MouseAdapter这个抽象类我们只需再重写我们需要用到的方法就可以了,而实现一个接口就要把他所有的抽象方法都要实现。这个五子棋的我们只用到的就是MouseReleased鼠标释放这一个,所以继承MouseAdapter显然更为简单。

      然后重写其中MouseReleased方法,在鼠标释放的时候获取该点的xy坐标,在panel上获取画布:getGraphics(); 后就可以在上面画棋子了~~这样第一步也就完成了。

      实现黑白交替呢~这里只需要一个控制变量,我使用的是一个boolean值state用来存储,true的时候表示该下黑子了,false的时候表示改下白子了。我们只需判断

if(state){

    下黑子;

     state = false;

}

else{

     下白子;

     state = true;

}

这样就完成了黑白子交替着下的功能~~

 

      下一步是让棋子正位,我使用的方法是又自定义了一个坐标修正的函数。

/*
	 * 下棋位置坐标修正的方法
	 */
	public int correctXY(int x) {
		x = x / 40;

		return x * 40;
	}

 

 

 

 

      我就是用这样一个correctXY方法,在获取所点位置的xy坐标的时候进行一个修正,例如:  int x = correctXY(e.getX());

      这样就把所获得到的点通过这个方法给修正了,看似好像除以四十又返回一个乘以四十好像没有变化,但这样是使得每一个获取到的坐标都是四十的倍数,也就是在正确的位置上。

      下棋的最后一步就是使得一个点位只能下一个棋子,这个就是很简单了,只要我们定义一个二维数组,行列均为15,也就是这个棋盘的行列数,在每一个位置下棋后都在二维数组的对应位置中存入下的什么棋子,例如下的黑棋则在那个位置附上1,白子则附为-1。所以只要在下棋的时候不只只是判定state的true或者false,同时在判定所下位置二维数组是否为0,若不为0则说明该位置有棋子则不执行下棋操作。so easy~~~

 

这样我们就可以在这个棋盘上面下棋了~~

 

最后一步~就是判段输赢的方法了

       使用的方法就是每在我们下棋的时候都应该判定一次,通过获得每次所下棋子的位置来向四周八个方向分别判断是否已经有五个棋子相连了。如果有则返回一个true。然后在用一个方法来当有判断五连的方法有返回true的话,就看当前点的棋子是什么颜色的,黑子的话就是黑子五连了,否则就是白子五连。

 监听器中的所有代码都放在一起啦:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.JPanel;

public class WZQ_listener extends MouseAdapter {
	/*
	 * 设置黑白棋标识 true表示黑子,false表示白子
	 */
	public static boolean state = true;
	public Graphics g;
	public int x, y;
	public static String[][] array = new String[700][700];
	public static int[][] array_win = new int[15][15];
	public static int[][] array_pve = new int[15][15];
	public static int count_max;
	public static int count_where = 0;
	public JPanel panel;
	public static Result result;
	public static List list;
	public static int val;

	/*
	 * 重载他·的构造方法
	 */
	public WZQ_listener(Graphics g) {
		this.g = g;

		// this.panel = panel;
	}

	/*
	 * 鼠标释放执行的方法
	 */
	public void mouseReleased(MouseEvent e) {
		x = correctXY(e.getX());
		y = correctXY(e.getY());
		System.out.println("x:"+x+"   y:"+y);
		/*
		 * 判定为人人对战
		 */
		if (ActListener.GameModel == 1) {
			if (x < 582 && x >= 0 && y < 582 && y >= 0) {
				if (state && array[x][y] == null) {
					g.setColor(Color.BLACK);
					g.fillOval(x, y, WZQ_config.Chess_size,
							WZQ_config.Chess_size);

					array[x][y] = "black";

					array_win[getXY(y)][getXY(x)] = 1;
					state = false;

				} else if (array[x][y] == null) {
					g.setColor(Color.WHITE);
					g.fillOval(x, y, WZQ_config.Chess_size,
							WZQ_config.Chess_size);

					array[x][y] = "white";

					array_win[getXY(y)][getXY(x)] = -1;

					state = true;
				}

				if (Win(getXY(y), getXY(x)) == 1) {
					result = new Result(1);
					result.initUI();
				} else if (Win(getXY(y), getXY(x)) == -1) {
					result = new Result(-1);
					result.initUI();
				}
				for (int i = 0; i < 15; i++) {
					for (int j = 0; j < 15; j++) {
						System.out.print(array_win[i][j] + "  ");
					}
					System.out.println("");
				}
				System.out.println("");
			}

		}

		/*
		 * 人机对战
		 */
		else if (ActListener.GameModel == 2) {
			if (x < 582 && x > 10 && y < 582 && y > 10 && array[x][y] == null) {
				g.setColor(Color.BLACK);
				g.fillOval(x - WZQ_config.Chess_size / 2, y
						- WZQ_config.Chess_size / 2, WZQ_config.Chess_size,
						WZQ_config.Chess_size);

				array[x][y] = "black";

				array_win[getXY(y)][getXY(x)] = 1;
				array_pve[getXY(y)][getXY(x)] = 0;
				for (int i = 0; i < 15; i++) {
					for (int j = 0; j < 15; j++) {
						System.out.print(array_pve[i][j] + "  ");
					}
					System.out.println("");
				}
				System.out.println("");

			}

		}

	}

	/*
	 * 下棋位置坐标修正的方法
	 */
	public int correctXY(int x) {
		x = x / 40;

		return x * 40;
	}

	public int getXY(int x) {
		x = x / 40;
		return x;
	}

	/*
	 * 判赢方法
	 */

	/*
	 * 判定横向五个相连
	 */
	public boolean winRow(int row, int column) {
		int count = 1;
		for (int i = column + 1; i < 15; i++) {// 向右查找
			if (array_win[row][column] == array_win[row][i]) {
				count++;
			} else
				break;
		}
		for (int i = column - 1; i >= 0; i--) {// 向左查找
			if (array_win[row][column] == array_win[row][i]) {
				count++;
			} else
				break;
		}

		if (count >= 5) {
			return true;
		} else
			return false;
	}

	/*
	 * 判定竖向五个相连
	 */
	public boolean winColumn(int row, int column) {
		int count = 1;
		for (int i = row + 1; i < 15; i++) {// 向右查找
			if (array_win[row][column] == array_win[i][column]) {
				count++;
			} else
				break;
		}
		for (int i = row - 1; i >= 0; i--) {// 向左查找
			if (array_win[row][column] == array_win[i][column]) {
				count++;
			} else
				break;
		}
		if (count >= 5) {
			return true;
		} else
			return false;
	}

	/*
	 * 判定斜向右下五个相连
	 */
	public boolean winRightDown(int row, int column) {
		int count = 1;
		for (int i = column + 1, j = row + 1; i < 15 && j < 15; i++, j++) {// 向右查找
			if (array_win[row][column] == array_win[j][i]) {
				count++;
			} else
				break;
		}
		for (int i = column - 1, j = row - 1; i >= 0 && j >= 0; i--, j--) {// 向左查找
			if (array_win[row][column] == array_win[j][i]) {
				count++;
			} else
				break;
		}
		if (count >= 5) {
			return true;
		} else
			return false;
	}

	/*
	 * 判定斜向左下五个相连
	 */
	public boolean winLeftDown(int row, int column) {
		int count = 1;
		for (int i = column - 1, j = row + 1; i >=0 && j < 15; i--, j++) {// 向右查找
			if (array_win[row][column] == array_win[j][i]) {
				count++;
			} else
				break;
		}
		for (int i = column + 1, j = row - 1; i <15 && j >= 0; i++, j--) {// 向左查找
			if (array_win[row][column] == array_win[j][i]) {
				count++;
			} else
				break;
		}
		if (count >= 5) {
			return true;
		} else
			return false;
	}

	public int Win(int row, int column) {
		if (winRow(row, column) || winColumn(row, column)
				|| winRightDown(row, column) || winLeftDown(row, column)) {
			if (array_win[row][column] == 1)
				return 1;
			else if (array_win[row][column] == -1)
				return -1;
		}
		return 0;
	}

}

 

 

       最后还有一点可以完善的,就是我所做的是判断有五连之后又会弹出一个新的界面,上面提示某某子五连,某某子获得胜利。同时提供两个按钮选择重新开始或者退出。~

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class Result extends JFrame{
	int i;
	JPanel panel;
	public Result(int i){
		this.i = i;
	}
	
	/*
	 * 定义一个生成界面的方法
	 */
	public void initUI(){
		this.setTitle("结果");
		this.setSize(new Dimension(400,200));
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		this.setLayout(new BorderLayout());
		this.setDefaultCloseOperation(HIDE_ON_CLOSE);
		
		panel = new JPanel();
		panel.setLayout(new FlowLayout());
		this.add(panel,BorderLayout.CENTER);
		if(i == 1){
			JLabel lab = new JLabel("黑子五连,黑子胜!");
			panel.add(lab,BorderLayout.CENTER);
			
		}
		else if(i == -1){
				JLabel lab = new JLabel("白子五连,白子胜!");
				panel.add(lab);
		}
		
		JPanel pal = new JPanel();
		JButton btn_restart = new JButton("重新开始");
		JButton btn_exit = new JButton("退出游戏");
		btn_restart.setActionCommand("restart");
		btn_exit.setActionCommand("exit");
		
		ActListener al = new ActListener();
		btn_restart.addActionListener(al);
		btn_exit.addActionListener(al);
		btn_restart.addMouseListener(al);
		btn_exit.addMouseListener(al);
		
		pal.setLayout(new FlowLayout());
		this.add(pal,BorderLayout.SOUTH);
		pal.add(btn_restart);
		pal.add(btn_exit);
		
		
		this.setVisible(true);

	}


}

 

 

这样,这个人人对战的五子棋可以说是就完成了。~~人机的之后会在完善的!

      有缺点不足麻烦指出~~#^_^。谢谢各位看的盆友~~~~~

最后附一张效果图哈:

 

 

0
1
分享到:
评论
2 楼 xiaoyjj 2012-11-11  
EastStone 写道
不错,很好

~~嘿。谢谢谢谢~
1 楼 EastStone 2012-11-11  
不错,很好

相关推荐

    java学习ing——初识文件

    在标签中提到的“源码”部分,学习Java文件操作时,查看和理解相关的API源码可以帮助深入理解其内部工作原理,提高问题解决能力。而对于“工具”,可能指的是使用IDE(如IntelliJ IDEA或Eclipse)提供的文件操作功能...

    编程ING:人人都能学会程序设计

    编程ING:人人都能学会程序设计编程ING:人人都能学会程序设计编程ING:人人都能学会程序设计编程ING:人人都能学会程序设计编程ING:人人都能学会程序设计编程ING:人人都能学会程序设计编程ING:人人都能学会程序...

    高中英语语法——动词ing形式的用法张PPT课件.pptx

    高中英语语法——动词ing形式的用法 动词-ing形式是在英语语法中非常重要的一种非谓语动词形式,它可以在句子中作主语、宾语、表语、定语、状语、宾补等多种成分。下面我们将对动词-ing形式的用法进行详细的分析和...

    高中英语语法——动词ing形式的用法PPT学习教案.pptx

    高中英语语法中,动词ing形式(也称为动名词)是英语学习中的一个重要概念,它在句子中有着多种用途。动词ing形式的构成是在动词后加上-ing,例如do-doing,be-being,ask-asking等。动词ing形式不具备人称和数的...

    java五子棋

    【Java五子棋】是一种基于Java编程语言实现的桌面游戏,玩家通过在棋盘上交替放置黑白棋子,目标是先形成连续的五个相同颜色的棋子直线(横、竖或斜线)来获胜。本项目可能包含了实现五子棋游戏的源代码,让我们深入...

    《JAVA面试题》--【java学习笔记】+【准备面试ING】.zip

    十余年JAVA从业经验,精通JAVA技术体系,有志于做JAVA技能提升的朋友可与我联系,交个朋友 十余年JAVA从业经验,精通JAVA技术体系,有志于做JAVA技能提升的朋友可与我联系,交个朋友 十余年JAVA从业经验,精通JAVA...

    数据结构与算法分析——java语言描述(第二版) 习题答案

    数据结构与算法分析——Java语言描述(第二版)是普林斯顿大学Mark Allen Weiss的经典之作,但是网上很少能找到Java描述第二版的课后习题,连作者的个人主页也明确表示不提供课后习题,只能到出版商那里去索取,这个...

    编程ING人人都能学会程序设计

    标题“编程ING人人都能学会程序设计”明确指出程序设计并非高深莫测,而是每个人都能够掌握的技能。这表明了现代教育理念倾向于将编程技能视为一种基本能力,如同阅读和写作一样,应该被广泛教授。 ### 知识点二:...

    java ing 小杨-day03.rar

    java ing 小杨-day03.rar

    java ing 小杨-day02.rar

    java ing 小杨-day02.rar

    java ing 小杨-day01.rar

    java ing 小杨-day01.rar

    《编程ING:人人都能学会程序设计》,全彩完整扫描版

    通过《编程 ing:人人都能学会程序设计》一书,你就能拥有这样的能力,甚至培养出对编程的兴趣。  本书在编写上采用了心理学的一些技巧,每一页都有绘制精美的彩图并配有相应的说明文字,通过图的方式加强说明,...

    毕业设计——社会捐赠监督

    【标题】:“毕业设计——社会捐赠监督” 在当今社会,公益捐赠已经成为许多企业和个人积极参与的活动,为了确保捐赠过程的透明度和公正性,社会捐赠监督系统显得尤为重要。本毕业设计旨在开发一个基于Java ...

    编程ING:人人都能学会程序设计 蔡学镛著 全彩

    通过《编程ING:人人都能学会程序设计》一书,你就能拥有这样的能力,甚至培养出对编程的兴趣。 本书在编写上采用了心理学的一些技巧,每一页都有绘制精美的彩图并配有相应的说明文字,通过图的方式加强说明,而且...

    阿里巴巴 Java 编码指南,Alibaba Java Coding Guidelines​,兼容 Idea 2023.3+

    《阿里巴巴 Java 编码指南》是业界广泛采用的编码规范,旨在提高代码质量和开发效率,尤其对于使用 IntelliJ IDEA 的开发者来说,此指南的兼容性更新至 2023.3+ 版本,确保了最新的开发环境支持。这份指南在 2024 年...

    毕业ing,本公司2011年最新Java面试题

    【标题】"毕业ing,本公司2011年最新Java面试题" 揭示了这是一份关于2011年某公司Java程序员面试的题目集合,可能包含了当年热门的技术和面试常见问题。2011年是Java技术发展的重要阶段,Java SE 6和7的使用广泛,而...

    IOS应用源码——两个计算器的源代码 inG_Calculator_1.53.zip

    在本资源中,我们拥有两个iOS应用的源代码——"inG_Calculator"的版本1.53。这个压缩包对于iOS开发者来说是一个宝贵的参考资料,尤其是那些正在学习或想要深入理解计算器应用开发的人员。下面我们将详细探讨iOS应用...

    cakephp框架 学习ing

    在这个"cakephp框架 学习ing"的主题中,我们将深入探讨 CakePHP 的核心特性、优势以及如何开始学习和使用它。 首先,让我们了解MVC模式。MVC是一种软件设计模式,将业务逻辑(Model)、用户界面(View)和数据控制...

Global site tag (gtag.js) - Google Analytics