18-4 ぐらぐらレール④

解説動画

解答画像

// -- 18-4 鉱石の価値計算 ----------------------------------------------------

// 発見した鉱石のデータの連想配列
let dic_foundMineralData184: { [key: string]: number[] } = {
    "blocks": [], // 発見した順の鉱石の、ブロック番号の配列
    "counts": [], // 発見した順の鉱石の、同種の鉱石の数の配列
    "values": [] // 発見した順の鉱石の、価値の配列
};

// 鉱石種類ごとの発見された数の連想配列
// キー:鉱石のブロック番号
// 値:鉱石の発見された数
let dic_mineralCounts184: { [key: number]: number } = {
    // 最初は空です
};

// 鉱石の価値の連想配列
// キー:鉱石のブロック番号
// 値:鉱石の価値
let dic_mineralValues184: { [key: number]: number } = {
    // 最初は空です
};

let airBlockId184 = 0; // 空気ブロックのID

let coalBlockId184 = 173; // 石炭ブロックのID

let arrowBlockId184 = 222; // 矢印ブロックのID

// 鉱石を発見する関数
function findMinerals184(foundMineralData: { [key: string]: number[] }): void {
    // 発見したブロック番号の配列
    let foundBlocks: number[] = [];
    while (true) {
        // 足元のブロックを読み取ります
        let foundBlock = agent.inspect(AgentInspection.Block, DOWN);
        if (foundBlock !== undefined && foundBlock !== coalBlockId184 && foundBlock !== arrowBlockId184) {
            // 発見したブロックを配列に追加します
            foundBlocks.push(foundBlock);
        }
        // 前のブロックを読み取ります
        let forwardBlock = agent.inspect(AgentInspection.Block, FORWARD);
        if (forwardBlock !== airBlockId184) {
            // 空気ブロックでなければ、ループを抜けます
            break;
        }
        // 前へ進みます
        agent.move(FORWARD, 1);
    }
    // 発見したブロック番号の配列を、データの連想配列に登録します
    foundMineralData["blocks"] = foundBlocks;
}

// 鉱石の種類ごとの数を数える関数
function countMinerals184(foundMineralData: { [key: string]: number[] }, mineralCounts: { [key: number]: number }): void {
    // 鉱石の種類ごとの数を数えます
    for (let blockId of foundMineralData["blocks"]) {
        // 未登録の鉱石の場合は、1を登録します
        if (mineralCounts[blockId] === undefined) {
            mineralCounts[blockId] = 1;
        } else {
            // 登録済みの鉱石の場合は、数を増やします
            mineralCounts[blockId] += 1;
        }
    }
}

// 鉱石の種類ごとの価値を計算する関数
function calculateMineralValues184(mineralCounts: { [key: number]: number }, mineralValues: { [key: number]: number }): void {
    // 鉱石の数の連想配列のキーを取得します
    let blocks = Object.keys(mineralCounts);
    // キーを順番に取り出して、価値を計算します
    for (let item of blocks) {
        // キーを数値に変換します
        let blockId = parseInt(item);
        // 価値を計算します
        let value = 10 - mineralCounts[blockId];
        // 価値が0未満の場合は、0にします
        if (value < 0) {
            value = 0;
        }
        // 価値を連想配列に登録します
        mineralValues[blockId] = value;
    }
}

// 発見した鉱石のデータを、鉱石の種類ごとの数と価値で更新する関数
function updateFoundMineralData184(foundMineralData: { [key: string]: number[] }, mineralCounts: { [key: number]: number }, mineralValues: { [key: number]: number }): void {
    // 発見した鉱石のブロック番号の配列を取得します
    let blocks = foundMineralData["blocks"];
    // ブロック番号を順番に取り出して、数と価値を更新します
    for (let blockId of blocks) {
        // 数を取得します
        let count = mineralCounts[blockId];
        // 価値を取得します
        let value = mineralValues[blockId];
        // 数と価値をデータに追加します
        foundMineralData["counts"].push(count);
        foundMineralData["values"].push(value);
    }
}

// データにもとづいて、合計の価値を計算する関数
function calculateTotalValue184(foundMineralData: { [key: string]: number[] }): number {
    // 合計の価値を初期化します
    let totalValue = 0;
    // 価値の配列を取得します
    let values = foundMineralData["values"];
    // 価値を順番に取り出して、合計の価値を計算します
    for (let value of values) {
        totalValue += value;
    }
    // 合計の価値を返します
    return totalValue;
}

// チャットコマンドで、プログラムを実行します
player.onChat("18-4", function () {
    // データの初期化をします
    dic_foundMineralData184 = {
        "blocks": [],
        "counts": [],
        "values": []
    };
    dic_mineralCounts184 = {};
    dic_mineralValues184 = {};

    // エージェントを1歩前進させます
    agent.move(FORWARD, 1);

    // エージェントを行き止まりまで移動させて、足元の鉱石を読み取ります
    findMinerals184(dic_foundMineralData184);

    // 鉱石の種類ごとの数を数えます
    countMinerals184(dic_foundMineralData184, dic_mineralCounts184);

    // 鉱石種類ごとの価値を計算します
    calculateMineralValues184(dic_mineralCounts184, dic_mineralValues184);

    // 鉱石の数と、鉱石の価値を、発見した鉱石のデータへ反映します
    updateFoundMineralData184(dic_foundMineralData184, dic_mineralCounts184, dic_mineralValues184);

    // 合計の価値を計算します
    let totalValue = calculateTotalValue184(dic_foundMineralData184);

    // 発見した鉱石のデータをプレイヤーに表示します
    player.say(`発見した鉱石のデータは、このようです:`);
    player.say(`ブロック番号:${dic_foundMineralData184["blocks"].join(", ")}`);
    player.say(`同種の鉱石の数:${dic_foundMineralData184["counts"].join(", ")}`);
    player.say(`価値:${dic_foundMineralData184["values"].join(", ")}`);

    // 合計の価値をプレイヤーに表示します
    player.say(`合計の価値は ${totalValue} です`);
});