Сделать Решатель Frogger


12

🐸🐸

Вы должны составить самую короткую программу, чтобы всегда находить оптимальное решение для упрощенной игры Frogger на сетке 9x9.

Элементы курса:

  • L- Бревно (длина: 3-4). Когда вы запрыгиваете на бревно, оно несет вас с собой.
  • V - Автомобиль (длина: 1-2)
  • Скорость (1-2): с левой стороны ряда будет скорость перемещения элементов в ряду.
  • Пробелы: между элементами всегда будет как минимум два пробела.
  • Направление: В секциях «Автомобиль» и «Журнал» направление движения в каждой полосе движения меняется влево и вправо.

Структура курса:

  • Если это столица, все идет как надо; если это строчные буквы, то идет налево. Все элементы подряд идут в одном направлении. Как только часть элемента исчезнет с экрана, он появится на противоположной стороне экрана.
  • Первый ряд - безопасная зона. Лягушка начинается с того места F, которое всегда одно и то же.
  • Следующие 3 ряда - это дороги с транспортными средствами.
  • Следующий ряд - безопасная зона.
  • Следующие 3 ряда - вода (касающаяся воды == смерть) с бревнами.
  • Как только вы достигнете Wпереулка вы выиграете.
  • Если лягушка умирает, она возвращается F

Управление игроком:

  • L - Осталось
  • R - Правильно
  • U - вверх
  • D - Вниз
  • W - Подожди

После того, как вы двигаетесь, другой кадр проходит. (Обратите внимание, что кадр проходит после вашего перемещения, а не одновременно с вашим перемещением.) Ваша программа должна дать оптимальное решение в виде последовательности символов, таких как URWUUL. Если у курса нет решения, ваша программа должна вывести N.

Примеры: (Поскольку я делал это вручную, я не знаю, являются ли они оптимальными решениями.)

0WWWWWWWWW
1 лл    
2 LLLL   
2 llll   
0         
1 вв 
1 В   
1 вв    
0 F    

Решение: WUWUUURWUULWUU

0WWWWWWWWW
2 lll   
1 LLLL  
1 лл   
0         
2 вв    
1 ВВ     
2 вв    
0 F    

Решение: WUWUWUUWUUWWUU

0WWWWWWWWW
2 llll  
2 LLL   
1 ллл  
0         
2 в 
1 ВВ ВВ 
1 в   
0 F    

Решение: WWUUUURURRWWUUU

0WWWWWWWWW
2 llll   
2 LLL   
1 лл   
0         
1 вв 
2 ВВВ 
2 ввв 
0 F    

Решение: N(Нет способа пройти первый ряд.)

Проверьте это в фрагменте, вставив курс в текстовое поле и нажав «Загрузить курс». Затем вставьте решение в поле «Ввод» и нажмите «Отправить».

Фрагмент. Сложно создавать тестовые примеры, поэтому я создал этот фрагмент, который позволяет вам увидеть, может ли ваша программа выполнять произвольно сгенерированные курсы. В целях тестирования все, что вам нужно сделать, это ввести решение вашей программы (например LRUWL...) в раздел «Ввод» и нажать «Подтвердить». Чтобы вернуть курс в исходное состояние, нажмите «Сброс». Дайте мне знать, если найдете ошибки.

var timer;
var f_x, f_y;
var replaced;
var copy;
document.body.onkeyup = function(e) {
  var a = document.activeElement;
  if (a !== controls && a !== data) hop(e.keyCode);
};

function setup() {
  stop();
  var rows = game.children;
  rows[0].innerHTML = "0WWWWWWWWW";
  load(logs, "L");
  rows[2].innerHTML = "0         ";
  load(cars, "V");
  rows[4].innerHTML = "0    F    ";
  copy = game.innerHTML;
  save();

  f_x = 5;
  f_y = 9;
  replaced = " ";
}

