JavaRush /Blog Java /Random-FR /Jeu Java pour débutants
timurnav
Niveau 21

Jeu Java pour débutants

Publié dans le groupe Random-FR
Bonjour amis et futurs collègues ! Jeu Java pour débutants - 1Tout récemment, j'ai passé un test pour participer à un projet réel, je l'ai réussi, mais il se trouve qu'en raison de circonstances personnelles, je n'ai pas pu participer au RP lui-même. Après des problèmes aussi intéressants que le test RP, les problèmes habituels du cours sont devenus un passe-temps moins attrayant, d'autant plus que j'en avais déjà résolu la plupart. Par conséquent, afin que mon talent ne soit pas gaspillé pour continuer à apprendre, j'ai décidé de créer un jeu Web multijoueur. Liens vers d'autres jeux :
  1. suite de cet article
  2. 2048
Tic Tac Toe me semblait être le jeu le plus simple, j'ai donc décidé de diviser la tâche en un certain nombre de sous-tâches :
  1. Application console pour tester la logique du jeu
  2. Multijoueur
  3. Attacher une base de données de joueurs à une application console
  4. Création du design front-end, rédaction de modèles de pages, interface de jeu
  5. Mettre tous ensemble
Il est possible que je sois réprimandé pour une telle séquence, et très probablement tous les projets sérieux sont construits dans une séquence complètement différente, je répondrai tout de suite, j'écrirai un article à ce sujet "pour les débutants" pour que tout le monde (y compris moi) peut apprendre ceci :) Eh bien, commençons à écrire une application console ! Je suivrai les mêmes étapes que les grands défis de niveau 20. Qu'y a-t-il dans le jeu tic-tac-toe ?!
  1. champ
  2. deux joueurs qui se relaient, l'un met une croix, l'autre un zéro. c'est simple.
Nous faisons du champ un champ standard 3x3. Comment stocker un tel champ ? la première option est un tableau à deux dimensions. Quels éléments ce tableau doit-il contenir ? La réponse est que nous devons réfléchir à ce que nous allons faire de ces éléments, c'est-à-dire les afficher et les comparer pour trouver le gagnant. Si nous les affichions uniquement à l'écran, alors il serait logique de les conserver sous forme de chaîne, alors le tableau lui-même et son affichage à l'écran en boucle ressembleraient à ceci :
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
l'écran afficherait :
O O _
_ X O
X X X
Mais en plus de l'affichage, nous avons également une comparaison des valeurs, et ici des options sont déjà possibles. Vous pouvez comparer des chaînes, vous pouvez créer une classe d'énumération spéciale ( enum), mais je préférerais comparer des nombres et les remplacer par « X » et « O » uniquement lorsqu'ils sont affichés à l'écran. Que ce soit, par exemple, 1 - "X", 2 - "O", 0 - "_". Alors, comment vérifier un champ pour une correspondance triple X ou O ?
Le tout premier algorithme vérifie tout le champ
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Combinaisons gagnantes :
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.
Vérification en comparant les nombres, mais il s'avère que vous devez vérifier ENTIER le champ, les 8 combinaisons, à chaque fois. Bien sûr, ce n'est pas grand-chose, il ne s'agit pas d'une recherche de nombres d'Armstrong compris entre 0 et 1 milliard, il n'y a pratiquement pas de calculs ici, mais vous voulez toujours quelque chose de plus optimal que de vérifier l'ensemble du champ. La deuxième idée qui m'est venue était de vérifier uniquement la cellule qui avait été marquée lors du coup précédent, afin que nous puissions toujours déterminer le gagnant, car nous saurons qui a fait ce coup. Ainsi, au lieu des 8 combinaisons, nous obtenons seulement 2, 3 ou 4 combinaisons, selon la cellule, voir l'image : Jeu Java pour débutants - 2Il faut maintenant comprendre comment déterminer quelle combinaison doit être lancée ? C'est là que j'ai réalisé que l'utilisation d'un tableau à deux dimensions n'était pas très pratique. J'ai décidé d'envisager d'autres options. Au début, j'ai eu l'idée que le champ puisse être conservé sous la forme d'un nombre à neuf chiffres, par exemple, le même champ que nous avons affiché à l'écran peut s'écrire comme ceci : 220012111, je vais vous expliquer entre mes doigts ce que c'est est... Le code est le même, 1 - "X", 2 - "O" , 0 – " ", ce qui signifie 220012111 = "OO__XOXXX", ou si après chaque troisième chiffre vous insérez un saut de ligne et ajoutez des espaces pour clarté:
О О _
_ Х О
Х Х Х
là encore, pratique pour le stockage, un dispositif d'affichage a été inventé, mais peu pratique pour la comparaison ! La solution a été trouvée lorsque j'ai numéroté les cellules de 1 à 9, puis j'ai réfléchi, car dans la programmation le compte à rebours commence à 0 et il est numéroté comme sur l'image. Jeu Java pour débutants - 3Vous n'avez pas remarqué de particularités ? si vous regardez l'image ci-dessus, il deviendra clair que les solutions avec 2 combinaisons ont un numéro de série impair, 4 combinaisons ont le numéro de série 4, 3 combinaisons ont le reste. Je suis donc arrivé à la conclusion qu'il fallait conserver le terrain de jeu dans un tableau régulier de nombres : une simple itération entre les nombres, la possibilité de comparer selon l'algorithme choisi, une simple sortie à l'écran. Quant à l'algorithme de comparaison lui-même. Allons-y dans l'ordre : dans toutes les options il y a une vérification de la ligne et de la colonne, on ne vérifie qu'elles. si la recherche ne donne pas de résultat, on vérifie le numéro de cellule pair/impair, s'il est impair, alors on retourne au jeu, cela ne sert à rien de vérifier plus loin, s'il est pair, on vérifie si cette cellule se trouve sur le diagonale gauche, les nombres de cette diagonale lorsqu'ils sont divisés par 4 ont un reste de 0. S'il est mensonger, on vérifie les correspondances, si aucune correspondance n'est trouvée, alors on vérifie le chiffre 4, sinon, on revient au jeu, si oui, nous allons plus loin dans le code et renvoyons le résultat de la vérification de la dernière diagonale. Probablement, pour une personne non préparée, c'est difficile à comprendre après avoir lu l'ensemble de lettres ci-dessus, mais quelqu'un peut dire qu'il y a beaucoup de lettres dans le code lui-même, ce qui peut être plus simple, je serai heureux d'en discuter. Nous avons réglé le problème, nous devons maintenant avoir affaire à deux utilisateurs qui se relaient et chacun d'eux a son propre signe, X ou O. Dans un premier temps, nous n'avons pas de fonctionnalité multi-utilisateurs, donc le Le moyen le plus simple serait d'utiliser les icônes une par une. X fait toujours le premier mouvement, O fait toujours le second, puis X encore, et ainsi de suite. Cela demande à être vérifié ( true/false ), et si vrai – alors le joueur actuel est X, si faux – alors O et au début de chaque mouvement flag=!flag Il reste à recevoir d'une manière ou d'une autre un signal des joueurs indiquant lequel cellule qu'ils choisissent. Ici, nous aurons besoin de nos inoubliables BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); joueurs qui entreront les numéros de cellule dans la console et en appuyant sur Entrée, ils feront un mouvement. La cellule correspondant au nombre saisi changera sa valeur de 0 à 1 ou 2, selon l'état actuel de la case à cocher, qui a été évoqué dans le paragraphe ci-dessus. C'est là qu'il est important de valider la saisie afin que personne ne puisse changer X en O alors que la cellule est déjà remplie :) Que peut entrer le joueur dans la console ?
  1. ligne vide
  2. lettres, signes de ponctuation, parenthèses... en un mot, non-chiffres
  3. nombres incorrects - négatifs ou en dehors de la taille du tableau, cellules occupées.
La méthode standard pour obtenir un chiffre à partir d'une chaîne est la méthode statique parseInt de la classe Integer. Integer.parseInt("2");Elle lève une exception NumberFormatExceptionsi elle ne peut pas obtenir un chiffre à partir d'une chaîne donnée. Nous pouvons fournir une protection contre les deux premiers points en interceptant cette exception. Pour le troisième point, je créerais une autre méthode qui vérifie la valeur saisie, mais il serait plus correct de déplacer la demande de chaîne dans une méthode distincte dans laquelle la validation sera effectuée, et elle ne renverra qu'un nombre. Pour résumer, nous avons créé un champ, réalisé une méthode qui l'affiche, réalisé une méthode qui vérifie "ce joueur a-t-il gagné d'une heure ?", et validé les numéros saisis. Il ne reste que très peu de choses à faire, recherchez un match nul - une méthode distincte qui parcourt le tableau, recherche 0 et affiche les résultats du jeu. C'est tout, le code est prêt, le jeu s'est avéré petit, une seule classe, donc les copieurs-colleurs coriaces peuvent, sans comprendre, simplement tout copier dans leur projet et l'exécuter tout seuls, j'étais comme ça moi-même, mais maintenant j'essaie de ne pas faire ça et je ne le recommande à personne :) Bonne chance à tous pour apprendre JAVA ! ps le reste des points - le multijoueur et la base de données viendront plus tard, j'ai déjà commencé à étudier le matériel :)
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;
        //мы здесь, значит, первый поиск не положительного результата
        //если meaning n находится на одной из граней - возвращаем false
        if (n%2!=0) return false;
        //проверяем принадлежит ли к левой диагонали meaning
        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;
    }
}
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION