import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
?
class PuzzlePanel extends JPanel implements KeyListener {
?
? ? private static final int TILE_SIZE = 80;
? ? private static final int BOARD_SIZE = 3;
?
? ? private String[][] puzzle;
? ? private String[][] solvedPuzzle;
?
? ? public PuzzlePanel() {
? ? ? ? setPreferredSize(new Dimension(TILE_SIZE * BOARD_SIZE, TILE_SIZE * BOARD_SIZE));
? ? ? ? setFocusable(true);
? ? ? ? addKeyListener(this);
? ? ? ? initializePuzzle();
? ? }
?
? ? private void initializePuzzle() {
? ? ? ? puzzle = new String[BOARD_SIZE][BOARD_SIZE];
? ? ? ? solvedPuzzle = new String[BOARD_SIZE][BOARD_SIZE];
?
? ? ? ? List<String> numbers = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", " ");
? ? ? ? Collections.shuffle(numbers);
?
? ? ? ? int index = 0;
? ? ? ? for (int i = 0; i < BOARD_SIZE; i++) {
? ? ? ? ? ? for (int j = 0; j < BOARD_SIZE; j++) {
? ? ? ? ? ? ? ? puzzle[i][j] = numbers.get(index);
? ? ? ? ? ? ? ? solvedPuzzle[i][j] = String.valueOf(index + 1);
? ? ? ? ? ? ? ? index++;
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? private void drawTile(Graphics g, String value, int row, int col) {
? ? ? ? int x = col * TILE_SIZE;
? ? ? ? int y = row * TILE_SIZE;
?
? ? ? ? g.setColor(Color.lightGray);
? ? ? ? g.fillRect(x, y, TILE_SIZE, TILE_SIZE);
?
? ? ? ? g.setColor(Color.black);
? ? ? ? g.drawRect(x, y, TILE_SIZE, TILE_SIZE);
?
? ? ? ? g.setColor(Color.black);
? ? ? ? Font font = new Font("Arial", Font.BOLD, 24);
? ? ? ? g.setFont(font);
?
? ? ? ? FontMetrics fm = g.getFontMetrics();
? ? ? ? int textWidth = fm.stringWidth(value);
? ? ? ? int textHeight = fm.getHeight();
?
? ? ? ? int centerX = x + (TILE_SIZE - textWidth) / 2;
? ? ? ? int centerY = y + (TILE_SIZE - textHeight) / 2 + fm.getAscent();
?
? ? ? ? g.drawString(value, centerX, centerY);
? ? }
?
? ? private void drawPuzzle(Graphics g) {
? ? ? ? for (int i = 0; i < BOARD_SIZE; i++) {
? ? ? ? ? ? for (int j = 0; j < BOARD_SIZE; j++) {
? ? ? ? ? ? ? ? drawTile(g, puzzle[i][j], i, j);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? private void checkIfSolved() {
? ? ? ? if (Arrays.deepEquals(puzzle, solvedPuzzle)) {
? ? ? ? ? ? JOptionPane.showMessageDialog(this, "恭喜你,拼图完成!", "拼图完成", JOptionPane.INFORMATION_MESSAGE);
? ? ? ? ? ? initializePuzzle();
? ? ? ? }
? ? }
?
? ? private void moveTile(int row, int col) {
? ? ? ? if (isValidMove(row, col)) {
? ? ? ? ? ? String temp = puzzle[row][col];
? ? ? ? ? ? puzzle[row][col] = puzzle[row + 1][col];
? ? ? ? ? ? puzzle[row + 1][col] = temp;
? ? ? ? ? ? checkIfSolved();
? ? ? ? }
? ? }
?
? ? private boolean isValidMove(int row, int col) {
? ? ? ? return row < BOARD_SIZE - 1 && puzzle[row + 1][col].equals(" ");
? ? }
?
? ? @Override
? ? protected void paintComponent(Graphics g) {
? ? ? ? super.paintComponent(g);
? ? ? ? drawPuzzle(g);
? ? }
?
? ? @Override
? ? public void keyTyped(KeyEvent e) {
? ? ? ? // 不需要实现
? ? }
?
? ? @Override
? ? public void keyPressed(KeyEvent e) {
? ? ? ? if (e.getKeyCode() == KeyEvent.VK_DOWN) {
? ? ? ? ? ? moveTile(getEmptyRow(), getEmptyCol());
? ? ? ? ? ? repaint();
? ? ? ? }
? ? }
?
? ? @Override
? ? public void keyReleased(KeyEvent e) {
? ? ? ? // 不需要实现
? ? }
?
? ? private int getEmptyRow() {
? ? ? ? for (int i = 0; i < BOARD_SIZE; i++) {
? ? ? ? ? ? for (int j = 0; j < BOARD_SIZE; j++) {
? ? ? ? ? ? ? ? if (puzzle[i][j].equals(" ")) {
? ? ? ? ? ? ? ? ? ? return i;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return -1;
? ? }
?
? ? private int getEmptyCol() {
? ? ? ? for (int i = 0; i < BOARD_SIZE; i++) {
? ? ? ? ? ? for (int j = 0; j < BOARD_SIZE; j++) {
? ? ? ? ? ? ? ? if (puzzle[i][j].equals(" ")) {
? ? ? ? ? ? ? ? ? ? return j;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return -1;
? ? }
}
?
public class PuzzelGameApp extends JFrame {
?
? ? public PuzzelGameApp() {
? ? ? ? setTitle("拼图游戏");
? ? ? ? setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
? ? ? ? setResizable(false);
?
? ? ? ? PuzzlePanel puzzlePanel = new PuzzlePanel();
? ? ? ? add(puzzlePanel);
?
? ? ? ? pack();
? ? ? ? setLocationRelativeTo(null);
?
? ? ? ? Timer timer = new Timer(1000, new ActionListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void actionPerformed(ActionEvent e) {
? ? ? ? ? ? ? ? puzzlePanel.repaint();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? timer.start();
? ? }
?
? ? public static void main(String[] args) {
? ? ? ? SwingUtilities.invokeLater(() -> {
? ? ? ? ? ? PuzzelGameApp puzzleGameApp = new PuzzelGameApp();
? ? ? ? ? ? puzzleGameApp.setVisible(true);
? ? ? ? });
? ? }
}
?
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
?
public class PuzzleGame {
?
? ? private static final String[][] puzzle = {
? ? ? ? ? ? {"1", "2", "3"},
? ? ? ? ? ? {"4", "5", "6"},
? ? ? ? ? ? {"7", "8", " "}
? ? };
?
? ? private static final String[][] solvedPuzzle = {
? ? ? ? ? ? {"1", "2", "3"},
? ? ? ? ? ? {"4", "5", "6"},
? ? ? ? ? ? {"7", "8", " "}
? ? };
?
? ? public static void main(String[] args) {
? ? ? ? shufflePuzzle();
? ? ? ? while (!isPuzzleSolved()) {
? ? ? ? ? ? displayPuzzle();
? ? ? ? ? ? moveTile();
? ? ? ? }
? ? ? ? System.out.println("恭喜你,拼图完成!");
? ? }
?
? ? private static void shufflePuzzle() {
? ? ? ? List<String> flatPuzzle = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", " ");
? ? ? ? Collections.shuffle(flatPuzzle);
?
? ? ? ? int index = 0;
? ? ? ? for (int i = 0; i < puzzle.length; i++) {
? ? ? ? ? ? for (int j = 0; j < puzzle[i].length; j++) {
? ? ? ? ? ? ? ? puzzle[i][j] = flatPuzzle.get(index++);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? private static void displayPuzzle() {
? ? ? ? for (String[] row : puzzle) {
? ? ? ? ? ? for (String tile : row) {
? ? ? ? ? ? ? ? System.out.print(tile + "\t");
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println();
? ? ? ? }
? ? ? ? System.out.println();
? ? }
?
? ? private static void moveTile() {
? ? ? ? Scanner scanner = new Scanner(System.in);
?
? ? ? ? System.out.print("请输入要移动的数字(1-8): ");
? ? ? ? String input = scanner.nextLine();
? ? ? ? String tileToMove = input.trim();
?
? ? ? ? // 寻找空白格的位置
? ? ? ? int emptyRow = -1;
? ? ? ? int emptyCol = -1;
? ? ? ? for (int i = 0; i < puzzle.length; i++) {
? ? ? ? ? ? for (int j = 0; j < puzzle[i].length; j++) {
? ? ? ? ? ? ? ? if (puzzle[i][j].equals(" ")) {
? ? ? ? ? ? ? ? ? ? emptyRow = i;
? ? ? ? ? ? ? ? ? ? emptyCol = j;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
?
? ? ? ? // 寻找要移动的数字的位置
? ? ? ? int tileRow = -1;
? ? ? ? int tileCol = -1;
? ? ? ? for (int i = 0; i < puzzle.length; i++) {
? ? ? ? ? ? for (int j = 0; j < puzzle[i].length; j++) {
? ? ? ? ? ? ? ? if (puzzle[i][j].equals(tileToMove)) {
? ? ? ? ? ? ? ? ? ? tileRow = i;
? ? ? ? ? ? ? ? ? ? tileCol = j;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
?
? ? ? ? // 判断是否可以移动
? ? ? ? if ((Math.abs(emptyRow - tileRow) == 1 && emptyCol == tileCol) ||
? ? ? ? ? ? ? ? (Math.abs(emptyCol - tileCol) == 1 && emptyRow == tileRow)) {
? ? ? ? ? ? // 交换空白格和要移动的数字的位置
? ? ? ? ? ? String temp = puzzle[emptyRow][emptyCol];
? ? ? ? ? ? puzzle[emptyRow][emptyCol] = puzzle[tileRow][tileCol];
? ? ? ? ? ? puzzle[tileRow][tileCol] = temp;
? ? ? ? } else {
? ? ? ? ? ? System.out.println("不能移动这个数字,请重新输入。");
? ? ? ? }
? ? }