|
|
|
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.
Public link: www.pyxelstudio.net/768v5qdx
File to execute with the public link
PYXEL DOCUMENTATION
|