Search code examples
swiftobjective-cnspredicategameplay-kit

Use NSPredicate with swift, but can not get the same result with code written by Objective-C


I wrote a piece of code with swift, but can not get the result expected. If you know the bug in the code, please help me, thank you very much in advance. This the code I wrote:

let assertingFactKey = "hunt" as NSString
//
let ruleSystem = GKRuleSystem()
let playerFar : NSPredicate = NSPredicate(format:"$distanceToPlayer.floatValue >= 10.0")
ruleSystem.add(GKRule(predicate: playerFar, assertingFact: assertingFactKey, grade: 1.0))
let playerNear = NSPredicate(format:"$distanceToPlayer.floatValue < 10.0")
ruleSystem.add(GKRule(predicate: playerNear, assertingFact: assertingFactKey, grade: 1.0))
        //
        for i in 1...30 {
            ruleSystem.state["distanceToPlayer"] = i
            ruleSystem.reset()
            ruleSystem.evaluate()
            let result = ruleSystem.grade(forFact:assertingFactKey) > 0.0
            if result {
                print ("**True : \(i)")
            } else {
                print ("**False")
            }
        }

The result is always to True.

I want to know the correct way to use GKRuleSystem in swift

The code with Objective-C:

   GKRuleSystem *ruleSystem = [[GKRuleSystem alloc] init];
   NSPredicate *playerFar = [NSPredicate predicateWithFormat:@"$distanceToPlayer.floatValue >= 10.0"];
   [ruleSystem addRule:[GKRule ruleWithPredicate:playerFar assertingFact:@"hunt" grade:1.0]];
   NSPredicate *playerNear = [NSPredicate predicateWithFormat:@"$distanceToPlayer.floatValue < 10.0"];
   [ruleSystem addRule:[GKRule ruleWithPredicate:playerNear retractingFact:@"hunt" grade:1.0]];
    
    for (NSUInteger i = 0; i<=30; i++) {
        ruleSystem.state[@"distanceToPlayer"] = @(i);
        [ruleSystem reset];
        [ruleSystem evaluate];
        BOOL result = ([ruleSystem gradeForFact:@"hunt"] > 0.0);
        if (result) {
            NSLog(@"true: %ld", i);
        } else {
            NSLog(@"false");
        }
    }

Solution

  • I gues there is a typo here. It was retractingFact in Objective-C and assertingFact in Swift.

    //Objc-C
    [ruleSystem addRule:[GKRule ruleWithPredicate:playerNear retractingFact:@"hunt" grade:1.0]];
    
    ///Swift
    ruleSystem.add(GKRule(predicate: playerNear, assertingFact: assertingFactKey, grade: 1.0))
    

    And you might consider changing to this rather than hard code in the format.

    let num = 10.0
    let playerFar = NSPredicate(format: "$distanceToPlayer.floatValue >= %f", num)