Тип integer

Добавлен , опубликован
Содержание:

Предисловие - для кого эта статья

Статья носит скорее более теоретический характер, хотя и дает достаточно пищи для размышлений о том, как код можно сделать намного проще и качественней. Предполагается что читатель достаточно хорошо знает JASS.

Теория

Тип integer в Jass это long signed int (в C) или попросту DWORD, это значит что он имеет 32 бита: 31 бит что бы обозначить само число и один знаковый бит. В JASS коде он может быть представлен в 8 (восьмеричная или octimal), 10 (десятеричная или decimal, самая привычная для большинства людей), 16 (шестнадцатеричная или hexadecimal) и 256(ASCII) нотации (системе счисления).
Чем одна система отличается от другой? (если Вы знакомы с этими понятиями можете пропустить этот абзац) В десятеричной системе переход в следующий разряд происходит когда число достигает 10 (9+1=10). Точно также и в других системах счисления: в восьмеричной системе 7+1=10 (причем 10 в ней реально равно 8 в десятеричной системе). В шестнадцатеричной системе что бы обозначить цифры (не путайте число и цифру, цифра - обозначение числа, поэтому разные цифры - в разных нотациях могут указывать на одно число), так вот, что бы обозначить в шестнадцатеричной системе цифру больше 9 мы будем использовать первые буквы английского алфавита: A=10, B=11, ... F=15. С 256 системой счисления дело обстоит также, ниже я выложу таблицу символов и значений (взято из WEU документации):
Хорошо, теперь вернемся к JASS. Что бы написать цифру в восьмеричной системе счисления мы должны приставить к ней 0
local integer i=012 // 10 в десятеричной си
Цифры без префиксов считаются десятичными, hex обозначается через 0x
local integer i=0x0f // 15 в десятеричной си
Ещё шестнадцатеричные могут обозначаться через 0X и $ (знак доллара) - прим. ScorpioT1000
256 цифры указываются обрамленными в апострофы
local integer i='A' // 65 в десятеричной си
Если Вы хотите перевести цифру в другую си - используйте WinCalc (есть такая программа в меню "пуск") переставленный в инженерный вид. Перевод числа из ASCII делается тоже достаточно просто: переведите каждый чар (ну т.е. символ) в hex, и вы получите 16ричное число. К примеру: 'A0a1', 'A' = 0x41, '0' = 0x30, 'a' = 0x61, '1' = 0x31, 'A0a1' равно 0x41306131 или 1093689649.
Помните, что большинство равкодов (кроме lightning, ubersplat) в JASS обычные integer, поэтому с ними возможны любые математические действия, что и будет описано дальше.
В JASS невозможно указать integer в двоичной (binary) системе счисления, но она очень важна для понимания всего материала. Как Вы могли догадаться, в ней переход в следующий разряд происходит при достижение 2: 1bin+1bin == 10bin (2dec). Теперь вернемся к нашему 32 битному integer
0x 7       a       9      8      0      1       f      0
     0111 1010 1001 1000 0000 0001 1111 0000
Один разряд в двоичной системе называется бит, восемь разрядов или двух разрядное шестнадцатеричное число - байт.
Напомню, что первый бит числа - знаковый бит, и он определяет будет ли оно положительным (0) или отрицательным (1). Положительные числа идут от 0x00000000 (0dec) до 0x7fffffff (2147483647dec), отрицательные от 0xffffffff (-1dec) до 0x80000000 (-2147483648dec). Что бы изменить знак числа надо инвертировать (где было 1 написать 0, где был 0 написать один) все биты числа и потом к нему прибавить 1.
  // в примере я использую однобайтовое число что бы было легче понять

  0000 0001 // +1dec
  1111 1110 // inv
  1111 1111 // -1dec
Теперь, хоть в JASS и нету побитовых операций над числами, можно имитировать их с помощью умножения и деления
   1000 1000 // *10bin  (<<)
1 0001 0000 // /100bin (>>)
   0000 0100
Биты, которые не помещаются в результате будут считаться потерянными. Также с помощью нескольких сдвигов мы сможем получить любые биты числа, имитировав тем самым логические побитовые операции, к примеру на нужно узнать значение 3 и 4 бита
  0110 **11**01 // *1000
  0**11**0 1000 // /100000
  0000 00**11**
Отлично! Но у нас могут возникнуть некоторые проблемы с знаковым битом при таких операциях
  0111 1100 // *1000
  1110 0000 // 1110 0000bin = -20dec

  1110 0000 // но мы можем изменить знаковый бит
 +1000 0000
  _____ _____
1 0110 0000
Так что мы смело можем прибавить 0x80000000, но есть еще более простой способ использовать бит "сепавратор", который всегда будет равен 0, и если он займет место знакового то результат все равно будет верным
  0vv! vvvv

  v - наши данные
  ! - бит сепаратор
Остается добавить, что деление или умножение на 10bin, 100bin, 1000bin это сдвиг влево или вправо на 1, 2, 3 бита (2^1 == 2 dec == 10 bin; 2^2 == 4 dec == 100 bin; 2^3 == 8 dec == 1000 bin; 2^n == сдвиг на n бит).
Хорошо, теперь попробуем применить это все на практике.

Практика

Тут я выложу несколько простых задач, в решение которых стоит применить полученные знания.

Золото за убийство

Мы должны добавить владельцу убившего юнита золота в зависимости от какой либо характеристики (к примеру у юнита есть способность или предмет +50% золота от крипов). На карте есть много всяких крипов, и от каждого должно даваться случайное количество золота, но пересчитанное по какой либо формуле. Функция, создающая texttag и добавляющая золота у нас есть, в нее просто надо сообщить его количество. Также сделайте два варианта, в первом 1 <=minGold <=maxGold <=80000000, во втором 1 <=minGold <=MaxGold <=75.

Добавление предмета

На карте существует ~60 типов различных героев. Когда какой либо герой достигнет 50 уровня надо создать уникальный для это типа героя артефакт возле него.

Данные юнита

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

Содержание
16
неплохо...с предметами особенно, интересно это может относится к обычным предметам?Видел в картах на какойто их сторон полоса с отрезками земли на которых различные предметы а на других нет...очевидно оно както выбирает ячейку и каким то образом дает предмет героям/ю.
38
Наконец ты соединил поток мыслей в что-то целое)
15
о! полезная статья, теперь про integer стало намного больше понятного и в тоже время еще осталось непонятного :) но со временем разберемся
14
Плохо одно - многие так и не поймут, как можно применять инты для хранения стольразной информации
2 комментария удалено
Чтобы оставить комментарий, пожалуйста, войдите на сайт.