30 scripts de juegos que usted puede escribir en PHP, Parte 1: Creando 10 scripts fundamentales

PHP es un lenguaje de programación de uso extenso, fácil de usar y fácil de aprender. Se ajusta muy bien para el desarrollo de scripts simples que usted puede utilizar para ayudarse en todo tipo de juegos. Así usted juegue juegos simples de papel y lápiz de un jugador, juegos de mesa complejos de roles con un grupo de personas, o juegos on-line de cualquier tipo, esta serie tiene algo para usted. Cada artículo de esta serie "30 scripts de juegos que usted puede escribir en PHP" cubrirá 10 scripts en 300 palabras o menos (3d10 significa "lanzar tres dados de 10 lados") que son lo suficientemente simples para un desarrollador principiante, pero lo también lo suficientemente útiles para un jugador experimentado. La meta es proporcionarle algo que usted pueda modificar para adaptarlo a sus necesidades, para que pueda impresionar a sus amigos y a jugadores sacando su computador portátil en la próxima sesión de juego.

Duane O'Brien, PHP developer, 自由职业者

Duane O'Brien ha sido una "navaja del ejército suizo" en términos tecnológicos desde que Oregon Trail era sólo en texto. Su color favorito es el sushi. Nunca ha ido a la luna.



12-07-2011

Inicio

Siendo al mismo tiempo un jugador maestro/contador de historias y un desarrollador, con frecuencia me hallo escribiendo pequeñas herramientas útiles y scripts para ayudarme cuando estoy ejecutando, jugando y planeando juegos. Algunas veces necesito una idea rápida. Otras veces, simplemente necesito toda una pila de nombres para Non-Player Characters (NPCs). Ocasionalmente, necesito idear números, trabajar en algunos contratiempos o integrar algunos juegos de palabras a algún juego. Muchas de estas tareas se tornan más manejables con un poco de trabajo de script adelantado.

Este artículo explorará 10 scripts fundamentales que pueden utilizarse en diferentes tipos de juegos. El archivo de código contiene la fuente completa de cada script que trataremos, y usted puede ver los scripts en acción en chaoticneutral.

Pasaremos por estos scripts bastante rápido. No cubriremos el tema de encontrar un host ni de configurar un servidor. Hay muchas compañías de hospedaje Web que ofrecen PHP, y el instalador XAMPP es fácil de usar si usted desea configurar el suyo propio. No emplearemos mucho tiempo hablando sobre las mejores prácticas PHP ni sobre técnicas de diseño de juegos. Estos scripts están diseñados para ser fáciles de entender, fáciles de usar y de uso rápido.


Un lanzador de dados básico

Muchos juegos y sistemas de juego necesitan dados. Comencemos con algo simple: lanzar un solo dado de seis lados. En esencia, no hay diferencia entre lanzar un dado de seis lados y seleccionar un número al azar entre 1 y 6. En PHP, esto es simple: echo rand(1,6);.

En muchos casos, eso sería más o menos suficiente. Pero cuando hablamos de juegos de oportunidades, nos gustaría algo un poco mejor. PHP ofrece un generador aleatorio de números mucho mejor: mt_rand(). Sin entrar en detalles sobre las diferencias entre los dos, es seguro suponer que mt_rand es un generador aleatorio de números más rápido y mejor: echo mt_rand(1,6);. Generalmente estaríamos más satisfechos si ponemos esto en una función.

Listado 1. Usando la función mt_rand() de generación aleatoria de números
function roll () {
    return mt_rand(1,6);
}

echo roll();

Luego podemos pasar el tipo de dado que queremos lanzar como un parámetro para la función.

Listado 2. Pasando el tipo de dado como un parámetro
function roll ($sides) {
    return mt_rand(1,$sides);
}

echo roll(6);   // roll a six-sided die
echo roll(10);  // roll a ten-sided die
echo roll(20);  // roll a twenty-sided die

Desde aquí, podemos avanzar para lanzar múltiples dados al mismo tiempo, retornando un conjunto de resultados, o lanzar múltiples dados de diferentes tipos al mismo tiempo, dependiendo de nuestras necesidades. Pero este simple script puede usarse para la mayoría de tareas.


Generador aleatorio de nombres

Si usted está ejecutando juegos, escribiendo historias o creando numerosos personajes al mismo tiempo, algunas veces es difícil estar inventando nombres nuevos. Observemos un generador aleatorio simple de nombres que puede usar para resolver este problema. Para empezar, construyamos dos arrays simples — uno de nombres y otro de apellidos.

Listado 3. Dos arrays simples de nombres y apellidos
$male = array(
    "William",
    "Henry",
    "Filbert",
    "John",
    "Pat",
);

$last = array(
    "Smith",
    "Jones",
    "Winkler",
    "Cooper",
    "Cline",
);

Luego podemos seleccionar un elemento al azar de cada array: echo $male[array_rand($male)] . ' ' . $last[array_rand($last)];. Para tomar un conjunto de nombres al mismo tiempo, simplemente podemos mezclar los arrays y tomar tantos como queramos.

Listado 4. Mezclando los arrays de nombres
shuffle($male);
shuffle($last);
for ($i = 0; $i <= 3; $i++) {
    echo $male[$i] . ' ' . $last[$i];
}

Tomando este concepto básico, podemos crear archivos de texto para guardar nuestros nombres y apellidos. Si ponemos un nombre por línea en nuestro archivo de texto, podemos separar fácilmente el contenido del archivo en la línea de nuevo personaje para construir nuestros arrays fuentes.

Listado 5. Creando archivos de texto para nuestros nombres
$male = explode('\n', file_get_contents('names.female.txt'));
$last = explode('\n', file_get_contents('names.last.txt'));

Construya o encuentre algunos buenos archivos de nombres (se incluyen algunos en el archivo de código), y nunca más necesitaremos crear nombres.


Generador de escenarios

Tomando los mismos principios básicos que hemos usado para crear el generador de nombres, podemos hacer lo que se llama un generador de escenarios. Esto es útil en los juegos de rol o en otras situaciones en las que necesitemos producir un conjunto pseudoaleatorio de circunstancias que puedan utilizarse para jugar un rol, improvisación, escritura, etc. Uno de mis juegos favoritos, Paranoia, incluye algo llamado "mezclador de misiones" en su GM Pack. El mezclador de misiones puede usarse para armar una misión tan rápido como lanzar un dado. Armemos nuestro generador de escenarios.

Contemple el siguiente escenario: Usted se despierta perdido en el bosque. Usted sabe que debe regresar a Nueva York, pero no sabe por qué. Usted puede oír perros ladrando y el inconfundible sonido cercano de las hostiles personas que le buscan. Usted tiene frío, está temblando y está desarmado. Cada frase en ese escenario presenta un aspecto específico del mismo:

  • "Usted se despierta perdido en el bosque" — Esto establece el escenario.
  • "Usted sabe que debe regresar a Nueva York" — Esto describe un objetivo.
  • "Usted puede oír perros ladrando" — Esto presenta a un antagonista.
  • "Usted tiene frío, está temblando y está desarmado" — Esto añade una complicación.

Tal como creamos archivos de texto para nuestros nombres y apellidos, comience creando un archivo de texto para cada escenario, objetivo, antagonista y complicación. En el archivo de código se incluyen archivos de muestra. Una vez tengamos estos archivos, el código para generar el escenario es bastante similar al código para generar los nombres.

Listado 6. Generando un escenario
$settings = explode("\n", file_get_contents('scenario.settings.txt'));
$objectives = explode("\n", file_get_contents('scenario.objectives.txt'));
$antagonists = explode("\n", file_get_contents('scenario.antagonists.txt'));
$complications = explode("\n", file_get_contents('scenario.complications.txt'));

shuffle($settings);
shuffle($objectives);
shuffle($antagonists);
shuffle($complications);

echo $settings[0] . ' ' . $objectives[0] . ' ' . $antagonists[0] . ' ' 
. $complications[0] . "<br />\n";

Podemos añadir elementos a nuestros escenarios agregando nuevos archivos de texto, o tal vez deseemos agregar múltiples complicaciones. Entre más agreguemos a nuestros archivos de texto base, más variados serán nuestros escenarios con el tiempo.


Creador y barajador de mazos de cartas

Si usted juega cartas y le interesa trabajar en algún script relacionado con cartas, vamos a construir un mazo de cartas con un barajador incorporado. Para comenzar, vamos a construir un mazo de cartas estándar. Necesitamos construir dos arrays — uno que guarde las pintas y otro que guarde los números y figuras. Más adelante esto aportará flexibilidad si deseamos agregar nuevas pintas o tipos de cartas.

Listado 7. Creación de un mazo de cartas básico
$suits = array (
    "Picas", "Corazones", "Tréboles", "Diamantes"
);

$faces = array (
    "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Ocho",
    "Nueve", "Diez", "J", "Q", "K", "As"
);

Luego construimos un arreglo de mazo que contenga todos los valores de las cartas. Podemos hacer esto simplemente utilizando un par de bucles foreach .

