JavaRush /Java Blogu /Random-AZ /Java oyunu başlayanlar üçün
timurnav
Səviyyə

Java oyunu başlayanlar üçün

Qrupda dərc edilmişdir
Salam dostlar və gələcək həmkarlar! Yeni başlayanlar üçün Java oyunu - 1Bu yaxınlarda mən real layihədə iştirak etmək üçün imtahan verdim, ondan keçdim, amma elə oldu ki, şəxsi şəraitə görə RP-nin özündə iştirak edə bilmədim. RP testi kimi maraqlı problemlərdən sonra adi kurs problemləri daha az cəlbedici bir əyləncəyə çevrildi, xüsusən də onların əksəriyyətini artıq həll etdiyim üçün. Buna görə də, öyrənməyə davam etmək üçün istedadımın boşa getməməsi üçün multiplayer veb oyunu yaratmağa qərar verdim. Digər oyunlara keçidlər:
  1. bu məqalənin davamı
  2. 2048
Tic Tac Toe mənə ən sadə oyun kimi görünürdü, ona görə də tapşırığı bir sıra alt tapşırıqlara bölmək qərarına gəldim:
  1. Oyun məntiqini yoxlamaq üçün konsol tətbiqi
  2. Multiplayer
  3. Oyunçu məlumat bazasının konsol proqramına əlavə edilməsi
  4. Front-end dizaynının yaradılması, səhifə şablonlarının yazılması, oyun interfeysi
  5. Hamısını bir yerə yığmaq
Belə bir ardıcıllığa görə məni qınamaq ehtimalı var və çox güman ki, bütün ciddi layihələr tamamilə fərqli bir ardıcıllıqla qurulur, mən dərhal cavab verəcəyəm, bu barədə "yeni başlayanlar üçün" bir yazı yazın ki, hamı (mən də daxil olmaqla) bunu öyrənə bilərsiniz :) Yaxşı. Gəlin konsol tətbiqi yazmağa başlayaq! Mən böyük səviyyəli 20 çağırışla eyni addımları izləyəcəyəm. tic-tac-toe oyununda nə var?!
  1. sahə
  2. növbə çəkən iki oyunçu, biri xaç qoyur, digəri sıfır. bu sadədir.
Sahəni standart 3x3 sahəyə çeviririk. Belə bir sahəni necə saxlamaq olar? birinci variant ikiölçülü massivdir. Bu massiv hansı elementləri ehtiva etməlidir? Cavab budur ki, bu elementlərlə nə edəcəyimizi düşünməliyik, bu, qalibi tapmaq üçün göstərmək və müqayisə etməkdir. Əgər biz onları yalnız ekranda göstərsəydik, onda onları sətir kimi saxlamaq məntiqli olardı, onda massivin özü və onu döngədə ekranda göstərmək belə olardı:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
ekranda göstərilir:
O O _
_ X O
X X X
Ancaq ekrana əlavə olaraq, dəyərlərin müqayisəsi də var və burada seçimlər artıq mümkündür. Siz sətirləri müqayisə edə bilərsiniz, xüsusi nömrələmə sinfi yarada bilərsiniz ( enum), lakin mən rəqəmləri müqayisə etməyə və onları yalnız ekranda göstərildikdə “X” və “O” ilə əvəz etməyə üstünlük verərdim. Məsələn, 1 - "X", 2 - "O", 0 - "_" olsun. Beləliklə, üçlü X və ya O uyğunluğu üçün bir sahəni necə yoxlamaq olar?
İlk alqoritm bütün sahəni yoxlamaqdır
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Qazanan kombinasiyalar:
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.
Rəqəmləri müqayisə etməklə yoxlanılır, lakin məlum olur ki, hər dəfə BÜTÜN sahəni, bütün 8 kombinasiyanı yoxlamaq lazımdır. Əlbəttə ki, bu çox deyil, bu, 0-dan 1 milyarda qədər olan Armstronq nömrələrinin axtarışı deyil, burada heç bir hesablama yoxdur, amma yenə də bütün sahəni yoxlamaqdan daha optimal bir şey istəyirsən. Mənə gələn ikinci fikir, yalnız əvvəlki hərəkətdə işarələnmiş xananı yoxlamaq idi, ona görə də qalibi hələ də müəyyən edə bilərik, çünki bu hərəkəti kimin etdiyini biləcəyik. Beləliklə, bütün 8 birləşmənin əvəzinə, hüceyrədən asılı olaraq yalnız 2, 3 və ya 4 kombinasiya alırıq, şəklə baxın: Yeni başlayanlar üçün Java oyunu - 2İndi hansı kombinasiyanın işə salınması lazım olduğunu necə müəyyənləşdirməliyik? Burada anladım ki, iki ölçülü massivdən istifadə o qədər də rahat deyil. Başqa variantlara baxmağa qərar verdim. Əvvəlcə belə bir fikrə gəldim ki, sahəni doqquz rəqəmli rəqəmdə saxlamaq olar, məsələn, ekranda göstərdiyimiz sahə belə yazıla bilər: 220012111, barmaqlarımda bunun nə olduğunu izah edəcəyəm. Bu... Kod eynidir, 1 - “X”, 2 - “O” , 0 – " ", yəni 220012111 = "OO__XOXXX" deməkdir və ya hər üçüncü rəqəmdən sonra sətir sonu daxil edirsinizsə və boşluq əlavə edirsinizsə aydınlıq:
О О _
_ Х О
Х Х Х
burada yenə saxlama üçün əlverişli, ekran üçün bir cihaz icad edildi, lakin müqayisə üçün əlverişsiz! Həll yolu 1-9 xanalarını nömrələyəndə tapıldı, sonra fikirləşdim, çünki proqramlaşdırmada geri sayım 0-dan başlayır və şəkildəki kimi nömrələnir.Heç Yeni başlayanlar üçün Java oyunu - 3bir özəllik görmədiniz? yuxarıdakı şəklə baxsanız, aydın olacaq ki, 2 kombinasiyalı məhlulların tək seriya nömrəsi, 4 kombinasiyanın seriya nömrəsi 4, 3 birləşmənin qalan hissəsi var. Beləliklə, mən belə bir nəticəyə gəldim ki, oyun sahəsini adi nömrələr massivində saxlamaq lazımdır: nömrələr arasında sadə təkrarlama, seçilmiş alqoritmə uyğun olaraq müqayisə etmək imkanı, ekrana sadə çıxış. Müqayisə alqoritminin özünə gəldikdə. Gəlin qaydada gedək: bütün variantlarda satır və sütunun yoxlanışı var, biz yalnız onları yoxlayırıq. axtarış nəticə verməsə, xana nömrəsini cüt/tək olub-olmadığını yoxlayırıq, təkdirsə, oyuna qayıdırıq, əlavə yoxlamağın mənası yoxdur, əgər cütdürsə, bu xananın üzərində olub-olmadığını yoxlayırıq. sol diaqonal, 4-ə bölünəndə bu diaqonalın nömrələri 0-a bərabərdir. Yalandırsa, uyğunluqları yoxlayırıq, uyğunluq tapılmırsa, 4 rəqəminin olub olmadığını yoxlayırıq, yoxsa, oyuna qayıdırıq, əgər bəli, kodu daha da irəliləyirik və sonuncu diaqonalı yoxlamanın nəticəsini qaytarırıq. Yəqin ki, hazırlıqsız bir insan üçün yuxarıdakı hərflər toplusunu oxuduqdan sonra bunu başa düşmək çətindir, amma kimsə deyə bilər ki, kodun özündə çoxlu hərf var, daha sadə ola bilər, bunu müzakirə etməkdən məmnun olaram. Biz sahəni sıraladıq, indi növbə ilə işləyən iki istifadəçi ilə məşğul olmalıyıq və onların hər birinin öz işarəsi var, X və ya O. Birinci mərhələdə bizdə çox istifadəçi funksiyası yoxdur, ona görə də ən asan yol nişanları bir-bir istifadə etmək olardı. X həmişə birinci hərəkəti edir, O həmişə ikincini edir, sonra yenidən X və s. Yoxlanmağı xahiş edir ( doğru/yanlış ) və əgər doğrudursa – o zaman cari oyunçu X-dir, əgər yalansa – onda O və hər hərəkətin əvvəlində bayraq=!bayraq Oyunçulardan hansısa bir şəkildə hansının olması barədə siqnal almaq qalır. seçdikləri hüceyrə. Burada unudulmaz Oyunçularımıza ehtiyacımız olacaq BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); , konsola hüceyrə nömrələrini daxil edəcək və Enter düyməsini basaraq hərəkət edəcək. Daxil edilmiş nömrəyə uyğun gələn xana yuxarıdakı paraqrafda müzakirə edilən qeyd qutusunun cari vəziyyətindən asılı olaraq dəyərini 0-dan 1-ə və ya 2-yə dəyişəcək. Hüceyrə artıq doldurulduqda heç kimin X-i O-ya dəyişdirə bilməməsi üçün girişi təsdiqləmək vacibdir :) Oyunçu konsola nə daxil edə bilər?
  1. boş xətt
  2. hərflər, durğu işarələri, mötərizələr... bir sözlə qeyri-rəqəmlər
  3. səhv nömrələr - mənfi və ya massiv ölçüsündən kənarda, işğal edilmiş hüceyrələr.
Sətirdən rəqəm əldə etmək üçün standart üsul Integer sinfinin statik metodu parseInt-dir.Verilmiş sətirdən rəqəm ala bilmədikdə Integer.parseInt("2");istisna atır.Bu istisnanı kəsməklə ilk iki nöqtədən qorunma təmin edə bilərik. NumberFormatExceptionÜçüncü nöqtə üçün, daxil edilmiş dəyəri yoxlayan başqa bir üsul yaradardım, lakin sətir sorğusunu doğrulamanın aparılacağı ayrı bir metoda köçürmək ən düzgün olardı və o, yalnız bir rəqəm qaytaracaq. Xülasə etmək üçün bir sahə yaratdıq, onu göstərən bir üsul yaratdıq, “bu oyunçunun bir saat qalib olub-olmadığını” yoxlayan bir üsul yaratdıq və daxil edilmiş nömrələri təsdiqlədik. Çox az qalıb, heç-heçəni yoxlayın - massivdən keçən və 0-ı axtaran və oyunun nəticələrini göstərən ayrıca üsul. Hamısı budur, kod hazırdır, oyun kiçik oldu, yalnız bir sinif oldu, buna görə sərt kopirayterlər başa düşmədən hər şeyi öz layihələrinə köçürə və özləri işlədə bilərlər, mən özüm də belə idim, amma indi bunu etməməyə çalışıram və heç kimə tövsiyə etmirəm :) JAVA-nı öyrənməkdə hər kəsə uğurlar! ps qalan məqamlar - multiplayer və verilənlər bazası daha sonra gələcək, mən artıq materialı öyrənməyə başlamışam :)
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;
    }
}
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION