JavaRush /Java блогу /Random-KY /JavaRush боюнча "Оюндар" бөлүмү: Пайдалуу теория

JavaRush боюнча "Оюндар" бөлүмү: Пайдалуу теория

Группада жарыяланган
JavaRush программасынын "Оюндар" бөлүмүндө сиз популярдуу компьютердик оюндарды жазуу үчүн кызыктуу долбоорлорду таба аласыз. Сиз популярдуу "2048", "Сапер", "Жылан" жана башка оюндардын өз versionсын түзгүңүз келеби? Бул жөнөкөй. Биз оюн жазууну кадам-кадам процессине айландырдык. бөлүмӨзүңүздү оюнду иштеп чыгуучу катары сынап көрүү үчүн сиз өнүккөн программист болуунун кажети жок, бирок Java бorминин белгилүү бир топтому дагы эле талап кылынат. Бул жерден сиз оюндарды жазууда пайдалуу боло турган маалыматтарды таба аласыз .

1. Мурас

JavaRush оюн кыймылдаткычы менен иштөө мурасты колдонууну камтыйт. Бирок анын эмне экенин билбесеңчи? Бир жагынан, бул теманы түшүнүү керек: ал 11-деңгээлде изилденет . Башка жагынан алганда, кыймылдаткыч атайылап абдан жөнөкөй болуп иштелип чыккан, ошондуктан сиз мурас боюнча үстүртөн бorм менен ала аласыз. Демек, мурас деген эмне? Жөнөкөй сөз менен айтканда, мурас бул эки класстын ортосундагы мамиле. Алардын бири ата-эне, экинчиси бала (мураскор класс) болуп калат. Бул учурда, ата-энелер классы анын урпак класстары бар экенин билбеши мүмкүн. Ошол. ал мураскор класстардын болушунан эч кандай өзгөчө пайда алbyte. Бирок тукум куучулук класска көптөгөн артыкчылыктарды берет. Ал эми эң негизгиси, ата-эне классынын бардык өзгөрмөлөрү жана методдору бала класста пайда болот, ата-эне класстын codeу бала класска көчүрүлгөндөй. Бул толугу менен туура эмес, бирок мурастын жөнөкөйлөштүрүлгөн түшүнүү үчүн ал эмне кылат. Бул жерде мурасты жакшыраак түшүнүү үчүн кээ бир мисалдар келтирилген. 1-мисал: эң жөнөкөй мурас.
public class Родитель {

}
Child классы extends ачкыч сөзүн колдонуу менен Parent классынан мураска алат .
public class Потомок extends Родитель {

}
Мисал 2: Ата-эне класстын өзгөрмөлөрүн колдонуу.
public class Родитель {

   public int age;
   public String name;
}
Child классы Ата-эне классынын жашы жана аты өзгөрмөлөрүн анда жарыялангандай колдоно алат .
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Мисал 3: Ата-энелер классынын ыкмаларын колдонуу.
public class Родитель {

   public int age;
   public String name;

   public getName() {
      return name;
   }
}
Child классы Parent классынын өзгөрмөлөрүн жана ыкмаларын анда жарыялангандай колдоно алат. Бул мисалда биз getName () ыкмасын колдонуп жатабыз.
public class Потомок extends Родитель {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Компилятордун көз карашы боюнча Descendant классы ушундай көрүнөт:
public class Потомок extends Родитель {

   public int age; //  унаследованная переменная
   public String name; //  унаследованная переменная

   public getName() { //  унаследованный метод.
      return name;
  }
   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}

2. Методду жокко чыгаруу

Кээде биздин Descendant классыбызды бардык өзгөрмөлөр жана методдор менен бирге абдан пайдалуу Ата-эне классынан мурастап алган учурлар болот, бирок кээ бир методдор биз каалагандай иштебейт. Же такыр биз каалабагандай эмес. Бул кырдаалда эмне кылуу керек? Биз өзүбүзгө жакпаган ыкманы жокко чыгара алабыз. Бул абдан жөнөкөй жасалат: биздин Descendant классыбызда биз жөн гана Ата-эне классынын методу сыяктуу кол тамгасы (баш аты) менен методду жарыялайбыз жана ага codeубузду жазабыз. 1-мисал: Методду жокко чыгаруу.
public class Родитель {

   public String name;

   public void setName (String nameNew) {
       name = nameNew;
  }

   public getName() {
      return name;
  }
}
printInfo() методу "Лука, Жок!!!" деген сөз айкашын басып чыгарат.
public class Потомок extends Родитель {

   public void setName (String nameNew) {
       name = nameNew + ",No!!!";
  }

