JavaRush /Java Blog /Random-ID /Game Java untuk pemula
timurnav
Level 21

Game Java untuk pemula

Dipublikasikan di grup Random-ID
Halo teman-teman dan kolega masa depan! Game Java untuk pemula - 1Baru-baru ini saya mengikuti tes untuk berpartisipasi dalam proyek nyata, lulus, tetapi kebetulan karena keadaan pribadi saya tidak dapat mengambil bagian dalam RP itu sendiri. Setelah soal-soal menarik seperti tes RP, soal-soal kursus yang biasa menjadi hobi yang kurang menarik, terutama karena saya sudah menyelesaikan sebagian besar soal tersebut. Oleh karena itu, agar bakat saya tidak terbuang sia-sia untuk terus belajar, saya memutuskan untuk membuat web game multiplayer. Tautan ke permainan lain:
  1. kelanjutan artikel ini
  2. 2048
Tic Tac Toe tampak seperti permainan paling sederhana bagi saya, jadi saya memutuskan untuk membagi tugas menjadi beberapa subtugas:
  1. Aplikasi konsol untuk menguji logika permainan
  2. Multipemain
  3. Melampirkan database pemain ke aplikasi konsol
  4. Membuat desain front-end, menulis templat halaman, antarmuka permainan
  5. Menyatukan semuanya
Ada kemungkinan saya akan dimarahi karena urutan seperti itu, dan kemungkinan besar semua proyek serius dibangun dalam urutan yang sama sekali berbeda, saya akan segera menjawab, menulis posting tentang ini "untuk pemula" sehingga semua orang (termasuk saya) dapat mempelajarinya :) Baiklah, mari kita mulai menulis aplikasi konsol! Saya akan mengikuti langkah yang sama seperti tantangan level 20 yang besar. Apa yang ada di permainan tic-tac-toe?!
  1. bidang
  2. dua pemain yang bergiliran, yang satu memberi tanda silang, yang lain nol. itu mudah.
