17-6 廃坑から覗く闇①

解説動画

解答コード

let dic_wheelName176: { [key: number]: string } = {
    1: "front",
    2: "rear"
};

let arr_wheelIdMap176 = [
    [1, 0, 0, 2, 2],
    [1, 0, 0, 2, 2],
    [0, 0, 0, 2, 2]
];

let dic_agentStatus176: { [key: string]: number } = {
	"row": 0,
	"col": 0,
	"direction": LEFT,
	"positiveDirection": LEFT
};

let arr_wheelBlocks176: number[][] = [
    [],  // 前輪のブロックID配列
    []   // 後輪のブロックID配列
];

function switchDirection176(direction: number) {
    if (direction == LEFT) {
        return RIGHT;
    }
    else {
        return LEFT;
    }
}

function moveInMap176(status: { [key: string]: number }) {
    // 移動先のマップ上の位置(行・列)
    let row = status["row"];
    let col = status["col"];

    // マップ上の行・列の上限・下限
    let colMin = 0;
    let colMax = arr_wheelIdMap176[row].length - 1;
    let rowMax = arr_wheelIdMap176.length - 1;

    // これから列を進む方向に応じて、次の列番号を決めます
    if (status["direction"] == status["positiveDirection"]) {
        // 順方向の場合は、列を進む
        col += 1;
    } else {
        // 逆方向の場合は、列を戻る
        col -= 1;
    }

    // 列の最初より前へ、または列の最後により後へ行こうとする場合は、
    // 列の番号はそのままで、次の行へ進んで、これから進む方向を切り替えます
    if (col < colMin || col > colMax) {
        col = status["col"];
        row += 1;
        // 行の上限よりも大きい行番号の場合は、移動を終わります
        if (row > rowMax) {
            return false;
        }
        // エージェントを次の行へ移動します
        agent.move(UP, 1);
        // 次の行の移動方向は、逆方向になります
        status["direction"] = switchDirection176(status["direction"]);
    } else {
        // それ以外の場合は、進む方向の列へエージェントを移動します
        agent.move(status["direction"], 1);
    }

    // 新しい行・列の番号を記録します
    status["row"] = row;
    status["col"] = col;

    // 移動を続けます
    return true;
}

function moveToOtherSide176(status: { [key: string]: number }, width: number) {
    // スタート地点の上へ移動(マップ上で今いる列が最初の列になるまで)
    let backCols = status["col"];
    let negativeDirection = switchDirection176(status["positiveDirection"]);
    agent.move(negativeDirection, backCols);
    status["col"] -= backCols;

    // スタート地点の反対側へ移動して後ろ向きになる
    agent.move(FORWARD, width);
    agent.turn(RIGHT);
    agent.turn(RIGHT);

    // スタート地点と同じ高さまで移動(マップ上で今いる行が最初の行になるまで)
    let backRows = status["row"];
    agent.move(DOWN, backRows);
    status["row"] -= backRows;

    // 反対側は鏡合わせなので、列を進む向きは元の向きと逆になる
    status["positiveDirection"] = switchDirection176(status["positiveDirection"]);

    // 最初の行をエージェントが移動する方向は、列を進む向きと同じにする
    status["direction"] = status["positiveDirection"];
}

function copyWheel176(status: { [key: string]: number }, blocks: number[][]) {
    let row = status["row"];
    let col = status["col"];
    let wheelId = arr_wheelIdMap176[row][col];
    if (wheelId > 0) {
        // 前にあるブロックのIDを調べる
        let blockId = agent.inspect(AgentInspection.Block, FORWARD);
        // ブロックのIDを記録する
        blocks[wheelId - 1].push(blockId);
    }
}

function pasteWheel176(status: { [key: string]: number }, blocks: number[][]) {
    let row = status["row"];
    let col = status["col"];
    let wheelId = arr_wheelIdMap176[row][col];
    if (wheelId > 0) {
        // 置くためのブロックを取り出す(記録からは消える)
        let blockId = blocks[wheelId - 1].shift();
        // 前にブロックを置く
        if (blockId >= 0) {
            agent.setItem(blockId, 1, 1);
            agent.place(FORWARD);
        }
    }
}

player.onChat("17-6", () => {
    // エージェント状態を初期化します
    dic_agentStatus176["col"] = 0;
    dic_agentStatus176["row"] = 0;
    dic_agentStatus176["direction"] = LEFT;
	dic_agentStatus176["positiveDirection"] = LEFT;
	
	// 車輪ブロック配列を初期化します
	arr_wheelBlocks176 = [[], []];

    player.say("=== トラクターの車輪修復開始 ===");

    // スタート地点から、コピー開始
    while (true) {
        // エージェントの前にあるブロックをコピーして連想配列に記録します
        copyWheel176(dic_agentStatus176, arr_wheelBlocks176);

        // エージェントを、マップ範囲内で次の位置へ移動します
        let shouldContinue = moveInMap176(dic_agentStatus176);
        if (shouldContinue == false) {
            // マップ範囲外に移動しようとしたときは、コピー終了します
            break;
        }
    }

    // コピー終了の地点から、スタート地点の反対側へ移動します
    moveToOtherSide176(dic_agentStatus176, 4);

    // スタート地点の反対側から、ペースト開始
    while (true) {
        // 連想配列に記録してあるブロックをエージェントの前へ置きます
        pasteWheel176(dic_agentStatus176, arr_wheelBlocks176);

        // エージェントを、マップ範囲内で次の位置へ移動します
        let shouldContinue = moveInMap176(dic_agentStatus176);
        if (shouldContinue == false) {
            // マップ範囲外に移動しようとしたときは、移動を終了します
            break;
        }
    }

    player.say("17-6 トラクターの車輪修復完了!");
});