JavaRush /وبلاگ جاوا /Random-FA /بازی جاوا برای مبتدیان
timurnav
مرحله

بازی جاوا برای مبتدیان

در گروه منتشر شد
سلام دوستان و همکاران آینده بازی جاوا برای مبتدیان - 1اخیراً برای شرکت در یک پروژه واقعی آزمایش دادم، آن را قبول کردم، اما اتفاقی افتاد که به دلیل شرایط شخصی نتوانستم در خود RP شرکت کنم. پس از مشکلات جالبی مانند آزمون RP، مسائل معمول دروس به سرگرمی کمتر جذابی تبدیل شدند، به خصوص که من قبلاً اکثر آنها را حل کرده بودم. بنابراین، برای اینکه استعدادم برای ادامه یادگیری هدر نرود، تصمیم گرفتم یک وب بازی چند نفره بسازم. لینک بازی های دیگر:
  1. ادامه این مقاله
  2. 2048
Tic Tac Toe برای من ساده ترین بازی به نظر می رسید، بنابراین تصمیم گرفتم این کار را به تعدادی زیرکار تقسیم کنم:
  1. نرم افزار کنسول برای تست منطق بازی
  2. چند نفره
  3. پیوست کردن پایگاه داده پخش کننده به یک برنامه کنسول
  4. ایجاد طراحی جلویی، نوشتن قالب های صفحه، رابط بازی
  5. همه اش را بگذار کنار هم
این احتمال وجود دارد که برای چنین سکانسی مورد سرزنش قرار بگیرم و به احتمال زیاد تمام پروژه های جدی در یک دنباله کاملاً متفاوت ساخته می شوند ، من فوراً پاسخ خواهم داد ، یک پست در مورد این "برای مبتدیان" بنویسید تا همه (از جمله من) می تواند این را بیاموزد :) خب بیایید شروع به نوشتن یک برنامه کنسول کنیم! من همان مراحل چالش های بزرگ سطح 20 را دنبال می کنم. در بازی تیک تاک چیست؟!
  1. رشته
  2. دو بازیکن که به نوبت می آیند، یکی صلیب می گذارد، دیگری صفر. ساده است.
