showEachStepOfGame=false  //or true
language="English"  //or "Chinese"
function calc(arr, x){
  let nx;
  if(arr[1] === ""){
    nx = arr[2] !== '/' ? eval(`${x}${arr[2]}${arr[3]}`) : (x >= Number(arr[3]) ? Math.round(eval(`${x}${arr[2]}${arr[3]}`)) : 0);      
  } else if(arr[3] === ""){
    nx = arr[2] !== '/' ? eval(`${arr[1]}${arr[2]}${x}`) : (x <= Number(arr[1]) ? Math.round(eval(`${arr[1]}${arr[2]}${x}`)) : 0); 
  }
  return Math.max(nx, 0)
}

function cdt(arr, x){
  let nx;
  if(arr[1] === ""){
    nx = arr[2] !== '=' ? eval(`${x}${arr[2]}${arr[3]}`) : eval(`${x}==${arr[3]}`);      
  } else if(arr[3] === ""){
    nx = arr[2] !== '=' ? eval(`${arr[1]}${arr[2]}${x}`) : eval(`${arr[1]}==${x}`); 
  }
  return nx
}

var ii=0
function solve(gameMap){
  console.log(gameMap)
  const dirs ={'D': [1, 0], 'U': [-1, 0], 'R': [0, 1], 'L': [0, -1]}
  let [n, m] = [gameMap.length, gameMap[0].length];
  
  let health = 0;
  let [X, Y] = [null, null];

  for(let i = 0; i < n; i++){
    for(let j = 0; j < m; j++){
      if(/^P(\d+)$/.test(gameMap[i][j])){
        health = Number(gameMap[i][j].slice(1));
        X = i;
        Y = j;
        gameMap[i][j] = '';
        break
      }
    }
  }

  const hash = (g, x, y, h) => g.map(row => row.join(',')).join('\n') + "&" + `${x},${y}` + "&" + h.toString()
  let queue = [[gameMap, X, Y, health, 0, ""]];                               
  let seen = new Set([hash(gameMap, X, Y, health)]);
  while(queue.length > 0){
    const [g, x, y, h, s, moves] = queue.pop();
    if(g[x][y] === 'S') {
      console.log("Solution found!");
      return moves;
    }
    for(let key of "RUDL"){
      let [dx, dy] = dirs[key];
      let [u, v] = [x + dx, y + dy];
      if(0 <= u && u < n && 0 <= v && v < m && g[u][v] !== "X"){
        if((g[u][v] === '' || g[u][v] == 'S') && !seen.has(hash(g, u, v, h))){            
          seen.add(hash(g, u, v, h))
          queue.push([g, u, v, h, s, moves + key])
        } else if(/^\d+$/.test(g[u][v]) ){
          let delta = Number(g[u][v]); 
          if(s == 0 && delta < h){
            let cpy = g.map(r => r.slice());
            cpy[u][v] = '';
            const st = hash(cpy, u, v, h - delta)
            if(!seen.has(st)){
              seen.add(st);
              queue.push([cpy, u, v, h - delta, s, moves + key])
            }
            
          } 
          else if(s > 0){
            let cpy = g.map(r => r.slice());
            cpy[u][v] = '';
            const st = hash(cpy, u, v, h)
            if(!seen.has(st)){
              seen.add(st);
              queue.push([cpy, u, v, h, s - 1, moves + key])
            }
          }
        } else if(/^\((\d*)([+\-/*])(\d*)\)$/.test(g[u][v])){
          const _m = g[u][v].match(/^\((\d*)([+\-/*])(\d*)\)$/);
//           console.log(_m)
          let nh = calc(_m, h);
          if(nh > 0){
            let cpy = g.map(r => r.slice());
            cpy[u][v] = '';
            const st = hash(cpy, u, v, nh)
            if(!seen.has(st)){
              seen.add(st);
              queue.push([cpy, u, v, nh, s, moves + key])
            }
          }

        } else if(/^\[(\d*)([+\-/*])(\d*)\]$/.test(g[u][v])){
          const _m = g[u][v].match(/^\[(\d*)([+\-/*])(\d*)\]$/);
          let cpy = g.map(r => r.slice());
          for(let i = 0; i < n; i++){
            for(let j = 0; j < m; j++){
              if(/^\d+$/.test(g[i][j])){
                cpy[i][j] = calc(_m, Number(cpy[i][j])).toString()
              }
            }
          }         
          
          cpy[u][v] = '';
          const st = hash(cpy, u, v, h)
          if(!seen.has(st)){
            seen.add(st);
            queue.push([cpy, u, v, h, s, moves + key])
          }
        } else if(/^(\d*)([<=>])(\d*)$/.test(g[u][v])){
          const _m = g[u][v].match(/^(\d*)([<=>])(\d*)$$/);

          let c = cdt(_m, h); 
          if(c){
            const st = hash(g, u, v, h)
            if(!seen.has(st)){
              seen.add(st);
              queue.push([g, u, v, h, s, moves + key])
            }
          }

        } else if(g[u][v] === 'B'){
          let nh = [...h.toString()]
          nh.reverse();
          nh = Number(nh.join(''))    
          let cpy = g.map(r => r.slice());
          cpy[u][v] = '';
          const st = hash(cpy, u, v, nh);
          if(!seen.has(st)){
            seen.add(st)
            queue.push([cpy, u, v, nh, s, moves + key])
          }                    
        } else if(g[u][v] === 'O'){
          let cpy = g.map(r => r.slice());
          cpy[u][v] = '';
          const st = hash(cpy, u, v, h);
          if(!seen.has(st)){
            seen.add(st)
            queue.push([cpy, u, v, h, s + 1, moves + key])
          }                    
        } 
        else if(g[u][v] === 'F'){              
          let cpy = g.map(r => r.slice());
          cpy[u][v] = '';
          for(let i = 0; i < n; i++){
            for(let j = 0; j < m; j++){
              if(/^\d+$/.test(cpy[i][j])){
                let val = [...cpy[i][j]]
                val.reverse();
                cpy[i][j] = Number(val.join('')).toString() 
              }
            }
          } 
          const st = hash(cpy, u, v, h);
          if(!seen.has(st)){
            seen.add(st)
            queue.push([cpy, u, v, h, s, moves + key])
          }                    
        }
      }
    }
  }
  console.log("No solution found")
}

const t = [
  [ '[-1]', '[+1]', 'F', 'X', 'S' ],
  [ '[-1]', '[+1]', 'F', 'X', '89' ],
  [ '[-1]', '[+1]', 'F', 'X', '18' ],
  [ '', '', '', 'P1', '' ]
]
var res =solve(t.map(x=>x.slice()))
console.log(res)

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: