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

多米诺骨牌程序开发问题:vector传递与游戏启动逻辑困惑

解决多米诺骨牌程序的两个核心问题

嘿,我来帮你搞定这两个开发中的问题,结合你的游戏规划给你具体的解决方案:

问题1:无法将vector从shuffle函数传入printDom,仅需显示playerDom

这个问题大概率是vector的传递方式或者函数参数匹配出了问题。你需要确保shuffle后的playerDom能正确传递到printDom,并且printDom只处理这个vector。

核心解决方案:

  • 用引用传递避免vector拷贝:如果shuffle函数是修改playerDom,直接传引用,这样修改会直接作用在原vector上,不需要返回值。
  • 确保printDom的参数就是playerDom,并且只遍历这个vector输出。

代码示例:

首先定义你的骨牌结构体(假设你还没定义):

struct Domino {
    int left;
    int right;
    Domino(int l, int r) : left(l), right(r) {}
};

然后是洗牌函数(C++11+推荐用shuffle代替旧的random_shuffle):

#include <vector>
#include <random>
#include <algorithm>
#include <iostream>

using namespace std;

// 洗牌函数:传引用修改原playerDom
void shuffleDominoes(vector<Domino>& playerDom) {
    random_device rd;
    mt19937 gen(rd()); // 生成随机数引擎
    shuffle(playerDom.begin(), playerDom.end(), gen);
}

// 打印玩家骨牌的函数:仅接收playerDom并输出
void printDom(const vector<Domino>& playerDom) {
    cout << "你的骨牌:";
    for (const auto& dom : playerDom) {
        cout << "[" << dom.left << "|" << dom.right << "] ";
    }
    cout << endl;
}

调用方式(确保shuffle后直接传playerDom给printDom):

int main() {
    // 初始化玩家骨牌(示例:先加几张测试)
    vector<Domino> playerDom;
    playerDom.emplace_back(1,2);
    playerDom.emplace_back(3,4);
    playerDom.emplace_back(5,6);

    // 洗牌
    shuffleDominoes(playerDom);
    // 打印玩家骨牌
    printDom(playerDom);

    // 其他逻辑...
    return 0;
}

这样就能保证printDom只显示playerDom的内容,不会出现传递失效的问题。


问题2:如何启动游戏并实现你的规划逻辑

根据你的游戏规划,我整理了一套完整的游戏启动和运行流程,包含初始化、回合循环、胜负判断的核心逻辑:

游戏核心流程步骤:

  1. 初始化所有骨牌:生成标准28张多米诺骨牌(从[0|0]到[6|6])
  2. 洗牌并分配骨牌:洗牌后给玩家和电脑各分7张,剩余的作为抽牌堆,选一张作为起始骨牌放入playedDom
  3. 游戏主循环:交替进行玩家和电脑回合,直到某一方骨牌为空
    • 玩家/电脑回合:判断是否有可匹配首尾点数的骨牌,有则放到playedDom的头部或尾部;没有则抽牌(抽牌堆空则跳过回合)
    • 胜负判断:每次回合后检查playerDom或computerDom是否为空,为空则对应方获胜

完整代码框架示例:

#include <vector>
#include <random>
#include <algorithm>
#include <iostream>
#include <iterator>

using namespace std;

struct Domino {
    int left;
    int right;
    Domino(int l, int r) : left(l), right(r) {}
};

// 洗牌函数(通用,可洗任意骨牌vector)
void shuffleDominoes(vector<Domino>& dominoes) {
    random_device rd;
    mt19937 gen(rd());
    shuffle(dominoes.begin(), dominoes.end(), gen);
}

// 打印骨牌的通用函数(可传任意骨牌vector)
void printDom(const vector<Domino>& dominoes, const string& label) {
    cout << label << ":";
    for (const auto& dom : dominoes) {
        cout << "[" << dom.left << "|" << dom.right << "] ";
    }
    cout << endl;
}

int main() {
    // -------------------------- 1. 初始化所有骨牌 --------------------------
    vector<Domino> allDominoes;
    for (int i = 0; i <= 6; ++i) {
        for (int j = i; j <= 6; ++j) {
            allDominoes.emplace_back(i, j);
        }
    }

    // -------------------------- 2. 洗牌并分配骨牌 --------------------------
    shuffleDominoes(allDominoes);

    vector<Domino> playerDom;
    vector<Domino> computerDom;
    vector<Domino> playedDom;

    // 玩家和电脑各拿7张
    for (int i = 0; i < 7; ++i) {
        playerDom.push_back(allDominoes.back());
        allDominoes.pop_back();
        computerDom.push_back(allDominoes.back());
        allDominoes.pop_back();
    }

    // 设置起始骨牌(从剩余堆拿第一张)
    if (!allDominoes.empty()) {
        playedDom.push_back(allDominoes.back());
        allDominoes.pop_back();
    }

    printDom(playedDom, "起始骨牌");
    printDom(playerDom, "你的初始骨牌");

    // -------------------------- 3. 游戏主循环 --------------------------
    bool gameRunning = true;
    while (gameRunning) {
        // 检查胜负
        if (playerDom.empty()) {
            cout << "\n🎉 你赢了!" << endl;
            gameRunning = false;
            break;
        }
        if (computerDom.empty()) {
            cout << "\n😢 电脑赢了!" << endl;
            gameRunning = false;
            break;
        }

        // -------------------------- 玩家回合 --------------------------
        cout << "\n===== 你的回合 =====" << endl;
        printDom(playedDom, "当前已出牌");
        int headVal = playedDom.front().left;
        int tailVal = playedDom.back().right;
        cout << "可匹配点数:头部[" << headVal << "] | 尾部[" << tailVal << "]" << endl;
        printDom(playerDom, "你的骨牌");

        bool playerPlayed = false;
        int choice;
        cout << "请输入要出的骨牌索引(从0开始,输入-1抽牌):";
        cin >> choice;

        if (choice == -1) {
            // 抽牌逻辑
            if (!allDominoes.empty()) {
                playerDom.push_back(allDominoes.back());
                allDominoes.pop_back();
                cout << "你抽了一张骨牌!" << endl;
                printDom(playerDom, "你的骨牌");
            } else {
                cout << "没有骨牌可抽,跳过回合!" << endl;
            }
        } else if (choice >= 0 && choice < playerDom.size()) {
            Domino chosen = playerDom[choice];
            bool canPlace = false;

            // 判断是否能放头部
            if (chosen.left == headVal) {
                swap(chosen.left, chosen.right);
                playedDom.insert(playedDom.begin(), chosen);
                canPlace = true;
            } else if (chosen.right == headVal) {
                playedDom.insert(playedDom.begin(), chosen);
                canPlace = true;
            }
            // 判断是否能放尾部
            else if (chosen.left == tailVal) {
                playedDom.push_back(chosen);
                canPlace = true;
            } else if (chosen.right == tailVal) {
                swap(chosen.left, chosen.right);
                playedDom.push_back(chosen);
                canPlace = true;
            }

            if (canPlace) {
                playerDom.erase(playerDom.begin() + choice);
                cout << "你出了骨牌:[" << chosen.left << "|" << chosen.right << "]" << endl;
                playerPlayed = true;
            } else {
                cout << "这张骨牌无法匹配,重新选择!" << endl;
                continue; // 回到输入步骤
            }
        } else {
            cout << "无效索引,请重新输入!" << endl;
            continue;
        }

        // -------------------------- 电脑回合 --------------------------
        cout << "\n===== 电脑回合 =====" << endl;
        bool computerPlayed = false;
        for (auto it = computerDom.begin(); it != computerDom.end(); ++it) {
            Domino chosen = *it;
            bool canPlace = false;

            // 检查头部匹配
            if (chosen.left == headVal || chosen.right == headVal) {
                if (chosen.left == headVal) swap(chosen.left, chosen.right);
                playedDom.insert(playedDom.begin(), chosen);
                canPlace = true;
            }
            // 检查尾部匹配
            else if (chosen.left == tailVal || chosen.right == tailVal) {
                if (chosen.right == tailVal) swap(chosen.left, chosen.right);
                playedDom.push_back(chosen);
                canPlace = true;
            }

            if (canPlace) {
                computerDom.erase(it);
                cout << "电脑出了骨牌:[" << chosen.left << "|" << chosen.right << "]" << endl;
                computerPlayed = true;
                break;
            }
        }

        if (!computerPlayed) {
            if (!allDominoes.empty()) {
                computerDom.push_back(allDominoes.back());
                allDominoes.pop_back();
                cout << "电脑抽了一张骨牌!" << endl;
            } else {
                cout << "电脑没有骨牌可抽,跳过回合!" << endl;
            }
        }
    }

    return 0;
}

关键细节说明:

  • 骨牌匹配时需要考虑翻转:比如已出牌头部是3,玩家的骨牌是[5|3],可以直接放头部;如果是[3|5],需要翻转成[5|3]再放头部
  • 抽牌堆空了之后,无法抽牌的玩家/电脑直接跳过回合
  • 每次回合后都要检查胜负条件,确保游戏能及时结束

内容的提问来源于stack exchange,提问作者jgato

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:18:08