Dedicado a mis proyectos en Gambas ,un lenguaje de programación parecido al Visual Basic + Java pero ampliamente mejorado y...¡¡para gnu/linux!!.La potencia del gnu/linux sumada a la facilidad del Basic



Consultas, Desarrollo de programas y petición de presupuestos:



Mostrando entradas con la etiqueta juegos de tablero. Mostrar todas las entradas
Mostrando entradas con la etiqueta juegos de tablero. Mostrar todas las entradas

viernes, 23 de enero de 2015

Desarrollo de Juegos de Tablero (8): Aplicación Reglas y como programarlas


Desarrollo de Juegos de Tablero (8):
Aplicación Reglas y como programarlas


En este artículo explicaré como aplicar reglas y programarlas en el juego de tablero que estamos desarrollando. Para explicar la forma de programarlo, el juego va a tener unas  reglas sencillas, así facilitará entender la forma de programarlo y en el futuro se podrá ampliar con toda la complejidad que queramos. Las reglas a programar serian las siguiente:
- Cada vez que un jugador caiga en una casilla, elige una carta de "suerte", y ejecuta lo que diga la carta. Hay 5 cartas de suerte:
Tres de las cartas son de movimiento, osea avanzamos o retrocedemos un numero de casillas que indique. Y dos cartas son para los puntos de Vida, nos da puntos o nos lo quita.
-Si  por una carta de suerte, nos trasladamos a otra casilla, no cogeremos ninguna carta, pasando el turno al siguiente jugador.
Empezamos:
1) Tenemos un archivo texto donde con varias secciones donde vamos a guardar:
Sección: [reglas casillas][/reglas casillas]
Contiene  la información de lo que hay  en la casilla. En este caso solo tenemos  "coger una carta de suerte", y lo indicamos como "cartasuerte". 
[reglas casillas]
1|cartasuerte
2|cartasuerte
....
          [/reglas casillas]

Nota: Si tuvieramos varias "barajas" de cartas o distintas opciones, lo indicaríamos.

Sección: [cartasuerte][/cartasuerte]
En esta sección definimos cada "carta": su texto, acción a realizar, y valor numérico para indicar número de casillas o puntos a sumar o restar:
  • [cartasuerte]
  • Viento a favor !!! avanzas 5 casillas |avanza|5
  • Viento en contra :( retrocede 2 casillas |retrocede|2
  • Llueve y hace mal tiempo :( retrocede 1 casilla|retrocede|1
  • Consigues Pescar, ganas 10 puntos de vida|puntosVida|10
  • Pierdes mucha agua potable, pierdes 5 puntos de vida|puntosVida|-5
  • [/cartasuerte]
2) Programas una nueva clase "Regla", que será la encargada de leer las reglas,

Private lineasReglas As String[]Private ListaCartaSuerte As String[]
Public rutaCartas As String = "Reglas/CartasDeSuerte.txt"
Public Sub _new()
cargaCartasSuerte()cargaReglas()
End
Public Sub cargaCartasSuerte()
Dim contenido As StringDim datosfichero As String
contenido = File.Load(rutaCartas)'las cartas vienen definida por:"texto|accion|puntuacion"datosfichero = Between(contenido, "[cartasuerte]", "[/cartasuerte]")ListaCartaSuerte = Split(datosfichero, "\n", "", True)
End
Public Sub cargaReglas()
Dim contenido As StringDim datosfichero As String
contenido = File.Load(rutaCartas)datosfichero = Between(contenido, "[reglas casillas]]", "[/reglas casillas]")lineasReglas = Split(datosfichero, "\n", "", True)
End



y ejecutarlas cuando un jugador llegue a la casilla.

Public Sub llega(jug As Jugador, casilla As Integer)
Dim accion As String
accion = Split(lineasReglas[casilla - 1], "|")[1] 'leo la parte de accion del jugador
jug.CumpliendoRegla = TrueejecutaRegla(jug, accion)
End
Public Sub ejecutaRegla(j As Jugador, accion As String)
Select Case accionCase "cartasuerte"AccionCartaSuerte(j)Case "pregunta"AccionCartaPregunta(j)Default'no hacer nada...End Select
End
Private Sub AccionCartaSuerte(j As Jugador)
Dim elegida As Integer
Dim carta As String[] 'el valor 0 continee el texto, y el valor 1 contiene la puntuacion
elegida = Int(Rnd(0, ListaCartaSuerte.count))Print elegida, ListaCartaSuerte[elegida]carta = Split(ListaCartaSuerte[elegida], "|")
Message.Info(carta[0])
Select Case carta[1]
Case "avanza"If (j.CasillaDondeEstoy + Val(carta[2]) - 1) > lineasReglas.count Thenj.Mueve(lineasReglas.count)Elsej.Mueve(j.CasillaDondeEstoy + Val(carta[2]) - 1)EndifCase "retrocede"If j.CasillaDondeEstoy - Val(carta[2]) - 1 > 0 Thenj.Mueve(j.CasillaDondeEstoy - Val(carta[2]) - 1)Elsej.Mueve(0)EndifCase "puntosVida"j.puntosVida += Val(carta[2])
End Select
End



3) Modificamos la clase Control de Partida, para llamar una instancia de la clase regla, para llegue el jugador a una casilla:

Public Sub Observador_LLegue(jug As Object, NumeroCasilla As Integer)

Dim mensaje As String
'Llega a una casilla
If jug.cumpliendoRegla = False Then
'no esta cumpliendo ninguna regla, tiene que leerla
reglasTablero.llega(jug, NumeroCasilla)
Else
'ha llegado a una casilla, pero porque ha cumplido una regla, no hay que ejecutar otra regla
jug.cumpliendoRegla = False
Endif

End
Nota:
La nueva propiedad "cumpliendoRegla" de la clase jugador, nos facilita saber si el jugador a llegado a la casilla por una desplazamiento ordenado por los dados o por si ha llegado cumpliendo alguna regla.

Aqui os dejo un video para ver tanto el código como la ejecución del programa:


Enlace del código fuente: alojado en google drive

Ya prácticamente esta el 90% del juego de tablero....
En el próximo articulo veremos como añadir un "enemigo" al juego. También nos falta añadir detalles gráficos como  una barra de puntos de cada jugador, mejora del formulario de mensajes, implementar el juego "por turnos" y un dado aleatorio.

Saludos.

Julio

jueves, 22 de enero de 2015

Desarrollo de Juegos de Tablero (6): Control de Partida Eventos Y Observadores


Desarrollo de Juegos de Tablero (6):
Control de Partida:  Eventos Y Observadores

En este artículo describiré la forma de como programar cuando una ficha/personaje llegue a una casilla y que el programa haga algo (mostrar un mensaje, dar una penalización o premio, etc.). Para ello vamos a usar la programación orientada a eventos, mediante el mecanismo de definir eventos y observadores.

 Creo que esta es la forma más genérica de programarlo y que luego admitirá añadirle más cosas o interacciones en el juego, aunque también se podría haber programado usando el Patrón Chain Of Responsibility: Cadena de Responsabilidad

Vamos a la explicación: 

1. Tenemos una clase llamada "Control de partida", que estará observando lo que ocurre en la partida, en este ejemplo va a observar a los jugadores que haya.
Esta clase tiene definido un observador:
Private ObservadorControl As Observer

También tiene un método llamado "addobservador", al que le pasamos un array de jugadores que debe de observar.
Public Sub addObservador(p As Object[])
'En nuestro caso las piezas a vigilar son las piezas de los jugadores
Dim objetoTmp As Object
For Each objetoTmp In p
ObservadorControl = New Observer(objetoTmp) As "Observador"

          Next
End



Ahora queremos que cuando se produzca un evento "_Llegue" de un jugador, aparezca un mensaje en el programa, con el nombre del jugador y la casilla a la que ha llegado. Se programaría asi:

Public Sub Observador_LLegue(jug As Object, NumeroCasilla As Integer)
Dim mensaje As String
'muestro datos del objeto 
mensaje = ("El jugador") & " " & jug.nombre & ", " & ("ha llegado a la casilla nº:") & " " & NumeroCasilla
Message.Info(mensaje)
End


2. Vamos a añadir el código necesario para la clase Jugador.
La clase jugador debe de producir el evento _Llegue, cuando sepa que ha llegado a la casilla.
Para ello tenemos que hacer 3 cosas:
2.1. Definir el evento _llegue

Event LLegue(pieza As Object, NumeroCasilla As Integer)

2.2. Hacer saltar el evento, cuando llegue a la casilla:
Raise Llegue(Me, NumeroCasilla) 'informo de que jugador a llegado a la casilla NumeroCasilla

2.3. ¿Cuando sabe el jugador que ha llegado a la casilla? Bien, eso lo sabe a traves su objeto miPiezaAnimada (de la clase PiezaAnimada). Esta clase en su  método  actualizaPosicion(), sabe cuando ha llegado a la casilla destino y cambia la animación a "miEstado.Parado". Lo que vamos a hacer, es en la parte del jugador:

2.3.1 Observar ese objeto "miPiezaAnimada", añadiendole un observador en el jugador

Public ObservadorCambioAnimacionAParada As Observer

2.3.2 que observe a la animación:
Me.ObservadorCambioAnimacionAParada = New Observer(Me.miPiezaAnimada) As "ObservadorAnimacion"

2.3.3 Y que cuando reciba un evento de miPiezaAnimada (que lo vamos a llamar _LlegadaCasilla), dispare el evento que _Llegue(), para que sea escuchado por el control de juego:
Public Sub ObservadorAnimacion_LLegadaCasilla(NumeroCasilla As Integer)
Raise Llegue(Me, NumeroCasilla)
'informo de que jugador a llegado a la casilla NumeroCasilla
End


2.3.4. Ahora en la clase PiezaAnimada, hay que añadirle:
2.3.4.1 Un evento "_llegadaCasilla"

Event LLegadaCasilla(NumeroCasilla As Integer)

2.3.4.2. Que se dispare cuando llegue a una casilla destino. Eso lo hacemos añadiendo al método actualizaPosicion(), el lanzamiento del evento _LlegadaCasilla:

Public Sub actualizaPosicion()
If casillaFinal = casillaInicial Then Return 'a llegado a la casilla de destino
contadorA += 1
          pto.x = casillaInicialX + difx * contadorA
pto.y = casillaInicialY + dify * contadorA
If casillafinalX = pto.x And casillafinaly = pto.y Then
          casillaInicial = casillaFinalmiEstadoAnimacion.CambioEstado(miEstado.Parado) 
AnimacionTmp = miEstadoAnimacion.animacionActual()
'--------------------------------------------------------------------------
          'lanzar evento de llegada a la casilla destino por parte de la pieza.
          '--------------------------------------------------------------------------
Raise LLegadaCasilla(Me.CasillaActual() + 1)
Endif
End


Resumiendo:
El mecanismo programado funciona así:
  • Cuando la clase piezaAnimada llegue a la casilla destino, produce un evento _LlegadaCasilla. 
  • Este es escuchado por el jugador, y produce otro evento _Llegue.
  • Este evento _Llegue es escuchado por el Control de Juego, que nos muestra un mensaje por pantalla dando el nombre del jugador y de la casilla a la que ha llegado.



Aqui teneis un video mostrando el programa:




Enlace de descarga del código fuente: alojado en drive google


En los  próximos artículos  veremos como implementar las reglas del juego, por ejemplo:
- Cuando llegue a una casilla roja, retroceda 2 casillas
- Cuando llegue a una casilla azul, se haga una pregunta, y si acierta gane 2 puntos.
- el objetivo del juego, será llegar a la casilla 43 ( el tesoro) y mostrar cuantos puntos ha tenido el jugador.

Saludos

Julio