在QBasic中进行Fox Rabbit Chase模拟的最佳方法

时间:2019-10-31 11:47:25

标签: algorithm simulation physics qbasic

我需要一些作业上的帮助。

问题定义

  

有一只兔子在距洞口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,也可以通过任何语言为我提供算法帮助。我只需要一个更好的算法来解决它。

1 个答案:

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