九宫格游戏(java实现)

代码思路:

创建了一个九宫格按钮类(继承了JButton),定义了一个九宫格类,先随机生成8个数,用网格排版放入9个格子,然后在游戏创建了3x3的矩阵用于存储状态,再对每个按键加监听器,当按下去时判断能否移动,能移动则交换空格和这个按钮的名字,每次按下去判断是否从1-8排布,判断是否赢。
由于随机生成的排序,所以没有考虑到无解的情况。如果要使有解,可以对于12345678这样的排列,逆序对为0,因此为偶排列,我们对其中的任意两个数进行交换一次,奇偶性对调,变成奇排列,再交换一次又变成偶排列,因此你可以初始化游戏时,通过对12345678进行偶数次有效移动即可。

代码

Play.java

package game;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

import javax.swing.*;
import java.util.*;
class Number extends JButton{//按键
	Number(int x,int y,String name){
		super(name);
		this.name=name;
		this.x=x;
		this.y=y;
	}
	private String name;
	private int x;//所在位置的x
	private int y;//所在位置的y
	String GetName() {
		return name;
	}
	int GetX() {
		return x;
	}
	int GetY() {
		return y;
	}
}

//九宫格
class Box extends JFrame{
/*
 * 成员变量
 */
	Number []n;//方块
	int [][]A=new int[3][3];//地图
	Box(){//初始化
		
		super("九宫格");
		final int N = 9;
		setSize(500,500);
		
		Container c = getContentPane();
		setLayout(new GridLayout(3,3));
		
		n = new Number[N];
		Font f=new Font("华文行楷",Font.BOLD,20);//根据指定字体名称、样式和磅值大小,创建一个新 Font。
		Init();
		for(int i=0;i<N-1;i++) {
			n[i]=new Number(i/3,i%3," "+(Rand[i]));
			n[i].setBackground(Color.yellow);
			n[i].setFont(f);
			c.add(n[i]);
			
			n[i].addActionListener(new Change());//添加监听器
		}
		
		
		n[N-1]=new Number(2,2,"");//空格
		n[N-1].setBackground(Color.yellow);
		n[N-1].setFont(f);
		n[N-1].addActionListener(new Change());
		c.add(n[N-1]);
		for(int i=0;i<A.length;i++) {
			for(int j=0;j<A[i].length;j++) {
				if(i==2&&j==2) {
					continue;
				}
				A[i][j]=Rand[i*3+j];
			}
		}
		A[2][2]=0;
		for(int i=0;i<A.length;i++) {
			for(int j=0;j<A[i].length;j++) {
				System.out.print(A[i][j]+" ");
			}
			System.out.println();
		}
		
		setVisible(true);
	}
	int []Rand;
	void Init() {//生成1-8的随机数
		Rand = new int[8];//随机数
		Random r = new Random(1);
		
		int n;
		LinkedList<Integer> l = new LinkedList<Integer>();
		for(int i=1;i<=8;i++) {
			n = r.nextInt(8);
			n=(int)(Math.random()*8);
			n = n+1;
			while(l.contains(n)) {
				n = (int)(Math.random()*8);
				n = n +1;
			}
			l.add(n);
		}
		for (int i = 0; i < l.size(); i++) {
           Rand[i]=l.get(i);
           
           System.out.println(Rand[i]);
        }
	}
	
	int []move=new int[2];//移动坐标
	boolean Move(int x,int y) {//是否可以移动
		int [][]Flag = {//四个方向
			{-1,0},{0,1},{1,0},{0,-1}
		};
		for(int i=0;i<4;i++) {//判断四个方向是否可以移动
			int xi,yi;
			xi=x+Flag[i][0];
			yi=y+Flag[i][1];
			if(xi>=0&&xi<=2&&yi>=0&&yi<=2&&A[xi][yi]==0) {//有空格,可以移动
				move[0]=xi;
				move[1]=yi;
				return true;
			}
		}
		return false;//是否不可以运动
	}
	
	boolean Win() {//是否赢
		boolean flag=true;
		
		for(int i=0;i<3;i++) {
			for(int j=0;j<3;j++) {
				System.out.print(A[i][j]+" ");
				if(i==2&&j==2) {
					if(A[i][j]!=0)
						flag = false;
				}
				else{
					if((A[i][j]!=i*3+j+1))
						flag=false;
				}
			}
			System.out.println();
		}
		if(flag) {
			System.out.println("你赢了");
		}
		return flag;
	}
	class Change implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO 自动生成的方法存根
			//((Number)e.getSource()).setText("取消");
			int x=((Number)e.getSource()).GetX();
			int y=((Number)e.getSource()).GetY();
			System.out.print(x+" "+y+"|||");
			String s = ((Number)e.getSource()).GetName();
			System.out.print(s);
			if(Move(x,y)) {
				System.out.println("可以移动");
				int t = A[x][y];
				System.out.print(t);
				A[x][y]=0;
				A[move[0]][move[1]]=t;
				
				System.out.println(move[0]+" "+move[1]);
				((Number)e.getSource()).setText("");
				System.out.println(t);
				n[move[0]*3+move[1]].setText(t+" ");
			}
			else {
				System.out.println("不可以移动");
			}
			if(Win()) {
				int res = JOptionPane.showConfirmDialog(null, "GameWin", "你赢了,是否继续", JOptionPane.YES_NO_OPTION);
				if (res == JOptionPane.YES_OPTION) {
					new Box();
				} else {
					return;
				}
			}
		}
		
	}
}

public class Play {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Box b = new Box();
		
	}

}

运行结果:

在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Who_Am_I.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值