JAVA第一个小项目——五子棋的制作(第一篇)


大家都应该知道五子棋吧,当自己和电脑打的时候有没有对电脑怎么下棋有过疑惑?为什么有时候连电脑都打不过呢,哈哈,那么这次我就来说一下自己制作五子棋这个小游戏的心得和领会吧。

首先先说一下简单的一些方面,要下五子棋,首先我们要把棋盘做出来对不对,那么大家都知道五子棋的棋盘是15*15的方格,那么有点java基础的就可以画出这个棋盘了是吧。不急,待会儿我们还要给出代码。另外说一下,我们在做一个东西的时候要先想好条件是什么,更具体的说就是那些条件是固定的。这样想的越多对我们的帮助就越大。因为我们做一个项目的时候,要写很多类的,类和类之间又有很多关系,如果知道了一些条件是固定的话,那么我们可以让所有的类继承这个接口,那么岂不是方便了很多,我们想想五子棋哪些条件是固定的,首先我们要存棋子,那么要有一个15*15的数组来存放吧,接下来我们要画棋子,那么棋子的大小也应该是固定的,对于画棋盘来说,边界的间距也是固定的等等,首先我们写出了一个接口,那么接下来我们在写类的时候就可以让类去继承这个接口,先贴出代码:

package GoBang;

public interface GoBangInterface 
{
	//棋子的大小
	public static final int Size = 44;
	public static final int X = 25;
	public static final int Y = 25;
	public static final int Row = 15;
	public static final int Coloum = 15;
	//存旗子的数组
	public static final int[][] array = new int[Row][Coloum];
}

那么接下来我们可以画棋盘了,先贴出代码:

package GoBang;

import java.awt.*;
import javax.swing.*;

public class GoBangPanel extends JPanel implements GoBangInterface{
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		GoBangPanel chesspanel = new GoBangPanel();
		chesspanel.gobang();
	}
	
	public void gobang()
	{
		//设置版面
		JFrame frame = new JFrame();
		frame.setTitle("五子棋");
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(3);
		frame.setSize(850,700);
		//设置布局
		frame.setLayout(new BorderLayout());
		
		frame.add(this,BorderLayout.CENTER);
		//在jpanel组件上画棋子
		JPanel panel1 = new JPanel();
		panel1.setBackground(Color.DARK_GRAY);
		panel1.setPreferredSize(new Dimension(150,0));
		frame.add(panel1,BorderLayout.EAST);
		
		frame.setVisible(true);
		
		GoBangListener listener = new GoBangListener(this);
		this.addMouseListener(listener);
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		Graphics2D gg = (Graphics2D) g;
		//画出整个棋盘
		for(int i = 0; i < Row; i++)//行
		{
			gg.drawLine(X, Y+i*Size, X+Size*(Coloum-1), Y+i*Size);
		}
		for(int i = 0; i < Coloum; i++)//列
		{
			gg.drawLine(X+i*Size, Y, X+i*Size, Y+Size*(Row-1));
		}
		//画出棋子
		for(int i = 0; i < array.length; i++)
			for(int j = 0; j < array[i].length; j++)
			{
				if(array[i][j] != 0)
				{
					if(array[i][j]%2 != 0)
					{
						gg.setColor(Color.black);
					}else
					{
						gg.setColor(Color.white);
					}
					int x = Y+j*Size-Size/2;
					int y = X+i*Size-Size/2;
					gg.fillOval(x, y, Size, Size);
				}
			}
	}
}

在这里说明两点,第一个为什么布局用了BorderLayout,因为这个包括了东西南北四个方向,因为五子棋肯定有悔棋,开始等等这些按钮组件,所以,我们要去把这些按钮组件和整个棋盘分开,所以我用了jpanel这个组件单独画的棋盘。那么再说一下,我为什么对paint这个重绘方法做了修改,这是因为如果不在paint里面把棋盘画好的话,那么运行的开始你是看不到棋盘的,再就是如果你最小化窗口再打开的话,棋盘也是会不见的,所以就决定了在paint方法里面画出这个棋盘,并且里面还有一部分就是画棋子,因为如果棋盘上有了棋子,那么在画棋盘的时候当然要把棋子也画上,总不能重新下吧,哈哈。

那么这样我们接下来就要对jpanel组件添加监听方法了,因为我们要下棋呀,并且棋子不能乱下,要下在直线和直线的焦点上,但是我们每次点击并不能那么的准确,所以我们就需要动动脑筋来确定把棋子下在哪个焦点上。那么我们就要实现这个GoBangListener了,贴出代码:

package GoBang;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class GoBangListener extends MouseAdapter implements GoBangInterface
{
	private Judge j;
	private GoBangPanel panel;
	private Graphics2D g;
	private GoBangAn an;
	private int x,y;
	private int num = 1;
	
	public GoBangListener(GoBangPanel panel)
	{
		this.panel = panel;
		g = (Graphics2D)this.panel.getGraphics();
		an = new GoBangAn(this.panel);
	}
	
	public void mouseReleased(MouseEvent e) 
	{
		//取得坐标
		x = e.getX();
		y = e.getY();
		//计算行列
		int row = (y-Y+Size/2)/Size;
		int coloum = (x-X+Size/2)/Size;
		
		if(row < Row && coloum < Coloum)
		{
			if(array[coloum][row] == 0)
			{
				//确定在数组的位置
				x = X+coloum*Size-Size/2;
				y = Y+row*Size-Size/2;
					
//				if(num%2 != 0 )
//				{
				g.setColor(Color.black);
//				}else
//				{
//					g.setColor(Color.white);
//				}
				array[row][coloum] = num;
				
				g.fillOval(x, y, Size, Size);
				j = new Judge(row,coloum);
				j.judge();
				an.update(row,coloum);
				num++;
				an.anticipate(num);
				num++;
			 }
		}
	}
}
这里还用到了其他类的一些方法,不过没关系,这些可以先不看,这里主要注意一下怎么确定棋子的位置,仔细想一下也是很简单的,但是提醒一下,电脑的0坐标是在左上角,以它为中心,x轴水平方向,远离0坐标的方向为正方向,y轴竖直方向,远离0坐标的方向为正方向。而且我们用数组来盛放棋子,数组的第一维是行也就是屏幕的y,第二位是列也就是屏幕的x,对于怎么计算棋子的位置根据棋盘的边界就可以确定了,很简单,看看代码就知道啦。

接下来我们说一下j是什么,这是一个类对象,那么,这个类是专门判断是不是游戏结束的,也就是有没有5个相同的棋子连在一块,这个怎么判断呢,很简单,暴力判断就可以,遍历整个数组,从四个大方向来判断就好了,分别是横竖,和两个斜着的方向,贴出代码:

package GoBang;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Judge implements GoBangInterface{
	private JFrame frame;
	private int x,y;
	private int count;
	
	public Judge(int x,int y)
	{
		this.x = x;
		this.y = y;
		count = 1;
		frame = new JFrame();
		frame.setTitle("结果");
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(3);
		frame.setSize(450,300);
	}
	
	public void judge()
	{
//		System.out.println(array[x][y]);
		count = 1;
		//竖向检查
		for(int i = x+1; i < Coloum; i++)
		{
			if(array[i][y] != 0 )
			{
				if((array[x][y]%2) == (array[i][y]%2))
				{
					count++;
				}else break;
			}else break;
		}
		for(int i = x-1; i >= 0; i--)
		{
			if(array[i][y] != 0 )
			{
				if((array[x][y]%2) == (array[i][y]%2))
					count++;
				else break;
			}else break;
		}
		if(count>=5)
		{
			if(array[x][y]%2 != 0)
			{
				JLabel label = new JLabel("黑棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}else 
			{
				JLabel label = new JLabel("白棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}
			return ;
		}
		count = 1;
		//横向检查
		for(int i = y+1; i < Row; i++)
		{
			if(array[x][i] != 0 )
			{
				if((array[x][y]%2) == (array[x][i])%2)
					count++;
				else break;
			}else break;
		}
		for(int i = y-1; i >= 0; i--)
		{
			if(array[x][i] != 0 )
			{
				if(array[x][y]%2 == array[x][i]%2)
					count++;
				else break;
			}else break;
		}
		if(count>=5)
		{
			if(array[x][y]%2 != 0)
			{
				JLabel label = new JLabel("黑棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}else 
			{
				JLabel label = new JLabel("白棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}
			return ;
		}
	
		count = 1;
		//斜向检查(从左上角到右下角)
		for(int i = x-1,j = y-1;i>=0&&j>=0; i--,j--)
		{
			if(array[i][j] != 0 )
			{
				if((array[x][y]%2) == (array[i][j]%2))
					count++;
				else break;
			}else break;
		}
		for(int i = x+1,j = y+1;i<Coloum&&j<Row; i++,j++)
		{
			if(array[i][j] != 0 )
			{
				if((array[x][y]%2) == (array[i][j]%2))
					count++;
				else break;
			}else break;
		}
		if(count>=5)
		{
			if(array[x][y]%2 != 0)
			{
				JLabel label = new JLabel("黑棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}else 
			{
				JLabel label = new JLabel("白棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}
			return ;
		}
		count = 1;
		//斜向检查(从左下角到右上角)
		for(int i = x-1,j = y+1;i>=0&&j<Row; i--,j++)
		{
			if(array[i][j] != 0 )
			{
				if((array[x][y]%2) == (array[i][j]%2))
					count++;
				else break;
			}else break;
		}
		for(int i = x+1,j = y-1;i<Coloum&&j>=0; i++,j--)
		{
			if(array[i][j] != 0 )
			{
				if((array[x][y]%2) == (array[i][j]%2))
					count++;
				else break;
			}else break;
		}
		if(count>=5)
		{
			if(array[x][y]%2 != 0)
			{
				JLabel label = new JLabel("黑棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}else 
			{
				JLabel label = new JLabel("白棋胜!!!!!");
				label.setPreferredSize(new Dimension(400,250));
				label.setFont(new Font("楷体",1,50));
				frame.add(label);
				frame.setVisible(true);
			}
			return ;
		}
	}
}

思路很简单,但是写起来还是比较麻烦的,那么到现在你已经可以下棋了,并且可以判断输赢,可以两个人玩一下,但是我们要实现人机大战,那怎么让电脑和你下棋呢?下篇文章我接着说,毕竟太长了,还是很两次比较好哈哈。

  • 25
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值