• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Boolean Expression

Status
Not open for further replies.
Level 31
Joined
Jul 10, 2007
Messages
6,306
Yes, this is purely test code. I got it working last night, but I don't recommend it's use ; P. The code is hella ugly right now, but yea, it's awesome! : D

Run it in a map with ErrorMessage and List to see it in action. It will print out the trees and so on. Those trees are the boolean expressions.

You can register/unregister stuff to them.

Anyways, I'm hella tired now, so going to sleep

JASS:
library BooleanExpression /* v1.0.0.0
************************************************************************************
*
*   */ uses /*
*   
*       */ ErrorMessage         /*          hiveworkshop.com/forums/submissions-414/snippet-error-message-239210/
*       */ List                 /*          hiveworkshop.com/forums/submissions-414/snippet-list-239400/
*
************************************************************************************/
    private keyword ListExpression
    private keyword NodeExpression
    
    scope NodeExpressionScope
        private struct Node extends array
            thistype root
            
            thistype left
            thistype right
            
            thistype next
            thistype prev
            
            boolexpr expression
            
            implement Alloc
            
            static method create takes nothing returns thistype
                return allocate()
            endmethod
            
            private method destroy takes nothing returns nothing
                if (left == 0) then
                    call DestroyBoolExpr(expression)
                    set expression = null
                    
                    set prev = 0
                    set next = 0
                else
                    set left = 0
                    set right = 0
                endif
                
                set root = 0
                
                call deallocate()
            endmethod
            
            method destroySub takes nothing returns nothing
                if (left == 0) then
                    call DestroyBoolExpr(expression)
                    set expression = null
                    
                    set prev = 0
                    set next = 0
                else
                    call left.destroySub()
                    call right.destroySub()
                    
                    set left = 0
                    set right = 0
                endif
                
                set root = 0
                
                call deallocate()
            endmethod
            
            private method replaceRootChild takes thistype newChild returns nothing
                set newChild.root = root
                
                if (root != 0) then
                    if (this == root.left) then
                        set root.left = newChild
                    else
                        set root.right = newChild
                    endif
                endif
            endmethod
            
            static method join takes Node left, Node right returns Node
                local Node this = Node.create()
                
                set this.left = left
                set this.right = right
                set left.root = this
                set right.root = this
                
                set expression = Or(left.expression, right.expression)
                
                if (left.left != 0) then
                    loop
                        exitwhen left.right == 0
                        set left = left.right
                    endloop
                    loop
                        exitwhen right.left == 0
                        set right = right.left
                    endloop
                endif
                
                return this
            endmethod
            
            static method listJoin takes Node prev, Node next returns nothing
                set prev.next = next
                set next.prev = prev
            endmethod
            
            method splitLeft takes nothing returns Node
                local thistype left = this.left
                
                set right.root = 0
                set left.root = 0
                
                call destroy()
                
                return left
            endmethod
            
            /*
            *   Returns the malformed Tree or 0
            */
            method remove takes nothing returns Node
                local thistype node = next
                local thistype replacer
                local thistype lastNode = 0
                local thistype nextRoot = node.root
                local thistype currentRoot = this.root
                local boolean right = currentRoot.right == this
                
                //call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(
            
                loop
                    exitwhen node == 0
                    set lastNode = node
                    
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(node.prev) + "->" + I2S(node))
                    
                    set node.root = currentRoot
                
                    if (currentRoot != 0) then
                        if (right) then
                            set currentRoot.right = node
                        else
                            set currentRoot.left = node
                        endif
                        
                        set right = not right
                    endif
                    
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(node) + ": " + NodeExpression(node.root).printTree(null))
                    
                    set replacer = node.root
                    loop
                        exitwhen replacer == 0
                        call DestroyBoolExpr(replacer.expression)
                        set replacer.expression = Or(replacer.left.expression, replacer.right.expression)
                        set replacer = replacer.root
                        exitwhen replacer == 0
                    endloop
                    
                    set currentRoot = nextRoot
                    set node = node.next
                    set nextRoot = node.root
                endloop
                
                if (prev == this) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"PREV ERROR")
                endif
                if (next == this) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"NEXT ERROR")
                endif
                
                if (prev != 0) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Delinking: " + I2S(prev)+" -> " + I2S(next))
                    set prev.next = next
                endif
                if (next != 0) then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Delinking: " + I2S(next)+" -> " + I2S(prev))
                    set next.prev = prev
                endif
                
                if (root.left == this) then
                    set root.left = 0
                elseif (root.right == this) then
                    set root.right = 0
                endif
                
                call destroy()
                
                loop
                    exitwhen lastNode.root == 0
                    set lastNode = lastNode.root
                endloop
                
                return lastNode
            endmethod
        endstruct
        
        struct NodeExpression extends array
            method operator root takes nothing returns thistype
                return Node(this).root
            endmethod
            method operator left takes nothing returns thistype
                return Node(this).left
            endmethod
            method operator right takes nothing returns thistype
                return Node(this).right
            endmethod
            method operator next takes nothing returns thistype
                return Node(this).next
            endmethod
            method operator prev takes nothing returns thistype
                return Node(this).prev
            endmethod
            method operator expression takes nothing returns boolexpr
                return Node(this).expression
            endmethod
            method operator expression= takes boolexpr expression returns nothing
                set Node(this).expression = expression
            endmethod
            static method create takes boolexpr expression returns thistype
                local Node node = Node.create()
                set node.expression = expression
                return node
            endmethod
            method destroySub takes nothing returns nothing
                call Node(this).destroySub()
            endmethod
            static method join takes Node left, Node right returns thistype
                return Node.join(left, right)
            endmethod
            static method listJoin takes Node prev, Node next returns nothing
                call Node.listJoin(prev, next)
            endmethod
            method splitLeft takes nothing returns thistype
                return Node(this).splitLeft()
            endmethod
            method remove takes nothing returns thistype
                return Node(this).remove()
            endmethod
            
            method toString takes nothing returns string
                local thistype i = this
                local string s = ""
                
                loop
                    exitwhen i.left == 0
                    set i = i.left
                endloop
                
                loop
                    exitwhen i.prev == 0
                    set i = i.prev
                endloop
                
                loop
                    if (s == "") then
                        set s = I2S(i)
                    else
                        set s = s + ", " + I2S(i)
                    endif
                    set i = i.next
                    exitwhen i == 0
                endloop
                
                return s
            endmethod
            
            method printTree takes string s returns string
                if (left == 0) then
                    return I2S(this)
                else
                    return "(" + I2S(this) + ")" + "[" + right.printTree(null) + ", " + left.printTree(null) + "]"
                endif
            endmethod
        endstruct
        
        scope ListExpressionScope
            private struct List_P extends array
                NodeExpression expression
                
                static thistype array expressionOwner
            
                implement List
            endstruct
            
            struct ListExpression extends array
                static method operator sentinel takes nothing returns integer
                    return List_P.sentinel
                endmethod
                method operator list takes nothing returns thistype
                    return List_P(this).list
                endmethod
                method operator first takes nothing returns thistype
                    return List_P(this).first
                endmethod
                method operator last takes nothing returns thistype
                    return List_P(this).last
                endmethod
                method operator next takes nothing returns thistype
                    return List_P(this).next
                endmethod
                method operator prev takes nothing returns thistype
                    return List_P(this).prev
                endmethod
                method operator expression takes nothing returns boolexpr
                    return List_P(this).first.expression.expression
                endmethod
                private method operator expression= takes boolexpr expression returns nothing
                    set List_P(this).first.expression.expression = expression
                endmethod
                
                private method clearExpressions takes nothing returns nothing
                    local thistype node = first
                    
                    loop
                        exitwhen node == 0
                        
                        call List_P(node).expression.destroySub()
                        
                        set node = node.next
                    endloop
                endmethod
                
                static method create takes nothing returns thistype
                    local thistype this = List_P.create()
                    
                    call List_P(this).enqueue()
                    
                    return this
                endmethod
                
                method destroy takes nothing returns nothing
                    call clearExpressions()
                    call List_P(this).destroy()
                endmethod
                
                method clear takes nothing returns nothing
                    call clearExpressions()
                    call List_P(this).clear()
                endmethod
                
                private method join takes NodeExpression expression returns nothing
                    local NodeExpression node
                
                    set this = first.next
                    
                    loop
                        exitwhen this == 0 or List_P(this).expression != 0
                        set this = next
                    endloop
                    
                    if (this == 0) then
                        return
                    endif
                    
                    set node = List_P(this).expression
                    
                    loop
                        exitwhen node.right == 0
                        set node = node.right
                    endloop
                    
                    call NodeExpression.listJoin(node, expression)
                endmethod
                
                method insert takes boolexpr expression returns thistype
                    local List_P node = first
                    local NodeExpression nodeExpression = NodeExpression.create(expression)
                    
                    if (node.expression == 0) then
                        set node.expression = nodeExpression
                        
                        call join(nodeExpression)
                    else
                        call NodeExpression.listJoin(node.expression, nodeExpression)
                        
                        set node.expression = NodeExpression.join(node.expression, nodeExpression)
                        loop
                            exitwhen node.next == 0 or node.next.expression == 0
                            
                            set node.next.expression = NodeExpression.join(node.next.expression, node.expression)
                            set node.expression = 0
                            
                            set node = node.next
                        endloop
                        
                        if (node.next == 0) then
                            set List_P(this).enqueue().expression = node.expression
                        else
                            set node.next.expression = node.expression
                        endif
                        
                        set node.expression = 0
                    endif
                    
                    set List_P.expressionOwner[node.next.expression] = node.next
                    
                    return nodeExpression
                endmethod
                
                method remove takes nothing returns nothing
                    local NodeExpression node = this
                
                    local NodeExpression root = this
                    local List_P listNode
                    
                    set root = this
                    loop
                        exitwhen root.root == 0
                        set root = root.root
                    endloop
                    
                    set listNode = List_P.expressionOwner[root]
                    set listNode.expression = 0
                    
                    set node = node.remove()
                    
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Got Node: " + I2S(node))
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"Got List Node: " + I2S(listNode))
                    
                    if (node == 0) then
                        set node = root
                    endif
                    
                    if (root != node) then
                        set listNode = List_P.expressionOwner[node]
                        set listNode.expression = 0
                    endif
                    
                    if (node.left == 0) then
                        return
                    endif
                    
                    loop
                        exitwhen node.left == 0 or node == 0
                        set root = node.right
                        set node = node.splitLeft()
                        set listNode = listNode.prev
                        set listNode.expression = node
                        set List_P.expressionOwner[node] = listNode
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"List_P.expressionOwner["+I2S(node)+"] = " + I2S(listNode))
                        set node = root
                    endloop
                    
                    if (node != 0) then
                        set listNode = listNode.prev
                        set listNode.expression = node
                        set List_P.expressionOwner[node] = listNode
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"List_P.expressionOwner["+I2S(node)+"] = " + I2S(listNode))
                    endif
                endmethod
                
                private static method run takes nothing returns nothing
                    local thistype this = create()
                    
                    local thistype n1 = insert(null)
                    local thistype n2 = insert(null)
                    local thistype n3 = insert(null)
                    local thistype n4 = insert(null)
                    local thistype n5 = insert(null)
                    local thistype n6 = insert(null)
                    local thistype n7 = insert(null)
                    local thistype n8 = insert(null)
                    local thistype n9 = insert(null)
                    local thistype n10 = insert(null)
                    local thistype n11 = insert(null)
                    local thistype n12 = insert(null)
                    local thistype n13 = insert(null)
                    local thistype n14 = insert(null)
                    local thistype n15 = insert(null)
                    local thistype n16 = insert(null)
                    
                    local List_P node = first
                    loop
                        loop
                            exitwhen node.expression != 0 or node == 0
                            set node = node.next
                        endloop
                        exitwhen node == 0
                        
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(node) + ": " + node.expression.printTree(null))
                        
                        set node = node.next
                    endloop
                    set node = first
                    loop
                        exitwhen node.expression != 0 or node == 0
                        set node = node.next
                    endloop
                    if (node != 0) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,node.expression.toString())
                    endif
                    
                    call n16.remove()
                    
                    set node = first
                    loop
                        loop
                            exitwhen node.expression != 0 or node == 0
                            set node = node.next
                        endloop
                        exitwhen node == 0
                        
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(node) + ": " + node.expression.printTree(null))
                        
                        set node = node.next
                    endloop
                    set node = first
                    loop
                        exitwhen node.expression != 0 or node == 0
                        set node = node.next
                    endloop
                    if (node != 0) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,node.expression.toString())
                    endif
                    
                    call n15.remove()
                    
                    set node = first
                    loop
                        loop
                            exitwhen node.expression != 0 or node == 0
                            set node = node.next
                        endloop
                        exitwhen node == 0
                        
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(node) + ": " + node.expression.printTree(null))
                        
                        set node = node.next
                    endloop
                    set node = first
                    loop
                        exitwhen node.expression != 0 or node == 0
                        set node = node.next
                    endloop
                    if (node != 0) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,node.expression.toString())
                    endif
                endmethod
                
                private static method onInit takes nothing returns nothing
                    call TimerStart(CreateTimer(), 0, false, function thistype.run)
                endmethod
            endstruct
        endscope
    endscope
endlibrary
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Just in case you don't know it.
If i remember correctly Or() and And() doesn't work like Condition() and Filter().
They create a new boolexpr each time they are called, no matter if the very same boolexpr is already created or not.

In other words, this should be true :

Or(Filter(function F1),Filter(function F2)) != Or(Filter(function F1),Filter(function F2))
 
Status
Not open for further replies.
Top