PYXEL STUDIO www.pyxelstudio.net/studio/3bdtmk
  • app.py
  • res.pyxres
app.py
import pyxel from pyxel import KEY_SPACE, KEY_LEFT, KEY_RIGHT # taille de la fenetre 168x168 pixels # ne pas modifier pyxel.init(168, 168, title="Puissance 4") #168 car divisible par 7 = 24 # Variables initiales grille_x = 0 grille_y = 20 # trou_x = 16 # trou_y = 25 tableau_width = 168 tableau_hight = 150 # Configuración de la cuadrícula Colone = 7 Ligne = 6 # Rayon trou Trou_R = 8 # Distance entre trou Dist_X = tableau_width // Colone #168//7 = 24 Dist_Y = tableau_hight // Ligne #150//6 = 25 Marge_haut = 4 #pyxel.load("[Puissance4].pyxres") SI NECESSAIRE LE FICHIER EXISTE # j1 = jaune et j2 = rouge menu = True #faut pas nonplus tout expliquer non? counter = 0 #Compte a rebour pour le menu... Affichage win_play = "personne" #Le joueur qui gagne la partie vict_p1 = 0 #NB de Victoires vict_p2 = 0 #NB de Victoires tour = 0 # pour savoir qui joue son tour pos_jetons_j = [[],[],[]] # positions jetons jaunes (j1) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive pos_jetons_r = [[],[],[]] # pos jetons rouges (joueur 2) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive positions_simplifees = [ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0] ] # Simplification par 0 1 ou 2 pour indiquer type de jeton, 0 = vide, 1 = eq 1 et 2 = eq 2 bottom = 0 #Definit si ou pas un jeton peut descendre et la profondeur maximale GAME_OVER = False #Rien a expliquer Tour_Jouable = False #Definit si un tour est jouable, depend de bottom tour_change = True #Definit si le tour d'un joueur est actif place_mode = True #mode placement def find_bottom(pos_jetons_j, pos_jetons_r): """ Pour connaitre y max , fond du tab variable car il peut y avoir un jeton en dessous :param pos_jetons_j: positions jetons jaunes (j1) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive :param pos_jetons_r: pos jetons rouges (joueur 2) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive :return: BOTTOM, y max """ bottom = 7 + 6*25 for jeton_mouvement in pos_jetons_j[1] + pos_jetons_r[1]: for jeton in pos_jetons_j[2] + pos_jetons_r[2]: if jeton[0] == jeton_mouvement[0]: # check colomne bottom = min(bottom, jeton[1] - 25) if len(pos_jetons_r[0]) or len(pos_jetons_j[0]) > 0: for jeton in pos_jetons_j[2] + pos_jetons_r[2]: for jeton_mouvement in pos_jetons_j[0] + pos_jetons_r[0]: if jeton[0] == jeton_mouvement[0]: # check colomne if jeton[1] == 7 + 25: bottom = 0 return bottom def tour_r(pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode): """ Prend touts les parametres de listes de jeton pour executer la phase du joueur r ou j selon le nom de la fonction, definit si l'on a besoin de generer un jeton pour le jouer puis offre la fonctionalite de le placer avec les flechettes avant d'appuyer sur espace pour le decaler a la liste indexe 1 de la liste de la couleur du joueur, une fois dans la liste 1 le tour du joueur finit :param pos_jetons_j: :param pos_jetons_r: :param tour: :param tour_change: :param bottom: :param place_mode: :return: """ if tour % 2 == 0 and place_mode == True: # POUR SAVOIR QUI JOUE if tour_change == True: pos_jetons_j[0].append([84, 7]) tour_change = False if pyxel.btnr(KEY_SPACE) and find_bottom(pos_jetons_j,pos_jetons_r) > 8+25: pos_jetons_j[1].append(pos_jetons_j[0][0]) pos_jetons_j[0].pop(0) place_mode = False tour += 1 return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode if pyxel.btnr(KEY_LEFT) and pos_jetons_j[0][0][0] > 23: #bouger la piece une fois vers left si les conditions mode actif et pas trop left sont vraies pos_jetons_j[0][0][0] -= 24 if pyxel.btnr(KEY_RIGHT) and pos_jetons_j[0][0][0] < 168 - 24: #bouger la piece une fois vers right si les conditions mode actif et pas trop right sont vraies pos_jetons_j[0][0][0] += 24 return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode def tour_j(pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode): """ Prend touts les parametres de listes de jeton pour executer la phase du joueur r ou j selon le nom de la fonction, definit si l'on a besoin de generer un jeton pour le jouer puis offre la fonctionalite de le placer avec les flechettes avant d'appuyer sur espace pour le decaler a la liste indexe 1 de la liste de la couleur du joueur, une fois dans la liste 1 le tour du joueur finit :param pos_jetons_j: :param pos_jetons_r: :param tour: :param tour_change: :param bottom: :param place_mode: :return: """ if tour % 2 == 1 and place_mode == True: # POUR SAVOIR QUI JOUE if tour_change == True: pos_jetons_r[0].append([84, 7]) tour_change = False if pyxel.btnr(KEY_SPACE) and find_bottom(pos_jetons_j,pos_jetons_r) > 25: pos_jetons_r[1].append(pos_jetons_r[0][0]) pos_jetons_r[0].pop(0) place_mode = False tour += 1 return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode if pyxel.btnr(KEY_LEFT) and pos_jetons_r[0][0][0] > 23: #bouger la piece une fois vers left si les conditions mode actif et pas trop left sont vraies pos_jetons_r[0][0][0] -= 24 if pyxel.btnr(KEY_RIGHT) and pos_jetons_r[0][0][0] < 168 - 24: #bouger la piece une fois vers right si les conditions mode actif et pas trop right sont vraies pos_jetons_r[0][0][0] += 24 return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode return pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode def tombee_r(pos_jetons_r,bottom,tour_change,place_mode, pos_jetons_j): """ Prend la liste de pions et si il y a des jetons dans l'indexe 1 il commence la tombee jsq le max de profondeur y, definit par find_bottom() :param pos_jetons_r: :param bottom: :param tour_change: :param place_mode: :param pos_jetons_j: :return: """ bottom = 0 if len(pos_jetons_r[1]) > 0: for jeton in pos_jetons_r[1]: if jeton[1] < find_bottom(pos_jetons_j,pos_jetons_r): jeton[1] += 25 #TOMBE break if jeton[1] == find_bottom(pos_jetons_j,pos_jetons_r): #FIN CHUTE pos_jetons_r[2].append(pos_jetons_r[1][0]) pos_jetons_r[1].pop(0) tour_change = place_mode = True return pos_jetons_r, bottom,tour_change,place_mode, pos_jetons_j def tombee_j(pos_jetons_j,bottom,tour_change,place_mode, pos_jetons_r): """ Prend la liste de pions et si il y a des jetons dans l'indexe 1 il commence la tombee jsq le max de profondeur y, definit par find_bottom() :param pos_jetons_r: :param bottom: :param tour_change: :param place_mode: :param pos_jetons_j: :return: """ bottom = 0 if len(pos_jetons_j[1]) > 0: for jeton in pos_jetons_j[1]: if jeton[1] < find_bottom(pos_jetons_j,pos_jetons_r): jeton[1] += 25 #TOMBE break if jeton[1] == find_bottom(pos_jetons_j,pos_jetons_r): #FIN CHUTE pos_jetons_j[2].append(pos_jetons_j[1][0]) pos_jetons_j[1].pop(0) tour_change = place_mode = True return pos_jetons_j, bottom,tour_change,place_mode, pos_jetons_r def simplificateur(pos_jetons_j,pos_jetons_r,positions_simplifees): """Simplifie les calculs de puissance 4 par simplifiant le tableau que l'ordinateur va calculer 1 pour jaune 2 pour rouge et 0 pour vide""" ligne = 0 colonne = 0 for jeton in pos_jetons_j[2]: if jeton: ligne = (jeton[1] - 32) // 25 #32 etant la separation entre la zone selection position et la zone des jetons, 25 etant l'espace entre case jouable y colonne = (jeton[0] - 12) // 24 #32 etant la separation entre le bord de l'ecran et la zone des jetons, 24 etant l'espace entre case jouable x positions_simplifees[ligne][colonne] = 1 #Remplace 0 par 1 for jeton in pos_jetons_r[2]: if jeton: ligne = (jeton[1] - 32) // 25 #32 etant la separation entre la zone selection position et la zone des jetons, 25 etant l'espace entre case jouable y colonne = (jeton[0] - 12) // 24 #32 etant la separation entre le bord de l'ecran et la zone des jetons, 24 etant l'espace entre case jouable x positions_simplifees[ligne][colonne] = 2 #Remplace 0 par 2 # if pyxel.frame_count % 30 == 0: # print(positions_simplifees," ", ligne, " ",colonne) # lignes pour debeuguer les positions, visualisation des pos simplifiees 1 fois par sec return positions_simplifees def detection_victoire(): """ Va verifier si il y a un gagnant et va nommer le gagnant Si le jeton annalise est jaune il va verifier si les jetons jaunes sont allignes Si le jeton annalise est Rouge il va verifier si les jetons Rouges sont allignes :return: Le gagnant de la partie sous forme de STR """ global positions_simplifees winner = "personne" for i in range(6): for j in range(7): if not 0 in positions_simplifees[i]: winner = "0" if positions_simplifees[i][j] == 1: if test_pos(i,j,1): winner = "Joueur Jaune" if positions_simplifees[i][j] == 2: if test_pos(i,j,2): winner = "Joueur Rouge" return winner def test_pos(i,j,valeur): """ La fonction va verifier TOUT pion qui lui est envoye pour voir si ce pion a 4 voisins allignes, il va verifier seuelemnt une fois axe x, une fois axe y et aussi les 4 diagonales possibles avec 1+d / i-d et j+d / j-d :param i: position sur y :param j: pos sur x :param valeur: couleur du jeton vise :return: True ou False selon nb de jetons allignes, True if jetons allignes = 4 Le compteur doit TOUJOURS commencer a = 1 """ global positions_simplifees compteur_jetons = 1 # vaut 1 car le test demarre considerant deja la position de 1 jeton valeur for d in range(1,4): # 1 a 4-1 car on sait deja que i+0 = i et j+0 = j if j+d < 7: if positions_simplifees[i][j+d] == valeur: compteur_jetons += 1 if compteur_jetons != 4: compteur_jetons = 1 for d in range(1, 4): if i+d < 6: if positions_simplifees[i+d][j] == valeur: compteur_jetons += 1 if compteur_jetons == 4: return True else: compteur_jetons = 1 for d in range(1, 4): # 1 a 4-1 car on sait deja que i+0 = i et j+0 = j if j + d < 7 and i + d < 6: if positions_simplifees[i + d][j + d] == valeur: compteur_jetons += 1 if compteur_jetons != 4: compteur_jetons = 1 for d in range(1, 4): if j - d >= 0 and i - d >= 0: if positions_simplifees[i - d][j - d] == valeur: compteur_jetons += 1 if compteur_jetons != 4: compteur_jetons = 1 for d in range(1, 4): if i + d < 6 and j - d >= 0: if positions_simplifees[i + d][j - d] == valeur: compteur_jetons += 1 if compteur_jetons != 4: compteur_jetons = 1 for d in range(1, 4): if i - d >= 0 and j + d < 7: if positions_simplifees[i - d][j + d] == valeur: compteur_jetons += 1 if compteur_jetons == 4: return True else: return False # ========================================================= # == UPDATE =============================================== # ========================================================= def update(): """ mise à jour des variables (30 fois par seconde) :return: TOUT (presque, sous forme de Global) """ global menu, counter, vict_p1, vict_p2, win_play, pos_jetons_r, pos_jetons_j, tour, bottom, GAME_OVER , tour_change, place_mode, positions_simplifees if tour % 2 == 0 and menu == False and counter == 0: pos_jetons_j , pos_jetons_r , tour , tour_change, bottom, place_mode = tour_r(pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode) if tour % 2 == 1 and menu == False and counter == 0: pos_jetons_j , pos_jetons_r , tour , tour_change, bottom, place_mode = tour_j(pos_jetons_j, pos_jetons_r, tour, tour_change, bottom, place_mode) pos_jetons_r, bottom, tour_change, place_mode, pos_jetons_j= tombee_r(pos_jetons_r,bottom,tour_change,place_mode, pos_jetons_j) pos_jetons_j, bottom, tour_change, place_mode, pos_jetons_r = tombee_j(pos_jetons_j,bottom,tour_change,place_mode, pos_jetons_r) positions_simplifees = simplificateur(pos_jetons_j,pos_jetons_r,positions_simplifees) win_play = detection_victoire() if win_play != "personne": GAME_OVER = True if win_play == "0": win_play = "EGALITE" if win_play == "Joueur Jaune" and counter == 0 and menu == False: vict_p1 = vict_p1 + 1 if win_play == "Joueur Rouge" and counter == 0 and menu == False: vict_p2 = vict_p2 + 1 # SI il n'y avait pas la variable counter et menu, le score augmenterait infiniment # print(positions_simplifees) # OUTIL DEBUG # ========================================================= # == DRAW ================================================= # ========================================================= def draw(): """création des objets (30 fois par seconde)""" global menu, counter, vict_p1, vict_p2, win_play, pos_jetons_r, pos_jetons_j, tour, bottom, GAME_OVER , tour_change , positions_simplifees # vide la fenetre pyxel.cls(0) if menu == True: pyxel.text(24,24,"menu",5) pyxel.text(24, 34, "Victoires J1: "+str(vict_p1), 5) pyxel.text(24, 44, "Victoires J2: " + str(vict_p2), 5) if pyxel.btnr(KEY_SPACE): #FIN DU MENU, INIT DU JEU, RESET DES VARIABLES CLEES menu = False GAME_OVER = False win_play = "personne" pos_jetons_j = [[], [], []] # positions jetons jaunes (j1) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive pos_jetons_r = [[], [], []] # pos jetons rouges (joueur 2) i = 0 pour le placement i = 1 pour quand le jeton tombe (animation) et i = 2 pour la pos definitive positions_simplifees = [ [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0] ] # Simplification par 0 1 ou 2 pour indiquer type de jeton, 0 = vide, 1 = eq 1 et 2 = eq 2 if menu == False and counter == 30: menu = True counter = 0 if counter < 30 and menu == False and GAME_OVER == True: counter += 1 pyxel.text(5, 74, str(win_play) + " gagne la partie", 7) if menu == False and counter == 0: pyxel.rect(grille_x, grille_y, tableau_width, tableau_hight, 1) for i in range(Ligne): for j in range(Colone): x = grille_x + Dist_X * j + Dist_X // 2 # y = grille_y + Dist_Y * i + Dist_Y //3 Marche pas y = grille_y + Marge_haut + Trou_R + i * Dist_Y pyxel.circ(x, y, Trou_R, 0) for piece in pos_jetons_j[2]: pyxel.circ(piece[0],piece[1],8,10) for piece in pos_jetons_j[1]: pyxel.circb(piece[0],piece[1],8,10) for piece in pos_jetons_j[0]: pyxel.circb(piece[0],piece[1],8,10) for piece in pos_jetons_r[2]: pyxel.circ(piece[0],piece[1],8,4) for piece in pos_jetons_r[1]: pyxel.circb(piece[0],piece[1],8,4) for piece in pos_jetons_r[0]: pyxel.circb(piece[0],piece[1],8,4) pyxel.run(update, draw)
Create an account to manage your projects and publish them on the playground.
Layout
Packages
If your project uses packages, list them bellow (names separated by commas). Packages that can be added are only packages built in Pyodide.
Example: numpy,pandas
Project Name
Documentation
LICENSE
Choose a license:


Public link
Share this link so people can discover your project / game.
File to execute with the public link
PYXEL DOCUMENTATION
Official documentation:
click on to run the code