(1-6)综合实战:最短路径规划实战

1.6  综合实战:最短路径规划实战

本项目基于CS:GO游戏地图,利用Dijkstra算法为玩家提供最短路径规划,考虑了地图中列车行驶时间,帮助玩家在游戏中更智慧地选择路径。通过集成计算机科学和游戏设计,项目旨在提升CS:GO玩家的战术决策和游戏体验,为他们提供更高效的导航方案。

1.6.1  项目介绍

随着电子竞技的兴起,Counter-Strike: Global Offensive(CS:GO)成为一款备受欢迎的多人射击游戏。在CS:GO的游戏模式中,特别是在“炸弹”模式中,玩家需要迅速而有效地找到并前往炸弹点(Bombsite)以完成任务。为了增添游戏的复杂性,游戏地图通常设计得非常庞大,其中包括了多种路径和地点。如图1-1所示。

图1-1  地图

本项目的背景源于对CS:GO游戏中玩家路径规划的探索,特别是在考虑了地图中列车的行驶时间后。在CS:GO的Train地图中,列车作为一种独特的地图元素,不仅为玩家提供了掩护,同时也增加了在地图上行进的挑战。为了提高游戏体验,项目采用了Dijkstra算法,这是一种用于寻找图中最短路径的经典算法,以确定玩家从起点到达炸弹点的最迅速路径。

通过该项目,玩家可以选择起始位置和目标炸弹点,系统将利用Dijkstra算法计算出最短路径,并考虑列车行驶时间,提供给玩家在游戏中更有效的导航方案。此项目不仅具有技术挑战,还对玩家的战术决策和游戏体验产生积极影响。

1.6.2  构建Graph

在开发这个项目之前,开首先创建了一个Graph表示Counter-Strike: Global Offensive(CS:GO)地图的数据结构。这个Graph是一个带有顶点和边的图,其中每个顶点代表地图上的一个位置,每条边表示两个位置之间的连接。Graph图的雏形如图1-2所示。

图1-2  Graph图的雏形

为了使Graph更加直观和标准,将图1-2继续油画城标准的Graph图,如图1-3所示。

图1-2  Graph标准图

本项目的开发过程始于地图的图形表示,然后演化到路径查找算法的实现,并最终形成用户界面和交互的完整程序。

1.6.3  具体实现

本项目的目的是通过 Dijkstra 算法找到在 CS:GO 地图上从一个起始点到达炸弹点的最短路径,并输出路径以及预计所需的时间。在主函数中,用户被要求选择起始点和目标炸弹点,然后调用 Dijkstra 函数来计算并输出最短路径和预计时间。

实例1-5:探索CS游戏玩家的最短路径codes/1/cs/main-bahasa.cpp

编写文件main-bahasa.cpp,使用Dijkstra算法在CS:GO地图中查找最短路径,帮助玩家确定从起点到炸弹点(Bombsite)的最短路径。通过输入起始点和目标炸弹点,程序输出最短路径以及估计的到达时间。代码使用邻接矩阵表示地图,优先队列选择最短距离的顶点,实现了路径和时间的计算与输出。

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

#define INF INT_MAX

using namespace std;

// 使用Dijkstra算法查找最短路径的函数
void dijkstra(vector<vector<int>>& graph, int start, int dest) {
    int n = graph.size();

    // 向量用于存储从起点到所有顶点的最短距离
    vector<int> distance(n, INF);

    // 向量用于存储从起点到每个顶点的最短路径
    vector<vector<int>> paths(n);

    // 优先队列用于选择具有最短距离的顶点
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    distance[start] = 0;
    pq.push(make_pair(0, start));

    while (!pq.empty()) {
        int u = pq.top().second;
        pq.pop();

        for (int v = 0; v < n; v++) {
            if (graph[u][v] != 0) {
                int weight = graph[u][v];
                if (distance[u] + weight < distance[v]) {
                    distance[v] = distance[u] + weight;
                    pq.push(make_pair(distance[v], v));

                    paths[v].clear();
                    paths[v].insert(paths[v].end(), paths[u].begin(), paths[u].end());
                    paths[v].push_back(u);
                }
            }
        }
    }

    // 打印从起点到目标的最短路径
    cout << "从顶点 " << char(start + 'A') << " 到炸弹点的最短路径是: ";
    for (int i = 0; i < paths[dest].size(); i++) {
        cout << char(paths[dest][i] + 'A') << " -> ";
    }
    cout << char(dest + 'A') << endl;

    // 打印从起点到目标的最短距离
    cout << "预计所需时间: " << distance[dest] << endl;
}

int main() {
    vector<vector<int>> graph = {
        {0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {2, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
        {0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0},
        {0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2},
        {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0},
        {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3},
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 3},
        {0, 0, 0, 0, 0, 0, 7, 6, 5, 0, 0, 2, 2, 0, 0, 0},
        {0, 0, 0, 4, 4, 0, 2, 2, 2, 0, 2, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 4, 3, 3, 0, 0, 0}
    };

    int startVertex, bomVertex;
    char start, bom;

    cout << "===================================================================" << endl;
    cout << "Program Penentuan Rute Terdekat Menuju Bombsite pada Permainan CSGO" << endl;
    cout << "===================================================================" << endl;
    cout << "Daftar Lokasi:" << endl;
    cout << "Vertex A melambangkan T Spawn (tempat awal teroris)" << endl;
    cout << "Vertex B melambangkan Big Blue" << endl;
    cout << "Vertex C melambangkan T Long" << endl;
    cout << "Vertex D melambangkan Break Room" << endl;
    cout << "Vertex E melambangkan Ladder" << endl;
    cout << "Vertex F melambangkan Lower Ramp" << endl;
    cout << "Vertex G melambangkan A3 Train" << endl;
    cout << "Vertex H melambangkan A2 Train" << endl;
    cout << "Vertex I melambangkan A1 Train" << endl;
    cout << "Vertex J melambangkan Boilers" << endl;
    cout << "Vertex K melambangkan Connector" << endl;
    cout << "Vertex L melambangkan Pink Train" << endl;
    cout << "Vertex M melambangkan Cloud" << endl;
    cout << "Vertex N melambangkan CT Spawn (tempat awal anti-teroris)" << endl;
    cout << "Vertex O melambangkan Bombsite A" << endl;
    cout << "Vertex P melambangkan Bombsite B" << endl;


    cout << "Pilih Vertex Awal (Gunakan Kapital): ";
    cin >> start;
    startVertex = start - 'A';

    cout << "Pemilihan Bombsite " << endl;
    cout << "Jika Bombsite A Ketik O " << endl;
    cout << "Jika Bombsite B Ketik P" << endl;
    cout << "Pilih Bom (Gunakan Kapital): ";

    cin >> bom;
    bomVertex = bom - 'O' + 14;

    dijkstra(graph, startVertex, bomVertex);

    return 0;
}

上述代码的实现流程如下所示。

  1. 首先,定义了一个函数dijkstra,该函数使用Dijkstra算法来计算从起点到目标点的最短路径。Dijkstra算法使用优先队列和邻接矩阵表示地图,初始化距离向量和路径向量,将起点加入优先队列。
  2. 然后,Dijkstra算法进入主循环,每次从优先队列中弹出距离最短的顶点,并更新与该顶点相邻的顶点的距离和路径。这个过程重复直到队列为空,确保所有顶点的最短路径被计算。
  3. 接着,在主函数中创建了一个CS:GO地图的邻接矩阵,并通过用户输入选择起点和目标炸弹点。通过调用dijkstra函数,程序计算并输出了从起点到目标炸弹点的最短路径,以及估计的到达时间。
  4. 最后,展示了CS:GO地图中各个顶点的标识,帮助玩家轻松选择起点和目标炸弹点,以便获取最短路径信息。

执行后首先根据提示选择起点:根据地图上显示的顶点信息,输入起点的字母表示(使用大写字母),例如,输入'A'代表T Spawn。然后选择目标炸弹点,根据提示输入字母'O'代表Bombsite A或字母'P'代表Bombsite B。完整的测试过程如下:

===================================================================
Program Penentuan Rute Terdekat Menuju Bombsite pada Permainan CSGO
===================================================================
Daftar Lokasi:
Vertex A melambangkan T Spawn (tempat awal teroris)
Vertex B melambangkan Big Blue
Vertex C melambangkan T Long
Vertex D melambangkan Break Room
Vertex E melambangkan Ladder
Vertex F melambangkan Lower Ramp
Vertex G melambangkan A3 Train
Vertex H melambangkan A2 Train
Vertex I melambangkan A1 Train
Vertex J melambangkan Boilers
Vertex K melambangkan Connector
Vertex L melambangkan Pink Train
Vertex M melambangkan Cloud
Vertex N melambangkan CT Spawn (tempat awal anti-teroris)
Vertex O melambangkan Bombsite A
Vertex P melambangkan Bombsite B
Pilih Vertex Awal (Gunakan Kapital): A
Pemilihan Bombsite
Jika Bombsite A Ketik O
Jika Bombsite B Ketik P
Pilih Bom (Gunakan Kapital): O
从顶点 A 到炸弹点的最短路径是: A -> B -> D -> O
预计所需时间: 8

本Dijkstra篇已完结:

(1-1)Dijkstra算法:Dijkstra算法简介-CSDN博客

(1-2)Dijkstra算法:Dijkstra算法的核心思想-CSDN博客

(1-3)Dijkstra算法:交通网络中的最短路径规划-CSDN博客

(1-4)Dijkstra算法:在机器人导航系统中的应用-CSDN博客

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值