C++老鼠迷宫

2023-05-16

#include<iostream>//输入输出流 
#include<fstream>//文件头文件
#include<conio.h>
#include<time.h>//时间的头文件
#include<windows.h>//使用系统头文件
#include<string>//字符串头文件
#include<stack>//栈头文件
#include<math.h>//数学函数头文件
#include<ctype.h>//命名函数

#define TIME 12//规定的游戏时间
#define maxsize 1000 //栈最多的元素个数

using namespace std;

int **map;//迷宫二维动态数组
int M, N;//迷宫行与列数
int start_x, start_y, end_x, end_y, x, y;//老鼠的开始位置,最终位置等全局变量
int g;
int h;//老鼠的原位置
ofstream out;//将输入的数组写入文件
bool victory = false;//bool变量开始为假,为真时结束

                     //求最短路径和所有路径
struct MazeRoute {
    int i;      //路径横坐标
    int j;      //路径纵坐标
    int d;     //方向
}Stack[maxsize], path[maxsize];      //定义栈和存放最短路径的数组

int top = -1;     //栈顶指针
int count = 1;   //路径数计数
int minlen = maxsize;     //最短路径长度 


void mazeframe(int x1, int y1, int x2, int y2) {//起始坐标与终点坐标 
    int i, j, d, find, k, m, n;
    int count = 1;
    top++;//栈不空,初始结点入栈 
    Stack[top].i = x1;
    Stack[top].j = y1;
    Stack[top].d = -1;
    map[x1][y1] = -1;//初始结点入栈
    while (top>-1) {//栈不空时循环 
        i = Stack[top].i;
        j = Stack[top].j;
        d = Stack[top].d;
        if (i == x2&&j == y2) {
            cout << "路径:" << count++;//找到出口,输出路径
            cout << endl;
            for (k = 0; k <= top; k++) {
                cout << "(" << Stack[k].i << "," << Stack[k].j << ")";
                if ((k + 1) % 7 == 0)//输出每7个结点时换行
                    cout << endl;
            }
            cout << endl;
            cout << "按回车键继续···\n";
            cout << endl;
            if (top + 1<minlen) {//比较输出最短路径
                for (k = 0; k <= top; k++)
                    path[k] = Stack[k];//将最短路径存入path[]中
                minlen = top + 1;
            }
            map[Stack[top].i][Stack[top].j] = 0;//让该位置变为其他路径的可走结点
            i = Stack[top].i;
            j = Stack[top].j;
            d = Stack[top].d;
        }
        find = 0;
        while (d<4 && find == 0) {//找下一个可走结点 
            d++;
            switch (d) {
            case 0:i = Stack[top].i - 1; j = Stack[top].j; break; //上面路可以移动时移动执行 
            case 1:i = Stack[top].i; j = Stack[top].j + 1; break; //右面路可以移动时移动执行 
            case 2:i = Stack[top].i + 1; j = Stack[top].j; break; //下面路可以移动时移动执行
            case 3:i = Stack[top].i; j = Stack[top].j - 1; break; //左面路可以移动时移动执行 
            }
            if (map[i][j] == 0 && map[i][j] != -1)
                find = 1;
        }
        if (find == 1) {//找到了下一个可走的结点 
            Stack[top].d = d;//修改原栈顶元素的d值
            top++;//下一个可走结点进栈
            Stack[top].i = i;
            Stack[top].j = j;
            Stack[top].d = -1;
            map[i][j] = -1;//避免重复走到该结点 
        }
        else {
            map[Stack[top].i][Stack[top].j] = 0;//让该位置变为其他路径的可走结点
            top--;
        }
    }
    cout << "最短路径:";
    cout << endl;
    for (k = 0; k<minlen; k++)
        cout << "(" << path[k].i << "," << path[k].j << ")";
    {
        if ((k + 1) % 7 == 0)
            cout << endl;
    }
    cout << endl;
}

