Advertisement
Szerelo

SeaWolf tengeri szimulációs játék Arduino-ra

Jun 18th, 2018
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 29.65 KB | None | 0 0
  1. /* Seawolf game - Tengeri üldözéses szimulátor játék  v 0.9 beta
  2.   Készítette: Szerzetes, 2018.06.19.
  3.   Licenc megkötés: A program bármely része vagy egésze bármilyen célra szabadon felhasználható. A szerző feltüntetése nem kötelező, csak illendő :)
  4.  
  5.   A játék menete egy válaszható méretű négyzethálón játszódik (ez most 20*20). Maximum 4 darab hajó üldöz egy víz alatti felderítő tengeralattjárót, mely 3 különbözű féle mélységben
  6.   közlekedhet. A pozícióját és a mélységet nem ismejük. Viszont minden körben a sonár jelzi, hogy milyen távolságban van tőlünk. Ez alapján kell megtalálni és
  7.   hatástalanítani egy víz alatti bombával, mely csak akkor hatásos, ha eltaláljuk a mélységet. Egy pozíción csak egy hajó tartózkodhat. A hajók minden körben 1 egységet
  8.   képesek mozogni bármelyik irányban. Ha nem találjuk el a célpont mélységét, akkor visszakerül a hajó az előző pozícióra, hogy egy másik hajó is tüzelhessen.
  9.   A tengeralattjáró mélysége a játék kezdetétől fogva nem változik, kivéve a legnehezebb fokozatot.
  10.   A tengeralattjáró kezdeti pozíciója nem lehet a bal alsó 10*10-es négyzetben.
  11.   A nehézségi fokozatok a felderítő tengeralattjáró mozgásában különböznek:
  12.   1 - A gyakorló módban nem mozog, csak helyben áll.
  13.   2 - A könnyű módban csak 2 irányban halad, csak jobbar-balra, vagy csak le-fel, a pálya széléhez érve pedig ellenkező irányt vált.
  14.   3 - A közepes fokozaton bármilyen irányban mozoghat és a pálya széléhez érve szintén bármilyen irányban haladhat tovább, de mindig csak egyenes vonalban.
  15.   4 - A nehéz fokozatban legalább 3 körig egy irányban halad, után irányt változtathat.
  16.   5 - A hardcore fokozatban bármikor irányt változtathat és csak ebben a fokozatban változtathat mélységet is.
  17.   A hajók mindig a következő pozícióról indulnak:
  18.   1. X=5, Y=0
  19.   2. X=10, Y=0
  20.   3. X=0, Y=5
  21.   4. X=0, Y=10
  22.   A hardver igény a következő:
  23.     1 db 4*16-os I2C vezérlővel ellátott LCD kijelző
  24.     1 db 4*4-es nyomógomb mátrix (elvileg elégséges a 3*4-es is, de a kijelzővel és I2C illesztővel együtt a HE Store-ból 4*4-es nyomógomb szerezhető be, ezért ez van használva)
  25.  */
  26. #include <Wire.h>
  27. #include <LiquidCrystal_I2C.h> // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
  28.  
  29. // A gombokhoz hozzárendelünk neveket. Az A,B,C,D,* és a 0 gombok nincsenek használva.
  30. //  '1','2','3','A'
  31. //  '4','5','6','B'
  32. //  '7','8','9','C'
  33. //  '*','0','#','D'
  34.  
  35. byte aa[8] = {    // Egyéni karakter definiálásához szükséges adatok. á karakter
  36.   B00110,
  37.   B00000,
  38.   B01110,
  39.   B00001,
  40.   B11111,
  41.   B10001,
  42.   B01111,
  43. };
  44. byte ee[8] = {      // é
  45.   B00110,
  46.   B00000,
  47.   B01110,
  48.   B10001,
  49.   B11111,
  50.   B10000,
  51.   B01110,
  52. };
  53. byte oo[8] = {      // ó
  54.   B00110,
  55.   B00000,
  56.   B01110,
  57.   B10001,
  58.   B10001,
  59.   B10001,
  60.   B01110,
  61. };
  62.  
  63. // Beállítjuk, hogy az I2C illesztő áramkör mely címen érhető el és az illesztő panelen található IC mely kivezetéseihez csatlakozik a kijelző:
  64. //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
  65. LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // lcd néven létrehozunk egy úgynevezett objektumot. A továbbiakban lcd névre való hivatkozással érhetjük el a kijelzőt.
  66.  
  67. byte meret=20;    // A pálya mérete 20*20
  68. byte szint,hajokszama,irany; // Sorban: nehézségi szint, a hajók száma, a tengeralattjáró iránya
  69. byte minimumlepes=1;   // A minimum lépések száma magasabb nehézségi szinten, hogy mikortól lehetséges az irányváltoztatás és mélység változtatás
  70. byte minimumlepes1=1;
  71. int X1,Y1,tavolsag,Xe,Ye,tavolsage,lepes;   // Sorban: átmeneti koordináta tárolás, távolság érték, átmeneti koordináta tárolás, korábbi távolság érték, lépések számlálása
  72. byte melyseg;   // Tengeralattjáró mélysége
  73. // Az első elem a hajó száma, a második dimenzió 1-2 rekesze az x,y koordináta, 3-irány. Az 5. hajó a tengeralattjáró.
  74. byte hajok[6][4] {      // A hajók koordinátáinak és irány érték adatainak tárolása
  75.   {5,0,5,0},
  76.   {10,0,5,0},
  77.   {0,5,5,0},
  78.   {0,10,5,0},
  79. };
  80. bool fut=0,Xhiba,Yhiba;   // Sorban: Elindulthat-e a játék, A tengaralattjáró következő pozíciója a pályán kívül van-e.
  81. byte GOMB;      // A billentyűzet mátrix beolvasása utáni megynomott gomb értéke
  82.  
  83. void setup()   // SETUP: csak egyszer hajtódik végre az itteni programrész
  84. {
  85.   Serial.begin(115200);   // Soros monitor indítása
  86.   Serial.println("Start"); // Jelezzük, hogy elindult a programunk
  87.   pinMode(6,INPUT);     // A billentyűzet mátrixra csatlakozó portok beállítása
  88.   pinMode(7,INPUT);     // A 6,7,8,9 a sorokra csatlakoznak
  89.   pinMode(8,INPUT);     // Míg a 2,3,4,5 az oszlopokra
  90.   pinMode(9,INPUT);
  91.   pinMode(2,INPUT);
  92.   pinMode(3,INPUT);
  93.   pinMode(4,INPUT);
  94.   pinMode(5,INPUT);
  95.   digitalWrite(6,HIGH); // Ezeken a portokon olvassuk le a gombok állapotát. Bekapcsoljuk a felhúzó ellenállásokat
  96.   digitalWrite(7,HIGH); // Így alap értékként magas szint lesz rajtuk.
  97.   digitalWrite(8,HIGH); // A megnyomott gombok alacsony szinre állítják a megfelelő bemenetet.
  98.   digitalWrite(9,HIGH);
  99.   lcd.begin(16,4);   // LCD kijelző alaphelyzetbe állítása és típusának megadása. Jelen esetben 4 soros és soronként 16 karakteres.
  100.   lcd.createChar(1, aa);  // Egyéni karakterek beállítása az LCD kijelző memóriájában
  101.   lcd.createChar(2, ee);  // Ezt minden bekapcsoláskor újra kell írni, mivel a kijelző kikapcsolásakor törlődik.
  102.   lcd.createChar(3, oo);
  103.  
  104. // A háttérvilágítás ki/be kapcsolása
  105. // A kijelző fényének 3-szor gyors ki-be kapcsolásával jelezzük, hogy elindult a játék.
  106.   for(int i = 0; i< 3; i++) // Egy for ciklus létrehozása: 3 paramétert kell megadni. Az elsőben létrehozzuk a ciklusváltozót, megadva a típusát és kezdő értékét, a második paraméterben a ciklus futásának a feltételét és a harmadik paraméter tartalmazza a ciklusváltozó változásának a mértékét.
  107.   {
  108.     lcd.backlight();  // A háttérvilágítás bekapcsolása
  109.     delay(250);       //Várakozás. Ilyenkor az Arduinó látszólag nem csinál semmit mindaddig, amíg a megadott időtartam véget nem ér.
  110.     lcd.noBacklight(); // A háttérvilágítás kikapcsolása
  111.     delay(250);       // A várakozás hosszát milliszekundumban adjuk meg.
  112.   }
  113.   lcd.backlight();
  114.  
  115. // A kijelzőre az üdvözlő szöveg kiírása
  116. // A SetCursor(oszlop, sor) parancs használata: először az oszlop, majd utána a sor pozíciója következik vesszővel elválasztva.
  117.   lcd.setCursor(5,0); // A kiírási pozíció, más néven kurzor (Cursor) pozíció megadása. Jelen esetben az első sor 6. oszlopa. A számozás nullától kezdődik!
  118.   lcd.print("HELLO!");  // A kijelzőre való kiírás a kurzor pozíciótól. A  kurzor pozíciója automatikusan az utoljára kiírt szöveg utáni pozícióra módosul.
  119.   delay(100);  // 1 másodperces várakozás, ami 1000 milliszekundumnak felel meg.
  120.   lcd.setCursor(2,1);
  121.   lcd.print("Seawolf game");    // Itt maradt az angol elnevezés, nincs ötletem magyarra
  122.   delay(1000);  
  123.   lcd.setCursor(3,3);
  124.   lcd.print("Good luck!");      // Ha már angol a név, maradjon ez is
  125.   delay(2000);  
  126.   lcd.clear();  // A kijelző törlése (szóköz karakterekkel való feltöltése, így látszólag üres lesz).
  127.   lcd.setCursor(0,0); // Az első sor első oszlopra kerül a következő kiírás
  128.  
  129. } // setup vége
  130.  
  131. void loop()   // LOOP: a program futása, folyamatosan újra és újra végrehajtódik ez a programrész
  132. {
  133.   if (fut==0) {
  134.     kezd();  
  135.   }
  136. for (byte i=1 ; i<=hajokszama ; i++) {  // Sorra vesszük a hajókat
  137.   ujra:     // Megjelöljük ezt a sort, hogy szükség esetén vissza tudjunk térni
  138.   lcd.clear();    // A kezdő "képernyő" kiírása.
  139.   lcd.print(i);
  140.   lcd.print(".haj");
  141.   lcd.write(3);
  142.   lcd.print(" X=");
  143.   lcd.print(hajok[i][1]);
  144.   lcd.print(" Y=");
  145.   lcd.print(hajok[i][2]);
  146.   lcd.setCursor(0,1);
  147.   lcd.print("Ir");
  148.   lcd.write(1);
  149.   lcd.print("ny:  1 2 3");
  150.   lcd.setCursor(8,2);
  151.   lcd.print("4 5 6");
  152.   lcd.setCursor(8,3);
  153.   lcd.print("7 8 9");
  154.   tavol(i);   // A hajó és a tengeralattjáró távolságának számítása és kiírása
  155.   GOMB=0;     // A megnyomott gomb értékének alphelyzetbe állítása, hogy a vizsgálatkor ne egy előzőleg megnyomott gomb értékét vegye. Itt a gombnyomás() függvény meghívása is jó megoldás lenne.
  156.   while (GOMB!=1 and GOMB!=2 and GOMB!=3 and GOMB!=4 and GOMB!=5 and GOMB!=6 and GOMB!=7 and GOMB!=8 and GOMB!=9) // Az irány gombok valamelyikének a megnyomására való várakozás
  157.   {
  158.     gombnyomas();   // A billenytűzet mátrix kezelése
  159.   }
  160.   irany=GOMB;
  161.   Xe=hajok[i][1];   // A hajó pillanatnyi pozíciójának az eltárolása
  162.   Ye=hajok[i][2];
  163.   switch (irany) {  // A kívánt irány vizsgálata
  164.     case 1:   // Az 1-es irány a bal-fel
  165.       Serial.print("1. irany ");
  166.       X1=hajok[i][1]-1;   // Az új X pozíció kiszámítása
  167.       if (X1<=-1) {       // A pályán belül van-e
  168.         Y1=hajok[i][2];   // A nem változó tengely koordinátájának beírása, mivel az X,Y koordináták együtt vannak kezelve (X a vizsgált, X1-ben van adat. az Y1-be változatlanül betöltjük a hajó Y adatát).
  169.         nemjo(i);         // A kívánt pozíció nem lehetséges, mivel pályán kívül van
  170.         delay(2000);      // Várakozás
  171.         goto  ujra;       // Az irány ismételt megadása, azaz vissza az irány megadásának a kezdetére
  172.       }
  173.       Y1=hajok[i][2]+1;   // Az új Y pozíció kiszámítása
  174.       if (Y1>=meret) {
  175.         X1=hajok[i][1];
  176.         nemjo(i);
  177.         delay(2000);
  178.         goto  ujra;
  179.       }
  180.       if (!utkozes()) {   // A kívánt pozíción van-e már egy másik hajó
  181.         goto ujra;        // Ha van, akkor újra a pozíció megadására
  182.       }
  183.       hajok[i][1]=X1;     // Az új X pozíció végelegesítése
  184.       hajok[i][2]=Y1;     // Az új Y pozíció végelegesítése
  185.       break;
  186.     case 2:
  187.       Serial.println("2. irany");
  188.       X1=hajok[i][1];
  189.       Y1=hajok[i][2]+1;
  190.       if (Y1>=meret) {
  191.         nemjo(i);
  192.         delay(2000);
  193.         goto  ujra;
  194.       }
  195.       if (!utkozes()) {
  196.         goto ujra;
  197.       }
  198.       hajok[i][2]=Y1;
  199.       break;
  200.     case 3:
  201.       Serial.println("3. irany");
  202.       X1=hajok[i][1]+1;
  203.       if (X1>=meret) {
  204.         Y1=hajok[i][2];
  205.         nemjo(i);
  206.         delay(2000);
  207.         goto  ujra;
  208.       }
  209.       Y1=hajok[i][2]+1;
  210.       if (Y1>=meret) {
  211.         X1=hajok[i][1];
  212.         nemjo(i);
  213.         delay(2000);
  214.         goto  ujra;
  215.       }
  216.       if (!utkozes()) {
  217.         goto ujra;
  218.       }
  219.       hajok[i][1]=X1;
  220.       hajok[i][2]=Y1;
  221.       break;
  222.     case 4:
  223.       Serial.println("4. irany");
  224.       X1=hajok[i][1]-1;
  225.       Y1=hajok[i][2];
  226.       if (X1<=-1) {
  227.         nemjo(i);
  228.         delay(2000);
  229.         goto  ujra;
  230.       }
  231.       if (!utkozes()) {
  232.         goto ujra;
  233.       }
  234.       hajok[i][1]=X1;
  235.       break;
  236.     case 5:     // 5-ös iránynál nincs vizsgálat, mivel nem lép a hajó.
  237.       Serial.println("5. irany");
  238.       break;
  239.     case 6:
  240.       Serial.println("6. irany");
  241.       X1=hajok[i][1]+1;
  242.       Y1=hajok[i][2];
  243.       if (X1>=meret) {
  244.         nemjo(i);
  245.         delay(2000);
  246.         goto  ujra;
  247.       }
  248.       if (!utkozes()) {
  249.         goto ujra;
  250.       }
  251.       hajok[i][1]=X1;
  252.       break;
  253.     case 7:
  254.       Serial.println("7. irany");
  255.       X1=hajok[i][1]-1;
  256.       if (X1<=-1) {
  257.         Y1=hajok[i][2];
  258.         nemjo(i);
  259.         delay(2000);
  260.         goto  ujra;
  261.       }
  262.       Y1=hajok[i][2]-1;
  263.       if (Y1<=-1) {
  264.         X1=hajok[i][1];
  265.         nemjo(i);
  266.         delay(2000);
  267.         goto  ujra;
  268.       }
  269.       if (!utkozes()) {
  270.         goto ujra;
  271.       }
  272.       hajok[i][1]=X1;
  273.       hajok[i][2]=Y1;
  274.       break;
  275.     case 8:
  276.       Serial.println("8. irany");
  277.       X1=hajok[i][1];
  278.       Y1=hajok[i][2]-1;
  279.       if (Y1<=-1) {
  280.         nemjo(i);
  281.         delay(2000);
  282.         goto  ujra;
  283.       }
  284.       if (!utkozes()) {
  285.         goto ujra;
  286.       }
  287.       hajok[i][2]=Y1;
  288.       break;
  289.     case 9:
  290.       Serial.println("9. irany");
  291.       X1=hajok[i][1]+1;
  292.       if (X1>=meret) {
  293.         Y1=hajok[i][2];
  294.         nemjo(i);
  295.         delay(2000);
  296.         goto  ujra;
  297.       }
  298.       Y1=hajok[i][2]-1;
  299.       if (Y1<=-1) {
  300.         X1=hajok[i][1];
  301.         nemjo(i);
  302.         delay(2000);
  303.         goto  ujra;
  304.       }
  305.       if (!utkozes()) {
  306.         goto ujra;
  307.       }
  308.       hajok[i][1]=X1;
  309.       hajok[i][2]=Y1;
  310.       break;
  311.   }
  312.   jo(i);  // Az irány megadása sikeres volt, az új pozíció kiírása
  313.   lcd.setCursor(0,1);
  314.   lcd.print("Tovabb: #");
  315.   while (GOMB!=12) {  // Várakozás a # gomb megnyomására
  316.     gombnyomas();
  317.     }
  318.   irany=GOMB;
  319.   if (tavolsag==0) {    // Ha a távolság a hajó és a tengeralattjáró között 0, akkor azonos pozíción vannak, meg lehet próbálni megsemmisíteni
  320.     lcd.setCursor(0,1);
  321.     lcd.print("FIRE!   1 2 3   ");
  322.     lcd.setCursor(0,2);
  323.     lcd.print("                ");
  324.     lcd.setCursor(0,3);
  325.     while (GOMB!=1 and GOMB!=2 and GOMB!=3) {   // Várakozás az 1,2, gomb megnyomására, ezek a 3 különböző lehetséges mélységek
  326.       gombnyomas();
  327.       }
  328.     irany=GOMB;
  329.     lcd.setCursor(0,1);
  330.     lcd.print("FIRE! : ");
  331.     lcd.print(irany);
  332.     lcd.print("       ");
  333.     lcd.setCursor(0,2);
  334.     lcd.print("                ");
  335.     lcd.setCursor(0,3);
  336.     lcd.print("                ");
  337.     if (irany==melyseg) {   // Eltaláltuk-e a mélységet vizsgálat
  338.       lcd.setCursor(6,2);   // Ha igen, akkor a győzelem felirat kiírása
  339.       lcd.print("WIN!");
  340.       lcd.setCursor(0,3);
  341.       lcd.print("Tovabb: #");
  342.       while (GOMB!=12) {  // És várakozás a # gomb megnyomására
  343.         gombnyomas();
  344.       }
  345.       asm volatile ( "jmp 0");  // Ezzel az assembler utasítással a reset vektor címére állítjuk a program számlálót, ami a teljes program újraindítását eredményezi (olyan, mintha most kapcsoltuk volna be vagy megnyomtuk volna a reset gombot az Arduino-n)
  346.       }
  347.     else {    // Nem sikerült eltalálni a célpontot
  348.       hajok[i][1]=Xe; // A lövés előtti pozícióra kerül vissza a hajó
  349.       hajok[i][2]=Ye;
  350.       jo(i);
  351.       lcd.setCursor(0,2);   // Hogy ne kelljen külön kiírni a hajó új koordinátáját, ezért a jo() függvényt használjuk, de ilyenkor az X1,Y1 adatok nem helyesek, mivel ez a 2 változó itt nincs használva
  352.       lcd.print("      MISS!     ");  // Ezért azt a sort letakarjuk a MISS felirattal.
  353.       while (GOMB!=12) {  // Várakozás a # gomb megnyomására
  354.         gombnyomas();
  355.         }
  356.       }
  357.     }
  358.    
  359.   }
  360.  
  361.   if (szint!=1){  // 1-es nehézségi szinten nem mozog a tengeralattjáró, így nincs szükség a lépésének a kiszámítására
  362.     geplep();     // A tengeralattjáró lépésének kiszámítása
  363.   }
  364.  
  365. }  /* --( loop vége )-- */
  366.  
  367. void geplep() {   // A tengeralattjáró lépésének kiszámítása
  368.   if (szint==4 or szint==5) { // 4-es és 5-ös nehézségi szinten néha irányt változtathat menet közben
  369.     minimumlepes++;
  370.     if (minimumlepes>=4) {  // Lehetséges-s az irányváltoztatás. Ez minden 4-ik lépésben lehet csak
  371.       minimumlepes=1;       // A számláló visszaállítása a kezdeti értékére
  372.       hajok[5][3]=random(1,9);   // Tengeralattjáró új haladási irányának a generálása (ami kis eséllyel lehet az előző is)
  373.       if (hajok[5][3]==5) {      // Ha 5 az irány, akkor az utolsó, a 9-es irány lesz helyette, hogy mozogjon
  374.         hajok[5][3]=9;
  375.       }
  376.     }
  377.   }
  378.   if (szint==5) {   // Az 5-ös nehézségi fokozatban a tengeralattjáró változtathatja a mélységét is
  379.     minimumlepes1++;
  380.     if (minimumlepes1>=2) {  //
  381.       melyseg=random(1,4);   // Új mélység generálása
  382.       minimumlepes1=1;       // A számláló visszaállítása a kezdeti értékre
  383.     }
  384.   }
  385.   ujra1:    // Az új pozíció sikeres kiszámításához megjelüljük ezt a sort
  386.   Serial.print("irany: ");
  387.   Serial.println(hajok[5][3]);
  388.   X1=hajok[5][1];   // A tengeralattjáró pozíciójának tárolása
  389.   Y1=hajok[5][2];
  390.   Serial.print("sub X: ");
  391.   Serial.print(X1);
  392.   Serial.print(" Y: ");
  393.   Serial.println(Y1);
  394.   switch (hajok[5][3]) {  // Megvizsgáljuk, hogy milyen irányban halad a tengeralattjáró
  395.     case 2:
  396.     Serial.println("fel");
  397.     if (fel()) {      // A fel() függvénnye negvizsgáljuk, hogy lehetséges-e a felfelé mozgás
  398.       hajok[5][3]=8;  // Nem lehetséges, ezért irányt kell változtatni. A 2-es irány ellentéte a 8-as irány
  399.       goto ujra1;     // Újra kezdjük a vizsgálatot
  400.     }
  401.     break;      
  402.     case 4:
  403.     Serial.println("bal");
  404.     if (balra()) {
  405.       hajok[5][3]=6;
  406.       goto ujra1;
  407.     }
  408.     break;      
  409.     case 6:
  410.     Serial.println("jobb");
  411.     if (jobbra()) {
  412.       hajok[5][3]=4;
  413.       goto ujra1;
  414.     }
  415.     break;      
  416.     case 8:
  417.     Serial.println("le");
  418.     if (le()) {
  419.       hajok[5][3]=2;
  420.       goto ujra1;
  421.     }
  422.     break;
  423.     case 1:   // Az 1-es irány átlós, így mind a 2 tengely vizsgálatára szükség van
  424.     Serial.println("bal-fel");
  425.     Xhiba=balra();  // Az X tengelyen lehetséges-e a lépés vizsgálata
  426.     Yhiba=fel();    // Az Y tengelyen lehetséges-e a lépés vizsgálata
  427.     if (Xhiba==1 and Yhiba==1) {  // Ha egyik tengelyen sem lehetséges, akkor az átló ellenkező irányába mozoghat csak. Ez a helyzet csak a bal felső sarokban fordulhat elő.
  428.         hajok[5][3]=9;      // Az 1-es irány ellenkező iránya a 9-es irány
  429.         goto ujra1;         // Újra kezdjük a vizsgálatot
  430.       }
  431.     if (Xhiba==1) {         // Ha az X tengelyen nem lehetséges a mozgás, akkor az Y irányt változatlanul hagyjuk és így az átló másik X iránya a 3-as irány. Ez a helyzet a pálya bal szélén fordulhat elő.
  432.         hajok[5][3]=3;
  433.         goto ujra1;
  434.       }
  435.     if (Yhiba==1) {         // Ha az Y tengelyen nem lehetséges a mozgás, akkor az X irányt változatlanul hagyjuk és így az átló másik Y iránya a 7-es irány. Ez a helyzet a pálya tetején fordulhat elő.
  436.         hajok[5][3]=7;
  437.         goto ujra1;
  438.       }
  439.     break;    // Az 1-es irány vizsgálatának a vége. Vegyük észre, hogy átlós mozgásnál elhelyezkedéstől függően mind a 3 maradék átlós irányban haladhat tovább.
  440.     case 3:
  441.     Serial.println("jobb-fel");
  442.     Xhiba=jobbra();
  443.     Yhiba=fel();
  444.     if (Xhiba==1 and Yhiba==1) {
  445.         hajok[5][3]=7;
  446.         goto ujra1;
  447.       }
  448.     if (Xhiba==1) {
  449.         hajok[5][3]=1;
  450.         goto ujra1;
  451.       }
  452.     if (Yhiba==1) {
  453.         hajok[5][3]=9;
  454.         goto ujra1;
  455.       }
  456.     break;
  457.     case 7:
  458.     Serial.println("bal-le");
  459.     Xhiba=balra();
  460.     Yhiba=le();
  461.     if (Xhiba==1 and Yhiba==1) {
  462.         hajok[5][3]=3;
  463.         goto ujra1;
  464.       }
  465.     if (Xhiba==1) {
  466.         hajok[5][3]=9;
  467.         goto ujra1;
  468.       }
  469.     if (Yhiba==1) {
  470.         hajok[5][3]=1;
  471.         goto ujra1;
  472.       }
  473.     break;
  474.     case 9:
  475.     Serial.println("jobb-le");
  476.     Xhiba=jobbra();
  477.     Yhiba=le();
  478.     if (Xhiba==1 and Yhiba==1) {
  479.         hajok[5][3]=1;
  480.         goto ujra1;
  481.       }
  482.     if (Xhiba==1) {
  483.         hajok[5][3]=7;
  484.         goto ujra1;
  485.       }
  486.     if (Yhiba==1) {
  487.         hajok[5][3]=3;
  488.         goto ujra1;
  489.       }
  490.     break;
  491.   }   //switch vége
  492.   hajok[5][1]=X1;   // Az új pozíció megadása a tegngeralattjárónak
  493.   hajok[5][2]=Y1;
  494.   Serial.print("sub X: ");
  495.   Serial.print(X1);
  496.   Serial.print(" Y: ");
  497.   Serial.println(Y1);
  498. }
  499.  
  500. bool jobbra() {   // Jobbra irányban lehetséges-e a mozgás. Ez egy BOOL (logikai) típusú függvény, ami azt jelenti, hogy a visszatérési értéke vagy igaz (1) vagy hamis (0) állapottal lehetséges
  501.   bool hiba=0;    // A hibajelző alacsony szintre állítása, feltételezve, hogy nem lesz hiba
  502.   X1=hajok[5][1]+1;   // A pillanatnyi pozíciót jobbra 1-el megnöveljük
  503.   if (X1>=meret) {    // Megvizsgáljuk, hogy a pályán belül van-e az új pozíció
  504.     hiba=1;           // Ha kívülre esik, akkor hibajelzőt magas szintre állítjuk
  505.   }
  506.   return hiba;        // A vizsgálatból való visszatérés a hibajelző állapotával.
  507. }
  508.  
  509. bool balra() {
  510.   bool hiba=0;
  511.   X1=hajok[5][1]-1;
  512.   if (X1<=-1) {
  513.     hiba=1;
  514.   }
  515.   return hiba;
  516. }
  517.  
  518. bool fel() {
  519.   bool hiba=0;
  520.   Y1=hajok[5][2]+1;
  521.   if (Y1>=meret) {
  522.     hiba=1;
  523.   }
  524.   return hiba;
  525. }
  526.  
  527. bool le() {
  528.   bool hiba=0;
  529.   Y1=hajok[5][2]-1;
  530.   if (Y1<=-1) {
  531.     hiba=1;
  532.   }
  533.   return hiba;
  534. }
  535.  
  536. int utkozes() {  // Az éppen pozíciót változtatní kívánó hajó a többi hajóval való ütközésének a vizsgálata, mivel egy koordinátán csak 1 hajó tartózkodhat
  537.   bool ok=1;     // Alapértelmezésként a logikai állapotú (BOOL) változó értéke igaz, ha nincs ütközés
  538.   for (byte i=0;i<=hajokszama;i++) {  // A pályán lévő hajókat sorra vesszük
  539.       if (hajok[i][1]==X1 and hajok[i][2]==Y1) {
  540.         ok=0;
  541.         lcd.setCursor(0,1);
  542.         lcd.print("!!!             ");
  543.         lcd.setCursor(0,2);
  544.         lcd.print("                ");
  545.         lcd.setCursor(0,3);
  546.         lcd.print("   Collison!    ");
  547.         delay(1000);
  548.       }
  549.   }
  550.   return ok;
  551. }
  552.  
  553. void jo(byte i)
  554. {
  555.   tavol(i);
  556.   lcd.setCursor(7,0);
  557.   lcd.print("         ");
  558.   lcd.setCursor(0,1);
  559.   lcd.print("                ");
  560.   lcd.setCursor(0,2);
  561.   lcd.print("T:");
  562.   lcd.print(tavolsage);
  563.   lcd.setCursor(7,2);
  564.   lcd.print("X=");
  565.   lcd.print(Xe);
  566.   lcd.print(" Y=");
  567.   lcd.print(Ye);
  568.   lcd.setCursor(7,3);
  569.   lcd.print("X=");
  570.   lcd.print(hajok[i][1]);
  571.   lcd.print(" Y=");
  572.   lcd.print(hajok[i][2]);
  573. }
  574.  
  575.  
  576. void nemjo(byte i)
  577. {
  578.   lcd.clear();
  579.   lcd.print(i);
  580.   lcd.print(".haj");
  581.   lcd.write(3);
  582.   lcd.print(" X=");
  583.   lcd.print(hajok[i][1]);
  584.   lcd.print(" Y=");
  585.   lcd.print(hajok[i][2]);
  586.   lcd.setCursor(0,1);
  587.   lcd.print(" !!!   X=");
  588.   lcd.print(X1);
  589.   lcd.print(" Y=");
  590.   lcd.print(Y1);
  591.   lcd.setCursor(0,3);
  592.   lcd.print(" Out of field! ");
  593. }
  594.  
  595. void kezd() {  // Kezdő paraméterek beállítása ill. generálása
  596.   randomSeed(analogRead(0));    // A randomgenerátor a nullás analóg bemeneten véletlenszerű értékű jellel inicializálódik
  597.   lcd.clear();      // Az lcd kijelző törlése
  598.   lcd.print("Neh"); // "Nehézségi fokozat (1-5: )" szöveg kiírása
  599.   lcd.write(2);     // Az é betű, mint egyedileg definiált karakter
  600.   lcd.print("zs");
  601.   lcd.write(2);
  602.   lcd.print("gi");
  603.   lcd.setCursor(0,1);
  604.   lcd.print("fokozat (1-5): ");
  605.  
  606.   while (GOMB!=1 and GOMB!=2 and GOMB!=3 and GOMB!=4 and GOMB!=5) // Az 1,2,3,4,5-ös gombok valamelyikének a megnyomására való várakozás
  607.   {
  608.     gombnyomas();   // A megnyomott gomb lekérdezése, ha volt egyáltalán
  609.   }
  610.   szint=GOMB;       // A megnyomott gomb értéke lesz a nehézségi szint értéke
  611.   GOMB=0;           // Újabb gombnyomás előkészítése, hogy ne a korábban megnyomott gomb értékét adja vissza a gombnyomas() függvény
  612.   lcd.setCursor(15,1);    // Az LCD kijelzőn beállítjuk a következő karakter helyét, ami a szöveg után éesz
  613.   lcd.print(szint);       // Az LCD kijelzőre kiírjuk a választott nehézségi szintet
  614.   Serial.print("szint "); // Majd Ezeket kiírjuk a soros monitorra
  615.   Serial.println(szint);
  616.   delay(1000);            // Várakozás 1 másodpercig
  617.   lcd.setCursor(0,2);     // Az újabb szöveg kezdetének meghatározása
  618.   lcd.print("Haj");       // "Hajók száma: (1-4): " szöveg kiírása
  619.   lcd.write(3);           // Az ó betű, mint egyedileg definiált karakter
  620.   lcd.print("k sz");
  621.   lcd.write(1);           // Az á betű, mint egyedileg definiált karakter
  622.   lcd.print("ma");
  623.   lcd.setCursor(0,3);
  624.   lcd.print("(1-4): ");
  625.   while (GOMB!=1 and GOMB!=2 and GOMB!=3 and GOMB!=4)     // Az 1,2,3,4-es gombok valamelyikének a megnyomására való várakozás
  626.   {
  627.     gombnyomas();     // A megnyomott gomb lekérdezése, ha volt egyáltalán
  628.   }
  629.   hajokszama=GOMB;    // A megnyomott gomb értéke lesz a hajók száma
  630.   GOMB=0;
  631.   Serial.print("hajo ");    // A soros monitorra kiírjuk ezt is
  632.   Serial.println(hajokszama);
  633.   lcd.print(hajokszama);    // Majd Az LCD kijelzőre is
  634.   melyseg=random(1,4);      // A tengeralattjáró mélységének 1-3 közötti értékének véletlenszerű beállítása
  635.   hajocimke:                // Ezt a sort meglelöljük egy címkével, hogy szükség esetén vissza tudjunk ide térni
  636.   hajok[5][1]=random(1,meret);   // Tengeralattjáró X pozíciója
  637.   hajok[5][2]=random(1,meret);   // Tengeralattjáró Y pozíciója
  638.   Serial.print("Generált új pozíció: ");    // A tengeralattjáró pozícióját kiírjuk a soros monitorra
  639.   Serial.print(hajok[5][1]);
  640.   Serial.print("-");
  641.   Serial.println(hajok[5][2]);
  642.   if (hajok[5][1]<=9 or hajok[5][2]<=9) {   // Ellenőrizzük, hogy a tengeralattjáró pozíciója nincs-e a bal alsó 10*10-es négyzetben
  643.     goto hajocimke;                         // Ha igen, akkor új koordinátákat generálunk, mindaddig, amíg a fenti feltétel nem teljesül
  644.   }
  645.  
  646.   hajok[5][3]=random(1,9);   // Tengeralattjáró haladási iránya, 8 irány van összesen
  647.  
  648. //  hajok[5][1]=2;   // Tengeralattjáró X pozíciója
  649. //  hajok[5][2]=2;   // Tengeralattjáró Y pozíciója
  650. //  hajok[5][3]=7;   // Tengeralattjáró haladási iránya
  651.  
  652.   if (hajok[5][3]==5) {   // Ha 5 az irány, akkor az utolsó, a 9-es irány lesz helyette, hogy mozogjon, mivel az 5-ös irány a nem mozgás
  653.     hajok[5][3]=9;
  654.   }
  655.   if (szint==1) {    // A 1-es nehézségi szinten nem mozog a tengeralattjáró
  656.     hajok[5][3]=5;
  657.   }
  658.   if (szint==2) {    // A 2-es nehézségi szinten csak bal-jobb vagy le-fel irányban mozog a tengeralattjáró
  659.     hajok[5][3]=random(1,5)*2;  // Ez 4 irány, a 2,4,6,8, amik páros számok, ezért megszorozzuk a generált számot 2-vel, hogy megkapjuk az első 4 páros számot
  660.   }
  661.   Serial.print("Melyseg, irany: ");
  662.   Serial.print(melyseg);
  663.   Serial.print(" - ");
  664.   Serial.println(hajok[5][3]);
  665.   hajok[1][1]=5;    // A játékos által irányított hajók kezdő pozícióinak megadása
  666.   hajok[1][2]=0;
  667.   hajok[2][1]=10;
  668.   hajok[2][2]=0;
  669.   hajok[3][1]=0;
  670.   hajok[3][2]=5;
  671.   hajok[4][1]=0;
  672.   hajok[4][2]=10;
  673.   for (byte i=1; i<=4 ; i++){   // Kezdetben minden hajó áll, azaz az irány értéke 5
  674.     hajok[i][3]=5;
  675.   }
  676.   fut=1;    // A főprogramban jelezzük, hogy indulhat a játék
  677.  
  678.   delay(1000);    // Még várunk 1 másodpercet
  679. }
  680.  
  681. void gombnyomas()   // A 4*4-es nyomógomb mátrix gombjainak lekérdezése
  682. {
  683.   GOMB=0;           // A kimeneti változó törlése
  684.   pinMode(5,OUTPUT);    // A nyomógombmátrix első sorára csatlakozó port kimenetként való beállítása
  685.   digitalWrite(5,LOW);  // És alacsony szintre húzása
  686.   if (digitalRead(6)==0) {  // Vizsgálat, hogy az első sorban első oszlopában lett-e megnyomva gomb. Nulla jelszintet vizsgálunk, mivel a kivezetésre kapcsolt jel alacsony logikai szintű.
  687.       GOMB=1;               // Ha igen, akkor értéket adunk neki
  688.   }
  689.   if (digitalRead(7)==0) {  // A második oszlopban található gomb. Ezeken gombnyomás nélkül magas szint található, mivel a kezdeti beállításoknál bekapcsoltuk a felhúzó ellenállást.
  690.       GOMB=2;
  691.   }
  692.   if (digitalRead(8)==0) {  // A harmadik oszlopban található gomb
  693.       GOMB=3;
  694.   }
  695.   if (digitalRead(9)==0) {  // A negyedik oszlopban található gomb
  696.       GOMB=13;
  697.   }
  698.   pinMode(5,INPUT);         // Az első sorra csatlakozó kivezetést visszaállítjuk bemenetre, hogy úgynevezett nagyimpedanciás állapotba kerüljön.
  699.   pinMode(4,OUTPUT);        // A második sorra csatlakozó portot állítjuk kimenetként
  700.   digitalWrite(4,LOW);      // Majd alacsony szintet állítunk be rajta
  701.   if (digitalRead(6)==0) {  // A korábban leírtaknek megfelelő a további működés
  702.       GOMB=4;
  703.   }
  704.   if (digitalRead(7)==0) {
  705.       GOMB=5;
  706.   }
  707.   if (digitalRead(8)==0) {
  708.       GOMB=6;
  709.   }
  710.   if (digitalRead(9)==0) {
  711.       GOMB=14;
  712.   }
  713.   pinMode(4,INPUT);
  714.   pinMode(3,OUTPUT);
  715.   digitalWrite(3,LOW);
  716.   if (digitalRead(6)==0) {
  717.       GOMB=7;
  718.   }
  719.   if (digitalRead(7)==0) {
  720.       GOMB=8;
  721.   }
  722.   if (digitalRead(8)==0) {
  723.       GOMB=9;
  724.   }
  725.   if (digitalRead(9)==0) {
  726.       GOMB=15;
  727.   }
  728.   pinMode(3,INPUT);
  729.   pinMode(2,OUTPUT);
  730.   digitalWrite(2,LOW);
  731.   if (digitalRead(6)==0) {
  732.       GOMB=11;
  733.   }
  734.   if (digitalRead(7)==0) {
  735.       GOMB=10;
  736.   }
  737.   if (digitalRead(8)==0) {
  738.       GOMB=12;
  739.   }
  740.   if (digitalRead(9)==0) {
  741.       GOMB=16;
  742.   }
  743.   pinMode(2,INPUT);
  744. }  // gombnyomás() függvény vége
  745.  
  746. void tavol(byte hajo)   // A tengeralattjáró és a hajo változóban megadott számú hajó távolságát számoló függvény
  747. {
  748.   int x,y;    // Csak ebben a függvényben érvényes változók
  749.   x=hajok[hajo][1]-hajok[5][1];   // A két vizsgálni kívánt objektum X koordinátájának különbsége. Az előjelnek nincs jelentősége. mivel később négyzetre emeljük.
  750.   y=hajok[hajo][2]-hajok[5][2];   // A két vizsgálni kívánt objektum Y koordinátájának különbsége
  751.   x=x*x;    // A számolást Pitagorasz tételével (a2+b2=c2) oldjuk meg
  752.   y=y*y;    // Ezért a két koordináta különbségeit négyzetre emeljük
  753.   lcd.setCursor(0,3);   // Az LCD kijelzőn beállítjuk a kiírandó szám pozícióját
  754.   lcd.print("T:");      // Majd "T: "-vel jelezzük, mint távolság
  755.   tavolsage=tavolsag;   // Eltároljuk a korábban számított értéket
  756.   tavolsag=sqrt(x+y);   // Kiszámoljuk a távolságot úgy, hogy a különségek négyzetének összegéből négyzetgyököt vonunk.
  757.   lcd.print(tavolsag);  // Majd kiírjuk a kapott értéket a kijelzőre.
  758.   lcd.print(" ");       // Kiírunk egy szóközt, hogy ha a korábbi érték 2 digites volt (pl. 10), akkor ne maradjon a kijelzőn a második digit (egy nulla)
  759. }  // tavol() függvény vége
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement