node.js中的意外标识符

时间:2018-11-19 00:43:48

标签: node.js

我正在尝试使用node.js运行代码,当前出现错误:

  

意外的标识符

代码文件如下:

/*
This script will bruteforce a live match from the TPP API
in Defiance mode and estimate winrates.
Requirements:
-An oauth for the TPP API: https://twitchplayspokemon.tv/show_oauth_token
-Node.js: https://nodejs.org/en/download/
-sync-request for Node.js: `npm install -g sync-request` (NPM should come 
installed with Node.js)
-Pokemon Showdown: https://github.com/Zarel/Pokemon-Showdown
You don't need to install its dependencies, the simulator itself does not 
require them.
-My PBR mod for Pokemon Showdown: https://github.com/mathfreak231/random- 
showdown-mods
enter code here`enter code here`This is required to accurately simulate PBR. 
Note that it is still in development.
Setup steps:
Copy the pbr directory from random-showdown-mods into Pokemon-Showdown/mods.
Fill in the relative path to Pokemon-Showdown/sim below
Fill in your TPP API oauth token below
Change the number constants if you wish
Then just `node defiancechan.js`, sit back, and enjoy your simulation!
Note that the PBR mod is *not* entirely accurate. Known inaccuracies 
include,
but are not limited to: draws are not handled properly, and Fury Cutter
still resets when it shouldn't.
*/

// Replace this with a relative path to Pokemon-Showdown/sim
const Sim = require('./../Pokemon-Showdown/sim');

// Replace this with your TPP oauth token
const TPP_OAUTH = "abc123xyz69420";

// Absolute maximum sample size.
const MAX_SAMPLE_SIZE = 1000;

// z* for your desired confidence level. This is used to calculate
// the margin of sampling error. Some common values:
// For 95% confidence: 1.959963986
// For 99% confidence: 2.575829303
// In practice this means that C% of your simulations will
// have the true proportion within the margin of error from
// the sampled proportion.
// If you don't know what any of this means, don't bother changing
// or paying attention to the "Margin of error" output at the end.
const Z_STAR = 2.575829303;

// Maximum time to run the simulation for, in milliseconds.
const MAX_TIME = 30000;

// If this is true, it prints some match logs (1 in DEBUG_EVERY) to stdout 
while it's bashing them.
const DEBUG = false;
const DEBUG_EVERY = 50;

// Set this to require a .json file to bash a match there instead of a live 
match.
const TEST_MATCH_PATH = null;

/////////////////////////////////////////
// DON'T EDIT ANYTHING BELOW THIS LINE //
/////////////////////////////////////////
const request = require('sync-request');

