初学java--五子棋

   其实五子棋呢主要包括三部分:五子棋棋盘和下棋子等关于Swing界面的应用;然后就是计算输赢的算法;最后就是人机对战的人工智能。刚刚开始做的时候是老老实实的画的棋盘,通过后来的学习知道了其实棋盘是可以找合适的棋盘图片粘贴的,目前还没找到想要的。。。。。。画棋盘就是一个循环画线的过程:

//画格子的方法
	private void drawchessbosrd(java.awt.Graphics g){
		//设置线条颜色
		g.setColor(java.awt.Color.BLACK);
		//循环画横线
		for(int i=0;i<Config.H_LINE;i++){
			g.drawLine(Config.X, Config.Y+i*Config.SIZE, Config.X+(Config.S_LINE-1)*Config.SIZE, Config.Y+i*Config.SIZE);
		}
		//循环画竖线
		for(int i=0;i<Config.S_LINE;i++){
			g.drawLine(Config.X+i*Config.SIZE, Config.Y, Config.X+i*Config.SIZE, Config.Y+(Config.S_LINE-1)*Config.SIZE);
		}
	}

 现在呢,棋盘有了,我们就需要在鼠标点击的格子交叉处下棋子,刚开始的棋子也是在窗体上得到一个画板然后画一个实心圆......后来学会了在那交叉点上画一个棋子的图片,图片怎么看上去也比一个平面圆有立体感啊!画图片的之前当然的计算出交叉点的坐标,这样才能在离点击的最近的地方画图片:

 //点击鼠标得到坐标
				 int x1=e.getX();
				 int y1=e.getY();
				//计算离鼠标点击地点最近的一个交叉点
				 if((x1-Config.X)%Config.SIZE<Config.SIZE/2){
					 j=(x1-Config.X)/Config.SIZE;
				 }else if((x1-Config.X)%Config.SIZE>Config.SIZE/2){
					 j=(x1-Config.X)/Config.SIZE+1;
				 }else{
					 j=(x1-Config.X-Config.SIZE/2)/Config.SIZE;
				 }
				 if((y1-Config.Y)%Config.SIZE<Config.SIZE/2){
				
					 i=(y1-Config.Y)/Config.SIZE;
				 }else if((y1-Config.Y)%Config.SIZE>Config.SIZE/2){
					 i=(y1-Config.Y)/Config.SIZE+1;
				 }else{
					 i=(y1-Config.Y-Config.SIZE/2)/Config.SIZE;
				 }
				 //开始下棋子,只能在没有下棋子的地方下
				 if(data[i][j]==0){
					 if(count==1){//在交叉点下黑子
						 //在交叉点画一个圆
						 URL url=this.getClass().getResource("b.png");
							//根据url创建图片对象
							ImageIcon  imageb=new ImageIcon(url);
							g.drawImage(imageb.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2, 
									Config.CHESS, Config.CHESS,back);						 count++;
																					 }
					 }else{//在交叉点下白子						 //在交叉点画一个圆
						 URL url=this.getClass().getResource("w.png");
							//根据url创建图片对象
							ImageIcon  imagew=new ImageIcon(url);
							g.drawImage(imagew.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2, 
									Config.CHESS, Config.CHESS,back);
						 count--;
																																}
				 }
			 }

 现在呢,棋子画上去了,我们就要判断一下输赢了。判断输赢的条件就是五子连珠,一颗棋子周围大家都知道有八个方向,所以呢就要向八个方向判断一下是否有相同的棋子,如果有就继续判断,一直到某个方向上有五颗相同的棋子,让程序输出一下输赢了就ok咯。判断输赢的方法大致都是一样的:

