import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class AppleOfFortune {

	private static final int ROWS = 7;
	private static final int COLS = 5;
	private static final String APPLE_EMOJI = "🍎";
	private static final String SNAKE_EMOJI = "🐍";
	private static final String HIDDEN_EMOJI = "❓";

	private static final double[] WIN_MULTIPLIERS = { 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 2.53968 };

	private String[][] grid;
	private double currentWinnings = 0.0; // 今ラウンドの獲得金額
	private double playerBalance = 0.0; // プレイヤーの所持金

	public AppleOfFortune() {
		grid = new String[ROWS][COLS];
	}

	private void initializeGameGrid() {
		Random random = new Random();
		for (int r = 0; r < ROWS; r++) {
			int numberOfSnakes;

			if (r < 2) {
				numberOfSnakes = 2;
			} else if (r < 5) {
				numberOfSnakes = 3;
			} else {
				numberOfSnakes = 4;
			}

			if (numberOfSnakes >= COLS) {
				numberOfSnakes = COLS - 1;
				if (numberOfSnakes < 0)
					numberOfSnakes = 0;
			}

			List<Integer> bombPositions = new ArrayList<>();
			while (bombPositions.size() < numberOfSnakes) {
				int newBombCol = random.nextInt(COLS);
				if (!bombPositions.contains(newBombCol)) {
					bombPositions.add(newBombCol);
				}
			}

			for (int c = 0; c < COLS; c++) {
				if (bombPositions.contains(c)) {
					grid[r][c] = SNAKE_EMOJI;
				} else {
					grid[r][c] = APPLE_EMOJI;
				}
			}
		}
	}

	private void displayGrid(int currentRow, int chosenCol) {
		System.out.println("\n--- 現在のゲーム状態 ---");
		for (int r = 0; r < ROWS; r++) {
			for (int c = 0; c < COLS; c++) {
				if (r < currentRow) {
					System.out.print("[ " + grid[r][c] + " ] ");
				} else if (r == currentRow && c == chosenCol) {
					System.out.print("[ " + grid[r][c] + " ] ");
				} else {
					System.out.print("[ " + HIDDEN_EMOJI + " ] ");
				}
			}
			System.out.println();

		}
		System.out.println("--------------------------");
		System.out.printf("現在の獲得金額（このラウンド）： %.2f\n", currentWinnings);
	}

	private void displayFinalGrid() {
		System.out.println("\n--- 最終ゲーム状態（全て公開） ---");
		for (int r = 0; r < ROWS; r++) {
			for (int c = 0; c < COLS; c++) {
				System.out.print("[ " + grid[r][c] + " ] ");
			}
			System.out.println();
		}
		System.out.println("----------------------------------------");
	}

	public void startGame() throws Exception {
		Scanner scanner = new Scanner(System.in);
		System.out.println("運命のリンゴへようこそ！");
		System.out.println();

		for (int i = 0; i < 5; i++)

		{
			Thread.sleep(1000);
			System.out.print("🍎🐍");
		}
		System.out.println();
		System.out.println();

		while (true) {
			System.out.print("ゲーム開始時の所持金を入力してください: ");
			try {
				playerBalance = scanner.nextDouble();

				if (playerBalance > 0) {
					break;
				} else {
					System.out.println("所持金は正の数でなければなりません。もう一度入力してください。");
				}
			} catch (InputMismatchException e) {
				System.out.println("無効な入力です。正しい数値を入力してください。");
				scanner.next(); // 無効入力を消費
			}
		}
		System.out.printf("初期所持金は %.2f です。\n", playerBalance);

		boolean playAgain = true;
		while (playAgain) {
			System.out.printf("\n--- 新しいゲーム ---\n現在の所持金: %.2f\n", playerBalance);

			double initialBet = 0.0;
			while (true) {
				if (playerBalance <= 0) {
					System.out.println("賭けるお金がありません！ゲームオーバーです。");
					playAgain = false;
					break;
				}
				System.out.println("今ラウンドの賭け金を入力してください");
				System.out.printf("(最大 %.2f）: ", playerBalance);
				try {
					initialBet = scanner.nextDouble();
					if (initialBet > 0 && initialBet <= playerBalance) {
						playerBalance -= initialBet;
						this.currentWinnings = initialBet;
						System.out.printf("%.2f を賭けました。残りの所持金: %.2f\n", initialBet, playerBalance);
						break;
					} else if (initialBet <= 0) {
						System.out.println("賭け金は正の数でなければなりません。もう一度入力してください。");
					} else {
						System.out.printf("所持金が足りません。現在の所持金は %.2f です。\n", playerBalance);
					}
				} catch (InputMismatchException e) {
					System.out.println("無効な入力です。正しい数値を入力してください。");
					scanner.next();
				}
			}
			if (!playAgain) {
				break;
			}

			initializeGameGrid();
			System.out.println();
			System.out.println("🍎（リンゴ）を選んで、🐍（ヘビ）を避けてください！");

			boolean roundLost = false;
			for (int currentRow = 0; currentRow < ROWS; currentRow++) {
				System.out.printf("\n--- 行 %d ---\n", currentRow + 1);
				displayGrid(currentRow, -1);

				int chosenCol = -1;
				while (true) {
					System.out.printf("列を選んでください (1-%d): ", COLS);
					try {
						chosenCol = scanner.nextInt() - 1;
						if (chosenCol >= 0 && chosenCol < COLS) {
							break;
						} else {
							System.out.println("無効な列です。1から" + COLS + "の数字を入力してください。");
						}
					} catch (InputMismatchException e) {
						System.out.println("無効な入力です。数字を入力してください。");
						scanner.next();
					}
				}

				displayGrid(currentRow, chosenCol);
				if (grid[currentRow][chosenCol].equals(SNAKE_EMOJI)) {
					System.out.println("\n痛っ！🐍（ヘビ）を見つけました！");
					System.out.println("このラウンドはゲームオーバーです！");
					displayFinalGrid();
					System.out.printf("%.2f の賭け金を失いました。\n", initialBet);
					currentWinnings = 0.0;
					roundLost = true;
					break;
				} else {
					currentWinnings *= WIN_MULTIPLIERS[currentRow];
					System.out.println();
					System.out.println("おめでとう！");
					System.out.println("🍎(リンゴ)を見つけました。");
					System.out.println();
					System.out.printf("現在の獲得金額（このラウンド）： %.2f\n", currentWinnings);

					if (currentRow < 2) {
						if (currentRow < ROWS - 1) {
							System.out.println();
							System.out.println("3行目が完成するまで続けてください。");
							System.out.println("続行するにはEnterキーを押してください...");
							scanner.nextLine(); // 改行消費
							scanner.nextLine(); // Enter待ち
						}
					} else if (currentRow < ROWS - 1) {
						System.out.print("次の行に進みますか？（続けるなら c)");
						System.out.print("それとも獲得金を受け取りますか？（受け取るなら t）: ");
						String choice = scanner.next().toLowerCase();
						if (choice.equals("t")) {
							System.out.println("\n賢い選択です！このラウンドの獲得金を受け取ることにしました。");
							System.out.printf("このラウンドで %.2f を獲得しました。\n", currentWinnings);
							playerBalance += currentWinnings;
							currentWinnings = 0.0;
							roundLost = false;
							break;
						}
					} else {
						System.out.println("\nおめでとうございます！全ての " + ROWS + " 行をクリアしました！");
						System.out.printf("このラウンドで %.2f 勝ちました！\n", currentWinnings);
						playerBalance += currentWinnings;
						currentWinnings = 0.0;
						roundLost = false;
						break;
					}
				}
			}

			System.out.printf("\n現在の所持金は: %.2f\n", playerBalance);
			if (playerBalance <= 0) {
				System.out.println();
				System.out.println("お金がなくなりました。プレイしてくれてありがとうございました！");
				playAgain = false;
			} else {
				System.out.print("もう一度プレイしますか？（y/n）：");
				String playAgainChoice = scanner.next().toLowerCase();
				playAgain = playAgainChoice.equals("y");
			}
			scanner.nextLine(); // 改行消費
		}

		System.out.println("運命のリンゴをプレイしてくれてありがとうございます！");
		scanner.close();
	}

	public static void main(String[] args) throws Exception {
		AppleOfFortune game = new AppleOfFortune();
		game.startGame();
	}
}
