最新要闻
- 不是“空中楼阁”:努比亚Pad 3D搭载全球最大Leia 3D内容生态
- 【报资讯】男子车停路边去吃烧烤 回来瞬间崩溃:路边已装上护栏
- 【独家焦点】作文游西湖300字(精选40篇)
- 千里托运奔驰GLC被淋满牛粪 女子崩溃:花1900元洗了5遍
- 【世界速看料】情侣打车3小时后跑单拉黑司机 司机:246元车费没了
- 世界资讯:微软承认向无法升级的设备推荐Win11:已进行修复
- 环球即时:压水堆
- 当前滚动:这些“领导”短信收到没?专门针对iPhone用户诈骗:全国多地预警
- 环球精选!王一博、梁朝伟《无名》北美院线扩映!豆瓣降至6.7分
- 当前简讯:大爷怒斥夜市挂日本元素油纸伞:主办方回应令人不解
- 环球头条:导演新海诚:中国动画电影迟早会超过日本
- 天天热文:开办以来首位!跨性别演员柏林电影节获奖
- 微速讯:长城放出王炸?长城水平对置八缸发动机摩托曝光 真猛兽
- 环球热头条丨可以两天一充的骁龙8 Gen2手机:出现了
- 每日热讯!马里肯涅巴地区发生武装抢劫 中使馆提醒关注当地安全情况
- 威马汽车再发内部信:部分员工复工 其余人员无薪休假
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
go A*寻路记录
(资料图)
1 func absInt(x int) int {2 if x < 0 {3 return -x4 }5 return x6 }
下面会用到此方法, int类型值取绝对值
1 type sp_item struct { 2 x int 3 y int 4 g int 5 h int 6 f int 7 p *sp_item 8 } 9 10 type sp_open []*sp_item11 12 func (sp sp_open) Len() int {13 return len(sp)14 }15 16 func (sp sp_open) Less(i, j int) bool {17 return sp[i].f < sp[j].f18 }19 20 func (sp sp_open) Swap(i, j int) {21 sp[i], sp[j] = sp[j], sp[i]22 }23 24 func (sp sp_open) exceptFirst() sp_open {25 var newSps []*sp_item26 for i := 1; i < len(sp); i++ {27 newSps = append(newSps, sp[i])28 }29 return newSps30 }31 32 func (sp sp_open) getIndex(x, y int) int {33 for i, v := range sp {34 if v.x == x && v.y == y {35 return i36 }37 }38 return -139 }
这是open列表(带检索的列表)
Len()
Less(i, j int)
Swap(i, j int)上面三个方法是自定义排序(sp_item.f从小到大排序)
exceptFirst()复制 sp_open 数组并返回, 不包含第一个 sp_item
getIndex(x, y int)
获取与参数x,y匹配的 sp_item,返回其当前索引或-1
1 type sp_close []int 2 3 func (sp sp_close) contains(x, y int) bool { 4 for k := 0; k < len(sp); k += 2 { 5 if sp[k] == x && sp[k+1] == y { 6 return true 7 } 8 } 9 return false10 }
这是close列表(不在检索的列表)
contains(x, y int)
sp_close 是否包含参数x,y
1 type sp_dots [8]int 2 3 func (sp sp_dots) getIndex(x, y int) int { 4 for i := 0; i < 8; i += 2 { 5 if sp[i] == x && sp[i+1] == y { 6 return i 7 } 8 } 9 return -110 }11 12 func (sp *sp_dots) put(x, y int) {13 _x := x - 114 x_ := x + 115 _y := y - 116 y_ := y + 117 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = x, _y, _x, y, x_, y, x, y_18 }19 20 func (sp *sp_dots) putA(x, y int) {21 _x := x - 122 x_ := x + 123 _y := y - 124 y_ := y + 125 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = _x, _y, x_, _y, _x, y_, x_, y_26 }
此类型用于获取参数x,y周围的4个点
put(x, y int)
填充 sp_dots, 周围正对面的四个索引点
putA(x, y int)
填充 sp_dots, 周围四个角的索引点
1 type SeekPath struct { 2 BevelAngle bool //是否可以走斜角 3 Timeout time.Duration //超时 4 Junction func(x, y int) bool //过滤 5 } 6 7 // x,y: 开始索引点; x1,y1: 结束索引点 8 func (sp SeekPath) GetPath(x, y, x1, y1 int) []int { 9 sTime := time.Now() 10 eTime := time.Now().Add(sp.Timeout) 11 12 var close sp_close //不在检测的列表 13 var dots, dotsA, dotsB sp_dots //周围的点 14 var isSort bool //如果为 true 则表示 open 列表已改变 15 16 node := &sp_item{ 17 x: x, y: y, 18 h: absInt(x1-x)*10 + absInt(y1-y)*10, 19 } 20 open := sp_open{node} 21 node.f = node.h 22 nd := node 23 24 for { 25 if len(open) == 0 || sTime.After(eTime) { 26 break 27 } 28 29 //sp_item.f 从小到大排序 30 if isSort { 31 isSort = false 32 sort.Sort(open) 33 } 34 35 //node 如果是目标就结束 36 node = open[0] 37 if node.x == x1 && node.y == y1 { 38 nd = node 39 break 40 } 41 42 if nd.h > node.h { 43 nd = node 44 } 45 46 open = open.exceptFirst() //从 open 列表删除第一个 47 close = append(close, node.x, node.y) //把 node 加入 close 列表 48 49 var state [4]bool //记录四个面是否合法 50 var dx, dy int 51 52 //四个面 53 dots.put(node.x, node.y) 54 for i := 0; i < 8; i += 2 { 55 dx, dy = dots[i], dots[i+1] 56 57 //在close列表 58 if close.contains(dx, dy) { 59 continue 60 } 61 62 //已在open列表 63 g := open.getIndex(dx, dy) 64 if g != -1 { 65 dot := open[g] 66 g = node.g + 10 67 if g < dot.g { 68 dot.g = g 69 dot.f = g + dot.h 70 dot.p = node 71 isSort = true 72 } 73 state[i/2] = true 74 continue 75 } 76 77 //索引点是否合法 78 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) { 79 close = append(close, node.x, node.y) 80 continue 81 } 82 83 g = node.g + 10 84 h := absInt(x1-dx)*10 + absInt(y1-dy)*10 85 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node}) 86 isSort = true 87 state[i/2] = true 88 } 89 90 //四个角 91 dotsA.putA(node.x, node.y) 92 for i := 0; i < 8; i += 2 { 93 dx, dy = dotsA[i], dotsA[i+1] 94 95 //在close列表 96 if close.contains(dx, dy) { 97 continue 98 } 99 100 //已在open列表101 g := open.getIndex(dx, dy)102 if g != -1 {103 dot := open[g]104 g = node.g + 14105 if g < dot.g {106 dot.g = g107 dot.f = g + dot.h108 dot.p = node109 isSort = true110 }111 continue112 }113 114 //索引点是否合法115 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {116 close = append(close, node.x, node.y)117 continue118 }119 120 is := true121 dotsB.put(dx, dy)122 for i := 0; i < 8; i += 2 {123 g = dots.getIndex(dotsB[i], dotsB[i+1])124 if g == -1 {125 continue126 }127 if !state[g/2] {128 is = false129 break130 }131 }132 if is {133 g = node.g + 14134 h := absInt(x1-dx)*10 + absInt(y1-dy)*10135 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})136 isSort = true137 }138 }139 }140 141 var path []int142 for nd != nil {143 path = append(path, nd.x, nd.y)144 nd = nd.p145 }146 147 return path148 }
外部可实例SeekPath 来获取寻路后的路径
使用示例:
1 // 此结构是用于创建 SeekPath 的参数, 由客户端定义 2 type hh_SeekPath struct { 3 BevelAngle bool `json:"bevelAngle"` 4 Disables []bool `json:"disables"` 5 LenX int `json:"lenX"` 6 LenY int `json:"lenY"` 7 X int `json:"x"` 8 Y int `json:"y"` 9 X1 int `json:"x1"`10 Y1 int `json:"y1"`11 }12 13 func main() {14 //设置可同时执行的最大CPU数15 runtime.GOMAXPROCS(runtime.NumCPU())16 http.Handle("/", http.FileServer(http.Dir("./")))17 18 http.HandleFunc("/hh", func(w http.ResponseWriter, r *http.Request) {19 w.Header().Set("Access-Control-Allow-Origin", "*") //*允许所有的域头20 21 value := r.FormValue("value")22 param := hh_SeekPath{}23 err := json.Unmarshal([]byte(value), ¶m)24 if err != nil {25 fmt.Println("hh error: ", err)26 return27 }28 29 length := len(param.Disables)30 lenMax := param.LenX * param.LenY31 sp := SeekPath{32 BevelAngle: param.BevelAngle,33 Timeout: time.Second * 10,34 35 //此回调如果返回false就把x,y添加到不在检索列表(close)36 Junction: func(x, y int) bool {37 //如果x,y超出最大边界就返回false38 if x >= param.LenX || y >= param.LenY {39 return false40 }41 //Disables[bool] 由客户端随机生成的障碍42 if length == lenMax {43 return param.Disables[x*param.LenY+y]44 }45 return true46 },47 }48 49 result, _ := json.Marshal(sp.GetPath(param.X, param.Y, param.X1, param.Y1))50 fmt.Fprint(w, *(*string)(unsafe.Pointer(&result)))51 })52 53 fmt.Println("浏览器地址: http://localhost:8080")54 log.Fatal(http.ListenAndServe(":8080", nil))55 }
下面是客户端代码(HTML)
1 2 3 4 5 6 7 12 13 14 15 16index.htmlgo A*寻路测试: 点击第一次为起点, 第二次点击为终点
17 18 <script src = "./js/main.js" type = "module"></script>19 20 21 22
1 import { CanvasEvent, CanvasImageCustom, CanvasImageDraw, CanvasImageScroll, CanvasImage } from "./lib/ElementUtils.js" 2 import { Ajax, UTILS } from "./lib/Utils.js"; 3 4 function main(){ 5 const size = 50; 6 const imgA = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#eeeeee").stroke("#cccccc"); 7 const imgB = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#333333").stroke("#000000"); 8 const imgS = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#00ff00"); 9 const imgE = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#ff0000");10 const imgP = new CanvasImageCustom().size(size, size).rect(size/2, 1).fill("#0000ff");11 const cid = new CanvasImageDraw({width: innerWidth, height: innerHeight});12 const cis = new CanvasImageScroll(cid, {scrollVisible: "auto"});13 const cie = new CanvasEvent(cid);14 15 //发送给服务器的寻路参数16 const param = {17 bevelAngle: true, //是否可走斜角18 disables: [], //禁用点19 lenX: Math.floor(innerWidth/size), //索引x轴长度20 lenY: 100, //索引y轴长度21 x:0, y:0, //起点22 x1: 0, y1: 0, //终点23 }24 var isEnd = true;25 const pathsCI = []26 const ajax = new Ajax({27 url: "http://localhost:8080/hh",28 success: v => {29 v = JSON.parse(v);30 for(let i = 0; i < v.length; i+=2){31 const ci = new CanvasImage(imgP).pos(v[i]*size, v[i+1]*size);32 pathsCI.push(ci);33 cid.list.push(ci);34 }35 cid.redraw();36 isEnd = true;37 },38 });39 40 //点击的回调方法41 var isSend = false;42 function onclick(event){43 if(isEnd === false) return alert("等待上一次的结果");44 const ci = event.target;45 if(isSend === false){46 isSend = true;47 param.x = Math.floor(ci.x / size);48 param.y = Math.floor(ci.y / size);49 imgS.pos(ci);50 const c = pathsCI.length;51 if(c !== 0){52 cid.list.splice(cid.list.indexOf(pathsCI[0]), c);53 pathsCI.length = 0;54 }55 } else {56 isEnd = isSend = false;57 param.x1 = Math.floor(ci.x / size);58 param.y1 = Math.floor(ci.y / size);59 ajax.send(`name=hh_SeekPath&value=${JSON.stringify(param)}`);60 imgE.pos(ci);61 }62 cid.redraw();63 }64 65 //创建视图和障碍点66 for(let x = 0, i = 0; x < param.lenX; x++){67 for(let y = 0, ci; y < param.lenY; y++, i++){68 if(UTILS.random(0, 1) < 0.3){69 param.disables[i] = false;70 ci = cid.list[i] = new CanvasImage(imgB).pos(x * size, y * size);71 } else {72 param.disables[i] = true;73 ci = cid.list[i] = new CanvasImage(imgA).pos(x * size, y * size);74 ci.addEventListener("click", onclick);75 }76 }77 }78 79 //end80 cis.bindScrolls();81 cid.list.push(imgS, imgE);82 cid.render();83 }84 85 main();
结果图:
源码下载地址:https://www.123pan.com/s/ylTuVv-nwhpH.html
-
59.类的自动转换和强制类型转换
程序清单11 16stonewt h pragmaonce stone h--Stonewt类声明 ifndefSTONEWT_H_ defineSTONEWT_H_class
来源: go A*寻路记录
59.类的自动转换和强制类型转换
不是“空中楼阁”:努比亚Pad 3D搭载全球最大Leia 3D内容生态
【报资讯】男子车停路边去吃烧烤 回来瞬间崩溃:路边已装上护栏
【独家焦点】作文游西湖300字(精选40篇)
千里托运奔驰GLC被淋满牛粪 女子崩溃:花1900元洗了5遍
【世界速看料】情侣打车3小时后跑单拉黑司机 司机:246元车费没了
世界资讯:微软承认向无法升级的设备推荐Win11:已进行修复
环球即时:压水堆
当前滚动:这些“领导”短信收到没?专门针对iPhone用户诈骗:全国多地预警
环球精选!王一博、梁朝伟《无名》北美院线扩映!豆瓣降至6.7分
当前简讯:大爷怒斥夜市挂日本元素油纸伞:主办方回应令人不解
环球头条:导演新海诚:中国动画电影迟早会超过日本
天天最资讯丨pat乙级链表问题
LWIP学习记录------ARP协议(1)
天天热文:开办以来首位!跨性别演员柏林电影节获奖
微速讯:长城放出王炸?长城水平对置八缸发动机摩托曝光 真猛兽
环球热头条丨可以两天一充的骁龙8 Gen2手机:出现了
每日热讯!马里肯涅巴地区发生武装抢劫 中使馆提醒关注当地安全情况
威马汽车再发内部信:部分员工复工 其余人员无薪休假
【全球热闻】视觉四边等宽!魅族20系列边框仅1.57mm:比iPhone 14 Pro都窄
全球热点!Go编程实战:博客备份
Markdown简明教程
《使命召唤》前景动荡
世界新资讯:上海一高校推出高启强同款猪脚面:师生直呼“舌尖上的《狂飙》”
乌苏啤酒大促:立减64元 折合3元/瓶到手
信息:女子考研期间生娃初试395分 回应外界好奇:多亏家人替自己分担很多
每日焦点!高德、百度地图红绿灯读秒很神奇 接入交管平台?真相并非如此
【天天新要闻】《我们的日子》里,不要忽视这些法律问题
天天资讯:俄州“毒火车”引发环境灾难后 美国又一货运列车脱轨
中兴通
全球热讯:读Java性能权威指南(第2版)笔记02_ Java SE API技巧上
世界动态:你昨晚关注的那个福利姬 可能是假的
世界即时看!国产新能源疯狂内卷!哈弗H6 PHEV官降1.5万 配置全系顶配
【世界报资讯】iPhone 15 Pro Max渲染图出炉:对比14 Pro Max边框更窄、机身更厚
对接水仙后台(支持AndLua+、FA、FA2、AIDE lua、Simple Lua等)
【全球报资讯】Golang基于Mysql分布式锁实现集群主备
世界观热点:薪资4K-5K!公司招聘财务要求做饭被吐槽像保姆
天天百事通!男子长期高血糖导致视网膜病变:不可逆
热头条丨不愧是万元机皇!酷安网友给三星Galaxy S23 Ultra打最高分
当前聚焦:《蚁人3》上映9天中国内地票房破2亿 网友:回到小众也挺好
世界微资讯!如何给公众号投稿赚钱_怎样给公众号投稿赚钱
双亲委派机制
天天微动态丨中国教师队伍建设研究/京师教师教育论丛
当前视讯!即将让核污水倒入大海!日本港口大量有毒海胆聚集 或出现爆发式增长
三星降低QD-OLED面板成本!让电视更具竞争力
世界关注:努比亚Z50新版下周首销:骁龙8 Gen2旗舰焊门员 性价比无敌
最新:python实现客户端和服务端的UDP相互通信
【报资讯】hbuilderx打正式包所需的私钥证书的创建方法
全球新动态:2.【go-kit教程】go-kit启动http服务
室内单目深度估计-4
最新:kaggle中训练得到的output太大该怎么下载?
世界热消息:2消息,中超新贵签约32岁国脚,5中超外援上诉国际足联
环球新动态:超市宣称1元纸币将退出历史引热议 网友直呼太突然:官方回应不属实
视点!女子患异食癖3年吃上百块粉饼:体检身体无异常
天天热点!刷题疑问
环球速读:史上最好的真全面屏手机!努比亚Z50 Ultra上架接受预约
天天精选!禁止自带食材 关停300家店 海底捞从巨亏41亿到盈利13亿
天天讯息:day04-原生的API&注解方式
【环球新要闻】Git使用
美食博主三亚买3888元海鲜被好心人提醒多花1700:当事人心累
热消息:秋裤先别着急脱!“春捂”到底该“捂”哪儿?
前沿资讯!2023年安卓之光!小米13 Ultra手机壳曝光:背部造型抢眼
餐馆接到网吧10个外卖订单 结果被刷9个差评 店主:下次亲自送餐
天天微速讯:门店2299元 GXG男士羊毛大衣0.8折清仓大促:实付199元!
世界热资讯!乐堡苏打气泡酒12罐到手19.9元:低糖0脂无负担
威马员工在线讨薪:被恶心到了、恶心的事还有更多
广州塞车登“热搜”?“甜蜜的烦恼”重回一线城市,中国经济活力加快恢复
【Tire树】高效统计字符串
80、90后泪目 国产暗黑《赵云传重制版》试玩
1岁男童误食降糖药成植物人:愿康复顺利
环球速看:中央人民广播电台民族节目中心
Ubuntu安装Zabbix6.0
秒睡令人羡慕?医生提醒:可能是种睡眠障碍
《流浪地球2》科幻成真?武汉国博用特效“加建”太空电梯
今头条!【element UI】在 el-select 与 el-tree 结合组件
环球热文:python教程:模块的搜索路径
Python中模块的四种方式
《原子之心》种族主义漫画引争议:涉嫌歧视黑人!官方道歉
世界速读:我国载人航天将对国际开放 多国航天员希望参与中国空间站
每日热讯!驱动拖后腿 Intel显卡被低估:2000元档A770理论可刚RTX 3070
受贿、泄露内幕信息!湖北原副省长曹广晶被公诉
天天快看点丨下周发售!《卧龙:苍天陨落》新预告发布:PC/主机通吃
最新消息:EQ电动车中国表现欠佳 奔驰CEO:打价格战不是好事
环球热点!101岁老人每天赶2场麻将 医生:身体状态70岁
What's past is prologue
全球新资讯:车商不收特斯拉 新车一个月亏7万:新能源二手车都不受待见 厂商频降价
H5N1禽流感致死事件引世卫关注:事发柬埔寨、9年来首次
环球热点评!下单就送鲜蔬汤 海福盛冻干粥5杯大促:券后仅20.9元!
“真香定律”稳定发挥 迈凯伦全新SUV效果图曝光:预计售价282万
世界今日讯!关于修订《中国高尔夫球协会赛事活动管理办法》的通知
环球微头条丨中越边境民族文化艺术考察研究
每日热点:女子在门缝发现针头 是大妈拿注射器推大量不明液体:整栋楼遭殃 网友气愤
地球中心到底有什么?科学家发现竟是一个超大铁球 跟书里讲得不一样
NET6接口项目基础框架项目
Java 8 Lambda 方法引用 简记
全球看热讯:(数据库系统概论|王珊)第七章数据库设计-第三节:概念结构设计
Blender插件:水滴生成器(Droplet Generator)
环球速递!《分布式技术原理与算法解析》学习笔记Day22
消炎止血、除口臭!中药黄芩牙膏大促:3支不到20块(送牙刷)