package capitulo04.bloque07;

import java.util.Scanner;

public class TresEnRaya {
    public static void main(String[] args) {
        int[][] tablero = new int[3][3];
        boolean turno = false;
        Scanner sc = new Scanner(System.in);


        System.out.println("Escoja si quiere jugar contra otro jugador o la IA");
        System.out.println("1. Jugador");
        System.out.println("2. IA");
        int respuesta = Integer.parseInt(sc.nextLine());
        if (respuesta == 1) {
            do {
                imprimirTablero(tablero);
                turno = siguienteMovimiento(turno, tablero, sc);
            } while (comprobarGanador(tablero) == -1);
            imprimirTablero(tablero);
            if (comprobarGanador(tablero) == 1) {
                System.out.println("Ha ganado el Jugador 1");
            } else if (comprobarGanador(tablero) == 2) {
                System.out.println("Ha ganado el Jugador 2");
            } else {
                System.out.println("Empate");
            }
        } else if (respuesta == 2) {
            do {
                imprimirTablero(tablero);
                turno = siguienteMovimientoIA(turno, tablero, sc);
            } while (comprobarGanador(tablero) == -1);
            imprimirTablero(tablero);
            if (comprobarGanador(tablero) == 1) {
                System.out.println("Ha ganado el Jugador");
            } else if (comprobarGanador(tablero) == 2) {
                System.out.println("Ha ganado la IA");
            } else {
                System.out.println("Empate");
            }


        } else {
            System.out.println(respuesta + " no es una respuesta válida");
        }


    }

    public static void imprimirTablero(int tablero[][]) {
        String[][] tableroVisual = new String[tablero.length][tablero[0].length];
        for (int i = 0; i < tablero.length; i++) {
            for (int j = 0; j < tablero[0].length; j++) {
                if (tablero[i][j] == 1) {
                    tableroVisual[i][j] = "X";
                } else if (tablero[i][j] == 2) {
                    tableroVisual[i][j] = "O";
                } else {
                    tableroVisual[i][j] = " ";
                }
            }
        }
        System.out.println("  | 1 | 2 | 3 |");
        System.out.println("---------------");
        System.out.println("a | " + tableroVisual[0][0] + " | " + tableroVisual[0][1] + " | " + tableroVisual[0][2] + " |");
        System.out.println("---------------");
        System.out.println("b | " + tableroVisual[1][0] + " | " + tableroVisual[1][1] + " | " + tableroVisual[1][2] + " |");
        System.out.println("---------------");
        System.out.println("c | " + tableroVisual[2][0] + " | " + tableroVisual[2][1] + " | " + tableroVisual[2][2] + " |");
        System.out.println("---------------");
    }

    public static int[] solicitarMovimiento(Scanner sc) {
        int[] movimiento = new int[2];
        while (true) {
            System.out.print("Introduzca su movimiento (a2 por ejemplo): ");
            String mov = sc.nextLine();
            if (mov.charAt(0) == 'a') {
                movimiento[0] = 1;
            } else if (mov.charAt(0) == 'b') {
                movimiento[0] = 2;
            } else if (mov.charAt(0) == 'c') {
                movimiento[0] = 3;
            } else {
                System.out.println("No ha introducido una letra de fila correcta");
            }

            int num = (mov.charAt(1) - '0');

            if (num >= 1 && num <= 3) {
                movimiento[1] = num;
            } else {
                System.out.println("No ha introducido un numero de columna correcto.");
            }

            if (movimiento[0] != 0 && movimiento[1] != 0) {
                movimiento[0] -= 1;
                movimiento[1] -= 1;
                break;
            }
        }
        return movimiento;
    }

    public static boolean siguienteMovimiento(boolean turno, int[][] tablero, Scanner sc) {
        if (!turno) {
            System.out.println("\n == Turno del Jugador 1 ==");


            while (true) {
                int[] mov = solicitarMovimiento(sc);

                if (tablero[mov[0]][mov[1]] == 0) {
                    tablero[mov[0]][mov[1]] = 1;
                    break;
                } else {
                    System.out.println("No se puede poner ficha ahí, ya había una ficha antes.");
                }
            }
        } else {
            System.out.println("\n == Turno del Jugador 2 ==");


            while (true) {
                int[] mov = solicitarMovimiento(sc);

                if (tablero[mov[0]][mov[1]] == 0) {
                    tablero[mov[0]][mov[1]] = 2;
                    break;
                } else {
                    System.out.println("No se puede poner ficha ahí, ya había una ficha antes.");
                }
            }
        }


        return !turno;
    }

    public static boolean siguienteMovimientoIA(boolean turno, int[][] tablero, Scanner sc) {
        if (!turno) {
            System.out.println("\n == Turno del Jugador 1 ==");


            while (true) {
                int[] mov = solicitarMovimiento(sc);

                if (tablero[mov[0]][mov[1]] == 0) {
                    tablero[mov[0]][mov[1]] = 1;
                    break;
                } else {
                    System.out.println("No se puede poner ficha ahí, ya había una ficha antes.");
                }
            }
        } else {
            System.out.println("\n == Turno de la IA ==");
            int[] mov = movimientoIA(tablero);
            tablero[mov[0]][mov[1]] = 2;
        }


        return !turno;
    }

    public static int[] movimientoIA(int[][] tablero) {
        int[] movimiento = checkearMovimientoIA(tablero, 2);

        if (movimiento[0] != -1 && movimiento[1] != -1) {
            return movimiento;
        }

        movimiento = checkearMovimientoIA(tablero, 1);

        if (movimiento[0] != -1 && movimiento[1] != -1) {
            return movimiento;
        }

        do {
            int x = (int) Math.round(Math.random() * 2);
            int y = (int) Math.round(Math.random() * 2);
            if (tablero[x][y] == 0) {
                movimiento[0] = x;
                movimiento[1] = y;
                break;
            }
        } while (true);

        return movimiento;
    }


    public static int[] checkearMovimientoIA(int[][] tablero, int jugador) {
        int[] movimiento = {-1, -1};

        // Filas
        for (int i = 0; i < tablero.length; i++) {
            if (tablero[i][0] == jugador && tablero[i][1] == jugador && tablero[i][2] == 0) {
                return new int[]{i, 2};
            }
            if (tablero[i][0] == jugador && tablero[i][2] == jugador && tablero[i][1] == 0) {
                return new int[]{i, 1};
            }
            if (tablero[i][1] == jugador && tablero[i][2] == jugador && tablero[i][0] == 0) {
                return new int[]{i, 0};
            }
        }

        // Columnas
        for (int i = 0; i < tablero[0].length; i++) {
            if (tablero[0][i] == jugador && tablero[1][i] == jugador && tablero[2][i] == 0) {
                return new int[]{2, i};
            }
            if (tablero[0][i] == jugador && tablero[2][i] == jugador && tablero[1][i] == 0) {
                return new int[]{1, i};
            }
            if (tablero[1][i] == jugador && tablero[2][i] == jugador && tablero[0][i] == 0) {
                return new int[]{0, i};
            }
        }

        // Diagonal izq-der
        if (tablero[0][0] == jugador && tablero[1][1] == jugador && tablero[2][2] == 0) {
            return new int[]{2, 2};
        }
        if (tablero[0][0] == jugador && tablero[2][2] == jugador && tablero[1][1] == 0) {
            return new int[]{1, 1};
        }
        if (tablero[1][1] == jugador && tablero[2][2] == jugador && tablero[0][0] == 0) {
            return new int[]{0, 0};
        }

        // Diagonal der-izq
        if (tablero[0][2] == jugador && tablero[1][1] == jugador && tablero[2][0] == 0) {
            return new int[]{2, 0};
        }
        if (tablero[0][2] == jugador && tablero[2][0] == jugador && tablero[1][1] == 0) {
            return new int[]{1, 1};
        }
        if (tablero[1][1] == jugador && tablero[2][0] == jugador && tablero[0][2] == 0) {
            return new int[]{0, 2};
        }

        return movimiento;
    }


    public static int comprobarGanador(int[][] tablero) {
        boolean ganadorJugador1 = false;
        boolean ganadorJugador2 = false;

        // Filas
        for (int i = 0; i < tablero.length; i++) {
            if (tablero[i][0] == 1 && tablero[i][1] == 1 && tablero[i][2] == 1) {
                ganadorJugador1 = true;
                break;
            } else if (tablero[i][0] == 2 && tablero[i][1] == 2 && tablero[i][2] == 2) {
                ganadorJugador2 = true;
                break;
            }
        }

        // Columnas
        for (int i = 0; i < tablero[0].length; i++) {
            if (tablero[0][i] == 1 && tablero[1][i] == 1 && tablero[2][i] == 1) {
                ganadorJugador1 = true;
                break;
            } else if (tablero[0][i] == 2 && tablero[1][i] == 2 && tablero[2][i] == 2) {
                ganadorJugador2 = true;
                break;
            }
        }

        // Diagonales
        if (tablero[0][0] == 1 && tablero[1][1] == 1 && tablero[2][2] == 1) {
            ganadorJugador1 = true;
        } else if (tablero[0][0] == 2 && tablero[1][1] == 2 && tablero[2][2] == 2) {
            ganadorJugador2 = true;
        }

        if (tablero[0][2] == 1 && tablero[1][1] == 1 && tablero[2][0] == 1) {
            ganadorJugador1 = true;
        } else if (tablero[0][2] == 2 && tablero[1][1] == 2 && tablero[2][0] == 2) {
            ganadorJugador2 = true;
        }

        if (ganadorJugador1) {
            return 1;
        } else if (ganadorJugador2) {
            return 2;
        }

        // Verificar si hay empate
        boolean matrizLlena = true;
        for (int i = 0; i < tablero.length; i++) {
            for (int j = 0; j < tablero[0].length; j++) {
                if (tablero[i][j] == 0) {
                    matrizLlena = false;
                    break;
                }
            }
        }

        if (matrizLlena) {
            return 0;
        }

        return -1;
    }

}
