首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游戏不打印或更新时,人工智能正在思考

游戏不打印或更新时,人工智能正在思考
EN

Stack Overflow用户
提问于 2022-02-06 16:48:17
回答 2查看 64关注 0票数 1

我有一个游戏,我正在开发的团结,那里的AI正在做大量的计算,当它是它的时候。它搜索深度1,然后2,然后3等位置。在每个深度之间,我想实例化一个游戏对象,并提供有关UI深度的信息。问题是,在AI完全完成之前,什么都不会发生,然后所有的项目都一次被添加。下面是一些更好地解释的代码:

代码语言:javascript
复制
private void AIMakeMove()
{
    for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
    {
        SearchPosition(currentDepth);
    }
}
 
private void SearchPosition(int _currentDepth)
{
    // Search the position to the given depth
    score = Negamax(_currentDepth);
 
     // Print things   PROBLEM HERE
    GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
    Debug.Log(_currentDepth);
}

我也尝试了一个简单的Debug.Log,而不是实例化,但同样的事情发生,然后,所有打印到控制台后,AI是完成其思维过程。

为什么我的UI不更新信息?我告诉它在运行第一次深度为0的迭代之后创建一些东西,但是它跳过了这个步骤,转而继续深度2。有人能告诉我如何在每个深度之间获取信息吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-07 09:10:06

问题是在人工智能完全完成之前什么都不会发生。

好的,只有当统一主线程被允许完成一个框架时,UI才会更新。

但是,您将阻塞主线程,直到所有迭代完成为止。

如果在每个实例化之间阻塞是可以的,那么只需使用柯鲁丁并执行以下操作

代码语言:javascript
复制
private void AIMakeMove()
{
    StartCoroutine(AIMakeMoveRoutine());
}

private IEnuemrator AIMakeMoveRoutine()
{
    for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
    {
        SearchPosition(currentDepth);

        // This now tells Unity to "interrupt" this routine here
        // render the current frame and continue from here in the next frame
        yield return null;
    }
}
 
private void SearchPosition(int _currentDepth)
{
    score = Negamax(_currentDepth);
 
    GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
    Debug.Log(_currentDepth);
}

这将在每次迭代完成后完成一个框架并启动一个新的框架(从而刷新UI)。

但是,如果这仍然过多地阻塞了应用程序的其余部分,那么您还应该实际运行计算异步,例如使用类似的Task

代码语言:javascript
复制
private void AIMakeMove()
{
    StartCoroutine(AIMakeMoveRoutine());
}

private IEnuemrator AIMakeMoveRoutine()
{
    for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
    {
        // you can yield another IEnuemrator -> executes this and waits for it to finish
        yield return SearchPosition(currentDepth);

        // This now tells Unity to "interrupt" this routine here
        // render the current frame and continue from here in the next frame
        yield return null;
    }
}
 
private IEnumerator SearchPosition(int _currentDepth)
{
    // run the NegamaxTask asynchronously in the background
    var task = Task.Run(() => Negamax(_currentDepth));
    // wait for the task to finish
    while(!task.IsCompleted)
    {
        // do nothing but skip frames to allow the rest of the application to run smoothly
        yield return null;
    }
    // If you do nothing else inside the loop this could also be written as
    //yield return new WaitWhile(() => !task.IsComoleted);
    // or
    //yield return new WaitUntil(() => task.IsCompleted);

    // since the task is already finished it is save / non-blocking to access the result now
    score = task.Result;
 
    var printItem = Instantiate(printItemPrefab, printItemParent.transform);
    Debug.Log(_currentDepth);
}

现在,这允许您的应用程序以正常的帧率继续运行,而在后台,您需要进行大量的计算,并在迭代完成时偶尔获得一个结果。

票数 1
EN

Stack Overflow用户

发布于 2022-02-06 16:52:43

尝试使用线程

代码语言:javascript
复制
private void AIMakeMove()
    {
        new System.Threading.Thread(() =>
        {
            for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
            {
                SearchPosition(currentDepth);
            }
        }).Start();
    }

    private void SearchPosition(int _currentDepth)
    {
        // Search the position to the given depth
        score = Negamax(_currentDepth);

        // Print things   PROBLEM HERE
        GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
        Debug.Log(_currentDepth);
    }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71009450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档