// 改变迷宫的函数
void change() {
    if (map[x][y] == 3) {//如果到达粮仓处就是获得胜利 
        victory = true;//因为初始化的victory为false 
    }
    map[x][y] = 2;//原来的路为人
    map[g][h] = 0;//原来的人变为路 
}

//画图以及移动函数
//画图函数 
void draw() {
    for (int val = 0; val<M; val++) {//行 
        for (int flag = 0; flag<N; flag++) {//列 
            if (map[val][flag] == 1) {//1为墙 
                cout << "■";//就是墙 
            }
            else if (map[val][flag] == 0) {//0为路 
                cout << "  ";
            }
            else if (map[val][flag] == 2) {//2为老鼠 
                cout << '\001' << " ";
            }
            else if (map[val][flag] == 3) {//3为粮仓 
                cout << '\003' << " ";
            }
        }
        cout << endl;//换行 
    }
}


//改变迷宫的墙与路 
void ChangeMaze(int i, int j) {
    int p;
    if (i == 0 || j == 0 || (i == 1 && j == 1) || (i == M - 2 && j == N - 2)) {//围墙与老鼠以及粮仓的位置不能改变
        cout << "这些位置是不能改变的";
    }
    else {
        cout << "将墙变为路请输入0,将路变为墙请输入1:";
        cin >> p;
        switch (p) {
        case 0:
            map[i][j] = 0; break;//将其变为路 
        case 1:
            map[i][j] = 1; break;//将其变为墙 
        }
    }
}

//向上的函数
void up() {
    if (map[x - 1][y] != 1) {//如果向上有通路 
        g = x;//将老鼠的原位置赋给g h,在change函数中变为路 
        h = y;
        x = x - 1;//改变老鼠的新位置,在change函数中实现 
    }
}


//向下的函数
void down() {
    if (map[x + 1][y] != 1) {//如果向下有通路 
        g = x;//将老鼠的原位置赋给g h,在change函数中变为路 
        h = y;
        x = x + 1;//改变老鼠的新位置,在change函数中实现 
    }
}

//向右的函数
void right() {
    if (map[x][y + 1] != 1) {//如果向右有通路 
        g = x;//将老鼠的原位置赋给g h,在change函数中变为路 
        h = y;
        y = y + 1;//改变老鼠的新位置,在change函数中实现 
    }
}

//向左的函数
void left() {
    if (map[x][y - 1] != 1) {//如果向左有通路 
        g = x;//将老鼠的原位置赋给g h,在change函数中变为路 
        h = y;
        y = y - 1;//改变老鼠的新位置,在change函数中实现 
    }
}

int CountLinesh(char *filename) {//统计迷宫数组的行数
    ifstream in;
    int n = 0;
    string temp;
    in.open(filename, ios::in);//ios::in 表示以只读的方式读取文件
    if (in.fail()) {//文件打开失败:返回0
        return 0;
    }
    else {//文件存在
        while (getline(in, temp)) {
            n++;
        }
        return n;
    }
    in.close();//关闭文件
}


int CountLinesz(char *filename) {
    ifstream in;
    int n = 0;
    int i;
    in.open(filename, ios::in);//ios::in 表示以只读的方式读取文件
    while (!in.eof()) {//判断是否到达文件尾 
        i = in.get();
        if (in.fail()) {
            break;
        }
        if (isdigit(i)) {
            n++;//总数加一 
        }
    }
    return n;
    in.close();
}


int main() {
    char choice;
    cout << "您是否想要自己构建迷宫呢?Y OR N: ";
    cin >> choice;
    switch (choice) {
    case 'Y':char sd[50];//文件路径字符数组
        cout << "请输入你要保存的文件路径:";
        cin >> sd;
        out.open(sd);
        cout << "请输入二维数组迷宫的行数与列数: ";
        int vb, vn, ch;
        cin >> vb >> vn;
        cout << "请输入二维数组表示的迷宫,其中0表示路,1表示墙,2表示老鼠,3表示粮仓:" << endl;
        int ql, qk;
        for (ql = 0; ql<vb; ql++) {
            for (qk = 0; qk<vn; qk++) {
                cin >> ch;
                out << ch << " ";
            }
            out << '\n';
        }
        out.close();
        break;
    case 'N':break;
    default:break;
    }
    int count = 0;//字符总数
    int hang = 0;//数组行数
    char p[50];
    ifstream in;
    int i;
    cout << "请输入要打开文件的路径:";
    cin >> p;
    count = CountLinesz(p);
    hang = CountLinesh(p);
    M = hang;
    N = count / M;//N为列数
    start_x = (M - 1) / 2;//老鼠的初始位置 
    start_y = (N - 1) / 2;
    end_x = M - 2;//粮仓的位置 
    end_y = N - 2;
    x = start_x;
    y = start_y;
    g = 0;
    h = 0;
    map = (int**)malloc(sizeof(int*)*M);
    for (int l = 0; l<M; l++) {
        map[l] = (int*)malloc(sizeof(int)*N);
    } //创建动态数组 
    in.open(p);
    for (int n = 0; n<M; n++) {
        for (int m = 0; m<N; m++) {
            in >> i;//将文件中的数字写入内存
            map[n][m] = i;//将内存中的数据写入到数组中 
        }
    }
    //接下来是初始化
    for (int sx = 0; sx<N; sx++) {
        map[0][sx] = 1;
    }
    for (int sc = 1; sc<M; sc++) {
        map[sc][0] = 1;
    }
    for (int sv = 1; sv<N; sv++) {
        map[M - 1][sv] = 1;
    }
    for (int sb = 1; sb<M - 1; sb++) {
        map[sb][N - 1] = 1;
    }
    map[(M - 1) / 2][(N - 1) / 2] = 2;
    map[M - 2][N - 2] = 3;
    map[M - 3][N - 2] = 1;
    in.close();

    draw();//先画原图
    char ch;//输入字符是否要改变墙与路
    cout << "是否要改变墙与路?Y OR N :";
    cin >> ch;
    while (ch == 'Y') {
        switch (ch) {
        case 'Y':int pa, pb;
            cout << "请输入你要改变的位置:";
            cin >> pa >> pb;
            ChangeMaze(pa, pb);
            break;
        case 'N':break;
        }
        cout << "是否要改变墙与路?Y OR N :";
        cin >> ch;
    }
    draw();
    clock_t start, finish;//即使开始和结束
    double totaltime;//程序执行的总时间
    start = clock();//计时开始
    while (!victory) {//victory为false时开始执行
        unsigned short k;//定义一个获取键盘消息的反映机制整型数
        Sleep(100);//将进程挂起100毫秒,也就是0.1秒
        k = _getch();
        if (27 == k) break;//?Esc???
        if (0 == k || 0xe0 == k) k |= _getch() << 8;//????
        switch (k) {
        case 0x48e0: up();    change(); system("cls"); draw(); break;//向上,改变位置,清屏,再画图,结束      
        case 0x4be0: left();  change(); system("cls"); draw(); break;//向左,改变位置,清屏,再画图,结束   
        case 0x50e0: down();  change(); system("cls"); draw(); break;//向下,改变位置,清屏,再画图,结束   
        case 0x4de0: right(); change(); system("cls"); draw(); break;//向右,改变位置,清屏,再画图,结束   
        default:break;
        }
    }
    finish = clock();//计时结束
    totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
cout << "\n此程序运行的总时间是" << totaltime << "秒!" << endl;
    if (totaltime<TIME) cout << "小于规定的时间12秒,恭喜你,你赢了!" << endl;
    else cout << "大于规定的时间12秒,很抱歉,你输了!" << endl;
    map[start_x][start_y] = 0;
    map[end_x][end_y] = 0;
    mazeframe(start_x, start_y, end_x, end_y);
    //删除动态数组
    for (int z = 0; z<M; z++) {
        delete[]map[z];//先撤销指针元素所指向的数组 
    }
    delete[]map;
    system("pause");
    return 0;
}




    以上是程序的截图,我们可以手动控制键盘的方向键来控制老鼠的移动
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++老鼠迷宫 的相关文章

  • 基于nand flash的文件系统的整理

    一 Nandflash简介 基本概念 xff1a flash芯片 block page 附加页 1 1结构 Flash芯片的擦除以块为单位 xff0c 写以页为单位 在每个flash芯片中包括非常多的块 xff0c 同款芯片上每个块的大小相
  • 卡普的21个NP完全问题-问题描述

    以下部分为卡普21个问题的名称 xff08 来自于维基百科https zh wikipedia org wiki E5 8D A1 E6 99 AE E7 9A 84 E4 BA 8C E5 8D 81 E4 B8 80 E5 80 8BN
  • 在终端使用命令卸载交叉编译工具

    ubuntu中可以使用命令行 sudo apt install gcc arm linux gnueabi 自动安装交叉编译工具 xff0c 但是往往软件版本太过超前了 xff0c 交叉编译时候使用的命令是 arm linux gnueab
  • ubuntu系统下降低风扇转速的方式

    我的本自从装了ubuntu之后风扇就呼呼的响个不停 xff0c 看了很多教程都是说强制降低风扇转速的方式 偶然看到了转速过快的原因是因为显卡与系统自带的驱动不兼容的问题 我的显卡是nvidia xff0c 安装显卡驱动步骤如下 xff1a
  • 怎样向visual studio加入vim的强大编辑能力,让装逼防不胜防!

    经常使用vim的小伙伴知道它的强大 私认为它最大的优势就是解放了你的右手 让鼠标成为了累赘 但是其学习曲线是相当陡峭的 虽然经常使用linux系统 但是偶尔还是会迫于形势缓缓胃口的 在使用VS的时候经常不自觉的就来一串ESC shift 冒
  • JGROUPS

    package com example jgroupsdemo import jakarta annotation PostConstruct import lombok extern slf4j Slf4j import org jgro
  • android studio仿真时遇到VT-x is disabled in BIOS解决办法

    在使用android studio run app时候遇到了 xff1a Intel HAXM is required to run this AVD VT x is disabled in BIOS 的错误提示 xff0c 导致无法进行仿
  • linux系统中resolv.conf文件详解

    etc resolv conf 它是DNS客户机配置文件 xff0c 用于设置DNS服务器的IP地址及DNS域名 xff0c 还包含了主机的域名搜索顺序 该文件是由域名解析器 xff08 resolver xff0c 一个根据主机名解析IP
  • yii2.0 basic版使用CRUD生成器的时候提示错误及页面显示错误

    在使用model生成器的时候不用加命名空间 xff0c 写好表名就可以直接生成了 但是在用CRUD的时候填写完controllers和model class之后点击生成会弹出错误提示 xff1a Class 39 TelBook 39 sp
  • linux日志对应内容

    var log messages 包括整体系统信息 xff0c 其中也包含系统启动期间的日志 此外 xff0c mail xff0c cron xff0c daemon xff0c kern和auth等内容也记录在var log messa
  • 常用证书操作函数

    现有的证书大都采用X 509规范 xff0c 主要同以下信息组成 xff1a 版本号 证书序列号 有效期 拥有者信息 颁发者信息 其他扩展信息 拥有者的公钥 CA对以上信息的签名 OpenSSL实现了对X 509数字证书的所有操作 包括签发
  • MongoDB 匹配查询和比较操作符

    一 匹配查询 1 查询所有 span class token operator gt span db accounts find span class token punctuation span span class token punc
  • 我的2014——典型程序员的一年,不想再重来

    兴冲冲地拿起 xff0c 信誓旦旦的搁在一边 xff0c 以为很快就会回来 xff0c 却一晃而过 xff0c 不再回来 xff1b 我不想再重复过去 xff0c 决定去做 xff0c 写下来 题记 已经记不起我2014的年初是否有过规划
  • 我的2016——程序员年到三十,工作第四年

    看到CSDN 我的2016 主题征文活动 已经是1月6号 xff0c 而截止时间是1月8号 xff0c 对比去年的总结是在闲等活动开始 xff0c 今年在时间上真的是天差地别 但是 xff0c 一年到头 xff0c 还是需要花些时间来回顾这
  • mac下 ndk_build: command not found

    参考 http blog csdn net greenbird811 article details 7543305 在mac下调用ndk build c代码文件提示错误 fix 1 启动终端Terminal 2 进入当前用户的home目录
  • 公司分配IP地址,求主机号码的最小值和最大值。

    问题描述如下 xff1a 姐 xff1a 注意减去2的实际意义 xff1a 网络地址后的第一个主机地址是本网段的网络地址192 168 0 0 xff0c 最 后一个主机地址是本网段的广播地址192 168 255 255
  • Erlang入门

    64 author sunxu 64 copyright C 2023 lt COMPANY gt 64 doc 64 end Created 16 2月 2023 22 16 module test author 34 sunxu 34
  • IPv4地址、IPv6地址和Mac地址的位数

    xff08 1 xff09 IPv4的地址是32位 xff0c 用点分十进制表示 xff0c 每八位划分 xff0c 也就是四个0 255的十进制数 xff0c 这是很常见的 xff08 2 xff09 IPv6的地址是128位 xff0c
  • 用C#连接数据库的方法

    连接SQL Server数据库的方法 xff1a 1 在程序中引用System Data SqlClient命名空间 2 编写连接字符串 xff0c 格式为 xff1a Data Source 61 服务器名称 Initial Catalo

随机推荐

  • gcc 不支持 //注释的解决

    这段时间用slickedit写代码 xff08 windows平台下 xff0c 装了Cygwin xff09 xff0c 编译器用的gcc xff0c 但是有个问题就是用 34 34 写注释的时候 xff0c 编译的时候有错 xff1a
  • python实现按照文件名称进行文件分类

    问题 xff1a 大量名称中带有数字的图片 视频 xff0c 根据名称中数字按照一定的等差数列来排序 xff0c 并且放入指定对应的文件夹中 span class token keyword import span os span clas
  • 【深度学习】Yolov3详解笔记及Pytorch代码

    Yolov3详解笔记及Pytorch代码 预测部分网络结构backbone xff1a Darknet 53output预测结果的解码 训练部分计算loss所需参数pred是什么target是什么loss的计算过程 预测部分 网络结构 DB
  • 【深度学习】各种卷积的理解笔记(2D,3D,1x1,可分离卷积)

    卷积 1 2D卷积单通道版本多通道版本 2 3D卷积3 1x1卷积作用应用 4 卷积算法5 可分离卷积空间可分离卷积深度可分离卷积 1 2D卷积 卷积的目的是从输入中提取有用的特征 在图像处理中 xff0c 卷积可以选择多种不同的滤波器 每
  • 【深度学习】(2+1)D模型框架结构笔记

    xff08 2 43 1 xff09 D 模型框架结构笔记 SpatioTemporalConv模块结构SpatioTemporalResBlock模块结构SpatioTemporalResLayer模块结构2Plus1DNet Spati
  • 【机器学习】LR回归(逻辑回归)和softmax回归

    LR回归 xff08 逻辑回归 xff09 和softmax回归 1 LR回归Logistic回归的函数形式Logistic回归的损失函数Logistic回归的梯度下降法Logistic回归防止过拟合Multinomial Logistic
  • 【深度学习】时间注意力模块与空间注意力模块

    注意力模块 通道 xff08 时间 xff09 注意力模块空间注意力模块 通道 xff08 时间 xff09 注意力模块 为了汇总空间特征 xff0c 作者采用了全局平均池化和最大池化两种方式来分别利用不同的信息 输入是一个 H W C 的
  • 【机器学习】机器学习与统计分布的关系

    这里写目录标题 1 常见的统计学分布1 xff09 离散分布a 伯努利分布b 二项分布c 泊松分布 2 xff09 连续分布a 正态分布 xff08 高斯分布 xff09 b 均匀分布 为什么我们喜欢用 sigmoid 这类 S 型非线性变
  • AKKA入门

    1 Guardian java package com example demo import akka actor typed javadsl ActorContext import akka actor typed ActorRef i
  • 【深度学习】深入理解Batch Normalization批标准化

    Batch Normalization 1 Internal Covariate Shift 问题2 BatchNorm的本质思想1 xff09 函数图像说明2 xff09 算法3 xff09 引入参数恢复表达能力4 xff09 公式 3
  • Autolabelimg自动标注工具

    目录 前言 一 工具原理和功能 1 原理 2 功能列表 二 实战 1 下载与安装 2 配置环境 3 开始使用 4 导入模型 5 选择标注类别 6 进行自动标注 三 总结 前言 在做机器视觉有监督方面 通常会面对很多数据集 xff0c 然后去
  • anchor base,anchor free和基于分割的图像检测

    目录 1 anchor base 2 anchor free 3 基于分割 reference 1 anchor base 什么是anchor based的目标检测方法呢 如果要让你定一个规则去一个图片上框一个物体 xff0c 你会怎么做呢
  • 我的2013:从北京到石家庄的软件开发历程

    记得是正月初八那天早上离开了老家 xff0c 坐上了开往北京的大巴车去北京准备新 的一年的奋斗 xff0c 车票120元了 涨价了20 xff0c 而且还没有地方报销去了 gt lt 因为年底的时候已经离职了 考虑到各公司部门人员 xff0
  • [机器学习] ML重要概念:梯度(Gradient)与梯度下降法(Gradient Descent)

    引言 机器学习栏目记录我在学习Machine Learning过程的一些心得笔记 xff0c 涵盖线性回归 逻辑回归 Softmax回归 神经网络和SVM等等 xff0c 主要学习资料来自网上的免费课程和一些经典书籍 xff0c 免费课程例
  • TPMS胎压芯片选择:英飞凌SP370、英飞凌SP40、飞思卡尔FXTH87

    简介TPMS Tire Pressure Monitoring System xff08 TPMS xff09 xff0c 轮胎压力监测系统 xff0c TPMS的作用是在汽车行驶过程中对轮胎气压进行实时自动监测 xff0c 并对轮胎漏气和
  • 2014年计算机求职总结--准备篇

    版权所有 xff0c 转载请注明出处 xff0c 谢谢 xff01 http blog csdn net walkinginthewind article details 13000431 找工作是一个长期准备的过程 xff0c 突击是没什
  • Code::Blocks之设置字体

    设置 S gt 编辑器 D gt 常规设置 gt 编辑器设置 xff1b 在 34 字体 34 中选择 34 选择 34 按钮 xff0c 进行字体 字形 大小的选择 xff1b 确定
  • 嵌入式软件面试问题总结

    1 DCS 答 xff1a DCS一般指分散控制系统 分散控制系统是以微处理器为基础 xff0c 采用控制功能分散 显示操作集中 兼顾分而自治和综合协调的设计原则的新一代仪表控制系统 集散控制系统简称DCS 也可直译为 分散控制系统 或 分
  • 通过字体名获取字体文件

    由于在GLFT FreeType中需要传入字体文件作为参数 xff0c 所以需要通过字体名来寻找字体文件 现已完成 xff0c 特此总结分享 参考链接 xff1a https www codeproject com Articles 123
  • C++老鼠迷宫

    include lt iostream gt 输入输出流 include lt fstream gt 文件头文件 include lt conio h gt include lt time h gt 时间的头文件 include lt wi