Найти в Дзене
ZDG

Как я учился программировать: Маленькие лайфхаки

Предыдущие части: Моя первая игра, Трудности и озарения

У тех, кто учится программировать, часто возникает специфическое поражение состояние мозга. Оно заключается в том, что узнав какой-нибудь приём программирования, новичок переключает на него все свои мысли, и пытается применять его для решения любых задач.

Давайте посмотрим на оператор if, без которого программирование было бы затруднено. Это условие "если... то". Сама концепция вполне понятна. Ведь мы в реальной жизни постоянно применяем условия:

– Купи булку хлеба в магазине. Если там будут яйца, то купи десяток.

Как только мы постигаем, что в языке программирования есть условия, мы начинаем строить программу, основываясь на условиях, так же, как если бы ходили за хлебом в магазин. Но некоторые так увлекаются, что начинают писать такой код:

если a == 1, то b = 1;
если a == 2, то b = 2;
если a == 3, то b = 3;
...

Если посмотреть на него формально, то всё правильно. Это условия, которые определяют значение переменной b в зависимости от значения переменной a. Но если посмотреть на саму зависимость (что многие или не понимают, или забывают сделать), то выяснится, что она очень простая:

b = a

И не нужно для этого проверять никакие условия.

Если вам кажется, что вышеприведённый пример слишком тупой, то во-первых, это реальный (и не единственный) пример из реальной жизни, а во-вторых, можем попробовать менее явно:

если a == 1, то b = 2;
если a == 2, то b = 4;
если a == 3, то b = 8;
...

Теперь уже нельзя сказать, что b = a, но по сути ничего не изменилось:

b = 2 ^ a

или:

b = 1 << a

Материал по теме: Битовые операции

Всё ещё слишком тупо? Хорошо, попробуем так:

если a == 1, то b = 'A';
если a == 2, то b = 'B';
если a == 3, то b = 'C';
...

Может, сейчас уже оправданно применять условие? Всё ещё нет:

b = chr(ord('A') + a - 1)

В общем, какая главная ошибка во всех этих примерах? Да, вроде бы есть условная зависимость между двумя значениями, и раз она условная, значит надо применять условия. Это самое первое, что приходит в голову. Но если эта зависимость не случайная, а вычисляемая, то её разумнее будет вычислить.

Наконец, более сложный пример:

if (a == 0) b = 'Hello';
if (a == 1) b = 'World';
if (a == 2) b = 'banana';

Как тебе такое, Илон Маск Ну здесь-то точно нет зависимости между словами и цифрами? Да, её нет. Значит, использовать условия в данном случае целесообразно? Да, возможно так. Но можно обойтись и без них:

words = ['Hello', 'World', 'banana'];
b = words[a];

Посмотрим на другие примеры.

Предположим, у нас есть некая переменная, которая должна принимать два состояния: 0 и 1. То есть это переключатель. Как он работает? Если переключатель в состоянии 1, то он переходит в состояние 0. Если он в состоянии 0, то переходит в состояние 1.

Здесь, как видим, присутствуют слова "если", а значит вполне очевидно, что нужно использовать условие:

если a == 0, то a = 1, иначе a = 0

Можно? Можно. Но что, если мы напишем так:

a = 1 - a

Получится то же самое. Если a = 1, то 1 - a = 0. Если a = 0, то 1 - a = 1. Мы реализовали логику переключателя, которая описывается словами "если", но при этом мы не использовали условия. Состояние мозга, которое видит "если" и применяет условия, разорвалось. Оказывается, можно было и по-другому.

Ну а если нужно менять не 0 и 1, а любые 2 числа, например, 31 и 85?

a = 31 + 85 - a

Проверим? Если a = 31, то 31 + 85 - 31 = 85. Если a = 85, то 31 + 85 - 85 = 31.

Наконец, ещё один пример.

Допустим, у вас есть некий счётчик, который должен обнулиться после достижения определённого значения. Скажем, если он больше 99, то должен стать 0. Опять "если"?

если a > 99, то a = 0

В данном случае альтернативой условию станет математическая операция взятия остатка от деления на 100. Остаток от деления на 100 всегда будет равен 0..99, что и требуется:

a = a mod 100

Если же ваш счётчик досчитывает до таких значений, как 4, 8, 16, 32, 64 и т.д., то есть степеней двойки, то его обнуление можно более эффективно сделать через битовую маску. Например, обнуление счётчика при достижении 256:

a = a & 255

Степени двойки очень часто используются в играх, поэтому данный сценарий весьма вероятен.

Напоследок хочу сказать, что избавившись от одной зависимости (то есть безудержного употребления условий), можно приобрести другую: стараться избавиться от условий во что бы то ни стало. Не стоит этого делать. Где-то условия могут быть быстрее, понятнее, нагляднее, где-то нет. Просто держите глаза открытыми.