Java实践项目---单机五子棋

项目目标:

  1. 绘制游戏界面,且实现重绘功能
  2. 绘制棋子(使棋子放在棋盘交点处)
  3. 黑白交替,保存棋子,判断输赢
  4. 实现开始和悔棋功能

绘制界面

public class WuZi {
	public void initUI(){
		MyFrame jf=new MyFrame();
//利用类MyFrame继承JFrame来实现重绘功能
		jf.setSize(1500,900);
		jf.setTitle("五子棋");
		jf.setLocationRelativeTo(null);
		jf.setDefaultCloseOperation(3);	
		FlowLayout flow= new FlowLayout();
		jf.setLayout(flow);
		DrawMouse mouse=new DrawMouse();
		String[]arr= {"开始","悔棋"};
//添加功能按钮
		for(int i=0;i<arr.length;i++) {
			JButton jb=new JButton(arr[i]);
			jb.setPreferredSize(new Dimension(100,50));
			jb.addActionListener(mouse);
			jf.add(jb);
		}
		jf.addMouseListener(mouse);		
		jf.setVisible(true);
		Graphics g=jf.getGraphics();
///画笔一定要声明在窗体设置可见以后
		mouse.g=g;
		jf.chess=mouse.chess;
//将mouse中的chess数组传给jf中的chess数组中
//chess是Chess类的数组,作用是存储已下棋子,便于重绘和判断输赢
	}
	public static void main(String[] args)
	{
		WuZi p=new WuZi();
		p.initUI();
	}

创建Chess类保存棋子及利用paint方法实现重绘功能

public class Chess {
	int x;
	int y;
	boolean col;
//col为true时为黑棋,为false时为白棋
	Chess(int x,int y,boolean col){
		this.x=x;
		this.y=y;
		this.col=col;
	}
	public void paint(Graphics g) {
		if(col) {
			g.setColor(new Color(0,0,0));
			g.fillOval(x-25, y-25, 50, 50);
		} else {
			g.setColor(new Color(250,250,250));
			g.fillOval(x-25, y-25, 50, 50);
		}
	}
}

public class DrawMouse implements MouseListener,ActionListener{
	Graphics g;
	Chess[] chess=new Chess[130];
	int index=0;
	int x1,y1;
	boolean col=true;
//coltrue为黑棋,false为白棋
	int[][] table=new int[11][11];
//利用table来保存,0为未下,1为黑棋,2为白棋
	String buttonName;
	boolean whiteWin=false;
	boolean blackWin=false;
	 public void actionPerformed(ActionEvent e) {
		 buttonName=e.getActionCommand();
		 if(buttonName.equals("悔棋")&&index>0) {
				index--;
				int X=(chess[index].x-50)/50;
				int Y=(chess[index].y-250)/50;
				table[Y][X]=0;
				chess[index]=null;
//将chess对象回收
				buttonName="开始";
		} 
	 }
	public void mouseClicked(MouseEvent e) {
		if(blackWin||whiteWin)return;
		if(buttonName.equals("开始")) {
		x1=e.getX();
		y1=e.getY();
		if(x1>=25&&x1<=575&&y1<=775&&y1>=225) {
			x1=(x1+25)/50*50;
			y1=(y1+25)/50*50;
//处理点击的坐标,使其处于最近的棋盘交点
			boolean ret=false;
			for(int i=0;chess[i]!=null;i++) {
				if(chess[i].x==x1&&chess[i].y==y1) {
					ret=true;
//判断是否点击位置有已下过的棋子
					break;
				}
			}
			if(ret) {
				return;
			}
			chess[index++]=new Chess(x1,y1,col);
//保存棋子信息
			if(col) {
				g.setColor(new Color(0,0,0));
				g.fillOval(x1-25, y1-25, 50, 50);
			} else {
				g.setColor(new Color(250,250,250));
				g.fillOval(x1-25, y1-25, 50, 50);
			}
			if(col) {
				int X=(x1-50)/50;
				int Y=(y1-250)/50;
				table[Y][X]=1;
			} else {
				int X=(x1-50)/50;
				int Y=(y1-250)/50;
				table[Y][X]=2;
			}
			if(win(table)==1) blackWin=true;
			else if(win(table)==2) whiteWin=true;
			col=!col;	
//改换另一种颜色棋子下棋
		} else {
			
		}
	}
		if(blackWin) {
			g.setFont(new Font("仿宋",Font.BOLD,40));
			g.setColor(Color.BLACK);
			g.drawString("Black Win!!!", 600, 400);
			return;
		}
		if(whiteWin) {
			g.setFont(new Font("仿宋",Font.BOLD,40));
			g.setColor(Color.BLACK);
			g.drawString("White Win!!!", 600, 400);
			return;
		}
    public void mousePressed(MouseEvent e) {
    
    }
    public void mouseReleased(MouseEvent e) {
    
    }
    public void mouseEntered(MouseEvent e) {
    
    }
    public void mouseExited(MouseEvent e) {
    	
    }
}

输赢判定算法

public static int win(int[][]table) {
		int dx[]= {0,1,1,1,0,-1,-1,-1};
		int dy[]= {1,1,0,-1,-1,-1,0,1};
//分别对应八个方向
		for(int i=0;i<11;i++) {
			for(int j=0;j<11;j++) {
				if(table[j][i]==0)continue;
				for(int k=0;k<8;k++) {
					int counts=0;
					int X=i;
					int Y=j;
					for(int m=0;m<4;m++) {
//每一个方向判断四次每次判断成功则counts++,最后counts为4则该种颜色棋子获胜
						X+=dx[k];
						Y+=dy[k];
						if(X<0||X>10||Y<0||Y>10)continue;
						if(table[j][i]==table[Y][X]) counts++;
					}
					if(counts==4) {
						if(table[j][i]==1) return 1;
						if(table[j][i]==2) return 2;
					}
				}
			}
		}
		return 0;
	}

MyFrame类实现重绘功能

public class MyFrame extends JFrame{
	Chess[] chess;
	public void paint(Graphics g) {
		super.paint(g);
		for (int i = 0; i <=10; i++) {
			g.drawLine(50, 250+i*50, 550, 250+i*50);
		}
		for (int i = 0; i <=10; i++) {
			g.drawLine(50+i*50, 250,50+i*50 , 750);
		}
		for(int i=0;chess[i]!=null;i++) {
			chess[i].paint(g);
		}
	}
}

效果图

点击开始键,正常开始游戏

 点击悔棋键(两次)后

 

 最终结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白木Channel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值