首页
学习
活动
专区
工具
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 编写异步任务

    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.8K70

    【译】如何避免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,可以使用数组(Array)或链表(Linked List)等数据结构来实现队列。 其实可以用窗口排队打饭为案例,先来的先排队打饭。...队列,新元素被添加到队列末尾,并等待其他已存在的元素被处理后才能被移除。当删除元素时,总是从队首开始移除元素。...因此可以对它们使用默认的出列操作: ---- 总结 JavaScript,队列(Queue)是一种具有先进先出(FIFO, First-In-First-Out)特性的数据结构,它可以用于计算机程序管理和存储元素...队列主要有两个基本操作: 入队(enqueue)和出队(dequeue),JavaScript可以使用数组(Array)或链表(Linked List)等数据结构来实现队列。

    27730

    JavaScript的数据结构(链表)

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

    17910

    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

    10510

    适配器JavaScript的体现

    适配器JavaScript的体现 适配器设计模式JavaScript中非常有用,处理跨浏览器兼容问题、整合多个第三方SDK的调用,都可以看到它的身影。...其实在日常开发,很多时候会不经意间写出符合某种设计模式的代码,毕竟设计模式就是老前辈们总结提炼出来的一些能够帮助提升开发效率的一些模版,源于日常的开发。...而适配器其实在JavaScript应该是比较常见的一种了。 维基百科,关于适配器模式的定义为: 软件工程,适配器模式是一种软件设计模式,允许从另一个接口使用现有类的接口。...代码的体现 而转向到编程,我个人是这样理解的: 将那些你不愿意看见的脏代码藏起来,你就可以说这是一个适配器 接入多个第三方SDK 举个日常开发的例子,我们在做一个微信公众号开发,里边用到了微信的支付模块...,官方已经实现了类似这样的工具函数:util.promisify 小结 个人观点:所有的设计模式都不是凭空想象出来的,肯定是开发的过程,总结提炼出的一些高效的方法,这也就意味着,可能你并不需要在刚开始的时候就去生啃这些各种命名高大上的设计模式

    1.4K10
    领券