You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
7.4 KiB
188 lines
7.4 KiB
import pygame
|
|
import random
|
|
import sys
|
|
|
|
pygame.init()
|
|
|
|
# --- Konstanty okna a rozvržení mřížky ---
|
|
SIRKA_OKNA = 600
|
|
VYSKA_OKNA = 600
|
|
FPS = 30
|
|
|
|
RADKY = 4
|
|
SLOUPCE = 4
|
|
KARTICKA_VELIKOST = 100
|
|
MEZERA = 20
|
|
|
|
# Výpočet celkové šířky a výšky mřížky, abychom ji mohli vycentrovat
|
|
Mrizka_sirka = (SLOUPCE * KARTICKA_VELIKOST) + ((SLOUPCE - 1) * MEZERA)
|
|
Mrizka_vyska = (RADKY * KARTICKA_VELIKOST) + ((RADKY - 1) * MEZERA)
|
|
|
|
# Odskoky zleva a shora pro vykreslování
|
|
Odsazeni_x = (SIRKA_OKNA - Mrizka_sirka) // 2
|
|
Odsazeni_y = (VYSKA_OKNA - Mrizka_vyska) // 2
|
|
|
|
# Barvy (R, G, B)
|
|
BILA = (255, 255, 255)
|
|
SEDA = (150, 150, 150)
|
|
TMAVE_MODRA = (20, 20, 80)
|
|
ZELENA_TEXT = (50, 255, 50)
|
|
|
|
# Potřebujeme 8 barev pro 8 párů = 16 karet
|
|
BARVY_PARU = [
|
|
(255, 0, 0), # Červená
|
|
(0, 255, 0), # Světle Zelená
|
|
(0, 0, 255), # Modrá
|
|
(255, 255, 0), # Žlutá
|
|
(255, 0, 255), # Fialová
|
|
(0, 255, 255), # Azurová
|
|
(255, 165, 0), # Oranžová
|
|
(139, 69, 19) # Hnědá
|
|
]
|
|
|
|
okno = pygame.display.set_mode((SIRKA_OKNA, VYSKA_OKNA))
|
|
pygame.display.set_caption("Pexeso (Hledání barevných párů)")
|
|
hodiny = pygame.time.Clock()
|
|
font = pygame.font.SysFont("arial", 40, bold=True)
|
|
font_maly = pygame.font.SysFont("arial", 20)
|
|
|
|
# --- Třída objektu - objektově orientované programování (OOP) ---
|
|
# Použití objektu pro "Kartičku" nám velmi zjednoduší udržování informace
|
|
# o tom, jaká barva na kartičce je, a jestli je otočená nebo zakrytá.
|
|
class Karticka:
|
|
def __init__(self, radek, sloupec, barva_vnitrku):
|
|
self.barva = barva_vnitrku
|
|
|
|
# Stavy kartičky (boolean)
|
|
self.odkryta = False # Zda ji hráč právě otočil
|
|
self.nalezena = False # Zda už hráč našel její pár (tím ji vyřadil)
|
|
|
|
# Výpočet její pevné x,y souřadnice na obrazovce podle toho v jakém je sloupci a řádku
|
|
self.x = Odsazeni_x + sloupec * (KARTICKA_VELIKOST + MEZERA)
|
|
self.y = Odsazeni_y + radek * (KARTICKA_VELIKOST + MEZERA)
|
|
|
|
# Uložíme si Rect pro zjišťování kolize s myší
|
|
self.rect = pygame.Rect(self.x, self.y, KARTICKA_VELIKOST, KARTICKA_VELIKOST)
|
|
|
|
def vykresli(self):
|
|
# Pokud je karta lícem nahoru (odkrytá nebo už nalezena), kreslíme její skrytou barvu
|
|
if self.odkryta or self.nalezena:
|
|
pygame.draw.rect(okno, self.barva, self.rect)
|
|
else:
|
|
# Rub karty - šedivá barva
|
|
pygame.draw.rect(okno, SEDA, self.rect)
|
|
|
|
# Obrys kolem kartičky pro lepší vzhled
|
|
pygame.draw.rect(okno, BILA, self.rect, 3)
|
|
|
|
def hlavni_smycka():
|
|
# 1. Příprava seznamu barev
|
|
# Seznam BARVY_PARU znásobíme 2, abychom od každé barvy měli dvě (pár)
|
|
barvy_do_hry = BARVY_PARU * 2
|
|
random.shuffle(barvy_do_hry) # Náhodně zamícháme pořadí
|
|
|
|
# 2. Vytvoření mřížky kartiček (2D pole)
|
|
# Vznikne struktura 'seznam v seznamu', ke kartě se přistoupí pomocí karticky[radek][sloupec]
|
|
karticky = []
|
|
index_barvy = 0
|
|
for radek in range(RADKY):
|
|
rada = []
|
|
for sloupec in range(SLOUPCE):
|
|
karta = Karticka(radek, sloupec, barvy_do_hry[index_barvy])
|
|
rada.append(karta)
|
|
index_barvy += 1
|
|
karticky.append(rada)
|
|
|
|
# Proměnné pro pamatování si, na které karty hráč zrovna kliknul
|
|
prvni_vybrana = None
|
|
druha_vybrana = None
|
|
|
|
pocet_pokusu = 0
|
|
nalezeno_paru = 0
|
|
|
|
while True:
|
|
# --- Zpracování událostí ---
|
|
for udalost in pygame.event.get():
|
|
if udalost.type == pygame.QUIT:
|
|
pygame.quit()
|
|
sys.exit()
|
|
|
|
# Zjišťování KLIKNUTÍ MYŠÍ
|
|
if udalost.type == pygame.MOUSEBUTTONDOWN and udalost.button == 1: # button 1 = levé tlačítko
|
|
|
|
# Bezpečnostní pojistka - zablokujeme klikání, pokud už máme 2 karty otočené
|
|
# a čekáme např. na jejich skrytí v případě, že se neshodují.
|
|
if prvni_vybrana is not None and druha_vybrana is not None:
|
|
continue
|
|
|
|
# Kde přesně je myš? Získáme X a Y obrazovky
|
|
mys_x, mys_y = pygame.mouse.get_pos()
|
|
|
|
# Projdeme všechny karty a zjistíme, jestli bod myši je v obdélníku karty
|
|
for radek in range(RADKY):
|
|
for sloupec in range(SLOUPCE):
|
|
karta = karticky[radek][sloupec]
|
|
|
|
# collidepoint() vrací True, pokud je x,y uvnitř obdélníku karty
|
|
if karta.rect.collidepoint(mys_x, mys_y):
|
|
# Otočíme kartu, jen když ještě není odkrytá nebo nalezena
|
|
if not karta.odkryta and not karta.nalezena:
|
|
karta.odkryta = True
|
|
|
|
# Je to první vybraná karta v tomto tahu?
|
|
if prvni_vybrana is None:
|
|
prvni_vybrana = karta
|
|
else:
|
|
# Je to druhá vybraná karta! Tah je dokončen.
|
|
druha_vybrana = karta
|
|
pocet_pokusu += 1
|
|
|
|
# --- Vykreslování ---
|
|
okno.fill(TMAVE_MODRA)
|
|
|
|
# Zavoláme metodu vykresli() pro všechny kartičky v tabulce
|
|
for radek in range(RADKY):
|
|
for sloupec in range(SLOUPCE):
|
|
karticky[radek][sloupec].vykresli()
|
|
|
|
# UI s počtem tahů
|
|
text_tahy = font_maly.render(f"Počet pokusů: {pocet_pokusu}", True, BILA)
|
|
okno.blit(text_tahy, (10, 10))
|
|
|
|
# Zpráva o vítězství
|
|
if nalezeno_paru == 8: # Maximum možných párů je polovina počtu karet
|
|
text_konec = font.render("Vítězství! Skvělá paměť.", True, ZELENA_TEXT)
|
|
rect = text_konec.get_rect(center=(SIRKA_OKNA // 2, VYSKA_OKNA - 30))
|
|
okno.blit(text_konec, rect)
|
|
|
|
# Provedeme "vyfocení" na obrazovku ABY BYLA DRUHÁ KARTA VIDĚT PŘED PAUZOU!
|
|
pygame.display.flip()
|
|
|
|
# --- Logika Pexesa (Vyhodnocení po odkrytí druhé karty) ---
|
|
if prvni_vybrana is not None and druha_vybrana is not None:
|
|
if prvni_vybrana.barva == druha_vybrana.barva:
|
|
# Našli jsme PÁR!
|
|
prvni_vybrana.nalezena = True
|
|
druha_vybrana.nalezena = True
|
|
nalezeno_paru += 1
|
|
else:
|
|
# NENAŠLI. Karty se k sobě nehodí.
|
|
# Musíme na 1 vteřinu zastavit program, aby si hráč stihl zapamatovat barvy.
|
|
# Použijeme pygame.time.wait(), které "zmrazí" program (hráč nemůže klikat atd.).
|
|
# Pro takhle jednoduché výukové pexeso je to naprosto v pořádku.
|
|
pygame.time.wait(1000)
|
|
|
|
# Zase je otočíme rubem vzhůru
|
|
prvni_vybrana.odkryta = False
|
|
druha_vybrana.odkryta = False
|
|
|
|
# Vynulujeme výběr pro další tah, ať hráč může volit další karty
|
|
prvni_vybrana = None
|
|
druha_vybrana = None
|
|
|
|
# Rychlost smyčky
|
|
hodiny.tick(FPS)
|
|
|
|
if __name__ == "__main__":
|
|
# Tady pexeso neběží donekonečna, po vítězství program čeká, dokud jej nezavřeme
|
|
hlavni_smycka()
|
|
|