zoukankan      html  css  js  c++  java
  • A*寻路 SLG 战棋寻路 控制台代码

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                test mytest = new test();
                //定义出发位置
                Point startingPoint = new Point();
                startingPoint.x = 1;
                startingPoint.y = 3;
                //定义目的地
                Point destination = new Point();
                destination.x = 5;
                destination.y = 0;
                //定义移动力
                int power = 10;
                DateTime time1 = DateTime.Now;
                mytest.FindWay(startingPoint, destination, power);
                DateTime time2 = DateTime.Now;
                mytest.PrintMap(startingPoint, destination);
                Console.WriteLine("用时:" + (time2 - time1));
            }
        }
        class test
        {
            //数值表示移动力消耗
           public byte[,] R = new byte[10, 10]{
                { 8, 8, 8, 8, 8, 1, 1, 1, 3, 1 },
                { 8, 1, 1, 1, 1, 1, 1, 1, 6, 1 },
                { 8, 8, 1, 8, 8, 1, 1, 2, 1, 1 },
                { 8, 8, 8, 8, 8, 1, 1, 1, 1, 1 },
                { 8, 8, 8, 2, 8, 1, 1, 1, 1, 1 },
                { 1, 8, 1, 2, 8, 1, 1, 3, 1, 1 },
                { 1, 1, 1, 1, 8, 1, 2, 1, 1, 2 },
                { 1, 2, 5, 1, 8, 1, 2, 1, 1, 1 },
                { 1, 1, 7, 1, 1, 1, 2, 2, 1, 1 },
                { 1, 1, 1, 1, 1, 2, 2, 3, 1, 1 }};
    
            //最终路径
            List<Point> way = new List<Point>();
            //开启列表
            List<Point> Open_List = new List<Point>();
            //关闭列表
            List<Point> Close_List = new List<Point>();
            //从开启列表查找F值最小的节点
            private Point GetMinFFromOpenList()
            {
                Point Pmin = null;
                foreach (Point p in Open_List) if (Pmin == null || Pmin.G + Pmin.H > p.G + p.H) Pmin = p;
                return Pmin;
            }
            //判断关闭列表是否包含一个坐标的点
            private bool IsInCloseList(int x, int y)
            {
                foreach (Point p in Close_List) if (p.x == x && p.y == y) return true;
                return false;
            }
            //判断开启列表是否包含一个坐标的点
            private bool IsInOpenList(int x, int y)
            {
                foreach (Point p in Open_List) if (p.x == x && p.y == y) return true;
                return false;
            }
            //从开启列表返回对应坐标的点
            private Point GetPointFromOpenList(int x, int y)
            {
                foreach (Point p in Open_List) if (p.x == x && p.y == y) return p;
                return null;
            }
            //检查当前节点附近的节点
            private void CheckGrid(Point nowPoint, Point startingPoint, Point destination)
            {
                for (int xt = nowPoint.x - 1; xt <= nowPoint.x + 1; xt++)
                {
                    for (int yt = nowPoint.y - 1; yt <= nowPoint.y + 1; yt++)
                    {
                        //排除超过边界、不相干和关闭列表中的点
                        if (!(xt >= 0 && xt < R.GetLength(0) && yt >= 0 && yt < R.GetLength(1))) continue;
                        if (IsInCloseList(xt, yt)) continue;
                        if (!(xt == nowPoint.x && yt - 1 == nowPoint.y) && !(xt - 1 == nowPoint.x && yt == nowPoint.y) && !(xt + 1 == nowPoint.x && yt == nowPoint.y) && !(xt == nowPoint.x && yt + 1 == nowPoint.y))
                            continue;
    
                        if (IsInOpenList(xt, yt))
                        {
                            Point pt = GetPointFromOpenList(xt, yt);
                            int G_new = nowPoint.G + R[pt.x, pt.y];
                            if (G_new < pt.G)
                            {
                                Open_List.Remove(pt);
                                pt.father = nowPoint;
                                pt.G = G_new;
                                Open_List.Add(pt);
                            }
                        }
                        else //不在开启列表中
                        {
                            Point pt = new Point();
                            pt.x = xt;
                            pt.y = yt;
                            pt.father = nowPoint;
                            pt.G = pt.father.G + R[pt.x, pt.y];
                            pt.H = Math.Abs(pt.x - destination.x) + Math.Abs(pt.y - destination.y);
                            Open_List.Add(pt);
                        }
                    }
                }
            }
            public void FindWay(Point startingPoint, Point destination, int power)
            {
                Open_List.Add(startingPoint);
                while (!(IsInOpenList(destination.x, destination.y))) //当终点存在开启列表中就意味着寻路结束了
                {
                    Point nowPoint = GetMinFFromOpenList();
                    Open_List.Remove(nowPoint);
                    Close_List.Add(nowPoint);
                    CheckGrid(nowPoint, startingPoint, destination);
                }
                Point p = GetPointFromOpenList(destination.x, destination.y);
                List<Point> temp = new List<Point>();
                while (p.father != null)
                {
                    temp.Add(p);
                    p = p.father;
                }
                temp.Reverse();
                foreach (Point pt in temp)
                {
                    if (pt.G > power) break;
                    way.Add(pt);
                }
            }
            public void PrintMap(Point startingPoint, Point destination)
            {
                for (int x = 0; x < 10; x++)
                {
                    for (int y = 0; y < 10; y++)
                    {
                        if (x == startingPoint.x && y == startingPoint.y) Console.Write("▲");
                        else if (x == destination.x && y == destination.y) Console.Write("▲");
                        else if (Contains(x,y)) Console.Write("★");
                        else Console.Write("□");
                    }
                    Console.Write("\n");
                }
            }
            private Boolean Contains(int x, int y)
            {
                foreach (Point p in way)
                    if (p.x == x && p.y == y) return true;
                return false;
            }
        }
        class Point
        {
            public Point() { }
            public int G;
            public int H;
            public int x;
            public int y;
            public Point father;
        }
    }
    

      

  • 相关阅读:
    双日历时间段选择控件—daterangepicker(汉化版)
    vue elementui table表格展开行每次只展开一行
    vue-pdf PDF文件预览
    async await
    vuex发送axios请求
    jq调用浏览器下载文件 window.open()
    禁止页面右键、选择、F12操作
    vue 点击一条消息跳转相应的页面且对应相应的大模块和办理状态
    vue-infinite-scroll 滚动加载下一页
    填写流程当前登录人可以填写除自己可填项外还可看到他前面经办人相关填写的内容,且经办人后面的不可见
  • 原文地址:https://www.cnblogs.com/rainstorm/p/2883194.html
Copyright © 2011-2022 走看看