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

五子棋

阅读更多
    今天终于是把五子棋之人人大战的基本功能实现了,本来是想把界面美化一下再写总结的。唉,后来发现还是算了吧。这个java搞界面真的不适合啊,于是乎先把总结写了再说,那些美化,以及功能的完善什么的等晚点在慢慢去弄吧。 
    那么,下面咱们进入正题,一起探讨一下其实现方法。

一、界面

    界面这东西java真心不适合弄啊,方正我是觉得好费心的。我的棋盘界面很简单朴素,就是由rows根横线和columns根竖线组成。具体代码如下:
 
   1.棋盘的绘制
public void paint(Graphics g){
		//调用父类paint方法
		super.paint(g);
		//绘制棋盘
		//划横线
		for(int i=0;i<config.rows;i++){
			g.drawLine(config.x0, config.y0+i*config.size,config.x0+    (config.columns-1)*config.size, config.y0+i*config.size);
		//划竖线
		 for(int j=0;j<11;j++){
			 g.drawLine(config.x0+j*config.size,config.y0, config.x0+j*config.size, config.y0+(config.rows-1)*config.size);
		 }
		}


   我的棋盘绘制是放在paint方法里面的。大家也看到了我的棋盘是用一根根横线和竖线组成的。  当然,肯定会有同学问,这段代码中诸如config.x0、y0、size、rows、colmns等变量都是哪来的,为什么不直接用数值体现呢,写的那么抽象。  呵呵,别急,下面我大家介绍一下我的这些变量。  首先还是看一段代码。

2.变量的设置
/**
 * 用于协定五子棋界面所需的一些数据常量  如线条个数  大小 直径。。。目的是便于今后修改
 * @author Administrator
 *
 */
public interface config{
		public 	static final int x0=50;//表格左上角起点的X值
		public 	static final int y0=50;//表格左上角起点的y值
		public	static final int rows=11;//横向线的条数
		public	static final int columns=11;//纵向线的条数
		public	static final int chess_size=40;//棋子直径
		public	static final int size=50;//单元格的大小

}


    嗯,没错,这些变量的值都是我事先定义好的,我之所以这么做是为了便于以后程序的扩展和调整。比如哪天我希望我的棋盘是15*15的大小,在这里我就只需要改2个地方。rows和colums的值。是不是很方便呢。

二、鼠标监听
   
    做好界面,接下来要做的事情就是为我们的界面添加一个鼠标监听器,当我们在棋盘网格上点击时,就会相应的放上一颗棋子。
    1.添加鼠标监听器
               
//给画布添加鼠标监听
		this.addMouseListener(new chesslistener(g,this));

                这个不用多说了吧,相信大家也练了很多了。
    2,改写鼠标监听中,鼠标释放的方法
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;


public class chesslistener extends MouseAdapter{

	private chessBorad chessborad; 
	private Graphics g[color=red];// 绘制棋子的对象
	public static  int [][]array=new int [config.rows][config.columns];// 存储 棋子的对象
	
	private  boolean state = true;// 表示黑白棋的标识,true!@@@@@@@@@@@黑棋,false@@@@@@@@@@@@@@白棋
	//构造函数
	public chesslistener(Graphics g,chessBorad chessborad){
		this.g=g;
		this.chessborad=chessborad;
	}
	[/color]
	public void mouseReleased(MouseEvent e) {

				// 获取到鼠标释放的坐标值
				int x = e.getX();
				int y = e.getY();
				// 计算当前棋子所在的行和列
				int row = (y - config.y0) / config.size;
				if[align=left][/align] ((y - config.y0) % config.size > config.size / 2) {
					row += 1;
				}
				int column = (x - config.x0) / config.size;
				if ((x - config.x0) % config.size > config.size / 2) {
					column += 1;
				}
				// 计算坐标
				int x1 = column * config.size + config.x0;
				int y1 = row * config.size + config.y0;
				if ((row < config.rows && row >= 0)
						&& (column < config.columns && column >= 0))
					// 如果等于0,则表示该位置没有下过棋子
					if (array[row][column] == 0) {
						if (state) {// 表示下黑棋
							g.setColor(Color.BLACK);
							//计算,棋子画在交叉点位置
							g.fillOval(x1 - config.size / 2,
									y1 - config.size / 2, config.chess_size,
									config.chess_size);
							state = false;
							// 存储棋子
							array[row][column] = -1;
						} else {
							// 表示下白棋
							g.setColor(Color.WHITE);
							g.fillOval(x1 - config.size / 2,
									y1 - config.size / 2, config.chess_size,
									config.chess_size);
							state = true;
							// 存储棋子
							array[row][column] = 1;
						}
						
						
						//判断输赢
					if(win.ISHwin(row, column,array,chessborad))
						state=true;  //   将状态再次改为黑棋先下
					if(win.ISSwin(row, column,array,chessborad))
						state=true;  //   将状态再次改为黑棋先下
					if(win.ISXwin(row, column,array,chessborad))
						state=true;  //  将状态再次改为黑棋先下
					
					}
					
		}

	}


[/align][/color]

三、判断输赢
    下五子棋,总有输赢,我们不可能不停地下下去,当一方获胜后(并告知用户谁获胜),本局就应该结束,重新开始新的一轮比赛。具体代码如下:
import java.awt.Component;

import javax.swing.JOptionPane;

/**
 * 判断胜负
 * @author 吴泽鑫
 * ISHwin() 判断是否为横向五子连心
 * ISSwin() 判断是否为竖向五子连心
 * ISXwin() 判断是否为斜向五子连心
 *
 */
public class win {
	  
	//判断横向
	public static boolean ISHwin(int row,int column,int [][]array,chessBorad chessborad){

		int count = 1;// 用于统计所连棋子个数,默认为一
		// 遍历这一行的右边列
		for (int i = column + 1; i < array[row].length; i++) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[row][i]) {
				count++;
			} else {
				break;
			}
		}
		// 遍历这一行的左边列
		for (int i = column - 1; i >= 0; i--) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[row][i]) {
				count++;
			} else {
				break;
			}
		}
		// 如果count等于5,说明五子连心,胜负已定
		if(count >= 5){
			if(array[row][column]==1&&array[row][column]!=0)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "白棋赢啦");
			else 
				if(array[row][column]==-1)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "黑棋赢啦");
			
			//胜负已定,需重新初始化界面,即将arry数组全部赋0
			for(int i=0;i<array.length;i++)
					for(int j=0;j<array[i].length;j++)
						array[i][j]=0;
				
			//刷新界面repaint()		
				chessborad.repaint();
				
				return true;
		}
		else 
			return false;
}
	
	public static boolean ISSwin(int row,int column,int [][]array,chessBorad chessborad){
		int count = 1;// 统计棋子个数的
		// 遍历这一列的右边行
		for (int i = row + 1; i < array.length; i++) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[i][column]) {
				count++;
			} else {
				break;
			}
		}
		// 遍历这一列的左边行
		for (int i = row - 1; i >= 0; i--) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[i][column]) {
				count++;
			} else {
				break;
			}
		}
		if(count >= 5){
			if(array[row][column]==1&&array[row][column]!=0)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "白棋赢啦");
			else 
				if(array[row][column]==-1)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "黑棋赢啦");
			
			//胜负已定,需重新初始化界面,即将arry数组全部赋0
			for(int i=0;i<array.length;i++)
				for(int j=0;j<array[i].length;j++)
					array[i][j]=0;
			//重新刷新界面repaint()
			chessborad.repaint();
			return true;
		}
		else
			return false;
	}
	
	//判断斜线方向
	
	public static boolean ISXwin(int row,int column,int [][]array,chessBorad chessborad){
		int count = 1;// 统计棋子个数的
		// 遍历左斜下部分
		for (int i = row + 1,j=column+1; i < array.length&&j<array[i].length; i++,j++) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[i][j]) {
				count++;
			} else {
				break;
			}
		}
		// 遍历左斜上部分
		for (int i = row - 1,j=column-1; i >= 0&&j>=0; i--,j--) {
			// 判断是否是相同的棋子
			if (array[row][column] == array[i][j]) {
				count++;
			} else {
				break;
			}
		}
		//// 遍历右斜下部分
		for(int i=row+1,j=column-1;i<array.length&&j>=0;i++,j--){
			if (array[row][column] == array[i][j]) {
				count++;
			} else {
				break;
			}
			
		}
		//// 遍历右斜上部分
		for(int i=row-1,j=column+1;i>=0&&j<array[i].length;i--,j++){
			if (array[row][column] == array[i][j]) {
				count++;
			} else {
				break;
			}
			
		}
		if(count >= 5&&array[row][column]!=0){
			
			if(array[row][column]==1)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "白棋赢啦");
			else 
				if(array[row][column]==-1)
				//弹出一个消息框,告诉用户结果
				JOptionPane.showMessageDialog(null, "黑棋赢啦");
			
			//胜负已定,需重新初始化界面,即将arry数组全部赋0
			for(int i=0;i<array.length;i++)
				for(int j=0;j<array[i].length;j++)
					array[i][j]=0;
			
			//重新刷新界面repaint()
			chessborad.repaint();
			return true;
			
		}
		else
			return false;
	}
	
	
}



   好啦,到这里,我的简单的五子棋之人人对战程序已经写好啦。。。当然在功能和界面上还有很多需要完善的,这都会在我今后慢慢进行改进的。。
2
0
分享到:
评论
7 楼 lancelotwjq 2012-11-07  
http://kight.gobang.jit.su/

6 楼 kidding87 2012-11-07  
我觉得判断win的条件就是所走的那个子决定的,判断应该从它出发
5 楼 mfkvfn 2012-11-07  
判断胜负那个写得不好。应该将判断和结果显示分开。

一个类只负责绘图,一个类进行控制,一个类维护数据模型,一个工具类(判断落子是否有效,判断是否有1方胜出)


public final class ChessUtils{

  public static boolean ISWin(Point lastChessPoint,Model chessDatas){
     return IsHWin(lastChessPoint,chessDatas) || IsSWin(lastChessPoint,chessDatas) || IsXWin(lastChessPoint,chessDatas);
  }

  private static boolean IsHWin(Point lastChessPoint,Model chessDatas){...}
  private static boolean IsSWin(Point lastChessPoint,Model chessDatas){...}
  private static boolean IsXWin(Point lastChessPoint,Model chessDatas){...}

}

public enum ChessType{
   BLACK,WHITE,NONE;
}

public final class Model{
   public Model(Config config){...}
   public boolean setChessAt(Point point,ChessType userType){...}
   public ChessType getChessAt(Point point){...}
}

public final class UI{
   public static void init(Graphics g,Config config){...}
   public static void drawChessAt(Graphics g,Point point,ChessType userType){...}
   public static void printResult(Graphics g,ChessType userType){...}
   public static void indicateCannotDo(Graphics g,ChessType userType){...}
}

public final class ChessEventListener{
...
//监听落子动作
if(getChessAt(point)==ChessType.NONE){ //这里可以下子
   model.setChessAt(point,chessType); //修改model
   UI.drawChessAt(g,point,chessType); //ui中画出这颗子
   if(ChessUtils.ISWin(point,model)){  //最后下子胜了
      UI.printResult(g,chessType);
   }
}else{
   UI.indicateCannotDo(g,chessType); //提示那个地方已经有子了,不可以在那里下
}
...
}


public class Chess{
   public static void main(String args[]){
  Graphics g=new XXXX();
  Config config=YYYYY;
  Model model=new Model(config);
  UI.init(g,config);
  g.addListener(new ChessEventListener());
  ...
}
}
4 楼 yscyfy 2012-11-07  
其实java的界面设计是很优美的,你不能只会拖拽是生成吧,那根本就不是一个合格的程序员该干的事情。
建议楼主看看论坛上有个叫“Swing 第X刀” 的帖子。
3 楼 javaboy8282 2012-11-06  
楼主 分享一下源代码
2 楼 须等待 2012-11-06  
感觉LZ判断输赢的算法效率比较低啊
1 楼 lvwenwen 2012-11-06  
哥们,辛苦了,把工程打包共享下,谢谢

相关推荐

    matlab-wuziqi.rar_matlab五子棋gui_五子棋_五子棋matlab_五子棋matlan_五子棋算法

    【标题】"matlab-wuziqi.rar"中包含的是一个使用MATLAB编程实现的五子棋GUI(图形用户界面)项目。这个项目是开发者基于MATLAB的M语言编写的,目的是为了创建一个可供人机对战或者双人对战的五子棋游戏。 【描述】...

    MFC 五子棋 一个简单的五子棋游戏

    《MFC实现的五子棋游戏详解》 五子棋是一种简单却富有策略性的棋类游戏,深受广大玩家喜爱。本文将围绕一个基于MFC框架实现的五子棋游戏进行详细解析,涵盖游戏的核心功能、数据结构设计以及关键算法。 首先,让...

    模拟连五子棋游戏,五子棋经典算法

    在IT行业中,游戏开发是一项既富有挑战性又充满乐趣的工作,尤其当涉及到经典的逻辑游戏时,如五子棋。五子棋是一种双人对弈的策略游戏,目标是在棋盘上形成连续的五个同色棋子,无论是横、竖还是斜线。在此,我们将...

    超强五子棋软件 奕心2015

    弈心——最强的五子棋引擎 尽管五子棋先后于1992年、2001年被计算机证明原始无禁手、原始有禁手规则下先手必胜,在五子棋专业比赛中采用现代开局规则(如基于无禁手的两次交换规则(Swap-2),基于有禁手的索索夫-8...

    用VC编写的一个五子棋:五子棋源代码

    《五子棋源代码解析与VC开发经验分享》 五子棋,又称连珠,是一种简单却富有策略性的双人对弈游戏。在计算机编程领域,实现五子棋的源代码是一个经典的练习项目,它涉及到图形用户界面设计、游戏逻辑算法以及事件...

    pythonAI五子棋_python教程_五子棋_

    五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。五子棋有两种玩法。玩法一:双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜。玩法二:自己形成五子连线...

    五子棋的实现(UML建模图)

    五子棋游戏软件的实现(UML建模图) 本文将对五子棋游戏软件的实现进行详细的介绍,包括软件的架构设计、类的构造、成员变量和成员函数的使用、消息机制的实现,以及游戏算法的概述。 首先,本文对 C++、MFC 和它...

    alphabeta搜索五子棋

    《AlphaBeta搜索在五子棋中的应用》 五子棋是一种深受人们喜爱的智力游戏,其规则简单,但策略深奥。在计算机科学领域,如何让计算机在游戏中展现出高超的棋艺,一直是人工智能研究的重要课题。本文将深入探讨Alpha...

    wrenju五子棋黑石汉化版

    《五子棋黑石汉化版:探索顶尖人机对弈体验》 五子棋,又称连珠,是一项历史悠久、深受人们喜爱的智力游戏。它简单易懂,但蕴含着深奥的策略与技巧,是智慧与策略的对决。而“renju五子棋”作为一款业内知名的...

    基于L inux的嵌入式五子棋游戏_ 6818开 发板五子棋,基于linux

    在本项目中,我们关注的是一个基于Linux的嵌入式五子棋游戏,它特别针对6818开发板设计。这个项目的核心是利用Linux操作系统的能力,在嵌入式硬件平台上实现一个可玩的五子棋游戏,允许玩家与计算机进行对弈。下面将...

    MFC双人对战五子棋

    《MFC实现双人对战五子棋游戏详解》 MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于构建Windows应用程序。在这个项目中,“MFC双人对战五子棋”是一个利用MFC框架开发的桌面游戏,旨在帮助用户在...

    java_五子棋 实习报告

    【Java五子棋实习报告】主要探讨了使用Java编程语言设计和实现五子棋游戏的过程,包括人机对战和玩家间的联网对战功能。在报告中,作者详细阐述了五子棋游戏的背景和历史,以及选择Java作为开发语言的原因。Java因其...

    五子棋人机对战_初级

    【标题】"五子棋人机对战_初级"是一个基于Java编程语言开发的简易五子棋游戏,专为初学者设计。这个项目的核心在于实现一个简单的命令行界面,允许玩家与计算机进行对战,从而体验到编程带来的乐趣和成就感。 ...

    QT五子棋人机对战人人对战

    QT五子棋是一款基于Qt框架开发的棋类游戏,它实现了经典的五子棋玩法,包括人与人之间的对战模式以及人与计算机的对战模式。在这款游戏中,玩家可以体验到传统五子棋的策略性和竞技性,同时,通过与AI的对弈,还能...

    基于C++的程序员Rock视频教程学习五子棋人机对战设计源码

    本资源提供了一套基于C++的程序员Rock视频教程学习的五子棋人机对战设计源码,包含34个文件,其中包括8个PNG图片文件,7个MP3音频文件,以及5个C++源代码文件。此外,还包括5个JPEG图片文件,4个头文件,以及2个...

    unity五子棋游戏demo源码

    unity五子棋游戏demo源码 Unity精品小游戏源码 , Unity完整项目源码 是Unitypackage包 , 新建空项目直接导入到项目里面就可以运行了,无需其他操作,适合二次开发和学习使用,都是经典游戏,需要其他游戏源码包可以看我...

    VC 五子棋源代码

    《VC五子棋源代码解析与学习指南》 在编程世界中,开发一款游戏是学习新语言和技术的绝佳方式。本文将围绕“VC五子棋源代码”这一主题,深入探讨C++编程语言在实现五子棋游戏中的应用,以及如何通过VC(Visual C++...

    用Java写的五子棋

    《Java实现的五子棋游戏详解》 五子棋,又称连珠,是一种深受人们喜爱的双人对弈策略游戏。在计算机编程领域,利用Java语言实现五子棋游戏是一项有趣的挑战,也是学习图形用户界面(GUI)、事件处理、算法设计等...

    基于FPGA的五子棋游戏

    本项目“基于FPGA的五子棋游戏”是利用FPGA技术来实现一个五子棋游戏系统,通过Verilog语言编程,结合VGA显示技术,提供了一个互动的游戏平台,玩家可以通过五个按键来控制游戏的进行。 1. **FPGA基础**:FPGA由...

    wuziqi.rar_Vc_五子棋_五子棋c_五子棋游戏

    《VC五子棋游戏开发详解》 五子棋,又称为连珠,是一种深受人们喜爱的智力游戏。在计算机领域,将五子棋游戏开发成软件,不仅可以供玩家娱乐,还可以作为研究人工智能的一个实例。本篇文章将围绕"VC五子棋游戏"这一...

Global site tag (gtag.js) - Google Analytics