首页 > 解决方案 > 关于必须行驶 100 公里距离的汽车的游戏

问题描述

这是我的任务:

有一辆30升汽油的汽车。

它需要从 0 到 100 公里行驶。

小车分步移动,每一步小车可以在 0 KM 到 6 KM 之间移动(生成一个随机数)。

该车的行驶里程为 1 KM/L。

您可以在道路上放置 5 个随机加油泵。

每次汽车准确地到达汽油泵时,汽车就会补充 20 升油。

编写一个 JavaScript 代码来运行这个游戏并打印汽车的每一步以及当前位置,剩余汽油。

在“开始”页面上添加一个应该开始游戏的按钮。在文档窗口中打印游戏结果。

如果再次单击开始按钮,它应该清除窗口并重新开始游戏。

我想检查汽车是否通过了汽油泵,如果是,则添加 20l,如果没有,则继续,但代码不会超出 switch 语句。我的代码如下:

document.addEventListener('DOMContentLoaded', function () {
    const btn = document.getElementById('butt');
    btn.addEventListener('click', startTheGame);
    const rootbody = document.querySelector('.rootbody');
    const start = document.querySelector('.start');

    function startTheGame() {
        if (rootbody.innerHTML === '') {
            const header = document.createTextNode('Game Started!');
            start.appendChild(header);
            const p = {
                PP1: 15,
                PP2: 30,
                PP3: 45,
                PP4: 60,
                PP5: 75,
            };

            const pps = document.createTextNode(
                `Petrol Pumps generated at ${p.PP1}, ${p.PP2}, ${p.PP3}, ${p.PP4}, ${p.PP5} `
            );
            rootbody.appendChild(pps);

            let posi = 0;
            let rem = 30;
            while (posi < 100) {
                // Generate a random number
                const random = Math.floor(Math.random() * 6 + 1);
                // For every random number you generate, add it to posi to get the position
                // till that point
                posi = posi + random;
                rem = parseInt(rem - random);
                switch (posi) {
                    case 15:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 16:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 17:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 18:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 19:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 20:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    default:
                        break;
                }
                switch (posi) {
                    case 30:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 31:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 32:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 33:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 34:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 35:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    default:
                        break;
                }
                switch (posi.value) {
                    case 45:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 46:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 47:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 48:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 49:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 50:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    default:
                        break;
                }

                switch (posi) {
                    case 60:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 61:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 62:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 63:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 64:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 65:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 66:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    default:
                        break;
                }
                switch (posi) {
                    case 75:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 76:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 77:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 78:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 79:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    case 80:
                        rem += 20;
                        console.log(`petrol rem ${rem}`);
                        break;
                    default:
                        break;
                }
                // check whether you have reached the destination or not
                // if reached break out of the loop and display destination
                // reached!!!!

                if (posi >= 100) {
                    document.body.querySelector(
                        '.rootbody'
                    ).innerHTML += ` - ${random}Kms travelled, Destination reached`;
                    break;
                }

                // append the posi and the step

                document.body.querySelector(
                    '.rootbody'
                ).innerHTML += `<br />Step - ${random}Kms travelled, position ${posi},
                petrol remaining ${rem}L
                <br/>`;
            }
        }
    }
});

标签: javascript

解决方案


switch当您有一组要测试的固定值并希望基于它们执行不同的事情时,语句很好。在这种情况下,泵的位置是随机的,如果你以后想跑 500 公里而不是 100 公里,你的代码将会增长并且无法维护。

更好的方法是生成一个位置数组,例如[10, 20, 25...]泵位置,每次迈出一步时,检查是否:

// Since we can only refill if there is a pump at the exact location we're at
pumpLocations.includes(position)

然后,您的代码中有很多重复。始终认为DRY (不要重复自己)。如果你发现自己用小的改动重写了相同的代码,试着想出一种方法来编写一次并重用它(例如,创建小的可重用函数)。

这也适用于常量。如果说明告诉您补充应该是20升,请始终想一想“如果要更改此值,我如何才能在 2 天内快速轻松地编辑我的代码?” . 这意味着您不应将数字20放在代码中的任何位置。将其存储在变量中一次,然后重复使用。也不要写PP1,,, PP2...。PP5使用数组,并假设计数将来会发生变化。

以下是一千种方法之一。

不要复制粘贴!看起来您的老师/讲师为您提供了代码模板,本示例未遵循该模板。所以他们会知道你是否这样做,而你不会学到任何东西。相反,请尝试查看使用的模式,并在调整您的练习版本之前获得一些灵感。

const rootBody = document.querySelector('.rootbody'),
      btn      = document.getElementById('butt');
      
btn.addEventListener('click', () => {
  rootBody.innerHTML = '';
  runGame();
});

function runGame() {
  // These values are constant during the game,
  // declare them here once and for all
  const consumptionPerKm    = 1,
        minStep             = 0,
        maxStep             = 6,
        initialPetrol       = 30,
        pumpsCount          = 5,
        refillAmount        = 20,
        startLocation       = 0,
        endLocation         = 100,
        petrolPumpLocations = getRandomIntegers(
                                 pumpsCount,
                                 startLocation,
                                 endLocation
                              ).sort();
                              
  // These represent the state at any given time
  let position = startLocation,
      petrol = initialPetrol;
      
  logStr(`You will find petrol pumps at these positions:\n${
         petrolPumpLocations}\nGood luck!\n`);
         
  if (isAtPump()) {
    petrol += refillAmount; // If there's a pump at the start
  }
      
  logState();
      
  // While we've not reached our destination and still have petrol
  while(position < endLocation && petrol > 0) {
    // Calculate some metrics for this step
    const autonomy          = petrol / consumptionPerKm,
          remainingDistance = endLocation - position,
          maxDistance       = Math.min(autonomy, remainingDistance, maxStep),
          stepDistance      = getRandomInteger(minStep, maxDistance),
          stepConsumption   = stepDistance * consumptionPerKm;
    
    // Adjust the state accordingly
    position += stepDistance;
    petrol -= stepConsumption;

    if (isAtPump()) {
      petrol += refillAmount;
    }
    logState();
  }
  
  if (position === endLocation) {
    logStr("You've reached your destination!");
  } else {
    logStr("Out of petrol :'(");
  }
  
  function isAtPump() {
    return petrolPumpLocations.includes(position);
  }
  
  function logState() {
    let str = `Position: ${position}km\tPetrol: ${petrol}L`;
    if (isAtPump()) {
      str += ` Found a pump! Refilled ${refillAmount}L`;
    }
    logStr(str);
  }
}

function getRandomInteger(min, max) {
  return Math.round(Math.random() * (max - min) + min);
}

function getRandomIntegers(n, min, max) {
  const res = [];
  
  while (res.length !== n) {
    const value = getRandomInteger(min, max);
    if (!res.includes(value)) {
      res.push(value);
    }
  }
  
  return res;
}

function logStr(str) {
  rootBody.innerHTML += '\n' + str;
}
<button id="butt">Start the game</button>
<pre class="rootbody"></pre>


推荐阅读