1. 基本任务介绍

算法目的:炸弹放在哪里可以最大杀伤?
编程难点

  1. 数组作为形参是深(是)?如果深,有必要应用?
    答:形参是实参的一份拷贝,是局部变量。但是数组是个例外,因为数组的数据太多了,将其一一赋值既麻烦又浪费空间,所以数组作为参数传递给函数的只是数组首元素的地址,数据还是在内存里的,函数在需要用到后面元素时再按照这个地址和数组下标去内存查找。也就是说后面的元素根本没到函数里来。因为数组的复制将导致连续的内存读与内存写,其时间开销取决于数组长度,有可能会变得非常大。为了避免复制数组的开销,才用指针代替数组。因此C语言使得当数组作为实参传递给函数的时候,将退化为同类型的指针,再传递指针的值。
    因此,在函数中修改数组值时,修改的是真的值。
  • 由于是通过指针传递,因此无法得到数组的长度。(在通过指针传递时,需要另外传入参数来传递数组的大小)
  • 传递引用时,同时将数组长度也传递进去了,所以传入时必须为相应长度的数组。并且,在传递引用时,需要注意用()将&aa括起来,否则编译器报错。
  1. 二维数组形参和一维不太一样
  • (Type (&str_)[size], char map_[][13]) 后面的13好像不能少
  1. 不能纯统计每行列的敌人,有墙的

代码


// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
# include <string>
#include<iostream>
using namespace std;
char map_[13][13] = {0};
std::string map2[] = {"#############",
"#GG.GGG#GGG.#",
"###.#G#G#G#G#",
"#.......#..G#",
"#G#.###.#G#G#",
"#GG.GGG.#.GG#",
"#G#.#G#.#.#.#",
"##G...G.....#",
"#G#.#G###.#G#",
"#...G#GGG.GG#",
"#G#.#G#G#.#G#",
"#GG.GGG#G.GG#",
"#############",
};int lines = sizeof(map_) / sizeof(map_[0][0]); //总共多长int col = sizeof(map_[0])/ sizeof(map_[0][0]); int row = lines / col;
template <typename  Type, int size>
void string2char(Type (&str_)[size], char map_[][13]) {for (int i = 0; i < size; i++) {for (int j = 0; j < str_[i].size(); j++) {map_[i][j] = str_[i][j];}}
}int get_range1(int i, int j) {int num = 0;for (int i_ = 0; i_ < row; i_++) {if (map_[i_][j] == 'G') num += 1;//num += map_[i_][j];}for (int i_ = 0; i_ < col; i_++) {if (map_[i][i_] == 'G') num += 1;//num += map_[i][i_];}return num;
}
int get_direction(int  currenti, int  currentj, int direction[2]) {int num = 0;while ((currenti >= 0 && currenti <= row)&&((currentj >= 0 && currentj <= col) )) {currenti += direction[0];currentj += direction[1];if (map_[currenti][currentj] == 'G') num += 1;if (map_[currenti][currentj] == '#')break;}return num;
}
int get_range(int i, int j) {int num = 0;int currenti=i, currentj=j;int direction[][2] = {{1,0},{0,1},{-1,0},{0,-1}};for (auto d : direction) {num += get_direction(i, j, d);}return num;
}void main() {string2char(map2, map_);int i = 0;// 遍历所有 map_ 的点位int num_ = 0;int maxi = 0;int maxj = 0;int max_num = 0;for (int i = 0; i < row;i++) {for (int j = 0; j < col; j++) {if (map_[i][j] == '.') {num_ = get_range(i, j);if (num_ > max_num) {maxi = i;maxj = j;max_num = num_;}}}}cout << maxi << "," << maxj << endl;return;
}

2. 基于广度搜索的炸弹人算法

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
# include <string>
#include<iostream>
using namespace std;
char map_[13][13] = {0};
std::string map2[] = {"#############",
"#GG.GGG#GGG.#",
"###.#G#G#G#G#",
"#.......#..G#",
"#G#.###.#G#G#",
"#GG.GGG.#.GG#",
"#G#.#G#.#.#.#",
"##G...G.....#",
"#G#.#G###.#G#",
"#...G#GGG.GG#",
"#G#.#G#G#.#G#",
"#GG.GGG#G.GG#",
"#############",
};int lines = sizeof(map_) / sizeof(map_[0][0]); //总共多长int col = sizeof(map_[0])/ sizeof(map_[0][0]); int row = lines / col;
template <typename  Type, int size>
void string2char(Type (&str_)[size], char map_[][13]) {for (int i = 0; i < size; i++) {for (int j = 0; j < str_[i].size(); j++) {map_[i][j] = str_[i][j];}}
}int get_direction(int  currenti, int  currentj, int direction[2]) {int num = 0;while ((currenti >= 0 && currenti <= row)&&((currentj >= 0 && currentj <= col) )) {currenti += direction[0];currentj += direction[1];if (map_[currenti][currentj] == 'G') num += 1;if (map_[currenti][currentj] == '#')break;}return num;
}
int get_range(int i, int j) {int num = 0;int currenti=i, currentj=j;int direction[][2] = {{1,0},{0,1},{-1,0},{0,-1}};for (auto d : direction) {num += get_direction(i, j, d);}return num;
}// ---------------// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <queue>
#include<vector>
#include<string>
using namespace std;struct Point {//行与列int row;int col;int step = 0;int range = -1;//默认构造函数Point() {row = col = -1;}Point(int x, int y, int step_ = 0) {this->row = x;this->col = y;step = step_;}bool operator==(const Point& rhs) const {if (this->row == rhs.row && this->col == rhs.col)return true;return false;}
};class Pos_find {public:int maze[13][13];int passed[13][13];int neighbour[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};  int row = sizeof(maze) / sizeof(maze[0]);int col = sizeof(maze[0]) / sizeof(maze[0][0]);int range_map[13][13] = { 0 }; //[]TODO: int range_map[row][col] = { 0 }; 为什么报错int obstacles = -1, blank = 0, enemy=-2;queue<Point> vecPath;Point ** mark = 0;template <class  T1, class  T2>bool valid_point(Point point, T1 obstacles = -1, T2 blank = 0) {//判断点是否可以作为下一 1 障碍物 2 边界 3 未走过int row = sizeof(maze) / sizeof(maze[0]);int col = sizeof(maze[0]) / sizeof(maze[0][0]);// 判断障碍物if (maze[point.row][point.col] == obstacles) {return false;}if (enemy != -2 && (maze[point.row][point.col] == enemy)) {return false;}// 判断边界if ((point.row < 0 || point.row > row - 1) || (point.col < 0 || point.col > col - 1))return false;else// 未走过if (passed[point.row][point.col] == 0)return true;else {cout << "wrong in valid" << endl;return false;}}int get_range(int i, int j) {int num = 0;//int currenti = i, currentj = j;int direction[][2] = {{1,0},{0,1},{-1,0},{0,-1}};for (auto d : direction) {num += get_direction(i, j, d);}return num;}int get_direction(int  currenti, int  currentj, int direction[2]) {int num = 0;while ((currenti >= 0 && currenti <= row) && ((currentj >= 0 && currentj <= col))) {currenti += direction[0];currentj += direction[1];if (maze[currenti][currentj] == 'G')num += 1;if (maze[currenti][currentj] == '#')break;}return num;}// 修改地图template <typename  Type, int size>void string2char(Type(&str_)[size]) {for (int i = 0; i < size; i++) {for (int j = 0; j < str_[i].size(); j++) {maze[i][j] = str_[i][j];}}obstacles = '#';blank = '.';enemy = 'G';}void mazePath( Point& start_pos, Point& target_pos) {vecPath = queue<Point>();// build a empty queuevecPath.push(start_pos);maze[start_pos.row][start_pos.col] = 1;int flag = 0;int row = sizeof(maze) / sizeof(maze[0]);int col = sizeof(maze[0]) / sizeof(maze[0][0]);Point temp_point, new_point;int i = 1;// 建立一个二维数组,每个数组里面是PointPoint** mark = new Point * [row];//[TODO] 这里不需要释放吗?//for (auto ) // ?auto 吗?[TODO]for (int i = 0; i < row; i++) {mark[i] = new Point[col];}// 开始的格子指向自己mark[0][0] = start_pos;// 指向数组的指针while (vecPath.empty() == false) {// 取temp_point = vecPath.front();// 获取相邻值for (auto deta : neighbour) {new_point = Point(temp_point.row + deta[0], temp_point.col + deta[1], temp_point.step + 1);if (valid_point(new_point, obstacles, blank)) { // 如果点可以加入maze[new_point.row][new_point.col] = temp_point.step + 1;mark[new_point.row][new_point.col] = temp_point;// 放入父节点vecPath.push(new_point);}if (new_point == target_pos) {flag = 1;break;}}vecPath.pop();if (flag == 1) break;i++;}if (vecPath.empty() == false) {// 获取最后一个格子的数值temp_point = vecPath.back();// 依据最后一个获取前一个while ((temp_point.row == start_pos.row && temp_point.col == start_pos.col) == false) {cout << " <" << temp_point.row << "," << temp_point.col << "> ";temp_point = mark[temp_point.row][temp_point.col];}}return;}void mazePath(Point& start_pos) {int num_ = 0;int maxi = 0;int maxj = 0;int max_num = 0;vecPath = queue<Point>();// build a empty queuevecPath.push(start_pos);//maze[start_pos.row][start_pos.col] = 1; []TODO:记录步伐应该放在一起,这种容易漏掉。max_num = get_range(start_pos.row, start_pos.col);range_map[start_pos.row][start_pos.col] = max_num;passed[start_pos.row][start_pos.col] = 1;int flag = 0;Point temp_point, new_point;int i = 1;// 建立一个二维数组,每个数组里面是PointPoint** mark = new Point * [row];//[TODO] 这里不需要释放吗?     //for (auto ) // ?auto 吗?[TODO]for (int i = 0; i < row; i++) {mark[i] = new Point[col];}// 开始的格子指向自己mark[0][0] = start_pos;// 指向数组的指针while (vecPath.empty() == false) {// 取temp_point = vecPath.front();// 获取相邻值for (auto deta : neighbour) {new_point = Point(temp_point.row + deta[0], temp_point.col + deta[1], temp_point.step + 1);if (valid_point(new_point, obstacles, blank)) { // 如果点可以加入//maze[new_point.row][new_point.col] = temp_point.step + 1; //[x]TODO: 随意修改成员变量不是好习惯 - > 新编量记录走过的地方num_ = get_range(new_point.row, new_point.col);range_map[new_point.row][new_point.col] = num_;mark[new_point.row][new_point.col] = temp_point;// 放入父节点passed[new_point.row][new_point.col] = temp_point.step + 1;vecPath.push(new_point);if (num_ > max_num) {maxi = new_point.row;maxj = new_point.col;max_num = num_;}}}vecPath.pop();//if (flag == 1) break;i++;}// 找到最大的点cout << max_num << endl;return;}
};  //[TODO] warning :警告    C26495  未初始化变量 Pos_find::mark。始终初始化成员变量(type.6)。        238  解决加 Point ** mark = 0;int main()
{// Pos_find map_;Point start_pt = Point(1, 3), end_pt = Point(4,4);//map_.mazePath(start_pt, end_pt);//  任务二// 修改地图map_.string2char(map2);map_.mazePath(start_pt);
}

数据结构- 炸弹人游戏相关推荐

  1. 炸弹人游戏开发系列(6):实现碰撞检测,设置移动步长

    前言 上文中我们实现了"玩家控制炸弹人"的功能,本文将实现碰撞检测,让炸弹人不能穿过墙.在实现的过程中会发现炸弹人移动的问题,然后会通过设置移动步长来解决. 说明 名词解释 具体状 ...

  2. (NO.00005)iOS实现炸弹人游戏(十一):怪物之火精灵

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 从本篇开始我们一次介绍一下游戏中敌人的制作过程.看过第一篇的小 ...

  3. (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多 ...

  4. (NO.00005)iOS实现炸弹人游戏(一):游戏的整体规划设计

    在这新的系列中,我们来尝试完成一款经典的游戏:炸弹人 这是以前红白机上的炸弹人,由于游戏可玩性强,玩法又简单,在后面的机型上陆续推出了很多款续作. 在随后的触屏设备上也出现了炸弹人的模拟版,用的是模拟 ...

  5. Bombermaaan-最好的开源炸弹人游戏(支持AI人机对战,SFC复刻版)

    关键词:炸弹人源代码,炸弹人AI算法 目录 一.游戏截图 二.基本信息 三.游戏设计介绍 四.道具说明 五.下载 一.游戏截图       二.基本信息 语言:C++ 平台:Windows / Lin ...

  6. C#游戏开发之炸弹人游戏开发

    笔者第一次发表文章,考虑不全多多包涵.也想借此机会和大家交流游戏开发.希望大神能指点一二.笔者是利用VS2010编译器,下面进入正题: 利用C#控件来实现2D游戏开发还是比较方便.先从总体上介绍炸弹人 ...

  7. 炸弹人游戏开发系列(8):放炸弹

    前言 上文中我们加入了1个敌人,使用A*算法寻路.本文会给我们的炸弹人增加放炸弹的能力. 说明 名词解释 xx类族 是指以xx为基类的继承树上的所有类. 本文目的 实现"放炸弹"功 ...

  8. 炸弹人游戏开发系列(2):初步设计

    前言 有了上文的初步需求分析后,就可以进入初步设计阶段了. 本文目的 得到初步的领域模型,对层和模块进行初步的划分. 本文主要内容 技术选择 开发环境 外部依赖 代码结构 开发方法 初步领域模型 高层 ...

  9. pygame开发的炸弹人游戏(详细讲解)

    前言 本次开发的游戏为炸弹人游戏,是一个经典的小游戏,4399.7k7k等上面就可以找到,本游戏基于python语言,基于pygame开发,pygame是 跨平台 Python模块,专为电子游戏设计. ...

最新文章

  1. SCSF 系列:Smart Client Software Factory 启动过程详解
  2. 成功解决urllib.error.URLError urlopen error Errno 11004 getaddrinfo failed
  3. 中国大学MOOC 人工智能导论第五章测试
  4. OCS2007R2部署之二准备AD及扩展
  5. java控制系统音量_Java 控制 Windows 系统音量-Go语言中文社区
  6. Gym102028G Shortest Paths on Random Forests 生成函数、多项式Exp
  7. iOS开发UI篇—程序启动原理和UIApplication
  8. linux查询语言,Linux结构化查询语言SQL——SQL的分类和DDL使用
  9. java集成Cplex:Cplex下载、IDEA环境搭建、docker部署
  10. 黑马程序员微信小程序开发前端教程_零基础玩转微信小程序P30 列式编程
  11. C语言课程设计图形库
  12. Android APK反编译技巧全讲解
  13. 从选课系统看软件开发周期
  14. ZZULIOJ 1882: 蛤玮的魔法【数学】
  15. 英文学术论文写作基础
  16. 读论文-OVSeg-基于遮罩自适应CLIP的开放词汇语义分割-Open-vicabulr semantic segmentation with mask-adaptived CLIP
  17. el-form内el-select与el-input纵向不对齐的问题
  18. html标识标志相关符号
  19. linux 查看开放的端口以及开放端口并且永久开放端口的方法
  20. 前端JavaScript+HTML

热门文章

  1. 优化企业会议解决方案
  2. 【调剂】沈阳航空航天大学2020年硕士研究生调剂信息
  3. 企业微信朋友圈可以删除吗?删除后别人还能看到吗?
  4. php 工程师面试题,PHP工程师面试题
  5. 文本转语音最新便携版Balabolka2.15.806 + 10个左右的发音人
  6. 《花开半夏》--3 对峙(1)
  7. SUMO中车辆类型的定义及路由文件的写法
  8. 一图看懂SAP仓储单位SU的应用
  9. html5 触摸 滚动,html5的触摸事件
  10. DAO PO BO DTO VO DO的区别