我需要一些作业上的帮助。
有一只兔子在距洞口100米的地方,有一只狐狸在与兔子孔垂直的方向上距兔子100米的地方。 (兔子位于(100,0),孔位于(100,100),狐狸位于(0,0)
兔子以给定的V1速度开始直奔洞,福克斯以给定的V2速度追逐兔子。使用QBasic模拟追赶,并在兔子被抓住或逃脱时打印。
我写了一些代码,但是没有按预期工作。即使狐狸捉住了兔子,它也会打印出兔子逃脱了
到目前为止,我的代码:
CLS
SCREEN 12
WINDOW (-20, 120)-(120, -20)
LINE (0, 0)-(100, 0)
LINE (0, 100)-(0, 0)
CIRCLE (100, 100), 1
INPUT "Input speed of rabbit, v1=", v1
INPUT "input speed of fox, v2=", v2
dlt=0.01
x1 = 0: x2 = 0
y1 = 100: y2 = 0
drw: PSET (x1, y1), 1: PSET (x2, y2), 2
x1 = x1 + dlt * v1
x2 = x2 + dlt * v2 * (x1 - x2) / SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
y2 = y2 + dlt * v2 * (y1 - y2) / SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
IF SQR((x1 - x2) ^ 2 + (y1 - y2) ^ 2) < 0.01 GOTO caught
IF x1 > 100 GOTO escaped
GOTO drw
caught: PRINT "rabbit got caught": GOTO finish
escaped: PRINT "rabbit escaped"
finish: END
如果您不了解QBasic,也可以通过任何语言为我提供算法帮助。我只需要一个更好的算法来解决它。
答案 0 :(得分:1)
首先:尽管您的任务是说兔子沿着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
语句。