如何解决这个复杂的递归问题,金字塔积分系统

1 投票
2 回答
861 浏览
提问于 2025-04-15 13:06

我正在为一个ARG游戏编写一个像金字塔一样的积分系统,但遇到了一个问题。当玩家进入游戏时,他们会开始一个新的“金字塔”,但如果某个玩家使用了其他玩家的推荐码,他们就会成为这个玩家的“孩子”,然后积分会往上升。

这里的问题不是积分的计算,我已经在你们的帮助下搞定了,而是如果一个用户的积分超过了他们的父母,他们应该在金字塔中交换位置。也就是说,用户的父母会变成他们的孩子,反之亦然。

我现在的Python代码运行得不太对,我也不知道为什么。

def verify_parents(user):
    """
    This is a recursive function that checks to see if any of the parents
    should bump up because they got more points than its parent.

    """
    from rottenetter.accounts.models import get_score

    try:
        parent = user.parent
    except:
        return False
    else:
        # If this players score is greater than its parent
        if get_score(user) > get_score(parent):
            # change parent
            user.parent = parent.parent
            user.save()

            # change parent's parent to current profile
            parent.parent = user
            parent.save()
        verify_parents(parent)

在我看来,这个逻辑应该是这样的:如果一个用户有父母,就检查一下这个用户的积分是否超过了他们的父母。如果超过了,就把这个用户的父母设置为他们父母的父母,然后把父母的父母设置为这个用户,这样他们就交换了位置。接着,再用父母作为目标调用同样的函数,这样可以检查父母的情况,然后继续往上检查。

但这并不总是有效,有时候人们并没有被正确地调整到合适的位置。

编辑:

当一个用户在金字塔中上升或下降一步时,他们的孩子会和他们一起移动,这样他们仍然和同一个父母有关联,除非他们也获得了更多积分并向上移动。所以其实不需要对父母做什么,对吧?

2 个回答

1

[根据你的评论进行的修正]

如果“移动”的结果并不打算改变树的结构(也就是说,当X成为它原来的父亲Y的父亲时,它把所有的孩子都给了Y),那么最简单的方法可能是把“金字塔节点”和“用户”的概念分开,形成一对一的关系。这样,如果‘交换’操作不改变树的结构,你只需要交换‘nodeA <=> userA’和‘nodeB <=> userB’之间的映射关系,让它们变成‘nodeA <=> userB’和‘nodeB <=> userA’。

由于树的结构没有改变,这样就自动确保了孩子们有正确的父亲。当然,缺点是你不能直接从用户记录中找到‘父亲’,需要通过节点来查找。

没有代码,因为我不太清楚你的应用细节——但希望如果这个方法适用,转成代码应该会很简单。

1

我觉得你的问题可能是因为你没有把profile的孩子设置成以parent作为他们的父母,除非在你的系统中,孩子不能同时也是父母(我认为不是这种情况)。

另外(或者可能和前面提到的同时进行),你可能想直接用parent = profile.parent,而不是parent = profile.parent.get_profile()

补充一下:我看到你确实改成了第二种形式,不过是用user代替了profile

总之,既然每个用户可以有多个孩子(就像你在其他回答的评论中提到的),你可能想在每个用户的对象中跟踪他们的孩子。可以这样做……

parent = user.parent
user.parent = parent.parent
parent.parent = user

children = user.children

for child in children:
    child.parent = parent

user.children = parent.children

for child in user.children:
    if child is user:
        child = parent

    child.parent = user

parent.children = children

for child in user.parent.children:
    if child is parent:
        child = user

不过这可能需要重新整理一下,我可能也漏掉了什么。

撰写回答