Update SAE

This commit is contained in:
HORVILLE 2021-12-04 00:08:27 +01:00
parent 5288ff1d8a
commit fb76f7bd0f
5 changed files with 77 additions and 230 deletions

View File

@ -1,5 +1,5 @@
taquin : main.o taquin.o utils.o graph_sup.o
gcc -o taquin.out main.o taquin.o utils.o graph_sup.o -lgraph -lm
gcc -Wall -ansi -o taquin.out main.o taquin.o utils.o graph_sup.o -lgraph -lm
main.o : main.c main.h
gcc -c main.c

View File

@ -5,7 +5,7 @@
#include <string.h>
#include "graph_sup.h"
#define FPS 120.0
#define FPS 15
//La liste des bouttons et leur nombre
button* Buttons;
@ -51,7 +51,7 @@ couleur GetColor(unsigned char r, unsigned char g, unsigned char b) {
}
void SetColor(unsigned char r, unsigned char g, unsigned char b) {
ChoisirCouleurDessin(GetColor(r, g, b));
ChoisirCouleurDessin(CouleurParComposante(r, g, b));
}
void SetColorC(couleur Color) {
@ -59,7 +59,7 @@ void SetColorC(couleur Color) {
}
void SetColorN(char* name) {
ChoisirCouleurDessin(GetColorN(name));
ChoisirCouleurDessin(CouleurParNom(name));
}
//Permet de faire tourner la partie graphique à X images par secondes définit par la constante FPS.

View File

@ -1,6 +1,9 @@
#ifndef _GRAPH_SUP_H
#define _GRAPH_SUP_H
#define WIDTH 1200
#define HEIGHT 700
struct Button {
int x;
int y;

View File

@ -12,7 +12,8 @@
int main(void) {
InitialiserGraphique();
CreerFenetre(100, 100, 1200, 700);
CreerFenetre((Maxx() - WIDTH) / 2, (Maxy() - HEIGHT) / 2, 1200, 700);
ChoisirTitreFenetre("Taquin"); /* Ben alors Denis, on nous cache des fonctions ? */
CreateTaquin("./images/luna.png", 500, 445, 4, 4);
Touche();
FermerGraphique();

View File

@ -6,250 +6,93 @@
#include "taquin.h"
#include "graph_sup.h"
#define OFFSET_X 650
#define OFFSET_Y 70
/* La marge en pixel entre chaque pièce du Taquin */
#define MARGIN 1
//Variables résponsables de la bonne division en cases et de l'apparence du Taquin.
int ** Taquin;
int Rows, Columns;
char TaquinFilename[500];
int OffsetX, OffsetY;
int ImageX, ImageY, PieceX, PieceY;
//Variables résponsable du bon positionement et de la bonne échelle de l'image.
int ImageX, ImageY, SizeX, SizeY;
int Lines, Columns;
unsigned char* Taquin;
char Filename[100];
void DrawPiece(int index, couleur color) {
int CoordX = (index % Columns) * PieceX;
int CoordY = (index / Columns) * PieceY;
int ImCoordX = (Taquin[index] % Columns) * PieceX;
int ImCoordY = (Taquin[index] / Columns) * PieceY;
ChargerImage(Filename, CoordX + OffsetX, CoordY + OffsetY, ImCoordX, ImCoordY, PieceX, PieceY);
SetColorC(color);
DessinerRectangle(CoordX + OffsetX, CoordY + OffsetY, PieceX - 1, PieceY - 1);
}
//Met à jour l'entièreté du Taquin.
void UpdateTaquin() {
for (int Y = 0; Y < Rows; Y++) {
for (int X = 0; X < Columns; X++) {
UpdatePiece(X, Y, Taquin[X][Y], GetColorN("black"));
}
}
int i;
couleur color = GetColor(0, 0, 0);
for (i = 0; i < Lines * Columns; i++) DrawPiece(i, color);
}
//Randomise le Taquin.
void RandomizeTaquin() {
}
/* Vérifie la validité des mouvements et met à jour le taquin graphiquement
si l'argument should_update est égal à 1.*/
int MovePiece(int index, int should_update) {
int moves[4] = {
index + 1,
index - 1,
index + Columns,
index - Columns
};
//Vérifie si le Taquin est en ordre et retourne 1 si oui, 0 si non.
int CheckVictory() {
int X, Y;
for (int i = 0; i < Rows * Columns; i++) {
X = i % Columns;
Y = i / Columns;
int i;
couleur color = GetColor(0, 0, 0);
for (i = 0; i < 4; i++) {
if (moves[i] >= 0 && moves[i] < Columns * Lines) {
if (Taquin[moves[i]] == 0) {
Taquin[moves[i]] = Taquin[index];
Taquin[index] = 0;
if (Taquin[X][Y] != i) return 0;
}
return 1;
}
//Met à jour une pièce spécifique du Taquin.
void UpdatePiece(int X, int Y, int Index, couleur Color) {
int StartX = OFFSET_X + (X * SizeX);
int StartY = OFFSET_Y + (Y * SizeY) + (500 - ImageY) / 2;
int IStartX = SizeX * (Index % Columns);
int IStartY = SizeY * (Index / Columns);
SetColorC(Color);
if (Index != 0) {
DessinerRectangle(StartX, StartY, SizeX-1, SizeY-1);
ChargerImage(TaquinFilename, StartX+1, StartY+1, IStartX, IStartY, SizeX-2, SizeY-2);
} else {
DessinerRectangle(StartX, StartY, SizeX-1, SizeY-1);
SetColorN("white");
RemplirRectangle(StartX + 1, StartY + 1, SizeX - 2, SizeY - 2);
}
}
//Vérifie la validité d'un mouvement de pièce et le fait s'il est valide.
//Renvoie si le mouvement est valide ou non ( 1 ou 0 )
int MovePiece(int X, int Y, int Index, int ShouldUpdate) {
int NewX = 0;
int NewY = 0;
if (X - 1 >= 0 && Taquin[X-1][Y] == 0) {
NewX = -1;
} else if (X + 1 < Columns && Taquin[X+1][Y] == 0) {
NewX = 1;
} else if (Y - 1 >= 0 && Taquin[X][Y-1] == 0) {
NewY = -1;
} else if (Y + 1 < Rows && Taquin[X][Y+1] == 0) {
NewY = 1;
} else return 0;
Taquin[X][Y] = 0;
Taquin[X + NewX][Y + NewY] = Index;
for (int i = 0; i < BT_Count; i++) {
if (Buttons[i].id == Index) Buttons[i].id = 0;
else if (Buttons[i].id == 0) Buttons[i].id = Index;
}
if (ShouldUpdate) {
UpdatePiece(X + NewX, Y + NewY, Index, GetColorN("black"));
UpdatePiece(X, Y, 0, GetColorN("red"));
}
return NewX + 2 * NewY;
}
void TaquinRenderLogicLoop() {
int CurID = -1, LastID = -1, LastX = 0, LastY = 0, Victory = 0;
//Variable indiquant quel périphérique controle actuellement le Taquin
//0 = Souris, 1 = Clavier
int Controller = 0;
//On lance la boucle principale qui servira de boucle graphique et logique.
//Elle met à jour le Taquin lorsqu'une pièce est bougée et déclenche les évenements logiques tels qu'un mouvement de pièce lors d'un clic.
while(!Victory) {
if (DrawNextFrame()) {
if (Controller == 0) {
SourisPosition();
CurID = GetButton(_X, _Y);
}
//Vérifie que la souris clique sur une pièce du Taquin et appelle la fonction de mouvement en fonction.
if (SourisCliquee() && CurID != -1) {
int handled = 0;
Controller = 0;
CurID = GetButton(_X, _Y);
for (int Y = 0; Y < Rows; Y++) {
for (int X = 0; X < Columns; X++) {
if (handled) break;
if (Taquin[X][Y] == CurID) {
int movement = MovePiece(X, Y, CurID, 1);
if (movement % 2 != 0) LastX += SizeX * movement;
else LastY += SizeY * (movement/2);
Victory = CheckVictory();
handled = 1;
break;
}
}
}
}
if (ToucheEnAttente()) {
int key = Touche();
if (CurID == -1) {
CurID = 0;
LastID = -1;
}
int DeltaX = 0, DeltaY = 0;
if (key == XK_Left) {
DeltaX--;
} else if (key == XK_Right) {
DeltaX++;
} else if (key == XK_Up) {
DeltaY--;
} else if (key == XK_Down) {
DeltaY++;
} else if (key == XK_space) {
int handled = 0;
for (int Y = 0; Y < Rows; Y++) {
for (int X = 0; X < Columns; X++) {
if (handled) break;
if (Taquin[X][Y] == CurID) {
int movement = MovePiece(X, Y, CurID, 1);
if (movement % 2 != 0) LastX += SizeX * movement;
else LastY += SizeY * (movement/2);
if (movement != 0) {
LastID = CurID;
CurID = 0;
}
Victory = CheckVictory();
handled = 1;
break;
}
}
}
}
if (DeltaX != 0 || DeltaY != 0) {
Controller = 1;
int handled = 0;
for (int Y = 0; Y < Rows; Y++) {
for (int X = 0; X < Columns; X++) {
if (handled) break;
if (Taquin[X][Y] == CurID) {
LastID = CurID;
CurID = Taquin[clamp(X + DeltaX, 0, Columns-1)][clamp(Y + DeltaY, 0, Rows-1)];
handled = 1;
break;
}
}
}
}
}
//Indicateur lumineux de la case actuellement sélectionnée.
if (CurID != LastID) {
for (int Y = 0; Y < Rows; Y++) {
for (int X = 0; X < Columns; X++) {
if (CurID == Taquin[X][Y]) {
if (CurID != -1) UpdatePiece(X, Y, CurID, GetColorN("red"));
if (LastID!= -1) UpdatePiece(LastX, LastY, LastID, GetColorN("black"));
LastID = CurID;
LastX = X;
LastY = Y;
}
}
if (should_update) {
DrawPiece(moves[i], color);
DrawPiece(index, color);
}
return 1;
}
}
}
return 0;
}
void ShowVictoryScreen() {
/* Crée le Taquin et lance les fonctions liées à la logique et au graphisme du Taquin */
void CreateTaquin(char * filename, int image_width, int image_height, int lines, int columns) {
/* On externalise les valeurs données afin de pouvoir facilement les utiliser plus tard. */
int i;
}
Lines = lines;
Columns = columns;
strcpy(Filename, filename);
//Initialise le Taquin, la fonction appelle la création graphique et logique du Taquin.
void CreateTaquin(char * FileName, int ImX, int ImY, int RowNumber, int ColumnNumber) {
Rows = RowNumber;
Columns = ColumnNumber;
ImageX = ImX;
ImageY = ImY;
SizeX = ImageX / Columns;
SizeY = ImageY / Rows;
ImageX = image_width;
ImageY = image_height;
PieceX = ImageX / Columns;
PieceY = ImageY / Lines;
strcpy(TaquinFilename, FileName);
OffsetX = WIDTH - 50 - ImageX;
OffsetY = (HEIGHT - ImageY) / 2 - 50;
//On alloue dynamiquement la mémoire afin de stocker l'arrangement des pièces du Taquin.
Taquin = calloc(Columns, sizeof(int*));
for (int i = 0; i < Columns; i++) {
Taquin[i] = calloc(Rows, sizeof(int));
}
/* On alloue l'espace mémoire nécéssaire au Taquin et on l'initialise en premier résolu. */
Taquin = calloc(Lines * Columns, sizeof(unsigned char));
for (i = 0; i < Lines * Columns; i++) Taquin[i] = i;
//On définit la position de départ de chaque pièce (au début en ordre, puis on randomise)
for (int i = 0; i < Columns * Rows; i++) {
Taquin[i % Columns][i / Columns] = i;
int StartX = OFFSET_X + SizeX * (i % Columns);
int StartY = OFFSET_Y + SizeY * (i / Columns) + (500 - ImageY) / 2;
AddButton(StartX, StartY, SizeX, SizeY, i);
}
//On affiche la solution à gauche
SetColorN("black");
DessinerRectangle(49, OFFSET_Y + (500 - ImageY) / 2 - 1, ImageX + 1, ImageY + 1);
ChargerImage(FileName, 50, OFFSET_Y + (500 - ImageY) / 2, 0, 0, ImageX, ImageY);
SetColor(0, 0, 0);
RemplirRectangle(48, OffsetY - 2, ImageX + 4, ImageY + 4);
RemplirRectangle(OffsetX - 1, OffsetY - 1, ImageX + 2, ImageY + 1);
ChargerImage(Filename, 50, OffsetY, 0, 0, ImageX, ImageY);
/*RandomizeTaquin()*/
UpdateTaquin();
TaquinRenderLogicLoop(); //Cette fonction est responsable de tout le déroulement de la partie.
ShowVictoryScreen(); //On est après une partie, on affiche l'écran de victoire.
/*TaquinRenderLoop()*/
/*ShowVictoryScreen()*/
}