Listado 8. Creación de un array de mazo de cartas
$deck = array();

foreach ($suits as $suit) {
    foreach ($faces as $face) {
        $deck[] = array ("face"=>$face, "suit"=>$suit);
    }
}

Cuando tenemos construido el array del mazo, fácilmente podemos barajarlo y repartir una carta al azar.

Listado 9. Barajando el mazo y repartiendo una carta al azar
shuffle($deck);

$card = array_shift($deck);

echo $card['face'] . ' of ' . $card['suit'];

Desde aquí, hay un corto trayecto hacia repartir manos de un mismo número establecido de cartas, o para crear un sabot de múltiples mazos.


Calculadora de posibilidades: Repartiendo cartas

Como podemos construir un mazo de cartas como hemos hecho, siguiendo la pinta y el número de cada carta individualmente, podemos utilizar el mazo de forma práctica para hacer algo como calcular las posibilidades de obtener una carta específica. Comencemos repartiendo dos manos de cinco cartas cada una.

Listado 10. Repartiendo dos manos de cinco cartas cada una
$hands = array(1 => array(), 2=>array());

for ($i = 0; $i < 5; $i++) {
    $hands[1][] = implode(" of ", array_shift($deck));
    $hands[2][] = implode(" of ", array_shift($deck));
}

Luego podemos analizar el mazo para ver cuántas cartas quedan y cuáles son las posibilidades de repartir una carta específica. Saber cuántas cartas quedan es fácil. Es simplemente contar cuántos elementos hay en el array $deck . Para obtener las posibilidades de repartir una carta específica, necesitamos una función que analice todo el mazo y que evalúe las cartas restantes para ver si coinciden.

Listado 11. Calculando las probabilidades de repartir una carta específica
function calculate_odds($draw, $deck) {
    $remaining = count($deck);
    $odds = 0;
    foreach ($deck as $card) {
        if (  ($draw['face'] == $card['face'] && $draw['suit'] == 
$card['suit'] ) ||
              ($draw['face'] == '' && $draw['suit'] == $card['suit'] ) ||
              ($draw['face'] == $card['face'] && $draw['suit'] == '' ) ) {
            $odds++;
        }
    }
    return $odds . ' in ' $remaining;
}

Ahora podemos seleccionar la carta que estamos tratando de obtener. Para facilitar esto, pase un array que se vea tal como una carta. Podemos buscar una carta específica.

Listado 12. Buscando una carta específica
$draw = array('face' => 'As', 'suit' => 'Picas');

echo implode(" of ", $draw) . ' : ' . calculate_odds($draw, $deck);

O podemos buscar una carta de una pinta y número dados.

Listado 13. Buscando una carta de una pinta y número dados
$draw = array('face' => '', 'suit' => 'Picas');
$draw = array('face' => 'As', 'suit' => '');

Repartidor de póquer simple

Ahora que tenemos un constructor de mazos de cartas y algo para ayudar a calcular las posibilidades de repartir cartas específicas, podemos armar un repartidor realmente simple para practicar manos de póquer. Para el propósito de este ejemplo, construiremos un repartidor de manos de cinco cartas. El repartidor repartirá cinco cartas del mazo. Usted especifica cuáles cartas desea descartar por número y el repartidor las reemplazará con otras cartas del mazo. No vamos a molestarnos poniendo límites ni reglas de la casa, aunque usted podrá notar que es un ejercicio personal satisfactorio.

Como se mostró en la sección anterior, genere y baraje un mazo y luego cree una mano simple de cinco cartas. Muestre estas cartas por su índice del array para poder especificar cuáles cartas devolver. Puede hacerlo usando recuadros de selección para señalar cuáles cartas va a reemplazar.

Listado 14. Usando recuadros de selección para señalar cuáles cartas va a reemplazar
foreach ($hand as $index =>$card) {
    echo "<input type='checkbox' name='card[" . $index . "]'> 
" . $card['face'] . ' of ' . $card['suit'] . "<br />";
}

Luego, evalúe la entrada array $_POST['card'] para saber cuáles cartas se han marcado para ser reemplazadas.

Listado 15. Evaluando la entrada
$i = 0;
while ($i < 5) {
    if (isset($_POST['card'][$i])) {
        $hand[$i] = array_shift($deck);
    }
}

Usando este script, usted puede ensayar su mano — valga la ironía — descubriendo las mejores formas de manejar un conjunto de cartas específico.


Juego del ahorcado

El Ahorcado es en esencia un juego de adivinar palabras. Dada una palabra de una longitud definida, tenemos un número limitado de intentos de adivinar letras. Si se adivina una letra que aparece en la palabra, todas las ocurrencias de la letra se llenarán. Después de un número establecido de intentos (usualmente seis) usted habrá perdido el juego. Para armar un juego de ahorcado rudimentario, necesitamos comenzar con una lista de palabras. Por ahora, hagamos un array simple.

Listado 16. Creando una lista de palabras
$words = array (
    "gigantes",
    "triángulo",
    "partícula",
    "pajarera",
    "mínimo",
    "inundación"
);

Usando las técnicas cubiertas antes, podemos mover estas palabras hacia un archivo de texto externo de lista de palabras e importarlas como queramos.

En cuanto tenemos la lista de palabras necesitamos seleccionar una al azar, mostrar un espacio en blanco para cada letra y comenzar a recibir los intentos. Necesitamos llevar la cuenta de los intentos correctos y fallidos, tras cada intento. Haremos eso sin complicarnos simplemente serializando los arrays de intentos y pasándolos junto con cada intento. Si deseamos evitar que las personas hagan trampa observando la página fuente, preferiríamos hacer algo un poco más seguro.

Construir arrays que contengan nuestras letras y nuestros intentos correctos/errados. Para intentos correctos, encontraríamos un array con las letras como teclas y los puntos como valores.

Listado 17. Creación de arrays para contener letras e intentos
$letters = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z');
$right = array_fill_keys($letters, '.');
$wrong = array();

Ahora necesitamos un poco de código para evaluar los intentos y mostrar la palabra a medida que avanza el juego de adivinarla.

Listado 18. Evaluando los intentos y mostrando el avance
if (stristr($word, $guess)) {
    $show = '';
    $right[$guess] = $guess;
    $wordletters = str_split($word);
    foreach ($wordletters as $letter) {
        $show .= $right[$letter];
    }
  
} else {
    $show = '';
    $wrong[$guess] = $guess;
    if (count($wrong) == 6) {
        $show = $word;
    } else {
        foreach ($wordletters as $letter) {
            $show .= $right[$letter];
        }
    }
}

En el archivo fuente podemos ver cómo serializar los arrays de intentos y pasarlos intento tras intento.


Ayudante para crucigramas

Sé que no es la forma correcta, pero algunas veces cuando usted está llenando un crucigrama puede estancarse tratando de buscar una palabra de cinco letras que comience con C y termine con T. Usando la misma lista de palabras que armamos para el Ahorcado, fácilmente podemos buscar palabras que coincidan con cierto patrón. Primero, establezca una forma para pasar palabras. Para facilitar esto, reemplace las letras faltantes con puntos: $guess = "c...t";. Como las expresiones regulares tratan al punto como caracter individual, fácilmente podemos analizar la lista de palabras en busca de coincidencias.

Listado 19. Analizando la lista de palabras
foreach ($words as $word) {
    if (preg_match("/^" . $_POST['guess'] . "$/",$word)) {
        echo $word . "<br />\n";
    }
}

Dependiendo de la calidad de nuestra lista de palabras y de la precisión de nuestros intentos, deberíamos poder obtener una lista de palabras razonable para usarla para posibles coincidencias. Usted deberá decidir por sí mismo(a) si "chest" o "cheat" es la mejor para "una palabra de cinco letras que signifique 'no jugar según las reglas'".


Mad Libber

Mad Libs es un juego de palabras en el que el jugador toma una corta historia y reemplaza tipos clave de palabras por palabras diferentes del mismo tipo, para crear una versión tonta de la misma historia. Tome el siguiente texto: "Estaba caminando por el parque cuando encontré un lago. Salté a él y tragué mucha agua. Tuve que ir al hospital". Comience reemplazando los tipos de palabras con indicadores de palabras diferentes. Comience cada señal con una raya al piso para evitar coincidencias accidentales de cadenas de caracteres.

Listado 20. Reemplazando tipos de palabras con indicadores de palabras
$text = "Cataba _VERBO_ando en el _LUGAR_ cuando encontré un _SUSTANTIVO_.
_VERBO_é a él/ella, y _VERBO_é(í) demasiado(a) _SUSTANTIVO_.  Tengo que ir al _LUGAR_.";

Luego cree un par de listas de palabras básicas. Para este ejemplo, no lo haremos elaborado en exceso.

Listado 21. Creando un par de listas de palabras básicas
$verbs = array('bombear', 'saltar', 'caminar', 'tragar', 'gatear', 'aullar', 'rodar');
$places = array('parque', 'hospital', 'ártico', 'océano', 'tienda', 'sótano',
    'ático', 'alcantarilla');
$nouns = array('agua', 'lago', 'asador', 'pies', 'gusano',
    'suciedad', 'río', 'motor rotativo de Wankel');

Ahora podemos evaluar repetidamente el texto para reemplazar las señales según se necesite.

Listado 22. Evaluando el texto
while (preg_match("/(_VERB_)|(_PLACE_)|(_NOUN_)/", $text, $matches)) {
    switch ($matches[0]) {
        case '_VERB_' :
            shuffle($verbs);
            $text = preg_replace($matches[0], current($verbs), $text, 1);
            break;
        case '_PLACE_' :
            shuffle($places);
            $text = preg_replace($matches[0], current($places), $text, 1);
             break;
        case '_NOUN_' :
            shuffle($nouns);
            $text = preg_replace($matches[0], current($nouns), $text, 1);
            break;
    }
}

echo $text;

Obviamente, este es un ejemplo simple y rudimentario. Entre más precisas sean nuestras listas de palabras, y entre más tiempo dediquemos a nuestro texto base, mejores resultados obtendremos. Ya hemos utilizado archivos de texto para crear listas de nombres y listas de palabras básicas. Usando el mismo principio, podemos crear listas de palabras separadas por tipo y uso para crear Mad Libs más diversos.


Selector de lotería

Adivinar los seis números correctos en una lotería es, por decirlo de alguna forma, estadísticamente improbable. A pesar de ello, muchas personas aún pagan por jugar, y si le gustan los números, puede ser divertido ver las tendencias. Vamos a armar un script que nos permita hacer seguimiento de los números ganadores y proporcionar los seis números menos seleccionados de nuestra lista.

(Aviso de límite de responsabilidad: Esto no le ayudará a ganar la lotería, así que por favor no gaste su dinero en los tiquetes. Esto sólo es por diversión.)

Guardamos los números ganadores de la lotería en un archivo de texto. Separamos los números individuales con una coma y ponemos cada conjunto de números en su propia línea. Cuando obtengamos el resultado del archivo, lo dividimos en líneas nuevas y separamos cada línea por comas, para obtener algo que se ve como el Listado 23.

Listado 23. Guardando los números ganadores de la lotería en un archivo de texto
$picks = array(
    array('6', '10', '18', '21', '34', '40'),
    array('2', '8', '13', '22', '30', '39'),
    array('3', '9', '14', '25', '31', '35'),
    array('11', '12', '16', '24', '36', '37'),
    array('4', '7', '17', '26', '32', '33')
);

Obviamente, esto no es un muy buen archivo base para generar estadísticas. Pero es un comienzo y lo suficiente para ilustrar los principios.

Establezca un array base para guardar el rango seleccionado. Por ejemplo, si seleccionamos números del 1 al 40 (esto es, $numbers = array_fill(1,40,0);, luego analizamos nuestros ganadores, incrementando los valores coincidentes apropiados.

Listado 24. Analizando nuestros ganadores
foreach ($picks as $pick) {
    foreach ($pick as $number) {
        $numbers[$number]++;
    }
}

Finalmente, ordenamos los números con base en el valor. Esto debe poner a los números que menos han ganado al frente del array.

Listado 25. Ordenando los números con base en el valor
asort($numbers);

$pick = array_slice($numbers,0,6,true);

echo implode(',', array_keys($pick));

Al agregar regularmente números ganadores reales de la lotería al archivo de texto que contiene nuestra lista de ganadores, podemos buscar una tendencia de los números seleccionados en el largo plazo. Es interesante ver la frecuencia con que aparecen algunos números.


Resumen

Este artículo es un recurso para que usted dé un salto hacia el uso de PHP para ayudar a enriquecer su experiencia de juego. En la Parte 2 de esta serie de "30 scripts de juegos que usted puede escribir en PHP", construiremos el código que se encuentra aquí y profundizaremos en scripts más complejos que le pueden beneficiar más.


Descargar

DescripciónNombretamaño
10 PHP scriptsos-php-gamescripts1-php10games1.zip377KB

Recursos

Aprender

Obtener los productos y tecnologías

  • Innove en su próximo proyecto de desarrollo de fuente abierta con software de prueba IBM, disponible para descarga o en DVD.
  • Descargue versiones de evaluación de productos IBM y practique con herramientas de desarrollo de aplicaciones y con productos de middleware de IBM DB2®, Lotus®, Rational®, Tivoli® y WebSphere®.

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Linux
ArticleID=710715
ArticleTitle=30 scripts de juegos que usted puede escribir en PHP, Parte 1: Creando 10 scripts fundamentales
publish-date=07122011