Прежде всего: хотя ваше назначение говорит о том, что кролик движется вдоль оси Y, вы, похоже, поменяли координаты X / Y по всему коду, так что на самом деле кролик перемещается по оси X в вашей реализации. Это немного сбивает с толку, но это не является причиной вашей проблемы.
Возможно, проблема связана с полем 0,01, который вы имеете в этом тесте:
IF SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2) < 0.01 GOTO caught
Если скоростьесли лиса достаточно высока, может случиться так, что она «обгоняет» кролика каждый раз, когда вычисляется его новое положение, и в конечном итоге оказывается на другой (чередующейся) стороне кролика с расстоянием, которое каждый раз больше 0,01. И поэтому вышеупомянутое условие никогда не будет выполнено.
Вместо проверки только для координаты Y (в вашей интерпретации X и Y), с помощью:
IF y2 >= 100 GOTO caught
Я также сделал реализацию вJavaScript (но с X и Y, как указано в вопросе), как с вашим условием «0.01», так и с предложенным исправлением. Если вы введете скорости V1 = 5 и V2 = 9, лиса сможет поймать кролика, но вы увидите разные результаты в обоих фрагментах:
Неправильно:
async function animate() {
cls();
line(0, 0, 100, 0, "black");
line(0, 100, 0, 0, "black");
circle(100, 100, 3, "black");
let v1 = input("rabbit");
let v2 = input("fox");
let dlt = 0.1;
let x1 = 100, y1 = 0; // rabbit
let x2 = 0, y2 = 0; // fox
while (true) {
let y1to = y1 + dlt * v1;
let dist = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
let x2to = x2 + dlt * v2 * (x1 - x2) / dist;
let y2to = y2 + dlt * v2 * (y1 - y2) / dist;
line(x1, y1, x1, y1to, "green");
line(x2, y2, x2to, y2to, "red");
y1 = y1to;
x2 = x2to;
y2 = y2to;
// Problematic condition:
if (dist < 0.01) return output("rabbit got caught");
if (y1 >= 100) return output("rabbit escaped");
await delay(5);
}
}
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
// Some helper functions for JavaScript:
const input = (id) => +document.getElementById(id).value;
function line(x1, y1, x2, y2, color) {
ctx.beginPath();
ctx.moveTo(x1+0.5, y1+0.5);
ctx.lineTo(x2+0.5, y2+0.5);
ctx.strokeStyle = color;
ctx.stroke();
}
function circle(x, y, r, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.arc(x+0.5, y+0.5, r, 0, 2 * Math.PI);
ctx.stroke();
}
const output = (msg) => document.querySelector("#result").textContent = msg;
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
function cls() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
output("");
}
// Bind a click handler for the button
document.querySelector("button").addEventListener("click", animate);
input { width: 4em }
.left { float: left; height: 180px; margin-right: 10px }
<div class="left">
<h3>Wrong implementation</h3>
Input speed of rabbit, v1= <input id="rabbit" type="number" value="5"><br>
Input speed of fox, v2= <input id="fox" type="number" value="9"><br>
<button>Go!</button><br>
</div>
<div>
<canvas width="105" height="105"></canvas>
<div id="result"></div>
</div>
Исправлено:
async function animate() {
cls();
line(0, 0, 100, 0, "black");
line(0, 100, 0, 0, "black");
circle(100, 100, 3, "black");
let v1 = input("rabbit");
let v2 = input("fox");
let dlt = 0.1;
let x1 = 100, y1 = 0; // rabbit
let x2 = 0, y2 = 0; // fox
while (true) {
let y1to = y1 + dlt * v1;
let dist = Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
let x2to = x2 + dlt * v2 * (x1 - x2) / dist;
let y2to = y2 + dlt * v2 * (y1 - y2) / dist;
line(x1, y1, x1, y1to, "green");
line(x2, y2, x2to, y2to, "red");
y1 = y1to;
x2 = x2to;
y2 = y2to;
// Corrected condition:
if (x2 >= 100) return output("rabbit got caught");
if (y1 >= 100) return output("rabbit escaped");
await delay(5);
}
}
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
// Some helper functions for JavaScript:
const input = (id) => +document.getElementById(id).value;
function line(x1, y1, x2, y2, color) {
ctx.beginPath();
ctx.moveTo(x1+0.5, y1+0.5);
ctx.lineTo(x2+0.5, y2+0.5);
ctx.strokeStyle = color;
ctx.stroke();
}
function circle(x, y, r, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.arc(x+0.5, y+0.5, r, 0, 2 * Math.PI);
ctx.stroke();
}
const output = (msg) => document.querySelector("#result").textContent = msg;
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
function cls() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
output("");
}
// Bind a click handler for the button
document.querySelector("button").addEventListener("click", animate);
input { width: 4em }
.left { float: left; height: 180px; margin-right: 10px }
<div class="left">
<h3>Corrected implementation</h3>
Input speed of rabbit, v1= <input id="rabbit" type="number" value="5"><br>
Input speed of fox, v2= <input id="fox" type="number" value="9"><br>
<button>Go!</button><br>
</div>
<div>
<canvas width="105" height="105"></canvas>
<div id="result"></div>
</div>
Последнее замечание к вашему коду: использование GOTO
осуждается. Вместо этого вы должны использовать цикл DO WHILE
для создания цикла, потенциально с оператором EXIT
, если это действительно необходимо.