   public void printInfo() {

      setName("Luke");
      System.out.println( getName());
   }
}
Компилятордун көз карашы боюнча Descendant классы ушундай көрүнөт:
public Потомок extends Родитель {

   public String name; //  унаследованная переменная

   public void setName (String nameNew) { //  Переопределенный метод взамен унаследованного

       name = nameNew + ", No!!!";
   }
   public getName() { //  унаследованный метод.

      return name;
   }
   public void printInfo() {

     setName("Luke");
     System.out.println(getName());
   }
}
2-мисал: мурастын бир аз сыйкыры (жана ыкманы жокко чыгаруу).
public class Родитель {

   public getName() {
      return "Luke";
  }
   public void printInfo() {

     System.out.println(getName());
   }
}
public class Потомок extends Родитель {

   public getName() {
      return "I'm your father, Luke";
  }
}
Бул мисалда: эгерде метод printInfo(Ата-эне классынан) Descendant классында жокко чыгарылбаса, бул ыкма Descendant классынын an objectисинде чакырылганда, анын ыкмасы Ата-эне классы getName()эмес, деп аталат.getName()
Родитель parent = new Родитель ();
parent.printnInfo();
Бул code экранда "Лука" деген жазууну көрсөтөт .
Потомок child = new Потомок ();
child.printnInfo();
Бул code "Мен сенин атаңмын, Лука" деген жазууну көрсөтөт ; .
Компилятордун көз карашы боюнча Descendant классы ушундай көрүнөт:
public class Потомок extends Родитель {

   public getName() {
      return "I'm your father, Luke";
   }
   public void printInfo() {

     System.out.println(getName());
   }
}

3. Тизмелер

Эгерде сиз Тизмелер менен тааныша элек болсоңуз, бул жерде тез праймер. Сиз JavaRush курсунун 6-7-деңгээлдери боюнча толук маалыматты таба аласыз . Тизмелердин массивдер менен көп окшоштуктары бар:
  • белгилүү бир типтеги көптөгөн маалыматтарды сактай алат;
  • алардын индекси/саны боюнча элементтерди алууга мүмкүндүк берет;
  • элементтин индекстери 0дөн башталат.
Тизмелердин артыкчылыктары: массивдерден айырмаланып, тизмелер көлөмүн динамикалык түрдө өзгөртө алат. Тизме түзүлгөндөн кийин дароо 0 өлчөмүнө ээ болот. Тизмеге элементтерди кошкон сайын анын өлчөмү чоңоёт. Тизмени түзүүнүн мисалы:
ArrayList<String> myList = new ArrayList<String>(); // создание нового списка типа ArrayList
Бурчтуу кашаадагы маани тизме сактай турган маалыматтардын түрү. Бул жерде тизме менен иштөө үчүн кээ бир ыкмалары бар:
Code Код эмне кыларын кыскача баяндоо
ArrayList<String> list = new ArrayList<String>(); Саптардын жаңы тизмесин түзүү
list.add("name"); Тизменин аягына элемент кошуңуз
list.add(0, "name"); Тизменин башына элемент кошуңуз
String name = list.get(5); Индекс боюнча элементти алыңыз
list.set(5, "new name"); Элементти индекси боюнча өзгөртүү
int count = list.size(); Тизмедеги элементтердин санын алыңыз
list.remove(4); Тизмеден бир нерсени алып салуу
Бул макалалардан тизмелер жөнүндө көбүрөөк биле аласыз:
  1. ArrayList классы
  2. Сүрөттөгү жумушчу ArrayList
  3. ArrayListтен элементти алып салуу

4. Массивдер

матрица деген эмне? Матрица - бул маалыматтар менен толтурула турган тик бурчтуу tableдан башка эч нерсе эмес. Башкача айтканда, бул эки өлчөмдүү массив. Сиз билгендей, Javaдагы массивдер an object болуп саналат. Стандарттык бир өлчөмдүү массив түрү intтөмөнкүдөй көрүнөт:
int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Муну визуалдык түрдө элестетип көрөлү:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
Жогорку сап уячалардын даректерин көрсөтөт. Башкача айтканда, 67 санын алуу үчүн 6 индекси бар массив элементине кирүү керек:
int number = array[6];
Бул жерде баары абдан жөнөкөй. Эки өлчөмдүү массив – бул бир өлчөмдүү массивдердин массиви. Бул тууралуу биринчи жолу угуп жатсаңыз, токтоп, аны башыңызга элестетиңиз. Эки өлчөмдүү массив төмөнкүдөй көрүнөт:
0 Бир өлчөмдүү массив Бир өлчөмдүү массив
1 Бир өлчөмдүү массив
2 Бир өлчөмдүү массив
3 Бир өлчөмдүү массив
4 Бир өлчөмдүү массив
5 Бир өлчөмдүү массив
6 Бир өлчөмдүү массив
7 Бир өлчөмдүү массив
Коддо:
int [][] matrix = {
{65, 99, 87, 90, 156, 75, 98, 78}, {76, 15, 76, 91, 66, 90, 15, 77}, {65, 96, 17, 25, 36, 75, 54, 78}, {59, 45, 68, 14, 57, 1, 9, 63}, {81, 74, 47, 52, 42, 785, 56, 96}, {66, 74, 58, 16, 98, 140, 55, 77}, {120, 99, 13, 90, 78, 98, 14, 78}, {20, 18, 74, 91, 96, 104, 105, 77} }
0 0 1 2 3 4 5 6 7
65 99 87 90 156 75 98 78
1 0 1 2 3 4 5 6 7
76 15 76 91 66 90 15 77
2 0 1 2 3 4 5 6 7
65 96 17 25 36 75 54 78
3 0 1 2 3 4 5 6 7
59 45 68 14 57 1 9 63
4 0 1 2 3 4 5 6 7
81 74 47 52 42 785 56 96
5 0 1 2 3 4 5 6 7
66 74 58 16 98 140 55 77
6 0 1 2 3 4 5 6 7
120 99 13 90 78 98 14 78
7 0 1 2 3 4 5 6 7
20 18 74 91 96 104 105 77
47 маанисин алуу үчүн [4][2] дарегиндеги матрица элементине кирүү керек.
int number = matrix[4][2];
Эгер байкасаңыз, матрицанын координаттары классикалык тик бурчтуу координаттар системасынан (декарттык координаттар системасы) айырмаланат. Матрицага кирүүдө сиз адегенде y, андан кийин x белгилейсиз , ал эми математикада адегенде x(x, y) белгиленет. Сиз өзүңүзгө суроо берип жаткандырсыз: “Эмне үчүн фантазияңыздагы матрицаны тескери буруп, элементтерге кадимки жол менен (x, y) жетүүгө болбойт? Бул матрицанын мазмунун өзгөртпөйт». Ооба, эч нерсе өзгөрбөйт. Бирок программалоо дүйнөсүндө матрицаларга “адегенде у, андан кийин х” түрүндөгү кайрылуу салтка айланган. Муну кадимкидей эле кабыл алуу керек. Эми матрицаны кыймылдаткычыбызга проекциялоо жөнүндө сүйлөшөлү (класс Game). Белгилүү болгондой, кыймылдаткычта берилген координаттарда оюн талаасынын клеткаларын өзгөртүүчү көптөгөн ыкмалар бар. Мисалы, setCellValue(int x, int y, String value). Ал координаттары менен белгилүү бир уячаны (x, y) маанисине коет value. Сиз байкагандай, бул ыкма адегенде классикалык координаттар системасындагыдай так х алат. Калган кыймылдаткыч ыкмалары да ушундай эле иштейт. Оюндарды иштеп чыгууда көбүнчө экрандагы матрицанын абалын кайра чыгаруу зарылчылыгы пайда болот. Муну кантип кылуу керек? Биринчиден, циклде сиз матрицанын бардык элементтерин кайталашыңыз керек. Экинчиден, алардын ар бири үчүн INVERTED координаттары менен көрсөтүү ыкмасын чакырыңыз. Мисал:
private void drawScene() {
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            setCellValue(j, i, String.valueOf(matrix[i][j]));
        }
    }
}
Албетте, инversion эки багытта иштейт. Сиз (i, j) ыкмасына setCellValueөтө аласыз , бирок ошол эле учурда матрицадан [j][i] элементин алыңыз. Инversion бир аз кыйындай сезorши мүмкүн, бирок муну эстен чыгарбоо керек. Жана ар дайым, кандайдыр бир көйгөйлөр пайда болсо, анда ал калем менен кагаз алып, матрицаны чийип, ага кандай процесстер болуп жатканын кайра чыгаруу керек.

5. Кокус сандар

Кокус сандар генератору менен кантип иштөө керек? Класс Gameметодду аныктайт getRandomNumber(int). Капоттун астында ал Randomjava.util пакетинен классты колдонот, бирок бул кокус сандар генератору менен иштөө принцибин өзгөртпөйт. Аргумент катары getRandomNumber(int)бүтүн санды алат . Бул сан генератор кайтара ала турган жогорку чек болот. Төмөнкү чек 0 болуп саналат. Маанилүү! Генератор ЭЧ КАЧАН жогорку чек санын кайтарbyte. Мисалы, getRandomNumber(3)кокустан чалса, ал 0, 1, 2 кайтара алат. Көрүнүп тургандай, 3 кайтара алbyte. Генераторду мындай колдонуу абдан жөнөкөй, бирок көп учурларда абдан натыйжалуу. Сиз кандайдыр бир чектерде кокус санды алышыңыз керек: Сизге үч орундуу сан керек деп элестетиңиз (100..999). Белгилүү болгондой, кайтарылган минималдуу сан 0. Демек, ага 100 кошуу керек болот.Бирок бул учурда жогорку чектен ашпоого кам көрүү керек. Максималдуу кокустук маани катары 999ду алуу үчүн getRandomNumber(int)1000 аргументи менен методду чакырышыңыз керек. Бирок 100дүн кийинки кошулуусу жөнүндө эсибизде: бул жогорку чекти 100гө түшүрүү керек дегенди билдирет. Башкача айтканда, codeду алуу үчүн кокус үч орундуу сан төмөнкүдөй болот:
int number = 100 + getRandomNumber(900);
Бирок, мындай жол-жобосун жөнөкөйлөтүү үчүн, кыймылдаткыч getRandomNumber(int, int)биринчи аргумент катары кайтып минималдуу санын алат ыкмасын камсыз кылат. Бул ыкманы колдонуу менен, мурунку мисал кайра жазылышы мүмкүн:
int number = getRandomNumber(100, 1000);
Кокус сандар кокус массив элементин алуу үчүн колдонулушу мүмкүн:
String [] names = {"Andrey", "Валентин", "Сергей"};
String randomName = names[getRandomNumber(names.length)]
Белгилүү бир ыктымалдуулук менен белгилүү окуяларды козгоо. Адамдын таңы мүмкүн болгон сценарийлер боюнча башталат: Уктап калган – 50%; өз убагында туруу – 40%; Күтүлгөндөн бир саат эрте турду - 10%. Элестетиңиз, сиз адамдын таңкы эмуляторун жазып жатасыз. Сиз белгилүү бир ыктымалдуулук менен окуяларды козгошуңуз керек. Бул үчүн, дагы бир жолу, кокус сандар генераторун колдонуу керек. Ишке ашыруу ар кандай болушу мүмкүн, бирок эң жөнөкөй алгоритм төмөнкүдөй болушу керек:
  1. биз санды түзүү керек болгон чектерди белгилейбиз;
  2. кокус санды түзүү;
  3. Биз алынган санды иштетебиз.
Ошентип, бул учурда, чек 10 болот. Келгиле, методду чакырып getRandomNumber(10), ал бизге эмнени кайтара аларын талдап көрөлү. Ал 10 санды (0дөн 9га чейин) кайтара алат жана ар бири бирдей ыктымалдуулук менен - ​​10%. Эми биз мүмкүн болгон бардык натыйжаларды бириктирип, аларды биздин мүмкүн болгон окуялар менен дал келтиришибиз керек. Фантазияңызга жараша комбинациялар көп болушу мүмкүн, бирок эң айкын үндөр: “Эгер кокустук сан [0..4] ичинде жатса - “Уктап кетти” окуясын чакырыңыз, эгер сан [5..8] ичинде болсо. ] - "Убагында ойгон" жана эгер сан 9 болсо, анда "Мен күтүлгөндөн бир саат эрте турдум". Баары абдан жөнөкөй: [0..4] ичинде 5 сан бар, алардын ар бири 10% ыктымалдуулук менен кайтып келе алат, алар жалпысынан 50% түзөт; [5..8] ичинде 4 сан бар, ал эми 9 10% ыктымалдыгы менен чыккан жалгыз сан. Коддо бул акылдуу дизайн дагы жөнөкөй көрүнөт:
int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Проспал ");
} else if (randomNumber < 9) {
    System.out.println("Встал вовремя ");
} else {
    System.out.println("Встал на час раньше положенного ");
}
Жалпысынан алганда, кокус сандарды колдонуу үчүн көптөгөн варианттар болушу мүмкүн. Мунун баары сиздин фантазияңыздан гана көз каранды. Бирок алар бир нече жолу натыйжа алуу керек болсо, эң натыйжалуу колдонулат. Ошондо бул жыйынтык мурункусунан башкача болот. Албетте, кандайдыр бир ыктымалдуулук менен. Баары болду! Эгер сиз Оюндар бөлүмү жөнүндө көбүрөөк билгиңиз келсе, бул жерде жардам бере турган кээ бир пайдалуу documentтер бар:
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION