解説動画
解答画像
// -- 18-7 落石を取り除いて線路を修復する ----------------------------------------------------
// 線路パターンの連想配列
let dic_railBlocks187: { [key: number]: number[] } = {
896: [66, 66, 66, 27, 66, 66, 66], // 鉄の原石 → 線路パターンの配列
22: [66, 27, 66, 66, 66] // ラピスラズリ → 線路パターンの配列
};
let airBlockId187 = 0; // 空気のブロックID(前方確認用)
let coalBlockId187 = 173; // 石炭のブロックID(終了条件用)
// エージェント状態の連想配列
let dic_agentStatus187: { [key: string]: number } = {
"block": 0, // 持つブロック番号
"forward": 0, // 前の移動距離
"placeDirection": DOWN // ブロックを置く方向
};
// エージェントを前へ移動させる関数
function moveForward187(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(FORWARD, 1);
if (!canMove) {
player.say("エージェントが前へ移動できません!");
return false;
}
agentStatus["forward"] += 1;
return true;
}
// エージェントを後ろ移動させる関数
function moveBack187(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(BACK, 1);
if (!canMove) {
player.say("エージェントが後ろへ移動できません!");
return false;
}
agentStatus["forward"] -= 1;
return true;
}
// エージェントにブロックを設置させる関数
function placeBlock187(agentStatus: { [key: string]: number }): boolean {
agent.setItem(agentStatus["block"], 1, 1);
let canPlace = agent.place(agentStatus["placeDirection"]);
if (!canPlace) {
player.say("エージェントがブロックを設置できません!");
}
return canPlace;
}
// がれきを取り除く関数
function doGrading187(agentStatus: { [key: string]: number }) {
// 修復を開始する地点の位置を記録します
let startForward = agentStatus["forward"];
// 終了条件まで繰り返します
while (true) {
// 前方のブロック番号を取得します
let forwardBlockId = agent.inspect(AgentInspection.Block, FORWARD);
if (forwardBlockId === coalBlockId187) {
// 終了条件を満たした場合は、終了します
player.say("石炭ブロックが見つかったので、終了します。");
break;
}
if (forwardBlockId !== airBlockId187) {
// がれきがある場合は、がれきを除去します
agent.destroy(FORWARD);
}
// 上方のブロック番号を取得します
let topBlockId = agent.inspect(AgentInspection.Block, UP);
if (topBlockId !== airBlockId187) {
// がれきがある場合は、がれきを除去します
agent.destroy(UP);
}
moveForward187(agentStatus);
}
// エージェントを修復開始地点まで戻します
while (agentStatus["forward"] > startForward) {
moveBack187(agentStatus);
}
}
// 足元の印を探す関数
function findMarker187(agentStatus: { [key: string]: number }, railBlocks: { [key: number]: number[] }): number {
// 終了条件まで繰り返します
while (true) {
// 前方のブロック番号を取得します
let forwardBlockId = agent.inspect(AgentInspection.Block, FORWARD);
if (forwardBlockId === coalBlockId187) {
// 終了条件を満たした場合は、終了します
player.say("石炭ブロックが見つかったので、終了します。");
return 0;
}
// 足元のブロックを調べます
let belowBlock = agent.inspect(AgentInspection.Block, DOWN);
// 印が見つかった場合、そのブロックIDを返します
if (railBlocks[belowBlock] != undefined) {
player.say(`印を発見しました:ID ${belowBlock}`);
return belowBlock;
}
// 見つからなかった場合、前に移動します
let canMove = moveForward187(agentStatus);
if (!canMove) {
// 前に移動できなくなった場合は、0を返します
return 0;
}
}
}
// 線路を修復する関数
function buildRails187(agentStatus: { [key: string]: number }, blocks: number[]) {
// 線路パターンでレールを設置していきます
for (let i = 0; i < blocks.length; i++) {
agentStatus["block"] = blocks[i];
placeBlock187(agentStatus);
// 前にブロックが無い時だけ、前へ移動します
let forwardBlockId = agent.inspect(AgentInspection.Block, FORWARD);
if (forwardBlockId == airBlockId187) {
moveForward187(agentStatus);
}
}
}
// チャットコマンド "18-7" を入力したときの処理
player.onChat("18-7", function () {
// エージェント状態を初期化します
dic_agentStatus187["block"] = 0;
dic_agentStatus187["forward"] = 0;
dic_agentStatus187["placeDirection"] = DOWN;
// エージェントに落石を取り除かせます
doGrading187(dic_agentStatus187);
// 印を探しながら、線路を修復します
while (true) {
let markerBlockId = findMarker187(dic_agentStatus187, dic_railBlocks187);
if (markerBlockId == 0) {
// 印が見つからないまま移動できなくなった場合は、終了します
break;
}
// 線路の材料ブロック番号の配列を取得します
let blocks = dic_railBlocks187[markerBlockId];
// 線路を修復します
buildRails187(dic_agentStatus187, blocks);
}
player.say("作業を終了します");
});