九宫格游戏(java实现)
程序员文章站
2024-01-08 13:01:46
...
代码思路:
创建了一个九宫格按钮类(继承了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();
}
}