# ============================================================
# BlackJack (21) - Raspberry Pi Pico W
# VERSION WOKWI - LCD 1602 modo paralelo 4 bits
#
# Pines LCD:
# RS -> GP8
# E -> GP9
# D4 -> GP10
# D5 -> GP11
# D6 -> GP12
# D7 -> GP13
# RW -> GND
# V0 -> GND (contraste maximo)
# VDD -> 3.3V
# A -> 3.3V (backlight)
# K -> GND
#
# Pines Botones (Pull-Up, activo LOW):
# J1 Pedir -> GP14
# J1 Parar -> GP15
# J2 Pedir -> GP16
# J2 Parar -> GP17
# ============================================================
import time
import random
from machine import Pin
# ============================================================
# DRIVER LCD 1602 - MODO PARALELO 4 BITS
# ============================================================
class LCD_4bit:
def __init__(self, rs, e, d4, d5, d6, d7):
self.rs = Pin(rs, Pin.OUT)
self.e = Pin(e, Pin.OUT)
self.d4 = Pin(d4, Pin.OUT)
self.d5 = Pin(d5, Pin.OUT)
self.d6 = Pin(d6, Pin.OUT)
self.d7 = Pin(d7, Pin.OUT)
self._init_lcd()
def _pulse(self):
self.e.value(1)
time.sleep_us(500)
self.e.value(0)
time.sleep_us(500)
def _write4(self, nibble):
self.d4.value((nibble >> 0) & 1)
self.d5.value((nibble >> 1) & 1)
self.d6.value((nibble >> 2) & 1)
self.d7.value((nibble >> 3) & 1)
self._pulse()
def _send(self, byte, mode):
self.rs.value(mode)
self._write4(byte >> 4) # nibble alto
self._write4(byte & 0x0F) # nibble bajo
def _cmd(self, byte):
self._send(byte, 0)
time.sleep_us(50)
def _char(self, byte):
self._send(byte, 1)
time.sleep_us(50)
def _init_lcd(self):
time.sleep_ms(50)
self.rs.value(0)
self.e.value(0)
# Secuencia de inicializacion en 4 bits
self._write4(0x03)
time.sleep_ms(5)
self._write4(0x03)
time.sleep_ms(1)
self._write4(0x03)
time.sleep_ms(1)
self._write4(0x02) # Cambiar a modo 4 bits
time.sleep_ms(1)
self._cmd(0x28) # 4 bits, 2 lineas, 5x8
self._cmd(0x0C) # Display ON, cursor OFF
self._cmd(0x06) # Entrada izq a der
self._cmd(0x01) # Limpiar
time.sleep_ms(2)
def clear(self):
self._cmd(0x01)
time.sleep_ms(2)
def set_cursor(self, col, row):
offsets = [0x00, 0x40]
self._cmd(0x80 | (offsets[row] + col))
def write(self, text):
for ch in text:
self._char(ord(ch))
def print_line(self, row, text):
text = text[:16]
while len(text) < 16:
text = text + " "
self.set_cursor(0, row)
self.write(text)
# ============================================================
# ESTADO DEL JUEGO
# ============================================================
STATUS_READY = "Listo para iniciar"
STATUS_ACTIVE = "Juego Activo"
STATUS_P1 = "Gana el jugador 1"
STATUS_P2 = "Gana el jugador 2"
STATUS_HOUSE = "La casa gana"
scores = [0, 0]
stopped = [False, False]
last_card = [None, None]
status = STATUS_READY
def reset_game():
global scores, stopped, last_card, status
scores = [0, 0]
stopped = [False, False]
last_card = [None, None]
status = STATUS_READY
def add_card(player):
global status
card = random.randint(1, 10)
scores[player] += card
last_card[player] = card
status = STATUS_ACTIVE
return card
def stop_player(player):
stopped[player] = True
check_winner()
def check_winner():
global status
if not (stopped[0] and stopped[1]):
return
s1, s2 = scores
b1, b2 = s1 > 21, s2 > 21
if b1 and b2: status = STATUS_HOUSE
elif b1: status = STATUS_P2
elif b2: status = STATUS_P1
elif s1 == s2: status = STATUS_HOUSE
elif s1 > s2: status = STATUS_P1
else: status = STATUS_P2
def game_over():
return status not in (STATUS_READY, STATUS_ACTIVE)
# ============================================================
# LCD HELPERS
# ============================================================
def lcd_welcome(lcd):
lcd.print_line(0, " BLACKJACK 21 ")
lcd.print_line(1, " Presiona boton ")
def lcd_update(lcd):
s1, s2 = scores
if last_card[0] is not None:
lc1 = str(last_card[0])
if len(lc1) < 2:
lc1 = " " + lc1
else:
lc1 = "--"
if last_card[1] is not None:
lc2 = str(last_card[1])
if len(lc2) < 2:
lc2 = " " + lc2
else:
lc2 = "--"
if status == STATUS_READY:
lcd_welcome(lcd)
return
# Linea 0: ultima carta de cada jugador
line0 = "J1 C:" + lc1 + " J2 C:" + lc2
lcd.print_line(0, line0)
# Linea 1: suma y estado
if game_over():
if status == STATUS_P1:
msg = "Gana J1!"
elif status == STATUS_P2:
msg = "Gana J2!"
else:
msg = "Casa gana"
s1s = str(s1)
s2s = str(s2)
line1 = "S1=" + s1s + " S2=" + s2s + " " + msg
lcd.print_line(1, line1[:16])
else:
st1 = "P" if stopped[0] else " "
st2 = "P" if stopped[1] else " "
s1s = str(s1)
if len(s1s) < 2:
s1s = " " + s1s
s2s = str(s2)
if len(s2s) < 2:
s2s = " " + s2s
line1 = "S1=" + s1s + st1 + " S2=" + s2s + st2
lcd.print_line(1, line1)
# ============================================================
# MONITOR SERIAL (simula refresco web cada 2 seg)
# ============================================================
def print_web_status():
print("====================================")
print(" ESTADO : " + status)
p1 = " J1 : " + str(scores[0]) + " pts"
p2 = " J2 : " + str(scores[1]) + " pts"
if stopped[0]:
p1 = p1 + " [PLANTADO]"
if stopped[1]:
p2 = p2 + " [PLANTADO]"
print(p1)
print(p2)
print("====================================")
# ============================================================
# DEBOUNCE
# ============================================================
DEBOUNCE_MS = 250
class Button:
def __init__(self, pin_num):
self.pin = Pin(pin_num, Pin.IN, Pin.PULL_UP)
self._last = 0
def pressed(self):
if not self.pin.value():
now = time.ticks_ms()
if time.ticks_diff(now, self._last) > DEBOUNCE_MS:
self._last = now
return True
return False
# ============================================================
# MAIN
# ============================================================
def main():
# LCD en modo paralelo 4 bits
lcd = LCD_4bit(rs=8, e=9, d4=10, d5=11, d6=12, d7=13)
# Botones
btn = [
Button(14), # J1 pedir [0]
Button(15), # J1 parar [1]
Button(16), # J2 pedir [2]
Button(17), # J2 parar [3]
]
lcd_welcome(lcd)
print("BlackJack listo. Usa los botones.")
print_web_status()
last_serial = time.ticks_ms()
while True:
if not game_over():
# J1 pedir carta
if btn[0].pressed() and not stopped[0]:
add_card(0)
lcd_update(lcd)
if scores[0] > 21:
stop_player(0)
lcd_update(lcd)
print_web_status()
# J1 plantarse
elif btn[1].pressed() and not stopped[0]:
stop_player(0)
lcd_update(lcd)
print_web_status()
# J2 pedir carta
if btn[2].pressed() and not stopped[1]:
add_card(1)
lcd_update(lcd)
if scores[1] > 21:
stop_player(1)
lcd_update(lcd)
print_web_status()
# J2 plantarse
elif btn[3].pressed() and not stopped[1]:
stop_player(1)
lcd_update(lcd)
print_web_status()
# Imprimir estado cada 2 segundos (simula refresco web)
now = time.ticks_ms()
if time.ticks_diff(now, last_serial) >= 2000:
last_serial = now
print_web_status()
# Reiniciar con J1 Parar o J2 Parar cuando termina el juego
if game_over():
if btn[1].pressed() or btn[3].pressed():
reset_game()
lcd_welcome(lcd)
print("Juego reiniciado.")
print_web_status()
time.sleep_ms(20)
main()Loading
pi-pico-w
pi-pico-w