[SYSTEM] Dynamic Group System

Thảo luận trong 'World Editor' bắt đầu bởi GrudgeBoy, 23/1/12.

  1. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    DYNAMIC GROUP SYSTEM version 1.0 - [1.24e] ​
    Convert from Unit-Group To Unit-Aray​

    đối với những ai yêu thích jass và vjass trong việc thiết kế custom map. Hẳn các bạn ai cũng biết kiểu dữ liệu group trong jass.

    group là kiểu dữ liệu khối chứa thông tin của 1 nhóm các unit có cùng điều kiện ( boolexpr ) hay không điều kiện.

    Nhưng để thao tác với group một cách dễ dàng và tùy biến thì rất khó bởi :
    - Khi pick each unit ta buộc phải sử dụng các callback function mà không được phép thêm tham số vào các hàm này. Điều này gây ra khó khăn, nhất là khi thiết kế spells, nếu làm việc với group thì không thể MUI hoàn toàn vì phải đụng chạm đến các biến globals
    - Khi muốn pick random 1 unit bất kì ta cũng phải sử dụng hàm BJ của bllizard rất dài dòng và rất dễ gây ra leaks

    Dynamic Group System ra đời nhằm mục đích khắc phục các điểm yếu trên và bảo đảm được rằng nó hoàn toàn có lợi trong việc thiết kế spells. Hơn nữa trong thuật toán chuyển đổi từ unit group sang unit array sẽ khiến chúng ta làm việc dễ dàng hơn, code ngắn hơn và không bao giờ gây ra leaks. Phần hướng dẫn cụ thể và cách sử dụng các functions, methods mình đã trình bày rất rõ ràng ngay trong trigger trong attached file bên dưới.
    'Dynamic Group System'
    - created by Kr.Linh - Vietnam
    - version 1.0 [1.24e+]
    - 2012
    - credit : KrCoder@yahoo.com
     

    Các file đính kèm:

    Chỉnh sửa cuối: 23/1/12
  2. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    - không có tham số có khó khăn hay không thì có lẽ tùy vào người làm, và dùng tham số global ở trường hợp này không sao cả
    với người dùng vJass thì việc truyền tham số lại càng dễ, một struct có thể truyền nhiều tham số và chỉ cần qua một global integer.
    làm với group có thể MUI hay không là do người làm, và nói vậy thì không thể có local group?

    phần lớn thì:
    Mã:
    loop
         set p = FirstOfGroup(g)
         exitwhen p==null
         call GroupRemoveUnit(g,p)
         //... other actions with "p" (picked unit)
    endloop
    
    nên việc truyền tham số là không cần thiết.

    - không dài dòng và hàm của Blizzard KHÔNG leak, ngoài ra hàm lấy random unit là một BJ có ích

    p.s: Blizzard chứ không phải bllizard =))

    edit: theo như demo map thì chỉ có thể có 8 group kiểu này?
     
    Chỉnh sửa cuối: 23/1/12
  3. KuKulKan

    KuKulKan T.E.T.Я.I.S

    Tham gia ngày:
    2/8/09
    Bài viết:
    629
    Nơi ở:
    Quận Thủ Đức, Thành phố Hồ Chí Minh
    Thêm 1 system ra đời, maker nhẹ người đi được 1 tí ^^.

    Đã test và có 1 vài ý kiến thế này

    Khi pick each unit ta buộc phải sử dụng các callback function mà không được phép thêm tham số vào các hàm này. Điều này gây ra khó khăn, nhất là khi thiết kế spells, nếu làm việc với group thì không thể MUI hoàn toàn vì phải đụng chạm đến các biến globals

    Vậy các boolexpr để truyền vào cho các Method trong SYS đó thì sao nhỉ ?, giả sử có 1 điều kiện GetWidgetLife(target) >= 0.405, trong khi cũng không thể nào truyền tham số cho target được, vậy cũng phải dùng 1 temp Global, mà đã vậy thì callback ngại gì không dùng luôn nhỉ.

    Khi muốn pick random 1 unit bất kì ta cũng phải sử dụng hàm BJ của bllizard rất dài dòng và rất dễ gây ra leaks

    Chưa chắc à :D

    Còn vấn đề làm spell thì hiện hầu như mọi người đều dùng temp globals khi xử lí boolexpr với callback function, bạn nghi ngờ tính MUI của nó à, bạn yên tâm, nếu dùng đúng thì nó chỉ được dùng trong 1 lần xử lí duy nhất, vậy nên dù có cast spell nhanh cỡ nào, dùng Timer tốc độ cao, thì CPU của bạn cũng xử lí theo 1 trình tự, không có bị "xung đột" đâu ^^.
     
  4. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    có 1 điều mình mạn phép nói :|, khi cậu đã bỏ thời gian viết 1 system rồi tại sạo lại không làm sẵn một ví dụ trong đó ?
     
  5. zollback

    zollback Youtube Master Race

    Tham gia ngày:
    16/5/10
    Bài viết:
    88
    Ý tưởng không tồi đâu, từ lâu mình đã khó chịu với cái kiểu dùng callback vô tội vạ của war3, nhiều cái luôn làm nó phức tạp hơn rất nhiều mặc dù chả cần thiết, còn việc phải động đến global thì ko ý kiến... <- cái này vô hại.
    Xăm soi 1 hồi thì thấy code của bạn... khá đẹp :) API thì chưa có thời gian phân tích, hy vọng đều là O(1) :))
     
    Chỉnh sửa cuối: 24/1/12
  6. Dorae.Mun

    Dorae.Mun Mr & Ms Pac-Man

    Tham gia ngày:
    9/11/11
    Bài viết:
    243
    Nơi ở:
    Thế kỉ 22
  7. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    @dh_g : mình xin lỗi, mình đã định làm 1 ví dụ rồi, nhưng mấy ngày qua bị bệnh, hết làm nổi nên upload lên luôn với lại mình nghĩ là mình đã có giải thích cụ thể các hàm và công dụng của nó ngay trong trigger rồi, nếu biết sơ về vjass thì vẫn có thể hiểu mà
    @dorae.Mun : không phải đâu, cái groupUtils đó vẫn là sử dụng cho group bình thường, vẫn phải dùng callback mà pick every unit, random unit thì vẫn vậy...

    @All : 1 diều mình có thể khẳng định khi cho ra đời hệ thống này là, code sẽ ngắn gọn hơn nhiều ( ít nhất là không phải tạo thêm mớ hàm callback, vừa lộn xộn vừa làm code khó hiểu và sau này muốn update cũng...hơi mệt )
     
    Chỉnh sửa cuối: 24/1/12
  8. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    ủa sao không thấy ai comment nữa nhỉ? vậy làm sao mình biết để update hoặc lỗi gì để vá đây
     
  9. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    đây là box WE kiểu như chỉ về cách làm map hay gì thôi. và không phải là 1 box để post system như nước ngoài. vì vậy có số comment đó cũng gọi là nhiều lắm rồi :-j
     
  10. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Thích comment hả. Ờ này thì comment:

    Suggestion
    - nhưng do ko có demo sử dụng nên vẫn chưa thân thiện :-??

    API
    - Nice code but API is not... KickOutUnit ??? What about removeUnit ? GetFirstUnit? just firstUnit is enough for me
    - Cách đặt tên method theo kiểu viết hoa chữ cái đầu câu có thể khiến cậu khó nhìn và phân biệt method với function

    Algorithm
    - trước hết về cái group base của blizzard thì tớ ko chắc có chậm hơn unit array hay ko.... nhưng việc cậu phải convert qua lại giữa 2 cái này là chậm hơn chỉ group rồi.
    - Về cái dinamic thì tớ chưa thấy đâu vì sys này đòi hỏi phải config cái maxinstance để đạt hiệu quả tối đa về số lượng unit trong 1 cái dynamic group cũng như số lượng group. Thế sao cậu ko làm như thế này <<<<<
    - Cụ thể hơn về thuật toán cũng như cách giải bài toán trong sys của cậu là ở function KickOutUnit

    Đầu tiên .IsUnitExist(t) đã là loop tất cả cái group 1 lần rồi. Sau đó cậu vãn phải loop lại 1 lần nữa để tìm lại index của unit đó để mà set null
    Tại sao ko đơn giản là cuối cái function return false rồi nếu tìm gặp unit đó thì xử lý nó rồi return true như funciton IsUnitExist?
    PHP:
            loop
                exitwhen i 
    == scount
                
    if( .u[i] == then
                    set 
    .u[i] = null
                    set 
    .count = .count 1
                    
    if( <= .ctake then
                        set 
    .ctake = .ctake 1
                    
    endif
                    if( 
    != scount then
                        set j 
    i
                        loop
                            exitwhen j 
    == .count
                            set 
    .u[j] = .u[1]
                            
    set j 1
                        endloop
                        set 
    .u[scount 1] = null
                    
    endif
                    
    set i scount // this's safe
                
    endif
    Cái này là thuật toán dồn và cậu lại phải loop. Thế tại sao cậu ko làm như sau có phải là nhanh ko?
    set .u=.u[.count - 1]
    set .u[.count - 1] = null
    set .count = .count - 1
    ctake lúc này dù sao cũng ko có ảnh hưởng gì cả.

    - Còn cái Clear của cậu được chạy cả khi khởi tạo và khi destroy. Thế là thừa rồi. Vì nếu ko destroy thì thì creat sẽ ko đụng lại cái cũ của cậu mà nếu đã destroy thì lại chả clear rồi mà phải clear lại lúc create.

    Error:
    - cái này thì tớ mới chỉ coi code ( vì chỉ có mỗi code thôi ) thì dùng 1 cách normal nhất có thể thì ko có lỗi ...
    - Nhưng cái cách để lấy ra lần lượt các unit trong group của cậu có vấn đề.
    PHP:
    /*                       'example' : local unit u = null                                                                */
    /*                                   loop                                                                               */
    /*                                       set u = g.TakeUnit() <= unit u se mang lan luot gia tri cac unit trong DGS     */
    /*                                       exitwhen u == null <= khi di hêt tât ca các unit có trong DGS thì giá tri tra  */
    /*                                                             vê se bang null ( ta dùng cách này de kêt thúc loop )    */
    /*                                       <'do anything u want'>                                                         */
    /*                                                 :                                                                    */
    /*                                                 :                                                                    */
    /*                                       <'..................'>                                                         */
    /*                                   endloop
    Thử tưởng tượng nếu có 2 cái KickOutUnit trong vòng loop trên thì chắc chắn sẽ có 1 unit bị lấy lại 2 lần! Điều này hoàn toàn có thể xảy ra khi code spell AOE.
    Đây là do vấn đề ctake của cậu
    - Mà cậu nghĩ system của cậu thì ko leak ư. Hơi nhầm. Nếu cậu ko destroy hay clear thì ko chỉ là leak đâu mà sẽ có nảy sinh cả lỗi nữa cơ :-"

    Cuối cùng hi vọng cậu ko nghĩ rằng tớ chặt chém gì cậu. Thực ra tớ chém thật đấy nhưng mang tính góp ý thôi.

    @dh-g: Box này là box WE giúp thảo luận các vấn đề khi làm map. Post system thì có gì sai? Nói thế để dhg biết mà tránh vào spam thôi. Tớ mà là mod thì cậu ăn nhiều thẻ lắm rồi :))
     
    Chỉnh sửa cuối: 29/1/12
  11. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    việc pick unit thì vẫn phải qua group cũ rồi convert ra group này, rõ ràng là chậm hơn so với group thường, sử dụng với tần số cao thì... performance drop

    lúc pick unit vẫn phải truyền tham số với boolexpr thôi, nếu dùng system này mà không cần thì cho ví dụ cái, với: DGSEnumUnitsInRange(real x,real y,real range,boolexpr filter) chẳng hạn

    thật sự số lần tôi phải dùng callback (ví dụ: ForGroup chẳng hạn) đếm trên đầu ngón tay, ngoài ra dùng loop với FirstOfGroup cả.

    chém y vài lần là bị kêu "hận y thấu xương", sao mà dám chém nữa? =))
     
  12. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    em đâu có nói thế khi nào đâu :-ss, có vài khi "khi chém với bác doom" :|
     
  13. btvinh

    btvinh Donkey Kong

    Tham gia ngày:
    15/1/11
    Bài viết:
    343
    P/s: còn cả tui nữa mà dh-g mau wên wá vậy :-w
     

Chia sẻ trang này