function save() {
  data.value = "";
  for (var i = 1; i <= 9; i++) {
    data.value += getRow(i).textContent;
    if (i < 9) data.value += "\n";
  }
}

function extLoad() {
  stop();
  var rows = data.value.split("\n");
  replaced = " ";
  for (var i = 0; i < rows.length; i++) {
    var r = getRow(i + 1);
    r.innerHTML = rows[i].replace(/ /g, "&nbsp;");
    if (rows[i].indexOf("V") !== -1 || rows[i].indexOf("L") !== -1) r.className = "right";
    else if (rows[i].indexOf("v") !== -1 || rows[i].indexOf("l") !== -1) r.className = "left";
    var f = rows[i].indexOf("F");
    if (f !== -1) {
      f_y = i + 1;
      f_x = f;
    }
  }
  copy = game.innerHTML;
}


function reset() {
  stop();
  game.innerHTML = copy;
  f_x = 5;
  f_y = 9;
  replaced = " ";
}

function play() {
  if (!timer) {
    timer = setInterval(next, 1500);
  }
}

function stop() {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
}

function input(i) {
  var s = controls.value;
  if (i === 0) {
    stop();
    sub.disabled = true;
  }
  if (s[i] === "L") hop(65);
  else if (s[i] === "U") hop(87);
  else if (s[i] === "R") hop(68);
  else if (s[i] === "D") hop(83);
  next();
  if (i < s.length - 1) setTimeout(function() {
    input(i + 1);
  }, 750);
  else sub.disabled = false;
}

function load(part, code) {
  for (var r = 0; r < 3; r++) {
    var row = part.children[r];
    var s = "";
    var dir = r % 2;
    row.className = dir === 1 ? "right" : "left";
    s += Math.floor(Math.random() * 2) + 1;
    var end = 0;
    for (var c = 0; c < 9-end;) {
      var spaces = Math.min(9 - end - c , Math.floor(Math.random() * 2) + 2);
      if(c === 0 && end===0) {
        spaces = Math.floor(Math.random()*4);
        end = Math.max(0,2-spaces);
      }
      s += "&nbsp;".repeat(spaces);
      c += spaces;
      var type = "";
      var len = 0;
      var rand = Math.floor(Math.random() * 2);
      if (code === "L") {
        type = dir === 1 ? "L" : "l";
        len = rand + 3;
      } else {
        type = dir === 1 ? "V" : "v";
        len = rand + 1;
      }
      if (c + len > 9-end) continue;
      s += type.repeat(len);
      c += len;

    }
    row.innerHTML = s + "&nbsp;".repeat(end);
  }
}

function next() {
  move(logs);
  move(cars);
}

function move(part) {
  var rows = part.children;
  for (var i = 0; i < rows.length; i++) {
    var s = rows[i].textContent;
    var f = s.indexOf("F") !== -1;
    if (f) {
      replace(f_y, f_x, false);
      s = rows[i].textContent;
    }
    var speed = s[0];
    var stuff = s.substring(1);
    var v = vel(speed, rows[i].className);
    rows[i].textContent = s[0] + shift(stuff, speed, rows[i].className);
    if (f) {
      if (part === logs) {
        f_x += v;
        if (f_x < 1 || f_x > 9) {
          go(5 - f_x, f_y - 9);
          return;
        }
      }
      replace(f_y, f_x, true);
      s = rows[i].textContent.substring(1);
      var c = f_x + v;
      var t = "";
      if (c > 9) t = s.substring(f_x) + s.substring(0, c - 9);
      else if (c < 0) t = s.substring(0, f_x) + s.substring(9 + c);
      else t = v > 0 ? s.substring(f_x, c) : s.substring(c, f_x);
      if (t.indexOf("V") !== -1 || t.indexOf("v") !== -1) {
        go(5 - f_x, f_y - 9);
      }

    }



  }
}


function vel(mag, dir) {
  var d = dir === "right" ? 1 : -1;
  var m = parseInt(mag);
  return d * m;
}