فیلد را یک فیلد استاندارد 3x3 می کنیم. چگونه می توان چنین میدانی را ذخیره کرد؟ گزینه اول یک آرایه دو بعدی است. این آرایه باید شامل چه عناصری باشد؟ پاسخ این است که ما باید فکر کنیم که با این عناصر چه خواهیم کرد، این نمایش و مقایسه برای یافتن برنده است. اگر فقط آنها را روی صفحه نمایش می دادیم، منطقی بود که آنها را به عنوان یک رشته نگه داریم، سپس خود آرایه و نمایش آن بر روی صفحه در یک حلقه چیزی شبیه به این خواهد بود:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
صفحه نمایش نشان می دهد:
O O _
_ X O
X X X
اما علاوه بر نمایش، مقایسه مقادیر نیز داریم و در اینجا گزینه هایی از قبل امکان پذیر است. می‌توانید رشته‌ها را مقایسه کنید، می‌توانید یک کلاس شمارش ویژه ( enum) ایجاد کنید، اما من ترجیح می‌دهم اعداد را با هم مقایسه کنیم و فقط زمانی که روی صفحه نمایش داده می‌شوند، «X» و «O» را جایگزین آن‌ها کنم. بگذارید مثلاً 1 - "X"، 2 - "O"، 0 - "_" باشد. بنابراین، چگونه یک فیلد را برای تطابق سه گانه X یا O بررسی می کنید؟
اولین الگوریتم بررسی کل فیلد است
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
ترکیب های برنده:
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.
بررسی با مقایسه اعداد، اما معلوم می شود که باید هر بار کل فیلد، هر 8 ترکیب را بررسی کنید. البته این خیلی زیاد نیست، این جستجوی اعداد آرمسترانگ در محدوده 0 تا 1 میلیارد نیست، در اینجا کمی بیش از هیچ محاسباتی وجود ندارد، اما شما هنوز چیزی بهینه تر از بررسی کل فیلد می خواهید. ایده دومی که به ذهنم رسید این بود که فقط سلولی را که در حرکت قبلی مشخص شده بود بررسی کنم، بنابراین ما همچنان می توانیم برنده را تعیین کنیم، زیرا می دانیم چه کسی این حرکت را انجام داده است. بنابراین، به جای هر 8 ترکیب، بسته به سلول، فقط 2، 3 یا 4 ترکیب دریافت می کنیم، تصویر را ببینید: بازی جاوا برای مبتدیان - 2اکنون باید بفهمیم که چگونه تعیین کنیم کدام ترکیب باید راه اندازی شود؟ اینجاست که متوجه شدم استفاده از آرایه دو بعدی خیلی راحت نیست. تصمیم گرفتم گزینه های دیگری را در نظر بگیرم. در ابتدا به این فکر افتادم که فیلد را می توان در یک عدد نه رقمی نگه داشت، مثلاً همان فیلدی را که روی صفحه نمایش می دهیم می توان اینگونه نوشت: 220012111، من در انگشتانم توضیح می دهم که چیست. است... کد یکسان است، 1 - "X", 2 - "O" , 0 - " "، که به معنی 220012111 = "OO__XOHX" است، یا اگر بعد از هر رقم سوم یک شکست خط وارد کنید و برای آن فاصله اضافه کنید. وضوح:
О О _
_ Х О
Х Х Х
در اینجا دوباره، برای ذخیره سازی راحت، دستگاهی برای نمایش اختراع شد، اما برای مقایسه ناخوشایند! راه حل وقتی پیدا شد که سلول ها را 1-9 شماره گذاری کردم، سپس فکر کردم، زیرا در برنامه نویسی شمارش معکوس از 0 شروع می شود و آن را مانند تصویر شماره گذاری می کنم. آیا بازی جاوا برای مبتدیان - 3شما به ویژگی خاصی توجه نکردید؟ اگر به تصویر بالا نگاه کنید، مشخص می شود که راه حل های دارای 2 ترکیب دارای شماره سریال فرد هستند، 4 ترکیب دارای شماره سریال 4 و 3 ترکیب دارای مابقی هستند. بنابراین من به این نتیجه رسیدم که باید زمین بازی را در یک آرایه منظم از اعداد نگه دارید: تکرار ساده بین اعداد، توانایی مقایسه با توجه به الگوریتم انتخاب شده، خروجی ساده روی صفحه نمایش. در مورد خود الگوریتم مقایسه. بیایید به ترتیب برویم: در همه گزینه ها یک بررسی از سطر و ستون وجود دارد، ما فقط آنها را بررسی می کنیم. اگر جستجو به نتیجه نرسید، شماره سلول را برای زوج/فرد بررسی می کنیم، اگر فرد است، سپس به بازی برمی گردیم، بررسی بیشتر فایده ای ندارد، اگر زوج باشد، بررسی می کنیم که آیا این سلول روی مورب سمت چپ، اعداد این مورب وقتی بر 4 تقسیم می شوند، باقیمانده 0 هستند. اگر دروغ باشد، مطابقت را بررسی می کنیم، اگر مطابقت پیدا نشد، سپس عدد 4 را بررسی می کنیم، اگر نه، به بازی برمی گردیم، اگر بله، کد را بیشتر می کنیم و نتیجه بررسی آخرین قطر را برمی گردانیم. احتمالاً برای یک فرد ناآماده درک این موضوع پس از خواندن مجموعه حروف بالا دشوار است، اما ممکن است کسی بگوید که حروف زیادی در خود کد وجود دارد که می تواند ساده تر باشد، خوشحال می شوم در این مورد بحث کنم. ما زمینه را مرتب کرده ایم، اکنون باید با دو کاربر که به نوبت انجام می دهند و هر کدام علامت مخصوص به خود را دارند، X یا O سروکار داریم. در مرحله اول، ما هیچ عملکرد چند کاربره نداریم، بنابراین ساده ترین راه این است که از نمادها یک به یک استفاده کنید. X همیشه اولین حرکت را انجام می دهد، O همیشه حرکت دوم را انجام می دهد، سپس X دوباره و غیره. التماس می‌کند ( درست/نادرست ) بررسی شود ، و اگر درست باشد - بازیکن فعلی X است، اگر نادرست است - سپس O و در ابتدای هر حرکت flag=!flag باقی می‌ماند که به نحوی سیگنالی از بازیکنان دریافت کنیم که در مورد آن سلولی که انتخاب می کنند در اینجا ما به BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); بازیکنان فراموش نشدنی خود نیاز خواهیم داشت که شماره سلول ها را وارد کنسول می کنند و با فشار دادن Enter حرکتی انجام می شود. سلول مربوط به عدد وارد شده بسته به وضعیت فعلی چک باکس که در پاراگراف بالا توضیح داده شد، مقدار خود را از 0 به 1 یا 2 تغییر می دهد. اینجاست که مهم است که ورودی را تایید کنیم تا وقتی سلول از قبل پر شده است، هیچکس نتواند X را به O تغییر دهد :) پخش کننده چه چیزی را می تواند وارد کنسول کند؟
  1. خط خالی
  2. حروف، علائم نگارشی، پرانتز... در یک کلمه، غیر اعداد
  3. اعداد نادرست - منفی یا خارج از اندازه آرایه، سلول های اشغال شده.
روش استاندارد برای گرفتن یک رقم از یک رشته، متد static parseInt از کلاس Integer است.اگر نتواند رقمی از یک رشته معین دریافت کند، Integer.parseInt("2");یک استثنا ایجاد می کند.ما می توانیم با قطع این استثنا، از دو نقطه اول محافظت کنیم. NumberFormatExceptionبرای نکته سوم، من متد دیگری ایجاد می کنم که مقدار وارد شده را بررسی می کند، اما صحیح ترین آن است که درخواست رشته را به یک متد جداگانه منتقل کنیم که در آن اعتبارسنجی انجام می شود و فقط یک عدد را برمی گرداند. به طور خلاصه، یک فیلد ایجاد کردیم، روشی ساختیم که آن را نمایش می‌دهد، روشی ساختیم که «آیا این بازیکن یک ساعت برنده شد؟» را بررسی می‌کند و اعداد وارد شده را اعتبارسنجی می‌کند. کار بسیار کمی باقی مانده است، برای قرعه کشی بررسی کنید - یک روش جداگانه که در آرایه اجرا می شود و 0 را جستجو می کند و نتایج بازی را نشان می دهد. این همه است، کد آماده است، بازی کوچک است، فقط یک کلاس، بنابراین کپی پاسترهای سخت می توانند بدون درک، همه چیز را در پروژه خود کپی کنند و آن را به تنهایی اجرا کنند، من خودم اینطور بودم، اما اکنون سعی می کنم این کار را نکنم و به کسی توصیه نمی کنم :) برای همه در یادگیری جاوا موفق باشید! ps بقیه نکات - چند نفره و دیتابیس بعدا میاد، من قبلا شروع کردم به مطالعه مطالب :)
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;
    }
}
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION