JavaRush /Java Blog /Random-IT /Gioco Java per principianti
timurnav
Livello 21

Gioco Java per principianti

Pubblicato nel gruppo Random-IT
Ciao amici e futuri colleghi! Gioco Java per principianti - 1Di recente, ho sostenuto un test per partecipare a un progetto reale, l'ho superato, ma è successo che a causa di circostanze personali non ho potuto prendere parte all'RP stesso. Dopo problemi così interessanti come il test RP, i soliti problemi del corso sono diventati un passatempo meno attraente, soprattutto perché ne avevo già risolto la maggior parte. Pertanto, affinché il mio talento non venga sprecato per continuare ad apprendere, ho deciso di creare un gioco web multiplayer. Collegamenti ad altri giochi:
  1. continuazione di questo articolo
  2. 2048
Tic Tac Toe mi è sembrato il gioco più semplice, quindi ho deciso di suddividere il compito in una serie di sottoattività:
  1. Applicazione console per testare la logica del gioco
  2. Multigiocatore
  3. Collegamento di un database di giocatori a un'applicazione console
  4. Creazione del design front-end, scrittura di modelli di pagina, interfaccia di gioco
  5. Mettere tutto insieme
C'è la possibilità che verrò rimproverato per una sequenza del genere, e molto probabilmente tutti i progetti seri sono costruiti in una sequenza completamente diversa, risponderò subito, scriverò un post su questo “per principianti” in modo che tutti (me compreso) può impararlo :) Bene, iniziamo a scrivere un'applicazione console! Seguirò gli stessi passaggi delle grandi sfide di livello 20. Cosa c'è nel gioco tris?!
  1. campo
  2. due giocatori che si alternano, uno mette una croce, l'altro uno zero. è semplice.
Rendiamo il campo un campo standard 3x3. Come può essere memorizzato un campo del genere? la prima opzione è un array bidimensionale. Quali elementi dovrebbe contenere questo array? La risposta è che dobbiamo pensare a cosa faremo con questi elementi, ovvero visualizzare e confrontare per trovare il vincitore. Se li visualizzassimo solo sullo schermo, sarebbe logico mantenerli come una stringa, quindi l'array stesso e visualizzarlo sullo schermo in un ciclo sarebbe simile a questo:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
lo schermo mostrerebbe:
O O _
_ X O
X X X
Ma oltre alla visualizzazione abbiamo anche un confronto dei valori e qui le opzioni sono già possibili. Puoi confrontare stringhe, puoi creare una classe di enumerazione speciale ( enum), ma preferirei confrontare i numeri e sostituirli con "X" e "O" solo quando visualizzati sullo schermo. Lascia che sia, ad esempio, 1 - "X", 2 - "O", 0 - "_". Quindi, come si controlla un campo per una corrispondenza tripla X o O?
Il primo algoritmo sta controllando l'intero campo
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Combinazioni vincenti:
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.
Controllo confrontando i numeri, ma risulta che devi controllare TUTTO il campo, tutte e 8 le combinazioni, ogni volta. Naturalmente, questo non è molto, questa non è una ricerca di numeri Armstrong nell'intervallo da 0 a 1 miliardo, qui ci sono poco più che nessun calcolo, ma vuoi comunque qualcosa di più ottimale che controllare l'intero campo. La seconda idea che mi è venuta è stata quella di controllare solo la cella che era stata contrassegnata nella mossa precedente, in modo da poter ancora determinare il vincitore, perché sapremo chi ha effettuato questa mossa. Pertanto, invece di tutte e 8 le combinazioni, otteniamo solo 2, 3 o 4 combinazioni, a seconda della cella, vedi figura: Gioco Java per principianti - 2Ora dobbiamo capire come determinare quale combinazione deve essere lanciata? È qui che mi sono reso conto che utilizzare un array bidimensionale non è molto conveniente. Ho deciso di considerare altre opzioni. All'inizio mi è venuta l'idea che il campo possa essere mantenuto in un numero di nove cifre, ad esempio lo stesso campo che abbiamo visualizzato sullo schermo può essere scritto così: 220012111, vi spiego tra le dita cosa è è... Il codice è lo stesso, 1 - “X”, 2 - “O” , 0 – " ", che significa 220012111 = "OO__XOXXX", o se dopo ogni terza cifra inserisci un'interruzione di riga e aggiungi spazi per chiarezza:
О О _
_ Х О
Х Х Х
anche qui, comodo per la conservazione, è stato inventato un dispositivo per la visualizzazione, ma scomodo per il confronto! La soluzione l'ho trovata quando ho numerato le celle da 1 a 9, poi ho pensato, perché nella programmazione il conto alla rovescia parte da 0 e l'ho numerato come in foto, Gioco Java per principianti - 3non hai notato particolarità? se osservate l'immagine qui sopra, apparirà chiaro che le soluzioni con 2 combinazioni hanno un numero di serie dispari, 4 combinazioni hanno il numero di serie 4, 3 combinazioni hanno il resto. Quindi sono giunto alla conclusione che è necessario mantenere il campo di gioco in una serie regolare di numeri: semplice iterazione tra numeri, capacità di confrontare in base all'algoritmo scelto, semplice output sullo schermo. Per quanto riguarda l'algoritmo di confronto stesso. Andiamo per ordine: in tutte le opzioni c'è il check della riga e della colonna, noi controlliamo solo loro. se la ricerca non dà risultati controlliamo se il numero di cella è pari/dispari, se è dispari torniamo al gioco, non ha senso controllare ulteriormente, se è pari controlliamo se questa cella si trova sulla diagonale sinistra, i numeri di questa diagonale quando divisi per 4 hanno resto 0. Se giace, controlliamo le corrispondenze, se non vengono trovate corrispondenze, controlliamo il numero 4, altrimenti torniamo al gioco, se sì, andiamo oltre nel codice e restituiamo il risultato del controllo dell'ultima diagonale. Probabilmente, per una persona impreparata, questo è difficile da capire dopo aver letto l'insieme di lettere sopra, ma qualcuno potrebbe dire che ci sono molte lettere nel codice stesso, il che può essere più semplice, ne parlerò volentieri. Abbiamo sistemato il campo, ora dobbiamo occuparci di due utenti che si alternano e ognuno di loro ha il proprio segno, X o O. Nella prima fase non abbiamo alcuna funzionalità multiutente, quindi il il modo più semplice sarebbe utilizzare le icone una per una. X fa sempre la prima mossa, O fa sempre la seconda, poi ancora X e così via. Chiede di essere controllato ( vero/falso ), e se vero – allora il giocatore attuale è X, se falso – allora O e all'inizio di ogni mossa flag=!flag Resta da ricevere in qualche modo un segnale dai giocatori su quale cella che scelgono. Qui avremo bisogno dei nostri indimenticabili BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Giocatori inseriranno i numeri di cellulare nella console, e premendo Invio si effettuerà una mossa. La cella corrispondente al numero inserito cambierà il suo valore da 0 a 1 o 2, a seconda dello stato attuale della casella di controllo, discusso nel paragrafo precedente. Qui è dove è importante convalidare l'input in modo che nessuno possa cambiare X in O quando la cella è già piena :) Cosa può inserire il giocatore nella console?
  1. riga vuota
  2. lettere, segni di punteggiatura, parentesi... in una parola, non numeri
  3. numeri errati: negativi o esterni alla dimensione dell'array, celle occupate.
Il metodo standard per ottenere una cifra da una stringa è il metodo statico parseInt della classe Integer. Integer.parseInt("2");Genera un'eccezione NumberFormatExceptionse non riesce a ottenere una cifra da una determinata stringa. Possiamo fornire protezione dai primi due punti intercettando questa eccezione. Per il terzo punto, creerei un altro metodo che controlli il valore inserito, ma sarebbe più corretto spostare la richiesta di stringa in un metodo separato in cui verrà eseguita la convalida e restituirà solo un numero. Per riassumere, abbiamo creato un campo, creato un metodo che lo visualizza, creato un metodo che verifica "questo giocatore ha vinto entro un'ora?" e convalidato i numeri inseriti. C'è molto poco da fare, controlla il pareggio: un metodo separato che attraversa l'array e cerca 0 e visualizza i risultati del gioco. Questo è tutto, il codice è pronto, il gioco si è rivelato piccolo, una sola classe, quindi i copiatori più ostinati possono, senza capire, semplicemente copiare tutto nel loro progetto ed eseguirlo da soli, anch'io ero così, ma ora cerco di non farlo e non lo consiglio a nessuno :) Buona fortuna a tutti per imparare JAVA! ps il resto dei punti: multiplayer e database arriveranno più tardi, ho già iniziato a studiare il materiale :)
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;
    }
}
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION