You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在网格中随机生成钻石位置?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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:01:20