const PBR_FORMAT = {
  id: 'tppbr',
  name: 'TPPBR',
  mod: 'pbr',
  ruleset: ["PBR Sleep Clause", "PBR Freeze Clause", "PBR Self-Destruct 
Clause", "PBR Destiny Bond Clause"],
  banlist: [],
  unbanlist: [],
  debug: true,
}

/**
  * because pokecat TriHard
  */
function convert_stats_table(stats) {
  let newstats = {};
  for (statname in stats) {
    newstats[statname.toLowerCase()] = stats[statname];
  }
  return newstats;
}

function main() {
  console.log("Getting current match...");
  let match;
  if (TEST_MATCH_PATH) {
    match = require(TEST_MATCH_PATH);
  } else {
    const res = request('GET', 
"https://twitchplayspokemon.tv/api/current_match", {
      headers: {
        'OAuth-Token': TPP_OAUTH
      },
    });
    match = JSON.parse(res.getBody('utf8'));
  }
  console.log("Done.");
  if ((match.base_gimmicks.includes('blind_bet') || 
match.base_gimmicks.includes('secrecy')) && !match.started) {
    throw new Error("Can't analyze a match unless all the Pokemon have been 
revealed.");
  }
  if (!match.base_gimmicks.includes('defiance')) {
    console.log("WARNING: This is not a defiance match!");
  }

  const startTime = Date.now();
  let wincounter = {
    Blue: 0,
    Red: 0,
    draw: 0,
  };
  let teams = [[], []];
  for (let i = 0; i < teams.length; i++) {
    for (const pokemon of match.teams[i]) {
      teams[i].push({
        name: pokemon.ingamename,
        species: pokemon.species.name, // TODO: handle forms
        item: pokemon.item.name,
        ability: pokemon.ability.name,
        moves: pokemon.moves.map(move => move.name),
        nature: pokemon.nature.name,
        gender: pokemon.gender ? pokemon.gender.toUpperCase() : 'N',
        evs: convert_stats_table(pokemon.evs),
        ivs: convert_stats_table(pokemon.ivs),
        level: pokemon.level,
        shiny: pokemon.shiny,
        happiness: pokemon.happiness,
      });
    }
  }

  const isRandomOrder = match.base_gimmicks.includes('random_order');
  const isTraitor = match.base_gimmicks.includes('traitor');
  const isFog = match.base_gimmicks.includes('fog');

  let battle;
  let i;
  console.log("Begin simulation of matches...");
  for (i = 1; i <= MAX_SAMPLE_SIZE; i++) {
    battle = new Sim.Battle({
       formatid: PBR_FORMAT,
    });
    // prevent battle from starting so we can edit stuff first
    battle.started = true;

    let newTeams = teams;
    if (isRandomOrder || isTraitor) {
      // TODO: In what order are these gimmicks applied?
      newTeams = battle.deepClone(teams);
      if (isRandomOrder) {
        for (let team of newTeams) {
           battle.shuffle(team);
        }
      }
      if (isTraitor) {
        // swap 2 pokes, same position
        const p = battle.random(3);
        const temp = newTeams[0][p];
        newTeams[0][p] = newTeams[1][p];
        newTeams[1][p] = temp;
      }
    }

    battle.join('p1', 'Blue', 1, newTeams[0]);
    battle.join('p2', 'Red', 2, newTeams[1]);

    for (const side of battle.sides) {
      for (const pokemon of side.pokemon) {
        pokemon.originalPosition = pokemon.position;
        for (const [m, move] of pokemon.baseMoveSlots.entries()) {
          // change move PP
          const moveData = battle.getMove(move.id);
          const oldMoveData = match.teams[side.n] 
   [pokemon.position].moves[m];
          move.pp = oldMoveData.pp;
          move.maxpp = moveData.pp * (5 + oldMoveData.pp_ups) / 5;
        }
        pokemon.clearVolatile(); // actually update the moveslots TriHard
      }
    }

    if (match.stage) {
      battle.colosseum = match.stage;
    } else if (isFog && battle.randomChance(1,2)) {
      // TODO: confirm this is correct
      battle.colosseum = 'courtyard';
    } else {
      battle.colosseum = battle.sample([
        'gateway', 'mainstreet', 'waterfall', 'neon', 'crystal',
        'sunnypark', 'magma', 'sunset', 'stargazer', 'lagoon',
      ]);
    }

    battle.started = false;
    battle.start();

    if (isFog) battle.setWeather('fog');

    while (!battle.ended) {
      if (battle.turn > 500) {
        console.log('===BEGIN BAD MATCH LOG EXPORT===');
        console.log(battle.log.join('\n'));
        console.log('===END BAD MATCH LOG EXPORT===');
        console.log('===BEGIN BAD MATCH INPUT LOG EXPORT===');
        console.log(battle.inputLog.join('\n'));
        console.log('===END BAD MATCH INPUT LOG EXPORT===');
        throw new Error("The match fucked up somehow.");
      }
      for (const side of battle.sides) {
        let result;
        switch (side.currentRequest) {
          case 'switch':
            // TPPBR switching rules.
            let target = null;
            for (let i = side.active.length; i < side.pokemon.length; i++) {
              const pokemon = side.pokemon[i];
              if (!(pokemon.fainted) && (!target || pokemon.originalPosition 
< target.originalPosition)) {
                target = pokemon;
              }
            }
            result = battle.choose(side.id, `switch ${target.position + 
1}`);
            if (!result) throw new Error(side.choice.error);
            break;
      case 'move':
        // Same as TPPBR, choose random moves until one works
        let tries = 0;
        do {
          result = battle.choose(side.id, `move ${battle.random(4) + 1}`);
          if (++tries > 50) throw new Error(`${side.id} stuck on a move 
choice: ${side.choice.error}`);
            } while (!result);
            break;
        }
      }
    }
    wincounter[battle.winner || 'draw']++;

    if (DEBUG && i % DEBUG_EVERY === 0) {
      console.log('===BEGIN RANDOM MATCH LOG EXPORT===');
      console.log(battle.log.join('\n'));
      console.log('===END RANDOM MATCH LOG EXPORT===');
      console.log('===BEGIN RANDOM MATCH INPUT LOG EXPORT===');
      console.log(battle.inputLog.join('\n'));
      console.log('===END RANDOM MATCH INPUT LOG EXPORT===');
    }

    battle.destroy();

    if (MAX_TIME && Date.now() - startTime >= MAX_TIME) {
      break;
    }
  }

  console.log(`Simulated ${i} battles in ${Date.now() - startTime}ms.`);
  console.log(`Blue win chance: ${wincounter['Blue'] / i}`);
  console.log(`Red win chance: ${wincounter['Red'] / i}`);
  console.log(`Draw chance: ${wincounter['draw'] / i}`);

  // Large Counts condition
  if (wincounter['Blue'] >= 10 && wincounter['Red'] >= 10) {
    let favoredWinrate = Math.max(wincounter['Blue'], wincounter['Red']) / 
i;
    let standardError = Math.sqrt(favoredWinrate * (1-favoredWinrate) / i);
    console.log(`Margin of error: ${Z_STAR * standardError}`);
  } else {
    console.log("Counts are too small to infer a margin of error.");
  }
}

main();

我已经填写了PC的所有信息以及应该执行的所有代码和下载,但我不确定自己做错了什么。帮助将不胜感激。谢谢。如果更简单,我还将提供我从中获取此代码的Github链接。 https://gist.github.com/mathfreak231/4229a28f419f4aa10fcb2eba9fdd57e9

1 个答案:

答案 0 :(得分:0)

我不确定这是否就是SO的格式,但是这里有一些多余的换行符:

  1. ruleset: ["PBR Sleep Clause", "PBR Freeze Clause", "PBR Self-Destruct在一起。下一行以Clause开头,这不是有效的JS关键字,因此会出现错误
  2. 在与throw new Error("Can't analyze a match unless all the Pokemon have been的行上,再次出现不必要的换行符。
  3. // If this is true, it prints some match logs (1 in DEBUG_EVERY) to stdout开头的注释行有换行符。
  4. // Set this to require a .json file to bash a match there instead of a live开头的注释行有换行符。

通常,更明确地读取错误消息。几乎总是会明确告诉您它认为错误在哪里。