Commit iniziale
This commit is contained in:
parent
6bf64eed23
commit
b2d6dfeae9
52
main.c
Normal file
52
main.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "sudoku.h"
|
||||
|
||||
int main(){
|
||||
int scelta;
|
||||
randomize();
|
||||
do{
|
||||
system("clear");
|
||||
printf("%-66s%-66s%s\n\n", SOTTOLINEATO GIALLO, "Sudoku", RESET BIANCO);
|
||||
printf("%-48s%s%s\n\n", ROSSO, "[1] "BIANCO, "Inserisci e risolvi uno schema");
|
||||
printf("%-48s%s%s\n\n", ROSSO, "[2] "BIANCO, "Genera e gioca uno schema");
|
||||
printf("%-48s%s%s\n\n", ROSSO, "[3] "BIANCO, "Informazioni");
|
||||
printf("%-48s%s%s\n\n", ROSSO, "[4] "BIANCO, "Esci");
|
||||
scanf("\n%d", &scelta);
|
||||
|
||||
switch(scelta){
|
||||
//risolvi
|
||||
case 1:{
|
||||
system("clear");
|
||||
printf("Da fare.\n");
|
||||
pausa();
|
||||
}
|
||||
|
||||
//gioca
|
||||
case 2:{
|
||||
inizializza(50);
|
||||
do{
|
||||
system("clear");
|
||||
stampa();
|
||||
leggi_mossa();
|
||||
cancella_errati();
|
||||
system("clear");
|
||||
stampa();
|
||||
}while(!corretto());
|
||||
|
||||
printf("Hai risolto il sudoku. Complimenti\n");
|
||||
pausa();
|
||||
break;
|
||||
}
|
||||
|
||||
//About
|
||||
case 3:{
|
||||
system(clear);
|
||||
printf("%-66s%-66s%s\n\n", SOTTOLINEATO GIALLO, "Sudoku", RESET BIANCO);
|
||||
printf("%-15s%s\n","", "Programma sviluppato da Michele Guerini Rocco in una stressante settimana di inizio autunno.");
|
||||
pausa();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}while(scelta != 4);
|
||||
}
|
5
makefile
Normal file
5
makefile
Normal file
@ -0,0 +1,5 @@
|
||||
SHELL = /bin/sh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
Tris-in-stile-c : main.c sudoku.c sudoku.h
|
||||
gcc -std=c99 main.c sudoku.c -o "Sudoku"
|
355
sudoku.c
Normal file
355
sudoku.c
Normal file
@ -0,0 +1,355 @@
|
||||
#include "sudoku.h"
|
||||
|
||||
/*
|
||||
* Restituisce un numero casuale nell'intervallo [min, max)
|
||||
*/
|
||||
int randomr(int min, int max){
|
||||
int base = rand();
|
||||
int intervallo = max - min;
|
||||
if (RAND_MAX == base)
|
||||
return randomr(min, max);
|
||||
if (base < RAND_MAX - (RAND_MAX % intervallo))
|
||||
return min + base / (RAND_MAX / intervallo);
|
||||
else
|
||||
return randomr(min, max);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restituisce due numeri casuali diversi
|
||||
*/
|
||||
int *randomd(){
|
||||
int *r = (int *)malloc(2 * sizeof(int));
|
||||
do{
|
||||
r[0] = randomr(1,9);
|
||||
r[1] = randomr(1,9);
|
||||
}while(r[0] == r[1]);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scambia due variabili.
|
||||
* Fallisce se si passa la stessa variabile 2 volte.
|
||||
*/
|
||||
void scambia(int* a, int* b){
|
||||
*a ^= *b;
|
||||
*b ^= *a;
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Blocca l'esecuzione finchè non viene premuto invio
|
||||
*/
|
||||
void pausa(){
|
||||
char c;
|
||||
do
|
||||
getchar();
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancella le evidenziature per i valori errati
|
||||
*/
|
||||
void cancella_errati(){
|
||||
for(int i=0; i<n; i++)
|
||||
for(int k=0; k<n; k++)
|
||||
if(sudoku[i][k][1] == 2)
|
||||
sudoku[i][k][1] = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancella la tabella del sudoku
|
||||
*/
|
||||
void vuota(){
|
||||
for(int i=0; i<n; i++)
|
||||
for(int k=0; k<n; k++){
|
||||
sudoku[i][k][0] = 0;
|
||||
sudoku[i][k][1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Inizializza la tabella del sudoku
|
||||
* generando uno schema
|
||||
*/
|
||||
void inizializza(int spazi){
|
||||
int base[n][n] = {\
|
||||
{6,9,7,1,4,3,8,2,5},\
|
||||
{4,1,8,9,2,5,6,3,7},\
|
||||
{2,5,3,8,7,6,4,9,1},\
|
||||
{7,3,2,4,6,8,5,1,9},\
|
||||
{8,4,9,3,5,1,7,6,2},\
|
||||
{5,6,1,2,9,7,3,8,4},\
|
||||
{3,8,4,7,1,9,2,5,6},\
|
||||
{1,2,6,5,3,4,9,7,8},\
|
||||
{9,7,5,6,8,2,1,4,3}\
|
||||
};
|
||||
int sostituzioni[9];
|
||||
|
||||
/* genera uno schema
|
||||
* facendo delle sostituzione
|
||||
* in uno di partenza.
|
||||
*/
|
||||
|
||||
for(int l=0; l<25; l++){
|
||||
int *r;
|
||||
|
||||
//scambia riga
|
||||
r = randomd();
|
||||
for(int i=0; i<n; i++){
|
||||
for(int k=0; k<n; k++)
|
||||
sostituzioni[k] = base[i][k];
|
||||
for(int s=0; s<9; s++)
|
||||
if (sostituzioni[s] == r[0])
|
||||
sostituzioni[s] = r[1];
|
||||
else if (sostituzioni[s] == r[1])
|
||||
sostituzioni[s] = r[0];
|
||||
for(int p=0; p<9; p++)
|
||||
for(int q=0; q<9; q++)
|
||||
base[i][q] = sostituzioni[q];
|
||||
}
|
||||
|
||||
//scambia colonna
|
||||
r = randomd();
|
||||
for(int i=0; i<n; i++){
|
||||
for(int k=0; k<n; k++)
|
||||
sostituzioni[k] = base[i][k];
|
||||
for(int s=0; s<9; s++)
|
||||
if (sostituzioni[s] == r[0])
|
||||
sostituzioni[s] = r[1];
|
||||
else if (sostituzioni[s] == r[1])
|
||||
sostituzioni[s] = r[0];
|
||||
for(int p=0; p<9; p++)
|
||||
for(int q=0; q<9; q++)
|
||||
base[q][i] = sostituzioni[q];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(int l=0; l<25; l++){
|
||||
int r = randomr(0,3);
|
||||
switch(r){
|
||||
|
||||
//colonna centrale fissa
|
||||
case 0:{
|
||||
for(int i=0; i<9; i++){
|
||||
for(int k=0; k<9; k++)
|
||||
sostituzioni[k] = base[i][k];
|
||||
for(int j=0; j<9; j++)
|
||||
if(j != 4)
|
||||
base[i][j] = sostituzioni[8-j] ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//riga centrale fissa
|
||||
case 1:{
|
||||
for(int k=0; k<9; k++){
|
||||
for(int i=0; i<9; i++)
|
||||
sostituzioni[i] = base[i][k];
|
||||
for(int j=0; j<9; j++)
|
||||
if(j!=4)
|
||||
base[j][k] = sostituzioni[8-j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//inversione riga 3-5
|
||||
case 2:{
|
||||
for(int i=0; i<9; i++)
|
||||
scambia(&base[3][i], &base[5][i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//inserisci gli spazi
|
||||
for(int i=0; i<spazi; i++){
|
||||
int unico = 0; //la casella è valida
|
||||
do{
|
||||
int x = randomr(0,9);
|
||||
int y = randomr(0,9);
|
||||
if(!base[x][x])
|
||||
unico = 1;
|
||||
else {
|
||||
base[x][y] = 0;
|
||||
unico = 0;
|
||||
}
|
||||
}while(unico == 1);
|
||||
}
|
||||
|
||||
//copia lo schema generato nella matrice
|
||||
for(int i=0; i<n; i++)
|
||||
for(int k=0; k<n; k++){
|
||||
sudoku[i][k][0] = base[i][k];
|
||||
if(!base[i][k])
|
||||
sudoku[i][k][1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Restituisce 0 se nella riga non sono presenti duplicati
|
||||
* altrimenti restituisce 1.
|
||||
*/
|
||||
int controlla_riga(int m){
|
||||
float media = 0;
|
||||
for(int i=0; i<n; i++)
|
||||
media += sudoku[m][i][0];
|
||||
if(media/9 != 5)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restituisce 0 se nella colonna non sono presenti duplicati
|
||||
* altrimenti restituisce 1.
|
||||
*/
|
||||
int controlla_colonna(int m){
|
||||
float media = 0;
|
||||
for(int i=0; i<n; i++)
|
||||
media += sudoku[i][m][0];
|
||||
if(media/9 != 5)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restituisce 0 se nel quadrante non sono presenti duplicati
|
||||
* altrimenti restituisce 1.
|
||||
*/
|
||||
int controlla_quadrante(int m){
|
||||
float media = 0;
|
||||
int **quadrante = ottieni_quadrante(m);
|
||||
for(int i=0; i<n; i++)
|
||||
media += quadrante[i][0];
|
||||
if(media/9 != 5)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restituisce un array di puntatori a intero del quadrante m.
|
||||
*/
|
||||
int **ottieni_quadrante(int m){
|
||||
int **quadrante = (int **)malloc(sizeof(int *) * n);
|
||||
int quadranti[][2] = {{0,0}, {0,3}, {0,6}, {3,0}, {3,3}, {3,6},{6,0}, {6,3}, {6,6}};
|
||||
int t = quadranti[m][0], s = quadranti[m][1], j = 0;
|
||||
for(int i=t; i<(t+3); i++)
|
||||
for(int k=s; k<(s+3); k++){
|
||||
quadrante[j] = sudoku[i][k];
|
||||
j++;
|
||||
}
|
||||
return quadrante;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evidenzia le casella errate.
|
||||
* m: numero della riga/colonna/quadrante.
|
||||
* tipo: 0 - riga,
|
||||
* 1 - colonna,
|
||||
* 2 - quadrante,
|
||||
*/
|
||||
void evidenzia(int m, int tipo){
|
||||
switch(tipo){
|
||||
//riga
|
||||
case 0:{
|
||||
for(int i=0; i<n; i++)
|
||||
if(sudoku[m][i][1])
|
||||
sudoku[m][i][1] = 2;
|
||||
break;
|
||||
}
|
||||
//colonna
|
||||
case 1:{
|
||||
for(int i=0; i<n; i++)
|
||||
if(sudoku[i][m][1])
|
||||
sudoku[i][m][1] = 2;
|
||||
break;
|
||||
}
|
||||
//quadrante
|
||||
case 2:{
|
||||
int **quadrante = ottieni_quadrante(m);
|
||||
for(int i=0; i<n; i++)
|
||||
if(quadrante[i][1])
|
||||
quadrante[i][1] = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Controlla la presenza di errori e li evidenzia.
|
||||
* Restituisce 0 se il sudoku non è corretto altrimenti 1.
|
||||
*/
|
||||
int corretto(){
|
||||
int errori = 0;
|
||||
for(int i=0; i<n; i++)
|
||||
if(controlla_riga(i)){
|
||||
evidenzia(i, 0);
|
||||
errori = 1;
|
||||
}
|
||||
for(int i=0; i<n; i++)
|
||||
if(controlla_colonna(i)){
|
||||
evidenzia(i, 1);
|
||||
errori = 1;
|
||||
}
|
||||
for(int i=0; i<n; i++)
|
||||
if(controlla_riga(i)){
|
||||
evidenzia(i, 2);
|
||||
errori = 1;
|
||||
}
|
||||
return !errori;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stampa la tabella del sudoku
|
||||
*/
|
||||
void stampa(){
|
||||
printf("\n\n\n");
|
||||
for(int i=0; i<n; i++){
|
||||
printf("%-25s", RESET);
|
||||
for(int k=0; k<n; k++){
|
||||
if(!sudoku[i][k][0])
|
||||
printf("%-12s ", RESET);
|
||||
else {
|
||||
switch(sudoku[i][k][1]){
|
||||
//Schema non modificabile
|
||||
case 0:{
|
||||
printf("%-12s%d ", BIANCO, sudoku[i][k][0]);
|
||||
break;
|
||||
}
|
||||
//Inseriti dal giocatore
|
||||
case 1:{
|
||||
printf("%-12s%d ", VERDE, sudoku[i][k][0]);
|
||||
break;
|
||||
}
|
||||
//Errati
|
||||
case 2:{
|
||||
printf("%-12s%d ", ROSSO, sudoku[i][k][0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n\n\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Legge la mossa del giocatore
|
||||
*/
|
||||
void leggi_mossa(){
|
||||
int x, y, m;
|
||||
printf("%s%s%s", VERDE, "(x,y,m): ", BIANCO);
|
||||
scanf("%d,%d,%d", &x, &y, &m);
|
||||
if(!sudoku[x][y][1])
|
||||
printf("%-50sNon puoi cambiare il numero in (%d,%d)",ROSSO, x, y);
|
||||
else if(!(0 < m < 10))
|
||||
printf("%-45sSolo numeri tra 1 e 9 estremi inclusi.", ROSSO);
|
||||
else if(!(0 < x < 10) || !(0 < y < 10))
|
||||
printf("%.45sLe cordinate sono tra 1 e 9 estremi inclusi.", ROSSO);
|
||||
else{
|
||||
sudoku[x][y][0] = m;
|
||||
return;
|
||||
}
|
||||
pausa();
|
||||
}
|
65
sudoku.h
Normal file
65
sudoku.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef _SUDOKU_H_
|
||||
|
||||
#define _SUDOKU_H_
|
||||
|
||||
/*Librerie Principali*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/*Colori ANSI*/
|
||||
#define NERO "\033[22;30m"
|
||||
#define BLU "\033[34m"
|
||||
#define GIALLO "\033[33m"
|
||||
#define BIANCO "\033[37m"
|
||||
#define ROSSO "\033[31m"
|
||||
#define VERDE "\033[32m"
|
||||
#define RESET "\033[0m"
|
||||
#define GRASSETTO "\033[1m"
|
||||
#define SOTTOLINEATO "\033[4m"
|
||||
|
||||
/*Definizioni*/
|
||||
#define randomize() srand((unsigned)time(NULL))
|
||||
#define n 9
|
||||
|
||||
/*Funzione specifiche degli os*/
|
||||
#ifdef __WIN32__
|
||||
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#define os 0
|
||||
#define clear "cls"
|
||||
#define sleep(x) Sleep(x)
|
||||
|
||||
#else
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#define os 1
|
||||
#define clear "clear"
|
||||
#define sleep(x) usleep(x*1000)
|
||||
|
||||
#endif
|
||||
|
||||
/*Prototipi*/
|
||||
|
||||
int *randomd(void);
|
||||
int randomr(int min, int max);
|
||||
void scambia(int* a, int* b);
|
||||
void stampa(void);
|
||||
void vuota(void);
|
||||
void cancella_errati(void);
|
||||
void evidenzia(int m, int tipo);
|
||||
void inizializza(int spazi);
|
||||
int controlla_colonna(int m);
|
||||
int controlla_riga(int m);
|
||||
int controlla_quadrante(int m);
|
||||
int **ottieni_quadrante(int m);
|
||||
void leggi_mossa(void);
|
||||
int corretto(void);
|
||||
void pausa(void);
|
||||
|
||||
/*Variabili globali*/
|
||||
int sudoku[n][n][2];
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user