Update SAE
This commit is contained in:
parent
5288ff1d8a
commit
fb76f7bd0f
@ -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
|
||||
|
@ -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.
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef _GRAPH_SUP_H
|
||||
#define _GRAPH_SUP_H
|
||||
|
||||
#define WIDTH 1200
|
||||
#define HEIGHT 700
|
||||
|
||||
struct Button {
|
||||
int x;
|
||||
int y;
|
||||
|
@ -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();
|
||||
|
@ -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()*/
|
||||
}
|
Loading…
Reference in New Issue
Block a user