O que é RNG em videogames ou geradores de números aleatórios

 Se tudo é previsível em um jogo, isso não é muito divertido. RNGs, ou geradores de números aleatórios, são uma forma de introduzir um toque de aleatoriedade e causalidade de que você precisa para apimentá-lo.

Neste artigo, aprenderemos como funcionam os geradores de números aleatórios.

Como funciona um gerador analógico de números aleatórios

A forma mais simples de um RNG é jogar dados ou moedas.

Usar um único dado ou moeda significa que cada valor tem a mesma probabilidade de ocorrer. Usar vários dados ou moedas, em vez disso, dará uma probabilidade mais baixa para os valores mais altos e mais baixos e uma probabilidade mais alta para os valores médios.

O jogo de mesa mais antigo conhecido, o Royal Game of Ur, usa quatro dados de 4 lados. Cada dado pode ter um valor de 0 ou 1, o que significa que o valor obtido por um único lançamento de dados pode ir de 0 a 4.

Todas as combinações possíveis obtidas jogando 4 dados, cada uma pode dar um valor de 0 ou 1

Existem 16 combinações possíveis, das quais uma fornece um valor de 0, 4 fornece um valor de 1, 6 fornece um valor de 2, 4 fornece um valor de 3 e uma fornece um valor de 4.

Neste caso, há 1/16 ou 6,25% de chance de obter 0, 1/4 ou 25% de chance de obter 1, 3/8 ou 37,5% de chance de obter 2, 1/4 ou 25% de chance de obter 3 e 1/16 ou 6,25% de mudança de obtenção de 4.

Jogos mais complexos têm manuais cheios de tabelas para determinar algo aleatoriamente.

Qualquer jogo que use dados possui um gerador analógico de números aleatórios.

Como funcionam os geradores de números aleatórios em videogames

Em videogames, os RNGs são muito menos perceptíveis e mais complexos, e os jogadores podem nem estar cientes de que existem. Existem muitas maneiras de gerar um número aleatório , mas como você realmente usa um?

Dividindo em termos mais simples, usar um RNG não é diferente do que você viu acima com o lance de dados usado para determinar um efeito de uma mesa. Você simplesmente não vê o lançamento dos dados.

Em um videogame, você pode usar um RNG para determinar que tipo de saque pode ser largado por um inimigo caído, ou o que você pode encontrar em um baú, ou que tipo de encontro aleatório estará à sua espera, ou mesmo como estará o tempo.

RNGs são usados, por exemplo, para viver jogos de mundo aberto sem que os desenvolvedores tenham que codificar cada seção de florestas, estradas e desertos. Em vez disso, os desenvolvedores codificam algumas possibilidades e permitem que o acaso determine o que acontece quando o jogador atinge um determinado ponto no mapa.

Você vai encontrar um urso, uma matilha de lobos ou alguns bandidos? O jogo faz sua versão de rolar um dado para determinar isso.

Vamos ver como codificar um exemplo simples de um Gerador de números aleatórios para entender melhor como eles realmente funcionam.

Como codificar um gerador de número aleatório

A maioria das linguagens de programação contém uma randomfunção. Esta função retorna um número aleatório e que tipo de número aleatório depende de sua implementação.

Por exemplo, em JavaScript , Math.random()retorna um número aleatório entre 0 (incluído) e 1 (não incluído). Em Python, randintfrom the randommodule retorna um número inteiro em um intervalo (Python também tem uma função que faz o mesmo que JavaScript Math.random).

Vamos considerar uma situação de videogame bastante comum: temos um inimigo que geralmente derruba um item comum, mas de vez em quando derruba algo raro. Esse inimigo pode ser, por exemplo, um lobo que pode soltar a pele de um lobo (comum) ou uma presa de lobo (rara).

Como você determina o que é "raro"? Isso depende de você - pode ser que 1 em 10 gotas seja um item raro ou 1 em 100 gotas seja um item raro. Um meio termo pode ter uma chance de 1 em 25 para itens raros. E para complicar um pouco, também pode haver 1 chance em 10 de nenhum item.

Nesse caso, você precisaria de uma função que retornasse um valor entre 0 e 1.

A chance de 1 em 25 é de 4% e a chance de 1 em 10 é de 10%. Na forma decimal, isso seria 0,04 e 0,1, respectivamente.

Nesse caso, você pode dizer que um número no intervalo de 0 a 0,04 fornece o item raro e um número no intervalo de 0,9 a 1 não fornece nenhum item.

Para evitar a fixação de uma linguagem, vamos primeiro ver como podemos codificar isso usando pseudocódigo . Esta não é uma linguagem de programação real - em vez disso, é uma maneira de quebrar a lógica do código. É como fazer anotações, pois é pessoal e terá sintaxe variada dependendo da pessoa que escreve.

FUNCTION wolfDrop
  randomNumber = random(0,1)
  IF
    randomNumber < 0.04
    THEN
     -> wolf fang
  ELSE IF
    randomNumber < 0.9
    THEN
     -> wolf pelt
  ELSE
    -> empty
  END IF
END FUNCTION

Ou uma versão mais detalhada:

Crie uma função chamada wolfDrope dentro dela armazene um número aleatório entre 0 (incluído) e 1 (excluído) na randomNumbervariável. Se randomNumbertiver um valor menor que 0.04a queda será uma presa de lobo, se randomNumbertiver um valor menor que 0.9a queda será uma pele de lobo, caso contrário não haverá queda.

function wolfDrop () {
  const randomNumber = Math.random();
  if (randomNumber < 0.04) {
    return "Wolf fang";
  } else if (randomNumber < 0.9) {
    return "Wolf pelt";
  } else {
    return;
  }
}

JavaScript

import random
def wolfDrop():
  randomNumber = random.random()
  if randomNumber < 0.04:
    return "Wolf fang"
  elif randomNumber < 0.9:
    return "Wolf pelt"
  else
    return

Script Pitão 

(defn wolf-drop []
  (let [random-number (rand)]
    (cond (< random-number 0.04) "Wolf fang"
          (< random-number 0.9) "Wolf pelt")))

Clojure

func wolfDrop() string {
    randomNumber := rand.Float64()
    switch {
        case randomNumber < 0.04:
            return "Wolf fang"
        case randomNumber < 0.9:
            return "Wolf pelt"
        default:
            return ""
    }
}

Golang

fun wolfDrop(): String {
    val randomNumber = Random.nextFloat()
    when {
        randomNumber < 0.04 -> return "Wolf fang"
        randomNumber < 0.9 -> return "Wolf pelt"
        else -> return ""
    }
}

Kotlin

def wolf_pelt() do
  random_number = :rand.uniform()
  cond do
    random_number < 0.04 -> "Wolf fang"
    random_number < 0.9 -> "Wolf pelt"
    true -> nil
  end
end

 Elixir

string WolfPelt() {
  var random = new Random();
  double randomNumber = random.NextDouble();
  if (randomNumber < 0.04) return "Wolf fang";
  if (randomNumber < 0.9) return "Wolf pelt";
  return null;
}

C #

extern crate rand;

fn wolf_drop() -> &'static str {
  let random_number: f64 = rand::random();
  if random_number < 0.04 {
    "Wolf fang"
  } else if random_number < 0.9 {
    "Wolf pelt"
  } else {
    ""
  }
}

Linguagem Ferrugem

#include <stdlib.h>
#include <string.h>
#include <time.h>

int wolf_drop(char *drop_item) {
  srand((unsigned) time(0));
  double random_number = 1.0 * rand() / RAND_MAX;
  if (random_number < 0.04) {
    strncpy(drop_item, "wolf fang\0", 10);
  } else if (random_number < 0.9) {
    strncpy(drop_item, "wolf pelt\0", 10);
  } else {
    strncpy(drop_item, "\0", 1);
  }
  return 0;
}

Linguagem C

function wolfdrop()
    randomnumber = rand()
    if randomnumber < 0.04
        return "wolf fang"
    elseif randomnumber < 0.9
        return "wolf pelt"
    else
        return ""
    end
end

Linguagem de programação Julia

Citamos trechos de código em Clojure, Golang, Kotlin, Elixir e C #, e a Jeremy pelos trechos em Rust, C e Julia.

Outros exemplos de math.random

Se você quiser aprender mais sobre tudo isso, pode ler este artigo sobre a função Math.random em JavaScript e criar um jogo de dados.

Você também pode ler este artigo sobre como usar o algoritmo de passeio aleatório e criar um mapa de masmorra aleatório com JavaScript para fazer mais experiências com RNGs.

Conclusão

Geradores de números aleatórios, ou RNGs, são usados ​​em muitos jogos. Neste artigo, você aprendeu como e por que eles são usados ​​e viu um exemplo de implementação.

Na próxima vez que você jogar um videogame, conseguirá identificar onde um RNG pode ser usado?

0 Comentários