Обсуждение:貓貓鬼差 — различия между версиями

Материал из Ролевая энциклопедии
Перейти к: навигация, поиск
(Новая страница: «== Подсчёт таблицы вероятностей == Вот мой алгоритм для подсчёта таблицы вероятностей. Он…»)
 
м (забыл подписаться)
 
Строка 1: Строка 1:
 +
{{создано}}
 
== Подсчёт таблицы вероятностей ==
 
== Подсчёт таблицы вероятностей ==
  
Вот мой алгоритм для подсчёта таблицы вероятностей. Он работает через перебор грубой силы, поэтому может работать медленно — впрочем, вряд ли кто-то будет запускать его часто.
+
Вот мой алгоритм для подсчёта таблицы вероятностей. Он работает через перебор грубой силы, поэтому может работать медленно — впрочем, вряд ли кто-то будет запускать его часто. [[Участник:Demetrius|Demetrius]] ([[Обсуждение участника:Demetrius|обсуждение]]) 22:52, 25 октября 2024 (MSK)
  
 
<pre>
 
<pre>

Текущая версия на 22:52, 25 октября 2024

Эта техническая страница
создана на RPGverse

Подсчёт таблицы вероятностей[править]

Вот мой алгоритм для подсчёта таблицы вероятностей. Он работает через перебор грубой силы, поэтому может работать медленно — впрочем, вряд ли кто-то будет запускать его часто. Demetrius (обсуждение) 22:52, 25 октября 2024 (MSK)

function addD6Roll(rollOutcomes) {
  return [1, 2, 3, 4, 5, 6].map(d6Value => rollOutcomes.map(outcomes => [...outcomes, d6Value])).flat()
}

var allPossibleRolls = addD6Roll(addD6Roll(addD6Roll([[1], [2], [3], [4], [5], [6]])))

// возвращает либо false, либо массив с двумя другими бросками (дубль убирает)
// если выпало два дубля, возвращает больший (меньший убирает)
function isDouble(rolls) {
  const doubledNumbers = rolls.filter(
    (number, index) => rolls.findIndex(
      (otherNumber, otherIndex) => otherIndex > index && otherNumber === number
    ) > -1
  )

  if (doubledNumbers.length < 1) return false

  doubledNumbers.sort()

  const [ doubledNumber ] = doubledNumbers
  let numRemoved = 0
  otherRolls = rolls.filter((item) => {
    if (item !== doubledNumber || numRemoved >= 2) {
      return true;
    }

    numRemoved++;
    return false
  })
  return otherRolls
}

function determineOutcome(rollResult, requiredDifficulty) {
  const doubleResult = isDouble(rollResult)
  if (!doubleResult) return 'fail';
  const sum = doubleResult.reduce((r, x) => r+x, 0);
  if (sum === 3) return 'dramaticFail';
  return sum >= requiredDifficulty ? 'success' : 'fail';
}

function doesAddingPlusOneGiveSucceess(rolls, requiredDifficulty) {
  for (i = 0; i < rolls.length; i++) {
    if (rolls[i] >= 6) continue;
    const changedRolls = [...rolls];
    changedRolls[i]++
    const outcome = determineOutcome(changedRolls, requiredDifficulty)
    if (outcome === 'success') return true
  }
  return false
}

function calculateResultChances(rolls, requiredDifficulty) {
  const numOutcomes = { success: 0, fail: 0, dramaticFail: 0, successWithRerolls: 0 };
  const percentages = {}
  rolls.forEach((roll, index) => {
    const outcome = determineOutcome(roll, requiredDifficulty)
    numOutcomes[outcome]++;
    if (outcome === 'success' || doesAddingPlusOneGiveSucceess(roll, requiredDifficulty)) {
      numOutcomes.successWithRerolls++;
    }
  })
  
  Object.entries(numOutcomes).forEach(([type, count]) => {
    percentages[type] = count / rolls.length;
  })
  return percentages;
}

function formatPercentage(n) {
  return (Math.round(n * 10000) / 100) + '%'
}

function percentagesForDifficulties(requiredDifficulty) {
  const { success, fail, dramaticFail, successWithRerolls } = calculateResultChances(allPossibleRolls, requiredDifficulty);
  const cells = [
    requiredDifficulty,
    formatPercentage(success),
    formatPercentage(successWithRerolls),
    formatPercentage(fail),
    formatPercentage(dramaticFail),
  ]
  return '| ' + cells.join(' || ')
}

function range(fromVal, toVal) {
  const result = []
  for (i = fromVal; i <= toVal; i++) {
    result.push(i)
  }
  return result
}

const tableData = range(1, 13).map(i => percentagesForDifficulties(i)).join('\n|-\n');

const result = `{| class="wikitable" style="margin:auto"
! rowspan="2" | Сложность (минус бонус) !! colspan="2" | Шанс успеха !! colspan="2" | Шанс неудачи
|-
! Обычный успех !! С прибавлением +1 !! Обычная неудача !! Драматический провал
|-
${tableData}
|}
`

console.log(result)