解説動画
解答コード
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 トラクターの車輪修復完了!");
});