/*****************************************************************/
/*                                                               */
/*   CASIO fx-9860G SDK Library                                  */
/*                                                               */
/*   File name : sudoku.c                                 */
/*                                                               */
/*   Copyright (c) 2006 CASIO COMPUTER CO., LTD.                 */
/*                                                               */
/*****************************************************************/

//Nicolas D'AVENIA 2010

#include "fxlib.h"
#include <stdio.h>
int tabaff[9][9];
unsigned char isLocked[9][9];

	int checkLignes() {
		//pour chaques lignes
		int ligne, i, j;
		for( ligne = 0; ligne<9; ligne++ ){
			for( i =0; i<9 ; i++){
				for( j = 0; j<9; j++ ){
					if(i!=j){
						if(tabaff[ligne][i]!=0){
							if(tabaff[ligne][i]==tabaff[ligne][j])return 1;
						}
					}
				}	
			}
		}
		return 0;
	}
	int checkColonnes() {
		//pour chaques colonnes
		int colonne, i, j;
		for( colonne = 0; colonne<9; colonne++ ){
			for( i =0; i<9 ; i++){
				for( j = 0; j<9; j++ ){
					if(i!=j){
						if(tabaff[i][colonne]!=0){
							if(tabaff[i][colonne]==tabaff[j][colonne])return 1;
						}
					}
				}	
			}
		}
		return 0;
	}
	
	 int checkCases() {
		int indexI, indexJ, i, j, ib, jb;
		for( indexI=0; indexI<9 ; indexI+=3){
			//0 3 6
			for( indexJ=0; indexJ<9 ; indexJ+=3){
				//0 3 6
				for( i=0 ; i<3; i++){
					for( j=0 ; j<3; j++){
						for( ib=0 ; ib<3; ib++){
							for( jb=0 ; jb<3; jb++){
								if(i!=ib || j!=jb){
									if(tabaff[indexI+i][indexJ+j]!=0){
										if(tabaff[indexI+i][indexJ+j]==tabaff[indexI+ib][indexJ+jb])return 1;
									}
								}
								
							}	
						}		
						
					}	
				}
			}
		}
		return 0;
	}
	int isFull() {
		int i, j;
		for(i =0; i<9 ; i++){
			for(j = 0; j<9; j++ ){
				if(tabaff[i][j]==0)return 0;
			}
		}		
		return 1;
	}

locked(){
	int i, j;
	for(i =0; i<9 ; i++){
		for(j = 0; j<9; j++ ){
			isLocked[i][j]=(tabaff[i][j]!=0);
		}
	}	
}

	int solve(int pos){
		int fin=0;
		while(isLocked[pos/9][pos%9])pos++;
		while(tabaff[pos/9][pos%9]<9 && !fin){
			tabaff[pos/9][pos%9]++;
			//dans l'ideal, il ne faut vérifier que la ligne, la colonne et le groupe qui correpond ŕ la position...
			if(!checkLignes() && !checkColonnes() && !checkCases()){
				//pas d'erreurs
				
				if(isFull())return 1;
				if(solve(pos+1)==1){
					fin=1;
				}
			}
		}
		if(!fin)tabaff[pos/9][pos%9]=0;
		return fin;
	}


afficher(){
	int a, b;
	char tabcraff[2];
	for(a=1;a<63;a+=7){
		for(b=3;b<=65;b+=7){
			PrintMini(b,a," ",0);
			if(tabaff[(6+a)/7-1][(4+b)/7-1]!=0){
				sprintf(tabcraff,"%d",tabaff[(6+a)/7-1][(4+b)/7-1]);
				PrintMini(b,a,tabcraff,0);
			}
		}
	}
}

resoudre(){
	locked();
	solve(0);
	afficher();

}

vider()
{
	int a, b;
	for(a=0;a<9;a++){
		for(b=0;b<9;b++){
			tabaff[a][b]=0;
		}
	}
	afficher();
}

controle()
{
	int tm;
	int j=0;
	int c=1;
	int d=3;
	int t=0;
	char tabcraff[2];
	unsigned int key;

	Bdisp_AllClr_DDVRAM();
	afficher();
	PrintMini(70,2,"BETA 2 By",0);
	PrintMini(70,10,"Nicolas D'AVENIA",0);

	Bdisp_DrawLineVRAM(63,1,63,63);
	Bdisp_DrawLineVRAM(21,2,21,63);
	Bdisp_DrawLineVRAM(42,2,42,63);
	Bdisp_DrawLineVRAM(1,21,61,21);
	Bdisp_DrawLineVRAM(1,42,61,42);
	Bdisp_DrawLineVRAM(1,63,62,63);

	PrintMini(70,29,"F4: VIDER",0);
	PrintMini(70,38,"F5: VERIFIER",0);
	PrintMini(70,47,"F6: RESOUDRE",0);

	for(tm=65;tm<120;tm+=21){
		Bdisp_DrawLineVRAM(tm,63,tm+16,63);
		Bdisp_DrawLineVRAM(tm,56,tm+19,56);
		Bdisp_DrawLineVRAM(tm,57,tm,62);
		Bdisp_DrawLineVRAM(tm+19,57,tm+19,59);
	}
	
	while(1){
		PrintMini(d,c,"x",0);
		GetKey(&key);
		if(key==KEY_CTRL_RIGHT){
			PrintMini(d,c," ",0);
			if(tabaff[(6+c)/7-1][(4+d)/7-1] ){
				sprintf(tabcraff,"%d",tabaff[(6+c)/7-1][(4+d)/7-1]);
				PrintMini(d,c,tabcraff,0);
			}

			if(d+7<=59)d+=7;
			else{
				d=3;
				c+=7;
				if(c>57)c=1;
			}

		}
		if(key==KEY_CTRL_LEFT){
			PrintMini(d,c," ",0);
			if(tabaff[(6+c)/7-1][(4+d)/7-1]){
				sprintf(tabcraff,"%d",tabaff[(6+c)/7-1][(4+d)/7-1]);
				PrintMini(d,c,tabcraff,0);
			}
			if(d-7>=3)d-=7;
			else{
				d=59;
				c-=7;
				if(c<0)c=57;
			}

		}
		if(key==KEY_CTRL_DOWN){
			PrintMini(d,c," ",0);
			if(tabaff[(6+c)/7-1][(4+d)/7-1]){
				sprintf(tabcraff,"%d",tabaff[(6+c)/7-1][(4+d)/7-1]);
				PrintMini(d,c,tabcraff,0);
			}
			if(c<57)c+=7;
		}
		if(key==KEY_CTRL_UP){
			PrintMini(d,c," ",0);
			if(tabaff[(6+c)/7-1][(4+d)/7-1]){
				sprintf(tabcraff,"%d",tabaff[(6+c)/7-1][(4+d)/7-1]);
				PrintMini(d,c,tabcraff,0);
			}
			if(c>1)c-=7;

		}
		if(key==KEY_CTRL_DEL || key==KEY_CHAR_0)tabaff[(6+c)/7-1][(4+d)/7-1]=0;
		if(key==KEY_CHAR_1)tabaff[(6+c)/7-1][(4+d)/7-1]=1;
		if(key==KEY_CHAR_2)tabaff[(6+c)/7-1][(4+d)/7-1]=2;
		if(key==KEY_CHAR_3)tabaff[(6+c)/7-1][(4+d)/7-1]=3;
		if(key==KEY_CHAR_4)tabaff[(6+c)/7-1][(4+d)/7-1]=4;
		if(key==KEY_CHAR_5)tabaff[(6+c)/7-1][(4+d)/7-1]=5;
		if(key==KEY_CHAR_6)tabaff[(6+c)/7-1][(4+d)/7-1]=6;
		if(key==KEY_CHAR_7)tabaff[(6+c)/7-1][(4+d)/7-1]=7;
		if(key==KEY_CHAR_8)tabaff[(6+c)/7-1][(4+d)/7-1]=8;
		if(key==KEY_CHAR_9)tabaff[(6+c)/7-1][(4+d)/7-1]=9;
		if(key==KEY_CTRL_F4)vider();
		if(key==KEY_CTRL_F5){
			//tester
		}
		if(key==KEY_CTRL_F6){
			//tester
			resoudre();
			afficher();
		}
	}

}

//****************************************************************************
//  AddIn_main (Sample program main function)
//
//  param   :   isAppli   : 1 = This application is launched by MAIN MENU.
//                        : 0 = This application is launched by a strip in eACT application.
//
//              OptionNum : Strip number (0~3)
//                         (This parameter is only used when isAppli parameter is 0.)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************
int AddIn_main(int isAppli, unsigned short OptionNum)
{
    unsigned int key;

    Bdisp_AllClr_DDVRAM();
    vider();
    controle();
    locate(1,4);
    Print((unsigned char*)"This application is");
    locate(1,5);
    Print((unsigned char*)" sample Add-In.");

    while(1){
        GetKey(&key);
    }

    return 1;
}




//****************************************************************************
//**************                                              ****************
//**************                 Notice!                      ****************
//**************                                              ****************
//**************  Please do not change the following source.  ****************
//**************                                              ****************
//****************************************************************************


#pragma section _BR_Size
unsigned long BR_Size;
#pragma section


#pragma section _TOP

//****************************************************************************
//  InitializeSystem
//
//  param   :   isAppli   : 1 = Application / 0 = eActivity
//              OptionNum : Option Number (only eActivity)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************
int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}

#pragma section

