如何在网格中随机生成钻石位置?C++ srand函数使用指导
解决玩家收集钻石并生成新随机位置的问题
我来帮你搞定这个作业瓶颈!你需要实现两个核心功能:检测玩家与钻石的碰撞并加分,以及生成不与旧位置(玩家、其他钻石/障碍物)重叠的新随机钻石位置,下面一步步拆解:
一、先搞懂srand()和rand()的用法
在C++里生成随机数,这俩函数是黄金搭档:
srand(unsigned int seed):用来设置随机数种子,一般用time(0)当种子(时间一直在变,每次运行程序的随机序列都不一样)。注意只需要在程序开头调用一次,别放进循环里!rand():生成0到RAND_MAX(通常是32767)的随机整数,用取模运算可以把它限制在你的棋盘范围里(比如1到5,对应你的s=5)。
记得先包含头文件:
#include <cstdlib> // 用于srand()和rand() #include <ctime> // 用于time()
二、核心功能实现:碰撞检测+新钻石生成
你需要在玩家移动后,检查是否碰到钻石;如果碰到,加分并生成新的合法随机位置(不能和玩家、其他钻石、障碍物重叠)。
修改后的完整代码(带注释)
我把你的代码做了补充和优化,关键改动都标在注释里了:
#include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main() { // 初始化随机数种子,只执行一次! srand(time(0)); int s = 5; char player = 'p'; char choice = 0; int pr = 1, pc = 1; // 把两个钻石的位置单独存储,避免联动变化 int dr1=2, dc1=2; int dr2=4, dc2=4; int br = 3, bc = 3; int score = 0; while (score != 25){ // 绘制棋盘 for (int i = 1; i <= s; i++){ for (int j = 1; j <= s; j++){ if (i == pr && j == pc){ cout << " " << player; } else if(i == dr1 && j == dc1){ cout << " " << 'D'; } else if (i == dr2 && j == dc2){ cout << " " << 'D'; } else if (i == br && j == bc){ cout << " " << 'B'; } else { cout << " *"; } } cout << endl; } cout << "当前分数: " << score << endl; // 实时显示分数,更直观 cout << "输入移动方向(u/d/l/r): "; cin >> choice; // 玩家移动逻辑+边界防溢出 if (choice == 'd'||choice=='D'){ pr = pr + 1; pr = pr > s ? s : pr; } if (choice == 'u' || choice == 'U'){ pr = pr - 1; pr = pr < 1 ? 1 : pr; } if (choice == 'r' || choice == 'R'){ pc = pc + 1; pc = pc > s ? s : pc; } if (choice == 'l' || choice == 'L'){ pc = pc - 1; pc = pc < 1 ? 1 : pc; } // 检测第一个钻石的碰撞 if (pr == dr1 && pc == dc1) { score++; // 生成新位置,直到不与关键位置重叠 do { dr1 = rand() % s + 1; // 生成1~s的随机行号 dc1 = rand() % s + 1; // 生成1~s的随机列号 } while ( (dr1 == pr && dc1 == pc) || (dr1 == dr2 && dc1 == dc2) || (dr1 == br && dc1 == bc) ); } // 检测第二个钻石的碰撞 if (pr == dr2 && pc == dc2) { score++; do { dr2 = rand() % s + 1; dc2 = rand() % s + 1; } while ( (dr2 == pr && dc2 == pc) || (dr2 == dr1 && dc2 == dc1) || (dr2 == br && dc2 == bc) ); } } cout << "恭喜通关!分数达到25分!" << endl; return 0; }
三、关键细节说明
- 随机数范围控制:
rand() % s + 1是因为rand()%s会生成0~s-1的数,加1后刚好匹配你从1开始的棋盘行/列号。 - do-while循环的作用:强制生成的新钻石位置避开玩家、另一个钻石、障碍物B,直到得到合法位置为止。
- 边界处理:加了防止玩家移出棋盘的判断,避免出现绘制错误或者位置越界的问题,这个是实用的小优化。
四、额外建议
- 你原来把第二个钻石绑定在第一个的
dr+2, dc+2位置,改成独立变量后,两个钻石可以各自随机生成,逻辑更清晰。 - 可以把“生成新钻石位置”的逻辑封装成函数,比如
void generateNewDiamond(int &r, int &c, int s, int pr, int pc, int otherR, int otherC, int br, int bc),这样不用重复写do-while的代码,让程序更整洁。
内容的提问来源于stack exchange,提问作者Hoshika
相关产品推荐
相关产品推荐

