Commit iniziale

This commit is contained in:
Rnhmjoj 2013-10-18 23:04:41 +02:00
parent 6bf64eed23
commit b2d6dfeae9
4 changed files with 477 additions and 0 deletions

52
main.c Normal file
View 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
View 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
View 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
View 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