JavaRush /Java Blog /Random-TL /Java game para sa mga nagsisimula
timurnav
Antas

Java game para sa mga nagsisimula

Nai-publish sa grupo
Kumusta mga kaibigan at mga kasamahan sa hinaharap! Laro ng Java para sa mga nagsisimula - 1Kamakailan lang, kumuha ako ng pagsusulit para makasali sa isang tunay na proyekto, naipasa ko ito, ngunit nagkataon na dahil sa mga personal na pangyayari ay hindi ako nakasali sa mismong RP. Pagkatapos ng mga kagiliw-giliw na problema tulad ng pagsusulit sa RP, ang karaniwang mga problema sa kurso ay naging hindi gaanong kaakit-akit na libangan, lalo na't nalutas ko na ang karamihan sa mga ito. Samakatuwid, upang hindi masayang ang aking talento sa patuloy na pag-aaral, nagpasya akong lumikha ng isang multiplayer web game. Mga link sa iba pang laro:
  1. pagpapatuloy ng artikulong ito
  2. 2048
Tic Tac Toe tila ang pinakasimpleng laro para sa akin, kaya nagpasya akong hatiin ang gawain sa ilang mga subtask:
  1. Console application para sa pagsubok ng lohika ng laro
  2. Multiplayer
  3. Pag-attach ng database ng player sa isang console application
  4. Paglikha ng front-end na disenyo, pagsusulat ng mga template ng pahina, interface ng laro
  5. Pinagsasama-sama ang lahat
May posibilidad na mapagalitan ako para sa gayong pagkakasunud-sunod, at malamang na ang lahat ng mga seryosong proyekto ay binuo sa isang ganap na magkakaibang pagkakasunud-sunod, sasagutin ko kaagad, magsulat ng isang post tungkol dito "para sa mga nagsisimula" upang ang lahat (kabilang ako) matutunan ito :) Well. Simulan natin ang pagsusulat ng console application! Susundin ko ang parehong mga hakbang tulad ng malaking antas 20 na mga hamon. Anong meron sa larong tic-tac-toe?!
  1. patlang
  2. dalawang manlalaro na humalili, ang isa ay naglalagay ng krus, ang pangalawa ay zero. ito ay simple.
