Пятница, 03.05.2024, 08:47


Главная
Регистрация
Вход
Dota Allstars ✪ World of WarCraft Приветствую Вас Гость | RSS  
Меню сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Главная » Статьи » Dota Allstars » Полезные статьи

WarCraft 3: Тип integer
WarCraft 3: Тип 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 в десятеричной си
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 героев, и он либо темный, либо светлый. Возможное количество таких юнитов, которым надо сопоставить эти данные неограниченно. Также добавлю условие что нельзя использовать глобальные переменные, массивы или кешь.

Категория: Полезные статьи | Добавил: TRACTOR (03.05.2012)
Просмотров: 2428 | Рейтинг: 0.0/0
Вход на сайт

Поиск

Copyright MyCorp © 2024Сделать бесплатный сайт с uCoz