public boolean horizontalWin(int r,int c) {
		//定义一个计数器,默认等于,当前下的棋子
		int count = 1;
		boolean state = false;
			//循环遍历数组,此处是遍历当前行的每一个单元格,现在是往右边判断
			for(int j=c+1;j<chesses[r].length;j++){
				//判断当前数组中的元素是否想等
				if(chesses[r][j] == chesses[r][c])
					//相等计数器加1
					count++;
				//不相等,则退出循环
				else
					break;
			}
			//循环遍历数组,此处是遍历当前行的每一个单元格,现在是往左边判断
			for(int j=c-1;j>0;j--){
				//判断当前数组中的元素是否想等
				if(chesses[r][j] == chesses[r][c])
					//相等计数器加1
					count++;
				//不相等,则退出循环
				else
					break;
			}
			//如果统计的数据大于4,就表示已经五颗相同颜色的棋子连在一起了,表示已经赢了
			if(count > 4)
				//状态修改为true.
				state = true;
		//}
		//返回状态
		return state;
	}

 不同的是每个方向的循环方式不一样而已,当有五颗棋子连珠的时候,就可以显示输赢了,显示之后当然要清空棋盘:

if(win.erectWin(i,j)||win.horizontalWin(i, j)||win.leftObliqueWin(i, j)||win.rightObliqueWin(i, j)){
							 javax.swing.JOptionPane.showMessageDialog(null,
								"黑子赢了(*^__^*) " );
									for(int i=0;i<data.length;i++){
										for(int j=0;j<data[i].length;j++){
											data[i][j]=0;
										}
									}
									paint(g);
						 }

 然而这时的五子棋还有很多不完善,比如:重绘等等,所以我们在下棋子的时候一定要用一个东西来保存当前棋子的信息,这个东西可以是二维数组,也可以是自定义队列,有了保存棋子的东西,那么重绘也就很简单了。如果我们想保存某一局棋局的时候,就需要用到文件保存了,吧当前棋局的所有信息存入一个文件中,读取的按照信息进行重绘:

public void savefile(int[][] data)  {
		//保存的文件名
		String filename="src\\cn\\tan\\lesson6\\chess";
		try {
			//新建输出流对象
			FileWriter fw = new FileWriter(filename);
			//循环输出数据
			for(int i=0;i<data.length;i++){
				for(int j=0;j<data[i].length;j++){
					fw.write(data[i][j]+"\t");
				}
			fw.write("\r\n");
			}
			//强制写入并关闭流对象
			fw.flush();
			fw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

 打开文件时的方法:

open.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				String command=e.getActionCommand();
				if(command.equals("打开文件")){
					String s = "";
					//读取文件文件名
					String fielname="src\\cn\\tan\\lesson6\\chess";
					try {
						//新建输入流对象
						FileReader fr=new FileReader(fielname);
						BufferedReader  br=new BufferedReader(fr);
						int [][] set=new int[12][12];
						for(int i=0;i<set.length;i++){
						 s=br.readLine();
						 String value[]=s.split("\t");
//						 paint(g);
						 for(int j=0;j<set.length;j++){
							//得到第i行j列的元素值
							 int m=Integer.parseInt(value[j]);
							 data[i][j]=m;
						 if(m==1){
							//设置颜色
								g.setColor(java.awt.Color.WHITE);
								//画棋子
								URL url=this.getClass().getResource("w.png");
								//根据url创建图片对象
								ImageIcon  imagew=new ImageIcon(url);
								g.drawImage(imagew.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2, 
										Config.CHESS, Config.CHESS,back);
								}
						
						 if(m==2){
							//设置颜色
//								g.setColor(java.awt.Color.BLACK);
								//画棋子
								URL url=this.getClass().getResource("b.png");
								//根据url创建图片对象
								ImageIcon  imageb=new ImageIcon(url);
								g.drawImage(imageb.getImage(),(Config.X + j * Config.SIZE) - Config.CHESS/ 2, (Config.Y + i * Config.SIZE)- Config.CHESS / 2, 
										Config.CHESS, Config.CHESS,back);							}
						 }
					 }
						fr.close();
						br.close();
					}
				catch (FileNotFoundException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
			
		});

 当然还有其他的比如重新开始、悔棋等功能就不再一一列举代码咯......至于人机对战仍在思索ing

 

你可能感兴趣的:(java,C++,c,swing,J#)