|
物品合成系统应该有很多人过了,这里只是想演示下hash表的用法。
利用hash表搜索合成公式。
[jass]
function GetHashTableValue takes integer key, integer ord returns integer
local integer index = ModuloInteger(key, 8191)
local integer inc = ModuloInteger(key, 8189) + 1
local integer step = 0
loop
exitwhen step > 8191
if udg_HashTableKey[index] == 0 then
return 0
elseif udg_HashTableKey[index] == key + 1000 then
if ord == 0 then
return udg_HashTableValue[index]
else
set ord = ord - 1
endif
elseif udg_HashTableKey[index] == key then
if ord == 0 then
return udg_HashTableValue[index]
else
return 0
endif
endif
set index = index + inc
if index >= 8191 then
set index = index - 8191
endif
set step = step + 1
endloop
return 0
endfunction
function SetHashTableValue takes integer key, integer value returns nothing
local integer index = ModuloInteger(key, 8191)
local integer inc = ModuloInteger(key, 8189) + 1
local integer step = 0
loop
exitwhen step > 8191
if udg_HashTableKey[index] == 0 then
set udg_HashTableKey[index] = key
set udg_HashTableValue[index] = value
return
elseif udg_HashTableKey[index] == key then
exitwhen udg_HashTableValue[index] == value
set udg_HashTableKey[index] = key + 1000
elseif udg_HashTableKey[index] == key + 1000 then
exitwhen udg_HashTableValue[index] == value
endif
set index = index + inc
if index >= 8191 then
set index = index - 8191
endif
set step = step + 1
endloop
endfunction
function AddComList6 takes integer itemA, integer itemB, integer itemC, integer itemD, integer itemE, integer itemF, integer itemG returns boolean
local integer count = 0
if udg_ComListCount > 1000 then
return false
endif
set udg_ComList[(udg_ComListCount-1)*8+1] = itemA
set udg_ComList[(udg_ComListCount-1)*8+2] = itemB
set udg_ComList[(udg_ComListCount-1)*8+3] = itemC
set udg_ComList[(udg_ComListCount-1)*8+4] = itemD
set udg_ComList[(udg_ComListCount-1)*8+5] = itemE
set udg_ComList[(udg_ComListCount-1)*8+6] = itemF
set udg_ComList[(udg_ComListCount-1)*8+7] = itemG
if itemA != 0 then
set count = count + 1
call SetHashTableValue(itemA, udg_ComListCount)
endif
if itemB != 0 then
set count = count + 1
call SetHashTableValue(itemB, udg_ComListCount)
endif
if itemC != 0 then
set count = count + 1
call SetHashTableValue(itemC, udg_ComListCount)
endif
if itemD != 0 then
set count = count + 1
call SetHashTableValue(itemD, udg_ComListCount)
endif
if itemE != 0 then
set count = count + 1
call SetHashTableValue(itemE, udg_ComListCount)
endif
if itemA != 0 then
set count = count + 1
call SetHashTableValue(itemA, udg_ComListCount)
endif
if itemF != 0 then
set count = count + 1
call SetHashTableValue(itemF, udg_ComListCount)
endif
if count == 0 then
return false
endif
set udg_ComListCount = udg_ComListCount + 1
return true
endfunction
function AddComList2 takes integer itemA, integer itemB, integer itemG returns boolean
return AddComList6(itemA, itemB, 0, 0, 0, 0, itemG)
endfunction
function AddComList3 takes integer itemA, integer itemB, integer itemC, integer itemG returns boolean
return AddComList6(itemA, itemB, itemC, 0, 0, 0, itemG)
endfunction
function AddComList4 takes integer itemA, integer itemB, integer itemC, integer itemD, integer itemG returns boolean
return AddComList6(itemA, itemB, itemC, itemD, 0, 0, itemG)
endfunction
function AddComList5 takes integer itemA, integer itemB, integer itemC, integer itemD, integer itemE, integer itemG returns boolean
return AddComList6(itemA, itemB, itemC, itemD, itemE, 0, itemG)
endfunction
function GetComListValue takes integer ord, integer index returns integer
if ord >= 1000 then
return 0
endif
return udg_ComList[8*(ord-1)+index]
endfunction
function ComItem takes unit u, integer itemid returns nothing
local integer ord = 0
local integer i
local integer j
local integer id
local integer listindex
local integer array items
local boolean array bools
set i = 0
loop
set items = GetItemTypeId(UnitItemInSlot(u, i))
set bools = false
set i = i + 1
exitwhen i >= 6
endloop
call BJDebugMsg("物品拿起:"+I2S(itemid))
loop
set listindex = GetHashTableValue(itemid, ord)
call BJDebugMsg("listindex:"+I2S(listindex))
exitwhen listindex == 0 or ord >= 8191
set i = 1
loop
exitwhen i > 6
set id = GetComListValue(listindex, i)
if id != 0 then
set j = 0
loop
if items[j] == id and bools[j] == false then
set bools[j] = true
exitwhen true
endif
set j = j + 1
exitwhen j >= 6
endloop
exitwhen j == 6
endif
set i = i + 1
endloop
if i == 7 then
set i = 0
loop
if bools == true then
call RemoveItem(UnitItemInSlot(u, i))
endif
set i = i + 1
exitwhen i >= 6
endloop
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl", u, "origin"))
call UnitAddItemById(u, GetComListValue(listindex, 7))
return
endif
set i = 0
loop
set bools = false
set i = i + 1
exitwhen i >= 6
endloop
set ord = ord + 1
endloop
endfunction
function InitComList takes nothing returns nothing
local integer i = 0
loop
exitwhen i > 8191
set udg_HashTableKey = 0
set i = i + 1
endloop
set udg_ComListCount = 1
call AddComList2('I000', 'I000', 'I001')
call AddComList2('I001', 'I001', 'I002')
call AddComList2('I002', 'I002', 'I003')
call AddComList3('I002', 'I003', 'I004', 'I008')
call AddComList3('I002', 'I003', 'I005', 'I007')
call AddComList3('I002', 'I003', 'I006', 'I009')
endfunction
[/jass] |
|