解説動画
解答画像
// -- 18-2 逆さまの封印柱を立てる --
// 封印柱の連想配列
// キー:柱を立てる場所の印のブロック番号
// 値:柱の材料ブロック番号の配列
let dic_pillerBlocks182: { [key: number]: number[] } = {
173: [4, 1, 98], // 印(石炭): 柱 [丸石, 石, 石レンガ]
896: [945, 48, 98], // 印(鉄の原石): 柱 [模様入りの凝灰岩, 苔むした丸石, 石レンガ]
22: [98, 98, 4] // 印(ラピスラズリ): 柱 [石レンガ, 石レンガ, 丸石]
};
//let torchBlockId = 50; // 松明のブロック番号
// エージェントの状態の連想配列
let dic_agentStatus182: { [key: string]: number } = {
"block": 0, // 持つブロック番号
"forward": 0, // 前の移動距離
"right": 0, // 右の移動距離
"up": 0, // 上の移動距離
"placeDirection": FORWARD // ブロックを置く方向
};
// 立てた封印柱の配列
let array_builtPillars182: number[] = [];
// エージェントを前へ移動させる関数
function moveForward182(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(FORWARD, 1);
if (!canMove) {
player.say("エージェントが前へ移動できません!");
return false;
}
agentStatus["forward"] += 1;
return true;
}
// エージェントを後ろへ移動させる関数
function moveBack182(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(BACK, 1);
if (!canMove) {
player.say("エージェントが後ろへ移動できません!");
return false;
}
agentStatus["forward"] -= 1;
return true;
}
// Extends エージェントを左に移動させる関数
function moveLeft182(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(LEFT, 1);
if (!canMove) {
player.say("エージェントが左に移動できません!");
return false;
}
agentStatus["right"] -= 1;
return true;
}
// エージェントを上に移動させる関数
function moveUp182(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(UP, 1);
if (!canMove) {
player.say("エージェントが上に移動できません!");
return false;
}
agentStatus["up"] += 1;
return true;
}
// エージェントを下に移動させる関数
function moveDown182(agentStatus: { [key: string]: number }): boolean {
let canMove = agent.move(DOWN, 1);
if (!canMove) {
player.say("エージェントが下に移動できません!");
return false;
}
agentStatus["up"] -= 1;
return true;
}
// エージェントにブロックを設置させる関数
function placeBlock182(agentStatus: { [key: string]: number }): boolean {
agent.setItem(agentStatus["block"], 1, 1);
let canPlace = agent.place(agentStatus["placeDirection"]);
if (!canPlace) {
player.say("エージェントがブロックを設置できません!");
}
return canPlace;
}
// エージェントを床まで移動させる関数
function moveToFloor182(agentStatus: { [key: string]: number }) {
let canMove = true;
while (canMove && agentStatus["up"] > 0) {
canMove = moveDown182(agentStatus);
}
}
// 封印柱の印を探す関数
function findMarker182(
agentStatus: { [key: string]: number },
pillarBlocks: { [key: number]: number[] }
): number {
while (true) {
// 足元のブロックを調べます
let belowBlock = agent.inspect(AgentInspection.Block, DOWN);
// 封印柱の印が見つかった場合、そのブロックIDを返します
if (pillarBlocks[belowBlock] != undefined) {
player.say(`印を発見しました:ID ${belowBlock}`);
return belowBlock;
}
// 見つからなかった場合、左に移動します
let canMove = moveLeft182(agentStatus);
if (!canMove) {
// 左に移動できなくなった場合は、0を返します
return 0;
}
}
}
// 封印柱を立てる関数
function buildPillar182(
agentStatus: { [key: string]: number },
blocks: number[]
) {
// 封印柱の各ブロックを設置していきます
for (let i = 0; i < blocks.length; i++) {
agentStatus["block"] = blocks[i];
placeBlock182(agentStatus);
moveUp182(agentStatus);
}
// 柱の上に松明を設置します
agentStatus["block"] = torchBlockId;
placeBlock182(agentStatus);
// エージェントを床まで戻します
moveToFloor182(agentStatus);
}
// チャットコマンドで封印柱を立てる処理を開始します
player.onChat("18-2", function () {
// エージェント状態を初期化します
dic_agentStatus182["block"] = 0;
dic_agentStatus182["forward"] = 0;
dic_agentStatus182["right"] = 0;
dic_agentStatus182["up"] = 0;
dic_agentStatus182["placeDirection"] = FORWARD;
// 封印柱の印を記録する配列を初期化します
array_builtPillars182 = [];
// エージェントを1歩前に移動させます
moveForward182(dic_agentStatus182);
while (true) {
// 地面の印を探します
let markerBlockId = findMarker182(dic_agentStatus182, dic_pillerBlocks182);
if (markerBlockId <= 0) {
// 印が見つけられないまま移動できなくなった場合は、終了します
player.say("エラー:移動できなくなりました");
break;
}
// 発見した印を配列に記録します
array_builtPillars182.push(markerBlockId);
// もし印が石炭(173)だったら、上に障害物があるので、柱の側面に回り込みます
if (markerBlockId === 173) {
moveLeft182(dic_agentStatus182);
moveForward182(dic_agentStatus182);
dic_agentStatus182["placeDirection"] = RIGHT;
}
// 封印柱の材料ブロック番号の配列を取得します
let blocks = dic_pillerBlocks182[markerBlockId];
// 封印柱のブロック番号を逆順にします
blocks.reverse();
// 封印柱を立てます
buildPillar182(dic_agentStatus182, blocks);
if (markerBlockId === 173) {
// 柱の側面に回り込んだときは、元の位置に戻ります
moveBack182(dic_agentStatus182);
dic_agentStatus182["placeDirection"] = FORWARD;
} else {
// 左へ移動します
moveLeft182(dic_agentStatus182);
}
// すべての封印柱を立て終わった場合は終了します
if (array_builtPillars182.length >= Object.keys(dic_pillerBlocks182).length) {
player.say("すべての封印柱を立て終わりました");
break;
}
}
player.say("作業を終了します");
});