Kami menjadikan bidang tersebut sebagai bidang standar 3x3. Bagaimana bidang seperti itu bisa disimpan? opsi pertama adalah array dua dimensi. Elemen apa yang harus ada dalam array ini? Jawabannya adalah kita perlu memikirkan apa yang akan kita lakukan dengan elemen-elemen tersebut, yaitu menampilkan dan membandingkan untuk mencari pemenangnya. Jika kita hanya menampilkannya di layar, maka logis untuk menyimpannya sebagai string, maka array itu sendiri dan menampilkannya di layar dalam satu lingkaran akan terlihat seperti ini:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
layar akan menampilkan:
O O _
_ X O
X X X
Namun selain tampilan, kami juga memiliki perbandingan nilai, dan di sini opsi sudah dimungkinkan. Anda dapat membandingkan string, Anda dapat membuat kelas enumerasi khusus ( enum), tetapi saya lebih suka membandingkan angka, dan menggantinya dengan “X” dan “O” hanya ketika ditampilkan di layar. Biarlah, misalnya, 1 - "X", 2 - "O", 0 - "_". Jadi, bagaimana Anda memeriksa bidang untuk kecocokan triple X atau O?
Algoritma pertama adalah memeriksa seluruh bidang
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Kombinasi pemenang:
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.
Pengecekannya dengan membandingkan angka, namun ternyata Anda perlu mencentang SELURUH kolom, ke-8 kombinasi, setiap saat. Tentu saja ini tidak banyak, ini bukan pencarian angka Armstrong dalam kisaran 0 hingga 1 miliar, hanya ada sedikit perhitungan di sini, tetapi Anda tetap menginginkan sesuatu yang lebih optimal daripada memeriksa seluruh bidang. Ide kedua yang muncul di benak saya adalah mencentang sel yang sudah ditandai pada langkah sebelumnya saja, agar kita tetap bisa menentukan pemenangnya, karena kita akan tahu siapa yang melakukan langkah tersebut. Jadi, alih-alih semua 8 kombinasi, kita hanya mendapatkan 2, 3 atau 4 kombinasi, bergantung pada selnya, lihat gambar: Game Java untuk pemula - 2Sekarang kita perlu mencari cara untuk menentukan kombinasi mana yang perlu diluncurkan? Di sinilah saya menyadari bahwa menggunakan array dua dimensi sangatlah tidak nyaman. Saya memutuskan untuk melihat opsi lain. Awalnya saya mendapat ide bahwa field tersebut dapat disimpan dalam angka sembilan digit, misalnya field yang sama yang kita tampilkan di layar dapat ditulis seperti ini: 220012111, saya akan menjelaskan dengan jari saya apa itu adalah... Kodenya sama, 1 - “X”, 2 - “O” , 0 – " ", yang artinya 220012111 = "OO__XOXXX", atau jika setelah setiap digit ketiga Anda memasukkan baris baru dan menambahkan spasi untuk kejelasan:
О О _
_ Х О
Х Х Х
di sini sekali lagi, nyaman untuk penyimpanan, perangkat untuk tampilan telah ditemukan, tetapi tidak nyaman untuk perbandingan! Solusinya ditemukan ketika saya memberi nomor pada sel 1-9, lalu saya berpikir, karena dalam pemrograman hitungan mundur dimulai dari 0 dan diberi nomor seperti pada gambar, Game Java untuk pemula - 3apakah Anda tidak melihat ada keanehan? jika dilihat gambar diatas terlihat jelas bahwa penyelesaian dengan 2 kombinasi mempunyai nomor urut ganjil, 4 kombinasi mempunyai nomor urut 4, 3 kombinasi mempunyai nomor urut 4. Jadi saya sampai pada kesimpulan bahwa Anda perlu menjaga arena bermain dalam susunan angka yang teratur: iterasi sederhana antar angka, kemampuan untuk membandingkan sesuai dengan algoritma yang dipilih, keluaran sederhana ke layar. Adapun algoritma perbandingannya sendiri. Mari kita mulai secara berurutan: di semua opsi ada tanda centang pada baris dan kolom, kami hanya memeriksanya. jika pencarian tidak membuahkan hasil, kita cek nomor sel genap/ganjil, jika ganjil maka kita kembali ke permainan, tidak ada gunanya memeriksa lebih lanjut, jika genap kita periksa apakah sel ini terletak di diagonal kiri, bilangan diagonal ini bila dibagi 4 mempunyai sisa 0. Kalau bohong kita cek kecocokannya, jika tidak ditemukan kecocokan maka kita centang angka 4, jika tidak kembali ke permainan, jika ya, kita menelusuri kode lebih jauh dan mengembalikan hasil pemeriksaan diagonal terakhir. Mungkin bagi orang yang belum siap, hal ini sulit dipahami setelah membaca kumpulan huruf di atas, namun mungkin ada yang mengatakan bahwa dalam kode itu sendiri ada banyak sekali huruf, yang bisa lebih sederhana, saya akan dengan senang hati membahasnya. Kami telah memilah bidangnya, sekarang kami harus berurusan dengan dua pengguna yang bergiliran dan masing-masing memiliki tandanya sendiri, X atau O. Pada tahap pertama, kami tidak memiliki fungsi multi-pengguna, jadi cara termudah adalah dengan menggunakan ikon satu per satu. X selalu melakukan gerakan pertama, O selalu melakukan gerakan kedua, lalu X lagi, dan seterusnya. Itu meminta untuk diperiksa ( benar/salah ), dan jika benar – maka pemain saat ini adalah X, jika salah – maka O dan di awal setiap gerakan flag=!flag Tetap menerima sinyal dari para pemain tentang yang mana sel yang mereka pilih. Di sini kita memerlukan BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Pemain yang tak terlupakan untuk memasukkan nomor sel ke dalam konsol, dan menekan Enter akan bergerak. Sel yang sesuai dengan nomor yang dimasukkan akan mengubah nilainya dari 0 menjadi 1 atau 2, bergantung pada status kotak centang saat ini, yang telah dibahas pada paragraf di atas. Di sinilah pentingnya memvalidasi input agar tidak ada yang bisa mengubah X menjadi O ketika sel sudah terisi :) Apa yang bisa pemain masukkan ke konsol?
  1. baris kosong
  2. huruf, tanda baca, tanda kurung... dalam satu kata, bukan angka
  3. angka yang salah - negatif atau di luar ukuran array, sel terisi.
Metode standar untuk mendapatkan digit dari string adalah metode statis parseInt dari kelas Integer. Integer.parseInt("2");Metode ini memunculkan pengecualian NumberFormatExceptionjika tidak dapat memperoleh digit dari string tertentu. Kita dapat memberikan perlindungan dari dua titik pertama dengan mencegat pengecualian ini. Untuk poin ketiga, saya akan membuat metode lain yang memeriksa nilai yang dimasukkan, tetapi akan lebih tepat jika memindahkan permintaan string ke metode terpisah di mana validasi akan dilakukan, dan hanya akan mengembalikan nomor. Ringkasnya, kami membuat kolom, membuat metode yang menampilkannya, membuat metode yang memeriksa “apakah pemain ini menang satu jam?”, dan memvalidasi angka yang dimasukkan. Hanya ada sedikit yang harus dilakukan, periksa hasil imbang - metode terpisah yang menjalankan array dan mencari 0, dan menampilkan hasil permainan. Itu saja, kodenya sudah siap, permainannya ternyata kecil, hanya satu kelas, jadi copy-paste yang tangguh, tanpa pemahaman, bisa menyalin semuanya ke proyek mereka dan menjalankannya sendiri, saya sendiri juga seperti itu, tapi sekarang saya mencoba untuk tidak melakukan itu dan tidak kepada siapa pun saya merekomendasikannya :) Semoga sukses untuk semuanya dalam belajar JAVA! ps poin selebihnya - multiplayer dan database akan menyusul nanti, saya sudah mulai mempelajari materinya :)
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;
    }
}
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION