JavaRush /Blog Java /Random-ES /Juego java para principiantes
timurnav
Nivel 21

Juego java para principiantes

Publicado en el grupo Random-ES
¡Hola amigos y futuros compañeros! Juego Java para principiantes - 1Recientemente, hice una prueba para participar en un proyecto real, la aprobé, pero resultó que por circunstancias personales no pude participar en el RP en sí. Después de problemas tan interesantes como el examen RP, los problemas habituales del curso se convirtieron en un pasatiempo menos atractivo, sobre todo porque ya había resuelto la mayoría de ellos. Por eso, para que mi talento no se desperdiciara para seguir aprendiendo, decidí crear un juego web multijugador. Enlaces a otros juegos:
  1. continuación de este artículo
  2. 2048
Tic Tac Toe me pareció el juego más sencillo, así que decidí dividir la tarea en varias subtareas:
  1. Aplicación de consola para probar la lógica del juego.
  2. Multijugador
  3. Adjuntar una base de datos de jugadores a una aplicación de consola
  4. Creación de diseño front-end, redacción de plantillas de páginas, interfaz de juegos.
  5. Poniendolo todo junto
Existe la posibilidad de que me regañen por tal secuencia, y lo más probable es que todos los proyectos serios se construyan en una secuencia completamente diferente, responderé de inmediato, escribiré una publicación sobre esto "para principiantes" para que todos (incluyéndome a mí) puedo aprender esto :) Bueno, ¡comencemos a escribir una aplicación de consola! Seguiré los mismos pasos que los grandes desafíos del nivel 20. ¿Qué hay en el juego tres en raya?
  1. campo
  2. dos jugadores que se turnan, uno pone una cruz, el otro un cero. es sencillo.
Hacemos del campo un campo estándar de 3x3. ¿Cómo se puede almacenar un campo así? la primera opción es una matriz bidimensional. ¿Qué elementos debe contener esta matriz? La respuesta es que debemos pensar qué haremos con estos elementos, esto es mostrar y comparar para encontrar el ganador. Si solo los mostráramos en la pantalla, entonces sería lógico mantenerlos como una cadena, entonces la matriz en sí y mostrarla en la pantalla en un bucle se vería así:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
la pantalla mostraría:
O O _
_ X O
X X X
Pero además de mostrar, también tenemos una comparación de valores, y aquí ya son posibles opciones. Puede comparar cadenas, puede crear una clase de enumeración especial ( enum), pero preferiría comparar números y reemplazarlos con "X" y "O" solo cuando se muestran en la pantalla. Sea, por ejemplo, 1 - "X", 2 - "O", 0 - "_". Entonces, ¿cómo se verifica que un campo coincida con triple X u O?
El primer algoritmo está comprobando todo el campo.
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Combinaciones ganadoras:
00-01-02, 10-11-12, 20-21-22, 00-10-20, 01-11-21, 02-12-22, 00-11-22, 20-11-02 — всего 8.
Verificando comparando números, pero resulta que necesitas verificar TODO el campo, las 8 combinaciones, cada vez. Por supuesto, esto no es mucho, no se trata de una búsqueda de números de Armstrong en el rango de 0 a 1 mil millones, aquí hay poco más que ningún cálculo, pero aún así desea algo más óptimo que verificar todo el campo. La segunda idea que se me ocurrió fue revisar solo la celda que estaba marcada en el movimiento anterior, así aún podemos determinar el ganador, porque sabremos quién hizo este movimiento. Por lo tanto, en lugar de las 8 combinaciones, obtenemos solo 2, 3 o 4 combinaciones, dependiendo de la celda, vea la figura: ¿ Juego Java para principiantes - 2Ahora tenemos que descubrir cómo determinar qué combinación debe ejecutarse? Aquí es donde me di cuenta de que usar una matriz bidimensional no es muy conveniente. Decidí mirar otras opciones. Al principio se me ocurrió la idea de que el campo se puede mantener en un número de nueve dígitos, por ejemplo, el mismo campo que mostramos en la pantalla se puede escribir así: 220012111, te explicaré con los dedos qué es... El código es el mismo, 1 - “X”, 2 - “O” , 0 – " ", que significa 220012111 = "OO__XOXXX", o si después de cada tercer dígito insertas un salto de línea y agregas espacios para claridad:
О О _
_ Х О
Х Х Х
Aquí nuevamente, conveniente para el almacenamiento, se inventó un dispositivo de visualización, ¡pero inconveniente para comparar! La solución la encontré cuando numeré las celdas del 1 al 9, entonces pensé, porque en programación la cuenta atrás empieza desde 0 y la numeré como en la imagen, ¿ Juego Java para principiantes - 3no notaste alguna peculiaridad? Si miras la imagen de arriba, quedará claro que las soluciones con 2 combinaciones tienen un número de serie impar, 4 combinaciones tienen el número de serie 4, 3 combinaciones tienen el resto. Entonces llegué a la conclusión de que es necesario mantener el campo de juego en una matriz regular de números: iteración simple entre números, la capacidad de comparar según el algoritmo elegido, salida simple a la pantalla. En cuanto al algoritmo de comparación en sí. Vayamos en orden: en todas las opciones hay una verificación de fila y columna, solo las verificamos. si la búsqueda no da resultado, comprobamos el número de celda par/impar, si es impar, volvemos al juego, no tiene sentido seguir comprobando, si es par, comprobamos si esta celda se encuentra en el diagonal izquierda, los números de esta diagonal cuando se dividen por 4 tienen un resto 0. Si miente, verificamos si hay coincidencias, si no se encuentran coincidencias, luego verificamos el número 4, si no, regresamos al juego, si sí, avanzamos en el código y devolvemos el resultado de verificar la última diagonal. Probablemente, para una persona no preparada, esto sea difícil de entender después de leer el conjunto de letras anteriores, pero alguien puede decir que hay muchas letras en el código en sí, lo cual puede ser más simple, estaré encantado de discutirlo. Hemos resuelto el campo, ahora tenemos que lidiar con dos usuarios que se turnan y cada uno de ellos tiene su propio signo, X u O. En la primera etapa, no tenemos ninguna funcionalidad multiusuario, por lo que el La forma más sencilla sería utilizar los iconos uno por uno. X siempre hace el primer movimiento, O siempre hace el segundo, luego X nuevamente, y así sucesivamente. Pide ser verificado ( verdadero/falso ), y si es verdadero , entonces el jugador actual es X, si es falso , entonces O y al comienzo de cada movimiento flag=!flag Queda por recibir de alguna manera una señal de los jugadores sobre qué celda que elijan. Aquí necesitaremos que nuestros inolvidables BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); jugadores ingresen los números de celular en la consola y presionen Enter para realizar un movimiento. La celda correspondiente al número ingresado cambiará su valor de 0 a 1 o 2, dependiendo del estado actual de la casilla de verificación, como se discutió en el párrafo anterior. Aquí es donde es importante validar la entrada para que nadie pueda cambiar X por O cuando la celda ya está llena :) ¿Qué puede ingresar el jugador en la consola?
  1. linea vacia
  2. letras, signos de puntuación, paréntesis... en una palabra, no números
  3. números incorrectos: negativos o fuera del tamaño de la matriz, celdas ocupadas.
El método estándar para obtener un dígito de una cadena es el método estático parseInt de la clase Integer. Integer.parseInt("2");Lanza una excepción NumberFormatExceptionsi no puede obtener un dígito de una cadena determinada. Podemos brindar protección contra los dos primeros puntos interceptando esta excepción. Para el tercer punto, crearía otro método que verifique el valor ingresado, pero lo más correcto sería mover la solicitud de cadena a un método separado en el que se realizará la validación y devolverá solo un número. En resumen, creamos un campo, creamos un método que lo muestra, creamos un método que verifica "¿este jugador ganó por una hora?" y validamos los números ingresados. Queda muy poco por hacer, verificar si hay empate: un método separado que recorre la matriz, busca 0 y muestra los resultados del juego. Eso es todo, el código está listo, el juego resultó ser pequeño, solo una clase, por lo que los copiadores duros pueden, sin entenderlo, simplemente copiar todo en su proyecto y ejecutarlo por su cuenta, yo mismo era así, pero ahora trato de no hacer eso y no se lo recomiendo a nadie :) ¡Buena suerte a todos en aprender JAVA! PD: el resto de los puntos: el modo multijugador y la base de datos vendrán más tarde, ya comencé a estudiar el material :)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GameField {

    static int [] canvas = {0,0,0,
                            0,0,0,
                            0,0,0};

    //012, 345, 678, 036, 147, 258, 048, 246
    public static void main(String[] args){

        boolean b;
        boolean isCurrentX = false;
        do {
            isCurrentX = !isCurrentX;
            drawCanvas();
            System.out.println("mark " + (isCurrentX ? "X" : "O"));
            int n = getNumber();
            canvas[n] = isCurrentX ? 1 : 2;
            b = !isGameOver(n);
            if (isDraw()){
                System.out.println("Draw");
                return;
            }
        } while (b);
        drawCanvas();
        System.out.println();

        System.out.println("The winner is " + (isCurrentX ? "X" : "O") + "!");
    }

    static int getNumber(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            try {
                int n = Integer.parseInt(reader.readLine());
                if (n >= 0 && n < canvas.length && canvas[n]==0){
                    return n;
                }
                System.out.println("Choose free cell and enter its number");
            } catch (NumberFormatException e) {
                System.out.println("Please enter the number");
            } catch (IOException e) {
            }
        }
    }

    static boolean isGameOver(int n){
        // 0 1 2
        // 3 4 5
        // 6 7 8
        //поиск совпадений по горизонтали
        int row = n-n%3; //номер строки - проверяем только её
        if (canvas[row]==canvas[row+1] &&
                canvas[row]==canvas[row+2]) return true;
        //поиск совпадений по вертикали
        int column = n%3; //номер столбца - проверяем только его
        if (canvas[column]==canvas[column+3])
            if (canvas[column]==canvas[column+6]) return true;
        //мы здесь, значит, первый поиск не положительного результата
        //если significado n находится на одной из граней - возвращаем false
        if (n%2!=0) return false;
        //проверяем принадлежит ли к левой диагонали significado
        if (n%4==0){
            //проверяем есть ли совпадения на левой диагонали
            if (canvas[0] == canvas[4] &&
                    canvas[0] == canvas[8]) return true;
            if (n!=4) return false;
        }
        return canvas[2] == canvas[4] &&
                canvas[2] == canvas[6];
    }

    static void drawCanvas(){
        System.out.println("     |     |     ");
        for (int i = 0; i < canvas.length; i++) {
            if (i!=0){
                if (i%3==0) {
                    System.out.println();
                    System.out.println("_____|_____|_____");
                    System.out.println("     |     |     ");
                }
                else
                    System.out.print("|");
            }

            if (canvas[i]==0) System.out.print("  " + i + "  ");
            if (canvas[i]==1) System.out.print("  X  ");
            if (canvas[i]==2) System.out.print("  O  ");
        }
        System.out.println();
        System.out.println("     |     |     ");
    }

    public static boolean isDraw() {
        for (int n : canvas) if (n==0) return false;
        return true;
    }
}
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION