Es tracta de la recreació d'un joc de sobretaula en el que s'ha d'avançar per un taulell on hi ha unes escales, que fan pujar el jugador, i unes serps, que el fan baixar. L'objectiu és anar de la part inferior del taulell fins a la superior, movent-se el nombre de caselles que indica un dau.
En el programa es fan servir les imatges següents (stairs1.png, DADO-1.bmp, DADO-2.bmp, DADO-3.bmp, DADO-4.bmp, DADO-5.bmp i DADO-6.bmp):
El programa és el següent:
import random from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle from adafruit_display_shapes.line import Line import board import displayio import terminalio from adafruit_display_text import label import time import digitalio from gamepadshift import GamePadShift import neopixel # Importar neopixel para controlar el LED RGB
# Configuración de la pantalla
display = board.DISPLAY
main_group = displayio.Group()
display.show(main_group)
# Configuración de botones
pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK),
digitalio.DigitalInOut(board.BUTTON_OUT),
digitalio.DigitalInOut(board.BUTTON_LATCH))
# Configuración del LED Neopixel
cadena = neopixel.NeoPixel(board.NEOPIXEL, 5, brightness=0.3)
# Constantes de botones
K_LEFT = 128
K_UP = 64
K_DOWN = 32 # Botón B
K_RIGHT = 16
K_A = 2
# Dimensiones del tablero
grid_width = 16
grid_height = 16
num_rows = 6
num_cols = 10
margin_top = 20
start_y = display.height - (num_rows * grid_height)
# Colores
warm_color = 0xFF4500
cool_color = 0x1E90FF
start_end_color = 0xFFC0CB
player1_color = (255, 255, 255)
player2_color = (0, 255, 0)
dice_color = 0xFFFF00
ladder_color = 0x006400
snake_color = 0xFFFFFF
# Función para generar posiciones aleatorias de serpientes y escaleras
def generar_posiciones_aleatorias(num_serpientes, num_escaleras):
total_casillas = num_rows * num_cols
posiciones = {}
usadas = set()
# Generar escaleras
for _ in range(num_escaleras):
while True:
inicio = random.randint(2, total_casillas - num_cols - 1)
fin = random.randint(inicio + num_cols, total_casillas - 1)
if inicio not in usadas and fin not in usadas and inicio < fin and inicio != 1 and fin != total_casillas:
posiciones[inicio] = fin
usadas.add(inicio)
usadas.add(fin)
break
# Generar serpientes
for _ in range(num_serpientes):
while True:
inicio = random.randint(num_cols + 1, total_casillas - 2)
fin = random.randint(1, inicio - num_cols)
if inicio not in usadas and fin not in usadas and inicio > fin and inicio != 1 and fin != total_casillas:
posiciones[inicio] = fin
usadas.add(inicio)
usadas.add(fin)
break
return posiciones
# Generar las posiciones de serpientes y escaleras
serpientes_escaleras = generar_posiciones_aleatorias(4, 4)
# Crear espacio negro superior
black_space = Rect(0, 0, display.width, margin_top, fill=0x000000)
main_group.append(black_space)
# Textos de los jugadores con círculos de color
text_group = displayio.Group()
player1_circle = Circle(display.width // 4 - 30, margin_top // 2, 5, fill=0xFFFFFF)
player1_label = label.Label(terminalio.FONT, text="Jugador1", color=0xFFFFFF)
player1_label.anchor_point = (0.5, 0.5)
player1_label.anchored_position = (display.width // 4 + 3, margin_top // 2)
player2_circle = Circle(3 * display.width // 4 - 42, margin_top // 2, 5, fill=0x00FF00)
player2_label = label.Label(terminalio.FONT, text="Jugador2", color=0xFFFFFF)
player2_label.anchor_point = (0.5, 0.5)
player2_label.anchored_position = (3 * display.width // 4 - 10, margin_top // 2)
dice_label = label.Label(terminalio.FONT, text="", color=dice_color)
dice_label.anchor_point = (1, 0.5)
dice_label.anchored_position = (display.width - 10, margin_top // 2)
text_group.append(player1_circle)
text_group.append(player1_label)
text_group.append(player2_circle)
text_group.append(player2_label)
text_group.append(dice_label)
main_group.append(text_group)
# Tablero con colores alternos
board_group = displayio.Group()
for row in range(num_rows):
for col in range(num_cols):
x = col * grid_width
y = start_y + row * grid_height
if (row, col) == (num_rows - 1, 0) or (row, col) == (0, 0): # Casilla inicial y final
color = start_end_color
else:
color = warm_color if (row + col) % 2 == 0 else cool_color
cell = Rect(x, y, grid_width, grid_height, fill=color, outline=0xFFFFFF)
board_group.append(cell)
main_group.append(board_group)
# Dibujar serpientes y escaleras
for start, end in serpientes_escaleras.items():
start_col = (start - 1) % num_cols
start_row = (start - 1) // num_cols
end_col = (end - 1) % num_cols
end_row = (end - 1) // num_cols
start_x = start_col * grid_width + grid_width // 2
start_y_coord = start_y + start_row * grid_height + grid_height // 2
end_x = end_col * grid_width + grid_width // 2
end_y = start_y + end_row * grid_height + grid_height // 2
if start < end: # Escaleras
line = Line(start_x, start_y_coord, end_x, end_y, color=ladder_color)
board_group.append(line)
# Cabeza de la escalera en la parte inferior
head_radius = 3
ladder_head = Circle(start_x, start_y_coord, head_radius, fill=ladder_color)
board_group.append(ladder_head)
else: # Serpientes (sin cabezas)
line = Line(start_x, start_y_coord, end_x, end_y, color=snake_color)
board_group.append(line)
# Fichas de los jugadores
player_radius = 4
player1_piece = Circle(0, 0, player_radius, fill=0xFFFFFF)
player2_piece = Circle(0, 0, player_radius, fill=0x00FF00)
main_group.append(player1_piece)
main_group.append(player2_piece)
# Variables de posición de los jugadores
player1_position = [0, num_rows - 1]
player2_position = [0, num_rows - 1]
# Función para mover la ficha al centro de una casilla
def move_player(player_piece, column, row):
if 0 <= column < num_cols and 0 <= row < num_rows:
player_piece.x = column * grid_width + grid_width // 2 - player_radius
player_piece.y = start_y + row * grid_height + grid_height // 2 - player_radius
# Reiniciar juego
def reiniciar_juego():
global player1_position, player2_position, turno_jugador, movimiento_restante, subio_fila, serpientes_escaleras
player1_position = [0, num_rows - 1]
player2_position = [0, num_rows - 1]
move_player(player1_piece, player1_position[0], player1_position[1])
move_player(player2_piece, player2_position[0], player2_position[1])
turno_jugador = 1
movimiento_restante = 0
subio_fila = False
serpientes_escaleras = generar_posiciones_aleatorias(4, 4)
main_group.append(board_group)
main_group.append(text_group)
# Mostrar pantalla de ganador
def mostrar_ganador(jugador):
black_screen = Rect(0, 0, display.width, display.height, fill=0x000000)
main_group.pop()
main_group.append(black_screen)
winner_label = label.Label(terminalio.FONT, text=f"¡Ganador Jugador {jugador}!", color=0xFFFFFF)
winner_label.anchor_point = (0.5, 0.5)
winner_label.anchored_position = (display.width // 2, display.height // 2 - 20)
restart_label1 = label.Label(terminalio.FONT, text="Pulsa Reset para", color=0xFFFFFF)
restart_label1.anchor_point = (0.5, 0.5)
restart_label1.anchored_position = (display.width // 2, display.height // 2 + 10)
restart_label2 = label.Label(terminalio.FONT, text="reiniciar la partida", color=0xFFFFFF)
restart_label2.anchor_point = (0.5, 0.5)
restart_label2.anchored_position = (display.width // 2, display.height // 2 + 30)
main_group.append(winner_label)
main_group.append(restart_label1)
main_group.append(restart_label2)
while True:
boto = pad.get_pressed()
if boto & K_DOWN: # Botón B
main_group.pop()
reiniciar_juego()
return
time.sleep(0.1)
# Mover fichas a posición inicial
move_player(player1_piece, player1_position[0], player1_position[1])
move_player(player2_piece, player2_position[0], player2_position[1])
# Bucle principal
turno_jugador = 1
movimiento_restante = 0
subio_fila = False
while True:
boto = pad.get_pressed()
if player1_position == [0, 0]:
mostrar_ganador(1)
continue
elif player2_position == [0, 0]:
mostrar_ganador(2)
continue
if movimiento_restante == 0:
if boto & K_A:
movimiento_restante = random.randint(1, 6)
dice_label.text = str(movimiento_restante)
cadena.fill(player1_color if turno_jugador == 1 else player2_color)
time.sleep(1)
cadena.fill((0, 0, 0))
subio_fila = False
else:
jugador_actual = player1_position if turno_jugador == 1 else player2_position
ficha_actual = player1_piece if turno_jugador == 1 else player2_piece
if boto & K_RIGHT and 0 <= jugador_actual[0] + 1 < num_cols:
jugador_actual[0] += 1
movimiento_restante -= 1
elif boto & K_LEFT and 0 <= jugador_actual[0] - 1 >= 0:
jugador_actual[0] -= 1
movimiento_restante -= 1
elif boto & K_UP and not subio_fila and 0 <= jugador_actual[1] - 1 >= 0:
jugador_actual[1] -= 1
movimiento_restante -= 1
subio_fila = True
move_player(ficha_actual, jugador_actual[0], jugador_actual[1])
if movimiento_restante == 0:
flat_position = jugador_actual[1] * num_cols + jugador_actual[0] + 1
if flat_position in serpientes_escaleras:
new_flat_position = serpientes_escaleras[flat_position]
jugador_actual[0] = (new_flat_position - 1) % num_cols
jugador_actual[1] = (new_flat_position - 1) // num_cols
move_player(ficha_actual, jugador_actual[0], jugador_actual[1])
turno_jugador = 2 if turno_jugador == 1 else 1
time.sleep(0.1)

Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.