feat: Initial commit
This commit is contained in:
245
Laboratorio 5/Esercizio 2/main.c
Normal file
245
Laboratorio 5/Esercizio 2/main.c
Normal file
@@ -0,0 +1,245 @@
|
||||
// Laboratorio 5 - Esercizio 2
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct tile_s {
|
||||
char c_o, c_v; // colore orizzontale e verticale
|
||||
int p_o, p_v; // punti orizzontali e verticali
|
||||
} tile;
|
||||
|
||||
typedef struct cell_s {
|
||||
int id, rot; // id tile e rotazione
|
||||
} cell;
|
||||
|
||||
void readTiles(tile **tiles, int *N, char *filename) {
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
printf("Errore nell'apertura del file %s",filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fscanf(fp, "%d", N);
|
||||
|
||||
*tiles = (tile *) malloc(*N * sizeof(tile));
|
||||
for (int i = 0; i < *N; i++) {
|
||||
fscanf(fp, " %c %d %c %d", &((*tiles)[i].c_o), &((*tiles)[i].p_o), &((*tiles)[i].c_v), &((*tiles)[i].p_v));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void readBoard(cell ***board, int *R, int *C, char *filename) {
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
printf("Errore nell'apertura del file %s",filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fscanf(fp, "%d %d", R, C);
|
||||
|
||||
*board = (cell **) malloc(*R * sizeof(cell *));
|
||||
for (int i = 0; i < *R; i++) {
|
||||
(*board)[i] = (cell *) malloc(*C * sizeof(cell));
|
||||
for (int j = 0; j < *C; j++) {
|
||||
fscanf(fp, " %d/%d", &(*board)[i][j].id, &(*board)[i][j].rot);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// funzione helper per ottenere il colore di un tile conoscendone la posizione
|
||||
// se `vert` è true restituisce il colore sulla verticale
|
||||
char getTileColor(tile *tiles, cell **board, int x, int y, bool vert) {
|
||||
cell c = board[x][y];
|
||||
|
||||
if (c.rot ^ vert)
|
||||
return tiles[c.id].c_v;
|
||||
|
||||
return tiles[c.id].c_o;
|
||||
}
|
||||
|
||||
// funzione helper per ottenere il punteggio di un tile conoscendone la posizione
|
||||
// se `vert` è true restituisce il punteggio sulla verticale
|
||||
char getTilePoints(tile *tiles, cell **board, int x, int y, bool vert) {
|
||||
cell c = board[x][y];
|
||||
|
||||
if (c.rot ^ vert)
|
||||
return tiles[c.id].p_v;
|
||||
|
||||
return tiles[c.id].p_o;
|
||||
}
|
||||
|
||||
int calcolaPunteggio(int R, int C, tile *tiles, cell **board) {
|
||||
int points = 0;
|
||||
for (int i = 0; i < R; i++) {
|
||||
char color = getTileColor(tiles, board, i, 0, false);
|
||||
int temp_points = getTilePoints(tiles, board, i, 0, false);
|
||||
bool ok = true;
|
||||
|
||||
for (int j = 1; ok && j < C; j++) {
|
||||
if (color != getTileColor(tiles, board, i, j, false))
|
||||
ok = false;
|
||||
temp_points += getTilePoints(tiles, board, i, j, false);
|
||||
}
|
||||
|
||||
// Aggiungo i punti solo se la riga è dello stesso colore
|
||||
if (ok) {
|
||||
points += temp_points;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < C; i++) {
|
||||
char color = getTileColor(tiles, board, 0, i, true);
|
||||
int temp_points = getTilePoints(tiles, board, 0, i, true);
|
||||
bool ok = true;
|
||||
|
||||
for (int j = 1; ok && j < R; j++) {
|
||||
if (color != getTileColor(tiles, board, j, i, true))
|
||||
ok = false;
|
||||
temp_points += getTilePoints(tiles, board, j, i, true);
|
||||
}
|
||||
|
||||
// Aggiungo i punti solo se la colonna è dello stesso colore
|
||||
if (ok) {
|
||||
points += temp_points;
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
void cercaMassimoR(int R, int C, int N, tile *tiles, bool * taken, cell **board, int depth, int * max, cell **sol) {
|
||||
// Terminazione
|
||||
if (depth == R*C) {
|
||||
int punteggio = calcolaPunteggio(R, C, tiles, board);
|
||||
|
||||
if (punteggio > *max) {
|
||||
*max = punteggio;
|
||||
// Copio soluzione
|
||||
for (int i = 0; i < R; i++) {
|
||||
for (int j = 0; j < C; j++) {
|
||||
sol[i][j] = board[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int r = depth / C;
|
||||
int c = depth % C;
|
||||
|
||||
// Provo ad aggiungere un tile solo se nella casella non è già presente un altro tile
|
||||
if (board[r][c].id == -1 && board[r][c].rot == -1) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (!taken[i]) {
|
||||
taken[i] = true;
|
||||
board[r][c].id = i;
|
||||
// Aggiungo in un verso
|
||||
board[r][c].rot = 0;
|
||||
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
|
||||
// Aggiungo nell'altro verso
|
||||
board[r][c].rot = 1;
|
||||
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
|
||||
taken[i] = false;
|
||||
}
|
||||
}
|
||||
// Pulisco la casella, in modo che nella esplorazione successiva
|
||||
// la funzione inserisca un altra tessera
|
||||
board[r][c].id = -1;
|
||||
board[r][c].rot = -1;
|
||||
} else {
|
||||
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
|
||||
}
|
||||
}
|
||||
|
||||
cell ** cercaMassimo(int R, int C, int N, tile *tiles, cell **board) {
|
||||
int max = 0;
|
||||
bool *taken = (bool *) malloc(N * sizeof(bool));
|
||||
|
||||
// Rimuovo dalla lista delle tessere disponibili quelle che sono già presenti sulla board
|
||||
for (int i = 0; i < R; i++) {
|
||||
for (int j = 0; j < C; j++) {
|
||||
if (board[i][j].id != -1)
|
||||
taken[board[i][j].id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
cell **solution = (cell **) malloc(R * sizeof(cell *));
|
||||
for (int i = 0; i < R; i++) {
|
||||
solution[i] = (cell *) malloc(C * sizeof(cell));
|
||||
}
|
||||
|
||||
cercaMassimoR(R,C,N,tiles,taken,board,0,&max,solution);
|
||||
|
||||
free(taken);
|
||||
return solution;
|
||||
}
|
||||
|
||||
void freeSolution(cell **solution, int R) {
|
||||
for (int i = 0; i < R; i++) {
|
||||
free(solution[i]);
|
||||
}
|
||||
free(solution);
|
||||
}
|
||||
|
||||
// Disegna la board
|
||||
void printBoard(int R, int C, cell **board, tile * tiles) {
|
||||
for (int i = 0; i < R; i++) {
|
||||
for (int j = 0; j < C; j++) {
|
||||
tile t = tiles[board[i][j].id];
|
||||
if (board[i][j].rot) {
|
||||
printf(" %c ", t.c_o);
|
||||
} else {
|
||||
printf(" %c ", t.c_v);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
for (int j = 0; j < C; j++) {
|
||||
tile t = tiles[board[i][j].id];
|
||||
if (board[i][j].rot) {
|
||||
printf("%c %d ", t.c_v, t.p_v);
|
||||
} else {
|
||||
printf("%c %d ", t.c_o, t.p_o);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
for (int j = 0; j < C; j++) {
|
||||
tile t = tiles[board[i][j].id];
|
||||
if (board[i][j].rot) {
|
||||
printf(" %d ", t.p_o);
|
||||
} else {
|
||||
printf(" %d ", t.p_v);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
tile *tiles;
|
||||
cell **board;
|
||||
int N, R, C;
|
||||
|
||||
readTiles(&tiles, &N, "tiles.txt");
|
||||
readBoard(&board, &R, &C, "board.txt");
|
||||
|
||||
cell **solution = cercaMassimo(R,C,N,tiles,board);
|
||||
|
||||
printBoard(R, C, solution, tiles);
|
||||
|
||||
freeSolution(solution, R);
|
||||
free(tiles);
|
||||
free(board);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user