algorithm - QBasic 中狐兔追逐模拟的最佳方式

标签 algorithm simulation physics qbasic

我的作业需要一些帮助。

问题定义

There is a rabbit 100 meters away from its hole and a fox 100 meters away from the rabbit in perpendicular direction to the hole. (rabbit at (100,0), hole at (100,100), fox at (0,0)

The rabbit starts running straight to the hole with a given V1 speed and Fox chases the rabbit with a given V2 speed. Simulate the chase using QBasic and print if the rabbit gets caught or escapes.

我写了一些代码,但它没有按预期工作。即使狐狸抓到了兔子,它也打印出兔子逃跑了

到目前为止我的代码:

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 语句。

关于algorithm - QBasic 中狐兔追逐模拟的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58642695/

相关文章:

python - 给定一个对象的坐标,如何确定它位于旋转坐标系的哪个象限?

c - 如何使用平方反比定律将光强度转换为线性值

algorithm - 带摩擦力的运动算法

python - Runge-Kutta 四阶方法。向后整合

algorithm - 是否有一种特定的算法来生成 n 个元素的所有组合,一次取 n-1 个

java - 检查所有订单的运行时间是多少?

algorithm - 计算设置比率矩形大小和位置以最大化与任意表面的交点

algorithm - 二叉搜索树内部路径长度分析

python - 分子动力学模拟器的最佳语言,可在生产中运行。 (Python+Numpy?)

vhdl - Active-HDL 仿真时钟交叉