QBasic中Fox Rabbit Chase模拟的最佳方式



我需要一些家庭作业方面的帮助。

问题定义

在离洞100米的地方有一只兔子,在垂直于洞的方向上,在离兔子100米的位置有一只狐狸。(兔子在(100,0(,洞在(100100(,狐狸在(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,你也可以帮助我学习任何语言的算法。我只需要一个更好的算法来解决它

首先:尽管您的任务表示兔子沿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语句。

相关内容

  • 没有找到相关文章

最新更新