Лучший способ для симуляции погони за кроликом в QBasic - PullRequest
1 голос
/ 31 октября 2019

Мне нужна помощь с домашним заданием.

Определение проблемы

Кролик находится в 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 Ответ

1 голос
/ 31 октября 2019

Прежде всего: хотя ваше назначение говорит о том, что кролик движется вдоль оси 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, если это действительно необходимо.

...