Two point o K-point
Capítulo 5 Implementación y desarrollo
5.2 Cómo medir la dificultad
Uno de los puntos más importantes al momento de empezar el desarrollo de este trabajo fue como determinar qué secciones de un nivel habían probado ser difíciles para el jugador. Determinar la dificultad de una sección se vuelve relativamente trivial una vez que uno es capaz de encontrar una fórmula que se puede aplicar a las piezas que componen dicha sección. Para determinar cómo componer la fórmula es necesario determinar primero qué métricas se utilizarán.
La primera métrica y quizás las más fácil de obtener sea el tiempo. Se podría argumentar que mientras más rápido se recorre un nivel más fácil es y no se estaría del todo equivocado si uno considera el tiempo total del nivel. Si uno tuviera varios niveles que fueron terminados por un jugador y los comparara de acuerdo al tiempo, aquellos que menos tiempo le llevaron probablemente sean los más fáciles. El problema del tiempo es que cuando uno quiere medir la dificultad de una sección de un nivel esta métrica empieza a fallar, porque el tiempo que le lleva a un jugador atravesar una pieza no es indicador de la dificultad de esa pieza particular sino de las que la rodean (problema con el que nos vamos a topar varias veces). Un buen ejemplo de esto es la figura 6, en esta sección del nivel es muy probable que el jugador se pare en una de las piezas anteriores a la trampa
esperando el momento oportuno para atraversala, en este caso el tiempo que cuesta atravesar la pieza es una consecuencia directa de la presencia de la trampa más adelante. Entonces tenemos una métrica que sirve pero solo cuando se utiliza para medir tramos y no es muy útil para comparar piezas individuales.
Figura 6.Ejemplo de registro posible utilización errónea del tiempo. El personaje se encuentra esperando la rotación de la sierra a tres bloques de distancia de la pieza que genera la dificultad
La segunda métrica y la más famosa es cantidad de muertes del jugador. Desde los principios de los juegos de plataforma que la cantidad de muertes en un nivel es un indicador directo de la dificultad que presenta el mismo. Con un simple evento que incrementa un contador cada vez que el jugador muere a causa de cierta pieza ya se obtiene un buen indicador de la dificultad que presenta esa pieza. No obstante seguimos con el mismo problema que con el tiempo, que un jugador muera sucesivamente en cierta pieza no es un indicador directo de la dificultad de la misma. Para ilustrar el problema, la figura 7 nos muestra un tramo con un salto largo, lo más probable es que si el jugador intenta atravesar esta sección y falla, la muerte se registre en la última sección del salto debido a que es en este punto que el personaje se queda sin velocidad si el salto no se ejecuta correctamente. Este registro en la última sección si es interpretado individualmente puede resultar en la deducción errónea que el jugador solo tiene problemas con saltos de un solo espacio. Para mitigar este problema una vez que una pieza registra una muerte, esta es contada en las dos piezas adyacentes, permitiendo representar así la contribución de las piezas adyacentes a la muerte del jugador. Esta contribución se podría aumentar aún más pero sería necesario idear una fórmula que permita una distribución más justa que una simple adyacencia (por tipo de pieza, proporcional al tiempo pasado en la pieza o
a la cantidad de inputs, etc) y lamentablemente no se contó con el tiempo suficiente para realizar las pruebas.
Figura 7. Un salto de largo 3 tiene tres piezas capaces de registrar el fallo del jugador
La última métrica que se incluye al momento de determinar la dificultad de una sección es la llamada input count, que mide la cantidad de teclas presionadas mientras se está en la pieza. El objetivo de este indicador es representar la dificultad motriz sin tener que depender del fallo del jugador, un buen jugador puede recorrer un nivel rápidamente y sin muertes pero no sin presionar ninguna tecla. La relación entre la dificultad y la cantidad de teclas presionadas proviene de que en un juego de plataforma un jugador no presiona simplemente una sola tecla durante todo el transcurso del juego, diferentes secciones le van a exigir combinaciones de habilidades (salto y movimiento horizontal) así como también va a tener que compensar por saltos largos o esquivar obstáculos en el aire.
Entonces se tienen las muertes ( ), el tiempo ( ) y el input count ( M T IC).Las tres métricas analizadas han probado ser útiles pero únicamente si se tienen en cuenta junto a las de otras piezas,es decir, es necesario analizarlas de forma conjunta para que aporten datos relevantes. La forma más simple de relacionar las tres métricas es una suma, la cuál le daría el mismo peso a cada una de las métricas, sin embargo, se observó que la presencia de un número positivo de muertes en una pieza es un gran indicador de dificultad, para potenciar este indicador se le agregó un multiplicador a este índice ( pM). La suma de las tres métricas es dividida por la cantidad de piezas que forman la sección ( ) L
para no generar un bias hacia secciones más largas. El resultado es la fórmula que se detalla a continuación:
T (M M) IC) / L
( + *p +
Figura 8. Ecuación que define la dificultad de una secuencia.
Para terminar se tienen en cuenta las diferentes veces que se pasa por una pieza en sucesivos intentos. Cada vez que se atraviesa una pieza se guardan las métricas respectivas: input count y tiempo, de esta manera se obtiene información más precisa al aumentar la cantidad de muestras. Una vez terminado el nivel se calculan los promedios de cada índice en cada pieza y son estos números los que se utilizan en la fórmula final.
Ahora que ya se tienen las métricas utilizadas en el cálculo de la dificultad hay que detallar cómo se realiza este cálculo. Una vez terminado el nivel y obtenidos los datos de cada una de las piezas que lo componen se realizan diferentes iteraciones sobre los datos para conseguir diversas combinaciones de piezas.
La figura 9 es un pseudocódigo que representa el funcionamiento general de la identificación de secuencias.
for (longitudPermutacion=3; longitudPermutacion< 5;longitudPermutacion ++) { maximo=nivel.Largo() - longitudPermutacion +1
ValorMuertes,ValorTiempo,ValorInputs = new float[maximo]; for (i=0;i<maximo;i++){
for (j=0;j<longitudPermutacion ;j++){
ValorMuertes[i]= ValorMuertes[i]+ valorMuertesNivel[i+j]; ValorTiempo[i]= ValorTiempo[i]+ valor Tiempo Nivel[i+j]; ValorInputs[i]= ValorInputs[i]+ valorInputsNivel[i+j];} }
}
Figura 9. Pseudo-código que detalla el funcionamiento de la identificación de secuencias y el cálculo de las métricas.
El algoritmo realiza tres iteraciones anidadas, la primera depende de los largos especificados de las secuencias, la segunda recorre todo el nivel y por último la tercera recopila todos los valores de cada patrón de la longitud especificada. Esto genera diversas secuencias muchas de las cuales están contenidas unas dentro de otras y que cada una tiene un valor de dificultad independiente del largo. Para evitar que la lista de secciones contengan una serie de secuencias que están contenidas unas en otras se implementó una rutina que determina cuando una contiene a otra, de ser así compara la dificultad de las
mismas y se queda con aquella que tenga el índice más grande, en caso de que el índice sea igual se elige la más corta.