function shift(s, n, d) {
  n = parseInt(n);
  for (var i = 0; i < n; i++) {
    if (d === "left") {
      s = s.substring(1) + s.substring(0, 1);
    } else {
      s = s.substring(s.length - 1) + s.substring(0, s.length - 1);
    }
  }
  return s;
}


function hop(k) {
  if (k === 65) go(-1, 0);
  else if (k === 87) go(0, 1);
  else if (k === 68) go(1, 0);
  else if (k === 83) go(0, -1);
}

function go(x, y) {


  replace(f_y, f_x, false);
  f_y -= y;
  f_x += x;
  replace(f_y, f_x, true);
  if (f_x < 1 || f_x > 9 || f_y > 9) {
    go(5 - f_x, f_y - 9);
    return;
  }



  if (f_y == 1) {
    alert("win!");
    go(5 - f_x, f_y - 9);
  }


}

function replace(y, x, f) {

  var row = getRow(y);
  if (!row) return false;

  var s = row.textContent;
  if (x < 1 || x >= s.length) return false;
  if (f) {
    replaced = s[x];
    if (replaced === "V" || replaced === "v" || (replaced.charCodeAt(0) === 160 && y < 5)) {
      go(5 - f_x, f_y - 9);

    } else {
      row.textContent = s.substring(0, x) + "F" + s.substring(x + 1);
    }
  } else {
    row.textContent = s.substring(0, x) + replaced + s.substring(x + 1);
  }

}

function getRow(y) {
  if (y < 1 || y > 9) return false;
  if (y === 1) return game.firstChild;
  if (y === 9) return game.lastChild;
  if (y > 5) return cars.children[y - 6];
  if (y < 5) return logs.children[y - 2];
  return game.children[2];
}
<body onload="setup()"><code id="game"><div></div><div id="logs"><div></div><div></div><div></div></div><div></div><div id="cars"><div></div><div></div><div></div></div><div></div></code>
  <input type="button" value="Step" onclick="next()" />
  <input type="button" value="Pause" onclick="stop()" />
  <input type="button" value="Play" onclick="play()" />
  <input type="button" value="Reset" onclick="reset()" />
  <input type="button" value="New Course" onclick="setup()" />
  <div>Controls: WASD</div>
  <div>Input:
    <input type="text" id="controls" />
    <input type="submit" onclick="input(0)" id="sub" />
  </div>
  <div>
    <textarea id="data" rows=9 cols=12></textarea>
    <input type="button" onclick="extLoad()" value="Load Course" />
    <input type="button" onclick="save()" value="Save Course" />
  </div>
</body>

Когда начать:

Связанный:

Смотрите также:


1
Для тех, кто их не видит, первые два символа поста - это Юникод U + 1F438: Лягушонок
кот

6
Решение:WWUUUURURRWWUUU -> Чуви играет на лягушке.
Цифровая травма

3
@DigitalTrauma "Пусть вуки победит" - C3PO, на игровой автомат.
FryAmTheEggman

И что произойдет, если лягушка коснется края экрана?
user81655

2
@quintopia Строчная буква слева, поэтому они идут налево.
геокавель

Ответы:


1

Javascript, 854 байта

function f(w){h=[];z=[];for(y=0;y<9;y++){l=w.split('\n')[y];r={s:parseInt(l[0]),d:1,e:[]};for(x=0;x<9;x++){c=l[1+x];if(c=='v'||c=='l')r.d=-1;r.e.push(c);}z.push(r);}h.push(z);h.push(z);for(g=2;g<40;g++){z=JSON.parse(JSON.stringify(z));for(y=0;y<9;y++){r=z[y];if(r.s>0&&(g%2==0||r.s==2)){i=0;t=0;if(r.d==-1){t=r.e[0];for(i=0;i<8;i++)r.e[i]=r.e[i+1];r.e[i]=t;}else{t=r.e[8];for(i=8;i>0;i--)r.e[i]=r.e[i-1];r.e[i]=t;}}}h.push(z);}j=15;k="";m(0,4,8,"","");return k==""?"N":k;function m(s,a,b,u,v){if(s<j){q={'U':[0,-1],'D':[0,1],'L':[-1,0],'R':[1,0]}[u];if(q)a+=q[0],b+=q[1];v+=u;if(!b){j=s;k=v;return;}if(s>0){for(i=0;i<3;i++){z=h[s*2+i-2];r=z[b];if(i&&(i==1||r.s==2)&&r.e[a].toUpperCase()=='L')a+=r.d;if(a<0||a>8||b>8)return;z=h[s*2+i-1];e=z[b].e;if(e[a].toUpperCase()=='V'||(b<4&&e[a].toUpperCase()!='L'))return;}}t="UWRLD";for(x in t)m(s+1,a,b,t[x],v);}}}

Ungolfed

function solve(input) {
    var grids = [];
    var maxgrid = 40;
    // load input
    var grid = [];
    var lines = input.split('\n');
    for (var y = 0; y < 9; y++) {
        var line = lines[y];
        var row = {
            speed: parseInt(line[0]),
            direction: 1,
            cells: []
        }
        for (var x = 0; x < 9; x++) {
            var c = line[1 + x];
            if (c == 'v' || c == 'l')
                row.direction = -1;
            row.cells.push(c);
        }
        grid.push(row);
    }
    grids.push(grid);
    grids.push(grid);
    // animate grids
    for (var g = 2; g < maxgrid; g++) {
        grid = JSON.parse(JSON.stringify(grid));
        for (var y = 0; y < 9; y++) {
            var row = grid[y];
            if (row.speed > 0 && (g % 2 == 0 || row.speed == 2)) {
                if (row.direction == -1) {
                    var i, temp = row.cells[0];
                    for (i = 0; i < 8; i++)
                        row.cells[i] = row.cells[i + 1];
                    row.cells[i] = temp;
                }
                else {
                    var i, temp = row.cells[8];
                    for (i = 8; i > 0; i--)
                        row.cells[i] = row.cells[i - 1];
                    row.cells[i] = temp;
                }
            }
        }
        grids.push(grid);
    }
    var best = 15;
    var best_moves = "";
    var forceExit = false;

    move(0, 4, 8, "", "");
    return best_moves == "" ? "N" : best_moves;

    function move(step, fx, fy, dir, moves) {
        if (step >= best)
            return "die";
        switch (dir) {
            case 'U':
                fy--;
                break;
            case 'D':
                fy++;
                break;
            case 'L':
                fx--;
                break;
            case 'R':
                fx++;
                break;
        }
        if (dir != '')
            moves += dir;
        if (fy == 0) {
            best = step;
            best_moves = moves;
            return "win";
        }
        if (step > 0) {
            for (var i = 0; i < 3; i++) {
                var grid = grids[step * 2 + i - 2];
                if (i > 0 && (i == 1 || row.speed == 2)) {
                    var row = grid[fy];
                    if (row.cells[fx].toUpperCase() == 'L')
                        fx += row.direction;
                }
                if (fx < 0 || fx > 8 || fy > 8)
                    return "die";
                var grid = grids[step * 2 + i - 1];
                var cells = grid[fy].cells;
                if (cells[fx].toUpperCase() == 'V')
                    return "die";
                if (fy < 4 && cells[fx].toUpperCase() != 'L')
                    return "die";
            }
        }
        move(step+1, fx, fy, 'U', moves);
        move(step+1, fx, fy, 'W', moves);
        move(step+1, fx, fy, 'R', moves)
        move(step+1, fx, fy, 'L', moves);
        move(step+1, fx, fy, 'D', moves)
    }
}

Я тестирую только Up, Wait и Right в примере, чтобы ускорить процесс:

JSFiddle


1
Удивительно, что кто-то наконец сделал это!
геокавель
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.