首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

A*在Javascript (带有p5.js)中不起作用

A*算法是一种常用的路径搜索算法,用于在图形或网络中找到最短路径。它通过评估每个节点的代价函数来确定下一步要探索的节点,直到找到目标节点。

在Javascript中,可以使用p5.js库来实现A算法。p5.js是一个基于Processing的JavaScript库,用于创建交互式图形和动画。它提供了一些方便的函数和方法,可以简化A算法的实现过程。

下面是一个简单的示例代码,演示了如何在Javascript中使用p5.js实现A*算法:

代码语言:txt
复制
// 创建一个表示节点的类
class Node {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.g = 0; // 从起点到当前节点的实际代价
    this.h = 0; // 从当前节点到目标节点的估计代价
    this.f = 0; // 总代价:f = g + h
    this.neighbors = []; // 相邻节点
    this.previous = undefined; // 前一个节点
  }
  
  // 计算当前节点到目标节点的估计代价(使用曼哈顿距离)
  heuristic(target) {
    return Math.abs(this.x - target.x) + Math.abs(this.y - target.y);
  }
  
  // 添加相邻节点
  addNeighbors(grid) {
    let x = this.x;
    let y = this.y;
    
    if (x > 0) {
      this.neighbors.push(grid[x - 1][y]);
    }
    if (x < grid.length - 1) {
      this.neighbors.push(grid[x + 1][y]);
    }
    if (y > 0) {
      this.neighbors.push(grid[x][y - 1]);
    }
    if (y < grid[x].length - 1) {
      this.neighbors.push(grid[x][y + 1]);
    }
  }
}

// 创建一个表示网格的二维数组
let grid = new Array(cols);

// 初始化网格
function setup() {
  // 设置画布大小
  createCanvas(400, 400);
  
  // 初始化每个节点
  for (let i = 0; i < cols; i++) {
    grid[i] = new Array(rows);
  }
  
  // 创建节点对象
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j] = new Node(i, j);
    }
  }
  
  // 添加相邻节点
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j].addNeighbors(grid);
    }
  }
  
  // 设置起点和目标节点
  start = grid[0][0];
  target = grid[cols - 1][rows - 1];
  
  // 开始A*算法
  astar();
}

// A*算法
function astar() {
  // 创建开放列表和关闭列表
  let openSet = [];
  let closedSet = [];
  
  // 将起点添加到开放列表
  openSet.push(start);
  
  while (openSet.length > 0) {
    // 在开放列表中找到f值最小的节点
    let winner = 0;
    for (let i = 0; i < openSet.length; i++) {
      if (openSet[i].f < openSet[winner].f) {
        winner = i;
      }
    }
    
    let current = openSet[winner];
    
    // 如果当前节点是目标节点,路径搜索完成
    if (current === target) {
      console.log("路径搜索完成");
      break;
    }
    
    // 将当前节点从开放列表中移除,并添加到关闭列表中
    openSet.splice(winner, 1);
    closedSet.push(current);
    
    // 遍历当前节点的相邻节点
    let neighbors = current.neighbors;
    for (let i = 0; i < neighbors.length; i++) {
      let neighbor = neighbors[i];
      
      // 如果相邻节点不在关闭列表中且不是障碍物
      if (!closedSet.includes(neighbor)) {
        let tempG = current.g + 1; // 计算从起点到相邻节点的实际代价
        
        // 如果相邻节点不在开放列表中,或者新的代价更小
        if (!openSet.includes(neighbor) || tempG < neighbor.g) {
          neighbor.g = tempG;
          neighbor.h = neighbor.heuristic(target);
          neighbor.f = neighbor.g + neighbor.h;
          neighbor.previous = current;
          
          // 如果相邻节点不在开放列表中,将其添加到开放列表中
          if (!openSet.includes(neighbor)) {
            openSet.push(neighbor);
          }
        }
      }
    }
  }
  
  // 重构路径
  let path = [];
  let temp = current;
  path.push(temp);
  while (temp.previous) {
    path.push(temp.previous);
    temp = temp.previous;
  }
  
  // 绘制路径
  for (let i = 0; i < path.length; i++) {
    path[i].show(color(0, 0, 255));
  }
}

// 绘制网格
function draw() {
  background(255);
  
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j].show(color(255));
    }
  }
}

在这个示例中,我们创建了一个表示节点的Node类,其中包含了计算代价、添加相邻节点等方法。然后,我们使用p5.js库创建了一个表示网格的二维数组,并初始化每个节点。接下来,我们使用A*算法来搜索最短路径,并将结果绘制在画布上。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • List.append() 在 Python 中不起作用,该怎么解决?

    在 Python 中,我们通常使用 List.append() 方法向列表末尾添加元素。然而,在某些情况下,你可能会遇到 List.append() 方法不起作用的问题。...问题描述虽然 List.append() 方法通常在 Python 中运行良好,但在某些情况下,它可能无法正常工作。以下是一些可能导致 List.append() 方法不起作用的情况:1....变量重新赋值在 Python 中,列表是可变对象,也就是说,它们可以通过引用进行修改。...列表作为函数参数另一个导致 List.append() 方法不起作用的常见情况是将列表作为函数的参数传递。在 Python 中,函数参数传递是通过对象引用实现的。...结论List.append() 方法在 Python 中通常是一个方便且常用的方法,用于向列表末尾添加元素。然而,当遇到某些情况时,它可能不起作用。

    2.7K20

    在 .NET Core 中运行 JavaScript

    一.前言 在 .NET Framework 时,我们可以通过V8.NET等组件来运行 JavaScript,不过目前我看了好几个开源组件包括V8.NET都还不支持 .NET Core ,我们如何在 .NET...Core 中运行 JavaScript 呢,答案是使用 NodeServices。...关于为何有在 .NET Core 中执行 JavaScript 这种需求,比较特殊,举个栗子:当你做模拟登录时,目标网站可能采用一些加密算法来计算特殊的值,如果你要完全模拟,那么除了用C#翻译这个算法还有个办法就是直接将这段加密算法...二.什么是 NodeServices NodeServices 是一个 ASP.NET Core 中间件,将它添加到 ASP.NET Core 管道中,该中间件调用Node在运行时执行JavaScript...首先,我们将首先创建一个包含返回问候消息的 NodeJs module 的简单JavaScript文件,保存在 scripts/greeter.js文件中: // greeter.js module.exports

    3.9K20

    在zabbix中实现发送带有图片的邮件和微信告警

    李白《春夜宴从弟桃花园序》 ---- 1 python实现在4.2版本zabbix发送带有图片的报警邮件 我们通常收到的报警,都是文字,是把动作中的消息内容当成了正文参数传给脚本,然后邮件或者微信进行接收...Falsedef text_to_html(text): #将邮件内容text字段转换成HTML格式 d=text.splitlines() #将邮件内容以每行作为一个列表元素存储在列表中...打开管理中的用户,点击需要设置邮件告警的用户,然后在报警媒介中添加报警媒介,在弹框中选择刚才定义的类型,然后填写想要发送的邮箱地址,最后添加 ?...2 python实现在4.2版本zabbix发送带有图片的微信告警 2.1 实现思路 ?...打开管理中的用户,点击需要设置邮件告警的用户,然后在报警媒介中添加报警媒介,在弹框中选择刚才定义的类型,然后填写企业微信中创建的部门id,最后添加 ?

    2.4K51

    策略模式 在JavaScript中的实现

    也就是违背了 开放-封闭原则 (Open-Close Principle,OCP) 分析 以上问题就很适合使用 策略模式 在JavaScript中,策略模式可以通过以下方式理解: 定义策略对象:首先,你需要定义一组策略对象...使用策略对象:在需要使用算法或行为的地方,你可以通过选择合适的策略对象来实现不同的功能。这样可以在不修改客户端代码的情况下改变算法或行为。...因为以上过程只需要表示为 解决方案 1 普通对象 在JavaScript中,对象 object 天然具备 判断哪种策略 - 使用策略能力 对象[策略](); obj[key](); // 定义策略对象...canvas.width / tileSize, canvas.height / tileSize, 0, 0, canvas.width, canvas.height); }, } // 在每一帧绘制视频画面到画布上

    4900

    在现代 JavaScript 中编写异步任务

    Node.js 开辟了一个在不同环境中甚至在 web 之外编写 JavaScript 的新时代。当然异步的情况也是可能的,例如创建新目录或写文件。...对返回值进行的后续操作无需存储在不会破坏代码节奏的 mkdir 之类的变量中;也无需在以后的步骤中创建新的作用域来访问 result 的值。...可以肯定地说,Promise 是该语言中引入的基本工件,对于在 JavaScript 中启用 async/await 表示法是必需的,你可以在现代浏览器和最新版本的 Node.js 中使用它。...我们仍然不知道 ECMAScript 规范在几年后的样子,因为我们一直在将 JavaScript 治理扩展到 web 之外,并尝试解决更复杂的难题。...与十年前刚刚开始在浏览器中编写代码时相比,我觉得现在 JavaScript 是“异步友好”的。

    2.4K30

    在 JavaScript 中对数组进行排序

    排序是您在学习JavaScript时将使用的众多基本方法之一。让我们回顾一下如何对不同的数据类型使用排序方法。 ---- 字符串 默认情况下, 排序方法按字母顺序组织其元素。...(在后面的示例中,此示例将有一个更广泛的版本!在此示例中,我们将使用 slice() 并将带有注入数字的字符串转换为数字。这样,我们就可以对所有数组元素进行排序,其中每个元素都是相同的数据类型。...在本例中,我们将使用正则表达式。 正则表达式(Regex)是组成搜索模式的字符序列。搜索模式可用于文本搜索和文本替换操作。 (当第一次面对Regex时,它真的很吓人。我个人还是觉得很困惑。...撇开外观不讲,它是一种高可用性和强大的代码类型,在许多情况下都很有用。)...{id: 5, name: 'Sade'} {id: 8, name: 'Nicolette'} {id: 9, name: 'Megan'} */ 个人笔记: 正则表达式真的很酷,但到目前为止,在我的职业生涯中

    4.9K70

    在JavaScript中的数据结构(队列)

    当我们在浏览器中打开新标签时,就会创建一个任务队列。这是因为每个标签都是单线程处 理所有的任务,它被称为事件循环。...在JavaScript中,可以使用数组(Array)或链表(Linked List)等数据结构来实现队列。 其实可以用窗口排队打饭为案例,先来的先排队打饭。...在队列中,新元素被添加到队列末尾,并等待其他已存在的元素被处理后才能被移除。当删除元素时,总是从队首开始移除元素。...因此可以对它们使用默认的出列操作: ---- 总结 在JavaScript中,队列(Queue)是一种具有先进先出(FIFO, First-In-First-Out)特性的数据结构,它可以用于在计算机程序中管理和存储元素...队列主要有两个基本操作: 入队(enqueue)和出队(dequeue),在JavaScript中可以使用数组(Array)或链表(Linked List)等数据结构来实现队列。

    30730

    【译】如何避免在JavaScript中阻塞DOM

    原文链接:https://www.sitepoint.com/avoiding-dom-blocking/ 在浏览器和在诸如Node.js的运行时环境中,JavaScript程序是运行在单线程上的。...例如:当一个按钮被点击后触发了一个事件,这个事件执行一个函数,在函数内进行了一些计算并更新DOM。一旦完成,浏览器便空闲下来,从任务队列中取出下一个任务来处理。...默认设置下,前面的例子中“入侵者”通过改变left-margin来移动。这个属性及相似的属性如left和width会导致在动画的每一步浏览器都需要对整个页面文档进行回流和重绘。...注意到因为肢体的摆动是由JavaScript控制的,所以它们仍然会因阻塞而暂停。 内存存储 更新内存中的对象要比使用写入磁盘的存储机制快得多。...一个好的折衷办法是使用内存中的对象来提高性能,然后在合适的时机对数据进行持久化——例如在卸载页面时: // get previously-saved data var store = JSON.parse

    2.8K10

    在JavaScript中的数据结构(链表)

    JavaScript链表是一种数据结构,用于存储和组织一系列的元素。它由一系列节点(Node)组成,每个节点包含了两部分:数据域(存储数据)和指针域(指向下一个节点)。...然而,在大多数语言中这种数据结构有一个缺点:数组的大小是固定的,从数组的起点或中间插入或移除项的成本很高,因为需要移动元素。...然而,链表的缺点是访问链表中的特定元素的时间复杂度较高,需要从头开始遍历链表直到找到目标节点。 ---- 详细的看一下列表 在JavaScript中,可以使用对象来实现链表。...remove(element):从列表中移除一项。 indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。...toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值。

    18410

    setImmediate() vs setTimeout() 在 JavaScript 中的区别

    setImmediate() vs setTimeout() 在 JavaScript 中的区别 在 JavaScript 中,setImmediate() 和 setTimeout() 都用于调度任务...JavaScript 的异步特性 JavaScript 以其非阻塞、异步行为而闻名,尤其是在 Node.js 环境中。...在 Node.js 中,事件循环处理不同的阶段,每个阶段负责执行某些类型的回调。它帮助管理非阻塞任务,确保函数可以异步执行。在这些阶段中,有不同的队列。...相反,它被放置在宏任务队列中,以便在下一个可用机会执行。 setImmediate() 另一方面,setImmediate() 设计用于在 I/O 事件完成后执行回调,在同一事件循环迭代中。...理解这些差异有助于你精确控制代码的运行时间,这在高性能应用程序中至关重要,因为时间和效率非常重要。 参考 setImmediate() vs setTimeout() in JavaScript

    11810
    领券