Ginagawa naming karaniwang 3x3 field ang field. Paano maiimbak ang gayong larangan? ang unang opsyon ay isang two-dimensional array. Anong mga elemento ang dapat maglaman ng array na ito? Ang sagot ay kailangan nating pag-isipan kung ano ang gagawin natin sa mga elementong ito, ito ay nagpapakita at naghahambing upang mahanap ang nanalo. Kung ipinapakita lang namin ang mga ito sa screen, magiging lohikal na panatilihin ang mga ito bilang isang string, kung gayon ang array mismo at ipinapakita ito sa screen sa isang loop ay magiging ganito ang hitsura:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
ipapakita ng screen ang:
O O _
_ X O
X X X
Ngunit bilang karagdagan sa pagpapakita, mayroon din kaming paghahambing ng mga halaga, at dito posible na ang mga opsyon. Maaari mong ihambing ang mga string, maaari kang lumikha ng isang espesyal na klase ng enumeration ( enum), ngunit mas gusto kong ihambing ang mga numero, at palitan ang mga ito ng "X" at "O" lamang kapag ipinapakita sa screen. Hayaan ito, halimbawa, 1 - "X", 2 - "O", 0 - "_". Kaya, paano mo susuriin ang isang field para sa isang triple X o O na tugma?
Ang pinakaunang algorithm ay sinusuri ang buong field
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Mga panalong kumbinasyon:
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.
Pagsuri sa pamamagitan ng paghahambing ng mga numero, ngunit lumalabas na kailangan mong suriin ang BUONG field, lahat ng 8 kumbinasyon, sa bawat oras. Siyempre, hindi ito magkano, hindi ito isang paghahanap para sa mga numero ng Armstrong sa saklaw mula 0 hanggang 1 bilyon, mayroong kaunti pa kaysa sa walang mga kalkulasyon dito, ngunit nais mo pa rin ang isang bagay na mas mahusay kaysa sa pagsuri sa buong larangan. Ang pangalawang ideya na dumating sa akin ay suriin lamang ang cell na minarkahan sa nakaraang paglipat, upang matukoy pa rin natin ang nanalo, dahil malalaman natin kung sino ang gumawa ng hakbang na ito. Kaya, sa halip na lahat ng 8 kumbinasyon, nakakakuha lamang tayo ng 2, 3 o 4 na kumbinasyon, depende sa cell, tingnan ang larawan: Laro ng Java para sa mga nagsisimula - 2Ngayon kailangan nating malaman kung paano matukoy kung aling kumbinasyon ang kailangang ilunsad? Dito ko napagtanto na ang paggamit ng two-dimensional array ay hindi masyadong maginhawa. Nagpasya akong isaalang-alang ang iba pang mga pagpipilian. Sa una ay nagkaroon ako ng ideya na ang field ay maaaring itago sa isang siyam na digit na numero, halimbawa, ang parehong field na ipinakita namin sa screen ay maaaring isulat ng ganito: 220012111, ipapaliwanag ko sa aking mga daliri kung ano ito ay... Ang code ay pareho, 1 - “X”, 2 - “O” , 0 – " ", na nangangahulugang 220012111 = "OO__XOXXX", o kung pagkatapos ng bawat ikatlong digit ay nagpasok ka ng line break at magdagdag ng mga puwang para sa kalinawan:
О О _
_ Х О
Х Х Х
dito muli, maginhawa para sa imbakan, isang aparato para sa pagpapakita ay naimbento, ngunit hindi maginhawa para sa paghahambing! Ang solusyon ay natagpuan noong binilang ko ang mga cell 1-9, pagkatapos ay naisip ko, dahil sa programming ang countdown ay nagsisimula sa 0 at binibilang ito tulad ng sa larawan. Larong Java para sa mga nagsisimula - 3Hindi mo ba napansin ang anumang mga kakaiba? kung titingnan mo ang larawan sa itaas, magiging malinaw na ang mga solusyon na may 2 kumbinasyon ay may kakaibang serial number, 4 na kumbinasyon ay may serial number 4, 3 kumbinasyon ang natitira. Kaya't dumating ako sa konklusyon na kailangan mong panatilihin ang larangan ng paglalaro sa isang regular na hanay ng mga numero: simpleng pag-ulit sa pagitan ng mga numero, ang kakayahang maghambing ayon sa algorithm na napili, simpleng output sa screen. Tulad ng para sa paghahambing algorithm mismo. Pumunta tayo sa pagkakasunud-sunod: sa lahat ng mga pagpipilian mayroong isang tseke ng hilera at haligi, ang mga ito lamang ang sinusuri namin. kung ang paghahanap ay hindi nagreresulta, sinusuri namin ang numero ng cell para sa kahit na / kakaiba, kung ito ay kakaiba, pagkatapos ay bumalik kami sa laro, walang saysay na suriin pa, kung ito ay kahit na, tinitingnan namin kung ang cell na ito ay namamalagi sa kaliwang dayagonal, ang mga numero ng dayagonal na ito kapag hinati sa 4 ay may natitirang 0. Kung ito ay kasinungalingan, tinitingnan namin ang mga tugma, kung walang nakitang mga tugma, pagkatapos ay tinitingnan namin ang numero 4, kung hindi, bumalik sa laro, kung oo, dumaan pa kami sa code at ibabalik ang resulta ng pagsuri sa huling dayagonal. Marahil, para sa isang hindi handa na tao, mahirap itong maunawaan pagkatapos basahin ang hanay ng mga titik sa itaas, ngunit maaaring sabihin ng isang tao na maraming mga titik sa code mismo, na maaaring maging mas simple, ikalulugod kong talakayin ito. Inayos namin ang field, ngayon kailangan naming harapin ang dalawang user na humalili at bawat isa sa kanila ay may sariling sign, X o O. Sa unang yugto, wala kaming anumang multi-user functionality, kaya ang ang pinakamadaling paraan ay ang paggamit ng mga icon nang paisa-isa. Palaging si X ang gumagawa ng unang galaw, palaging ginagawa ni O ang pangalawa, pagkatapos ay muli ang X, at iba pa. Ito ay humihiling na suriin ( true/false ), at kung totoo – kung gayon ang kasalukuyang manlalaro ay X, kung mali – pagkatapos ay O at sa simula ng bawat galaw flag=!flag Ito ay nananatiling kahit papaano ay tumanggap ng senyales mula sa mga manlalaro tungkol sa kung alin cell na kanilang pinili. Dito kakailanganin namin ang aming hindi malilimutang BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); mga Manlalaro ay ipasok ang mga numero ng cell sa console, at ang pagpindot sa Enter ay gagawa ng isang hakbang. Ang cell na naaayon sa ipinasok na numero ay babaguhin ang halaga nito mula 0 hanggang 1 o 2, depende sa kasalukuyang estado ng checkbox, na tinalakay sa talata sa itaas. Dito mahalaga na i-validate ang input para walang makapagpalit ng X sa O kapag napuno na ang cell :) Ano ang maipasok ng player sa console?
  1. walang laman na linya
  2. mga titik, mga bantas, mga bracket... sa isang salita, hindi mga numero
  3. maling mga numero - negatibo o sa labas ng laki ng array, mga cell na inookupahan.
Ang karaniwang paraan para sa pagkuha ng digit mula sa isang string ay ang static na pamamaraan na parseInt ng klase ng Integer. Integer.parseInt("2");Naghagis ito ng exception NumberFormatExceptionkung hindi ito makakuha ng digit mula sa isang string. Maaari tayong magbigay ng proteksyon mula sa unang dalawang puntos sa pamamagitan ng pagharang sa exception na ito. Para sa pangatlong punto, gagawa ako ng isa pang paraan na sumusuri sa inilagay na halaga, ngunit ito ay pinakatama na ilipat ang kahilingan ng string sa isang hiwalay na paraan kung saan isasagawa ang pagpapatunay, at magbabalik lamang ito ng isang numero. Upang buod, gumawa kami ng field, gumawa ng paraan na nagpapakita nito, gumawa ng paraan na nagsusuri ng "kung nanalo ba ang manlalarong ito sa loob ng isang oras?", at napatunayan ang mga inilagay na numero. Napakakaunti na lang ang natitira, tingnan kung may draw - isang hiwalay na paraan na tumatakbo sa array at naghahanap ng 0, at ipinapakita ang mga resulta ng laro. Iyon lang, handa na ang code, ang laro ay naging maliit, isang klase lamang, kaya ang mga mahihirap na copy-pasters ay maaaring, nang walang pag-unawa, kopyahin lamang ang lahat sa kanilang proyekto at patakbuhin ito sa kanilang sarili, ako mismo ay ganoon, ngunit ngayon sinusubukan kong huwag gawin iyon at hindi sa sinumang inirerekumenda ko ito :) Good luck sa lahat sa pag-aaral ng JAVA! ps the rest of the points - multiplayer and database will come later, sinimulan ko na pag-aralan ang material :)
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;
    }
}
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION