15パズルのJavaプログラム

15パズルは、4x4の盤面に1から15の数字が書かれたタイルと、1つの空きスペースからなるゲームです。ゴールは、数字の順序を逆にして空きスペースが右下にある状態にすることです。以下に15パズルのルールを説明します:

  • パズルの初期状態では、数字のタイルが1から15までが左上から順に配置され、最後のタイルは空きスペース(以下のサンプルコードでは0)となっています。
  • ゲーム中は、空きスペースの隣にある数字のタイルを空きスペースに移動することができます。(以下のサンプルコードでは0を動かす)
  • タイルは上下左右にスライドすることができますが、斜めには移動できません。
  • タイルをスライドさせると、そのタイルが空きスペースの位置に移動し、空きスペースはそのタイルの元の位置に移動します。
  • タイルをスライドさせるたびに、ゲームの盤面が変化します。
  • ゲームの目標は、数字のタイルをスライドさせて全てのタイルを正しい順序に並べ、空きスペースを右下に移動することです。
  • ゴール状態では、空きスペースが右下にあり、数字のタイルが1から15までが順番通りに並んでいる状態です。

15パズルは、戦略的なスライド操作を行うことで解くことができます。目標は全ての数字を正しい位置に移動することなので、数字の順序を逆転させないように注意しながらパズルを解いてください。

import java.util.Random;
import java.util.Scanner;

public class FifteenPuzzle {
    private static final int SIZE = 4; // パズルのサイズ(4x4)

    private int[][] puzzle; // パズルの盤面
    private int emptyRow; // 空きマスの行番号
    private int emptyCol; // 空きマスの列番号

    public FifteenPuzzle() {
        puzzle = new int[SIZE][SIZE];
        emptyRow = SIZE - 1;
        emptyCol = SIZE - 1;
    }

    public void initialize() {
        int count = 1;
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                puzzle[i][j] = count++;
            }
        }
        puzzle[emptyRow][emptyCol] = 0;
    }

    public void shuffle() {
        Random rand = new Random();
        for (int i = 0; i < 1000; i++) {
            int randomMove = rand.nextInt(4);
            move(randomMove);
        }
    }

    public void move(int direction) {
        int newRow = emptyRow;
        int newCol = emptyCol;

        if (direction == 0 && emptyRow > 0) { // 上に移動
            newRow--;
        } else if (direction == 1 && emptyCol < SIZE - 1) { // 右に移動
            newCol++;
        } else if (direction == 2 && emptyRow < SIZE - 1) { // 下に移動
            newRow++;
        } else if (direction == 3 && emptyCol > 0) { // 左に移動
            newCol--;
        } else {
            return; // 不正な移動方向
        }

        puzzle[emptyRow][emptyCol] = puzzle[newRow][newCol];
        puzzle[newRow][newCol] = 0;
        emptyRow = newRow;
        emptyCol = newCol;
    }

    public boolean isSolved() {
        int count = 1;
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                if (i == SIZE - 1 && j == SIZE - 1) {
                    if (puzzle[i][j] != 0) {
                        return false;
                    }
                } else {
                    if (puzzle[i][j] != count++) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    public void printBoard() {
        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                System.out.print(puzzle[i][j] + "\t");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        FifteenPuzzle game = new FifteenPuzzle();

        game.initialize();
        game.shuffle();

        while (!game.isSolved()) {
            game.printBoard();
            System.out.print("Enter move (0を動かしてください: 上, 1: 右, 2: 下, 3: 左): ");
            int move = scanner.nextInt();
            game.move(move);
        }

        System.out.println("おめでとうございます!パズルを解きました!");
        scanner.close();
    }
}