////////////////////////////////////////////////////////////////////////////////
//
//	COMMENTAIRES
  //
  //	Nom					sudoku.sce
  //	Auteur				Jérôme LABATUT 
  //	Date de création		2019-12-28
  //
  //	Version Scilab			6.0.1
  //	Module Atoms requis		Aucun
  //
  //	Objectif				Résolution de grilles de Sudoku
  //	
	funcprot(0)
	clearglobal()
	clear()
	
	xdel(winsid())
	tohome()
	clc()
	
	global JEU
  //
//
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
//
//	FONCTIONS MODELE
  //
  //	Initialisation des paramètres
  //
  //	Sélection d'une grille dans la base des grilles incomplètes
  //
  //	Filtrage direct (trivial)
  //	Filtrage indirect (méthode dite de Découpage)
  //	Actualisation d'une grille selon les filtres
  //	Evaluation des critères d'arrêt
  //
  //	Recherche d'une cellule libre
  //	Validation des contraintes à partir d'une cellule 
  //	Algorithme de résolution par filtrages
  // Résolution récursive d'une grille
//
////////////////////////////////////////////////////////////////////////////////

function affecterParametresModele()
	global JEU
	
	// Paramètres du jeu
		JEU.Ordre =				3
		JEU.Taille =				JEU.Ordre*JEU.Ordre
		
		JEU.ZerosL =				zeros(1, JEU.Taille)
		JEU.ZerosC =				zeros(JEU.Taille, 1)
		JEU.ZerosB =				zeros(JEU.Ordre, JEU.Ordre)
		JEU.ZerosH =				zeros(1, 1, JEU.Taille)
		
		JEU.Uns =					ones(JEU.Taille, JEU.Taille)
end

function parametre = donnerNiveau(matricule, nomParametre)
	select matricule
		// NIVEAU FACILE
		   case '2005-07-10_1' then
			nomNiveau =			'FACILE     2005-07-10 Le Figaro'
			Grille =				[0, 6, 1, 0, 3, 0, 0, 2, 0;	...
								 0, 5, 0, 0, 0, 8, 1, 0, 7;	...
								 0, 0, 0, 0, 0, 7, 0, 3, 4;	...
								 0, 0, 9, 0, 0, 6, 0, 7, 8;	...
								 0, 0, 3, 2, 0, 9, 5, 0, 0;	...
								 5, 7, 0, 3, 0, 0, 9, 0, 0;	...
								 1, 9, 0, 7, 0, 0, 0, 0, 0;	...
								 8, 0, 2, 4, 0, 0, 0, 6, 0;	...
								 0, 4, 0, 0, 1, 0, 2, 5, 0	]
		   case '2005-07-27_1' then
			nomNiveau =			'FACILE     2005-07-27 Le Figaro'
			Grille =				[4, 8, 0, 0, 1, 0, 0, 2, 9;	...
								 0, 0, 1, 2, 0, 9, 5, 0, 0;	...
								 6, 0, 0, 0, 0, 0, 0, 0, 3;	...
								 0, 7, 0, 0, 5, 0, 0, 3, 0;	...
								 0, 0, 9, 3, 0, 4, 7, 0, 0;	...
								 0, 1, 0, 0, 2, 0, 0, 9, 0;	...
								 2, 0, 0, 0, 0, 0, 0, 0, 1;	...
								 0, 0, 3, 8, 0, 6, 9, 0, 0;	...
								 9, 5, 0, 0, 3, 0, 0, 6, 7	]
		   case '2005-08-06_1' then
			nomNiveau =			'FACILE     2005-08-06 Le Figaro'
			Grille =				[0, 0, 4, 3, 0, 0, 2, 8, 0;	...
								 9, 2, 0, 0, 8, 6, 0, 5, 0;	...
								 6, 0, 0, 0, 0, 0, 0, 0, 1;	...
								 0, 4, 0, 0, 0, 0, 0, 0, 9;	...
								 0, 1, 0, 0, 2, 0, 0, 7, 0;	...
								 3, 0, 0, 0, 0, 0, 0, 4, 0;	...
								 8, 0, 0, 0, 0, 0, 0, 0, 2;	...
								 0, 6, 0, 2, 5, 0, 0, 1, 3;	...
								 0, 9, 5, 0, 0, 3, 7, 0, 0	]
		   case '2005-08-10_1' then
			nomNiveau =			'FACILE     2005-08-10 Le Figaro'
			Grille =				[4, 0, 0, 7, 0, 1, 0, 0, 6;	...
								 7, 2, 0, 0, 0, 0, 0, 8, 9;	...
								 0, 0, 6, 0, 0, 0, 5, 0, 0;	...
								 0, 9, 0, 1, 0, 5, 0, 6, 0;	...
								 0, 0, 0, 9, 3, 8, 0, 0, 0;	...
								 0, 7, 0, 6, 0, 4, 0, 5, 0;	...
								 0, 0, 7, 0, 0, 0, 6, 0, 0;	...
								 1, 3, 0, 0, 0, 0, 0, 4, 8;	...
								 6, 0, 0, 2, 0, 3, 0, 0, 5	]
		   case '2005-08-29_1' then
			nomNiveau =			'FACILE     2005-08-29 El Païs'
			Grille =				[6, 0, 0, 0, 0, 0, 0, 0, 8;	...
								 0, 3, 0, 0, 9, 0, 0, 7, 0;	...
								 0, 4, 7, 1, 0, 5, 6, 9, 0;	...
								 0, 0, 8, 6, 0, 7, 1, 0, 0;	...
								 0, 6, 0, 0, 0, 0, 0, 2, 0;	...
								 0, 0, 2, 4, 0, 9, 8, 0, 0;	...
								 0, 2, 9, 3, 0, 1, 7, 8, 0;	...
								 0, 7, 0, 0, 6, 0, 0, 1, 0;	...
								 1, 0, 0, 0, 0, 0, 0, 0, 9	]	
		
		// NIVEAU MOYEN
		   case '2005-07-10_2' then
			nomNiveau =			'MOYEN      2005-07-10 Le Figaro'
			Grille =				[0, 0, 7, 0, 0, 0, 9, 0, 0;	...
								 2, 0, 0, 5, 0, 7, 0, 0, 6;	...
								 0, 8, 0, 1, 0, 4, 0, 7, 0;	...
								 0, 4, 0, 0, 1, 0, 0, 3, 0;	...
								 6, 0, 1, 0, 0, 0, 8, 0, 9;	...
								 0, 9, 0, 0, 8, 0, 0, 6, 0;	...
								 0, 5, 0, 8, 0, 9, 0, 1, 0;	...
								 1, 0, 0, 6, 0, 3, 0, 0, 2;	...
								 0, 0, 6, 0, 0, 0, 3, 0, 0	]
		   case '2005-07-27_2' then
			nomNiveau =			'MOYEN      2005-07-27 Le Figaro'
			Grille =				[0, 4, 6, 0, 9, 0, 5, 1, 0;	...
								 0, 0, 2, 3, 0, 1, 9, 0, 0;	...
								 0, 0, 0, 6, 0, 5, 0, 0, 0;	...
								 6, 7, 0, 0, 0, 0, 0, 5, 4;	...
								 0, 8, 0, 0, 0, 0, 0, 6, 0;	...
								 5, 2, 0, 0, 0, 0, 0, 9, 8;	...
								 0, 0, 0, 7, 0, 4, 0, 0, 0;	...
								 0, 0, 5, 2, 0, 9, 8, 0, 0;	...
								 0, 6, 1, 0, 8, 0, 7, 2, 0	]
		   case '2005-08-06_2' then
			nomNiveau =			'MOYEN      2005-08-06 Le Figaro'
			Grille =				[0, 0, 0, 0, 0, 0, 0, 1, 0;	...
								 0, 0, 0, 0, 9, 7, 6, 0, 4;	...
								 0, 7, 3, 4, 0, 0, 5, 0, 0;	...
								 2, 0, 0, 0, 3, 0, 0, 4, 0;	...
								 0, 0, 4, 9, 1, 6, 2, 0, 0;	...
								 0, 5, 0, 0, 8, 0, 0, 0, 3;	...
								 0, 0, 9, 0, 0, 2, 8, 5, 0;	...
								 4, 0, 2, 5, 6, 0, 0, 0, 0;	...
								 0, 3, 0, 0, 0, 0, 0, 0, 0	]
		   case '2005-08-10_2' then
			nomNiveau =			'MOYEN      2005-08-10 Le Figaro'
			Grille =				[0, 0, 0, 0, 0, 0, 3, 0, 0;	...
								 0, 8, 0, 0, 0, 3, 0, 0, 9;	...
								 0, 2, 4, 0, 7, 0, 0, 8, 6;	...
								 9, 0, 0, 0, 0, 5, 4, 0, 8;	...
								 0, 0, 0, 4, 0, 2, 0, 0, 0;	...
								 1, 0, 6, 9, 0, 0, 0, 0, 5;	...
								 5, 6, 0, 0, 3, 0, 1, 4, 0;	...
								 4, 0, 0, 5, 0, 0, 0, 9, 0;	...
								 0, 0, 7, 0, 0, 0, 0, 0, 0	]
		
		// NIVEAU DIFFICILE
		   case '2005-07-10_3' then	// '100 Su Doku No 1' p. 31 ( First éditions )
			nomNiveau =			'DIFFICILE  2005-07-10 Le Figaro'
			Grille =				[0, 0, 0, 1, 0, 0, 2, 6, 0;	...
								 7, 0, 0, 0, 3, 0, 0, 0, 0;	...
								 3, 0, 2, 0, 8, 0, 4, 0, 0;	...
								 0, 0, 0, 4, 0, 8, 0, 0, 1;	...
								 0, 3, 5, 0, 0, 0, 9, 4, 0;	...
								 2, 0, 0, 3, 0, 5, 0, 0, 0;	...
								 0, 0, 6, 0, 5, 0, 7, 0, 9;	...
								 0, 0, 0, 0, 4, 0, 0, 0, 8;	...
								 0, 5, 7, 0, 0, 9, 0, 0, 0	]
		   case '2005-07-27_3' then	// '100 Su Doku No 1' p. 38 ( First éditions )
			nomNiveau =			'DIFFICILE  2005-07-27 Le Figaro'
			Grille =				[0, 3, 0, 0, 0, 8, 0, 0, 5;	...
								 0, 0, 5, 0, 0, 0, 8, 0, 7;	...
								 0, 0, 0, 0, 4, 0, 9, 0, 0;	...
								 0, 0, 0, 3, 9, 0, 4, 0, 0;	...
								 0, 5, 9, 0, 7, 0, 2, 1, 0;	...
								 0, 0, 2, 0, 6, 5, 0, 0, 0;	...
								 0, 0, 7, 0, 5, 0, 0, 0, 0;	...
								 5, 0, 1, 0, 0, 0, 7, 0, 0;	...
								 6, 0, 0, 9, 0, 0, 0, 2, 0	]
		   case '2005-08-06_3' then	// '100 Su Doku No 1' p. 47 ( First éditions )
			nomNiveau =			'DIFFICILE  2005-08-06 Le Figaro'
			Grille =				[6, 0, 0, 0, 9, 0, 1, 8, 0;	...
								 0, 3, 0, 0, 0, 6, 7, 0, 0;	...
								 7, 0, 0, 0, 0, 0, 0, 2, 0;	...
								 5, 0, 0, 0, 2, 4, 0, 0, 0;	...
								 0, 0, 0, 6, 0, 3, 0, 0, 0;	...
								 0, 0, 0, 9, 8, 0, 0, 0, 7;	...
								 0, 2, 0, 0, 0, 0, 0, 0, 8;	...
								 0, 0, 9, 1, 0, 0, 0, 7, 0;	...
								 0, 8, 7, 0, 5, 0, 0, 0, 9	]
		   case '2005-08-10_3' then
			nomNiveau =			'DIFFICILE  2005-08-10 Le Figaro'
			Grille =				[0, 9, 0, 5, 6, 8, 0, 2, 0;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 5, 6, 0, 0, 0, 7, 9, 0;	...
								 3, 0, 0, 4, 0, 9, 0, 0, 7;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 4, 0, 0, 2, 0, 1, 0, 0, 8;	...
								 0, 7, 4, 0, 0, 0, 5, 1, 0;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 2, 0, 1, 3, 4, 0, 7, 0	]
		   case '15-280_3' then
			nomNiveau =			'DIFFICILE  Le Monde 15-280'
			Grille =				[0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 0, 0, 0, 0, 0, 0, 7, 5;	...
								 0, 0, 0, 0, 0, 0, 6, 1, 9;	...
								 0, 0, 0, 0, 0, 3, 0, 0, 0;	...
								 0, 0, 5, 0, 6, 0, 0, 0, 4;	...
								 0, 8, 0, 0, 0, 9, 7, 6, 3;	...
								 0, 2, 1, 0, 9, 8, 0, 4, 0;	...
								 0, 5, 4, 0, 3, 0, 0, 9, 0;	...
								 0, 9, 8, 0, 4, 6, 0, 3, 2	]
		   case '32_3' then			// '100 Su Doku No 1' p. 32 ( First éditions )
			nomNiveau =			'DIFFICILE  100 Su Doku No 1 p. 32'
			Grille =				[0, 0, 8, 0, 9, 0, 0, 0, 0;	...
								 0, 7, 0, 0, 0, 0, 2, 8, 0;	...
								 0, 6, 4, 1, 0, 0, 3, 0, 9;	...
								 0, 0, 0, 8, 0, 5, 9, 0, 0;	...
								 5, 0, 0, 0, 0, 0, 0, 0, 1;	...
								 0, 0, 9, 3, 0, 4, 0, 0, 0;	...
								 8, 0, 2, 0, 0, 7, 5, 6, 0;	...
								 0, 9, 7, 0, 0, 0, 0, 1, 0;	...
								 0, 0, 0, 0, 6, 0, 7, 0, 0	]
		   case '33_3' then			// '100 Su Doku No 1' p. 33 ( First éditions )
			nomNiveau =			'DIFFICILE  100 Su Doku No 1 p. 33'
			Grille =				[0, 0, 0, 7, 0, 2, 0, 0, 0;	...
								 1, 0, 0, 0, 4, 0, 0, 0, 7;	...
								 6, 5, 0, 0, 0, 0, 0, 9, 4;	...
								 4, 7, 0, 8, 0, 1, 0, 6, 2;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 5, 8, 0, 2, 0, 9, 0, 1, 3;	...
								 8, 6, 0, 0, 0, 0, 0, 7, 5;	...
								 9, 0, 0, 0, 6, 0, 0, 0, 8;	...
								 0, 0, 0, 9, 0, 8, 0, 0, 0	]
		   case '34_3' then			// '100 Su Doku No 1' p. 34 ( First éditions )
			nomNiveau =			'DIFFICILE  100 Su Doku No 1 p. 34'
			Grille =				[0, 0, 7, 2, 3, 8, 0, 0, 0;	...
								 0, 6, 0, 7, 0, 0, 0, 5, 0;	...
								 0, 0, 0, 4, 0, 0, 0, 0, 2;	...
								 9, 0, 0, 0, 0, 0, 8, 6, 7;	...
								 1, 0, 0, 0, 0, 0, 0, 0, 3;	...
								 6, 4, 8, 0, 0, 0, 0, 0, 5;	...
								 7, 0, 0, 0, 0, 3, 0, 0, 0;	...
								 0, 2, 0, 0, 0, 5, 0, 3, 0;	...
								 0, 0, 0, 1, 7, 4, 9, 0, 0	]
		   case '35_3' then			// '100 Su Doku No 1' p. 35 ( First éditions )
			nomNiveau =			'DIFFICILE  100 Su Doku No 1 p. 35'
			Grille =				[5, 0, 7, 0, 0, 0, 0, 0, 9;	...
								 0, 8, 0, 0, 0, 2, 1, 7, 0;	...
								 0, 1, 0, 0, 6, 0, 0, 0, 4;	...
								 0, 9, 0, 0, 3, 0, 0, 0, 0;	...
								 0, 0, 1, 7, 0, 9, 3, 0, 0;	...
								 0, 0, 0, 0, 4, 0, 0, 6, 0;	...
								 8, 0, 0, 0, 5, 0, 0, 2, 0;	...
								 0, 7, 6, 2, 0, 0, 0, 9, 0;	...
								 4, 0, 0, 0, 0, 0, 6, 0, 8	]
		
		// NIVEAU DIABOLIQUE
			case '2005-08-06_4' then
				nomNiveau = 		'DIABOLIQUE 2005-08-06 Le Figaro'
				Grille =			[0, 8, 0, 7, 9, 0, 0, 0, 0;	...
								 0, 0, 0, 0, 0, 2, 0, 9, 0;	...
								 0, 0, 3, 0, 0, 8, 4, 5, 0;	...
								 0, 0, 8, 0, 0, 0, 0, 0, 1;	...
								 0, 9, 6, 0, 0, 0, 3, 7, 0;	...
								 3, 0, 0, 0, 0, 0, 2, 0, 0;	...
								 0, 3, 2, 5, 0, 0, 9, 0, 0;	...
								 0, 4, 0, 8, 0, 0, 0, 0, 0;	...
								 0, 0, 0, 0, 6, 4, 0, 2, 0	]
			case '2005-08-10_4' then // '100 Su Doku No 1' p. 86 ( First éditions )
				nomNiveau = 		'DIABOLIQUE 2005-08-10 Le Figaro'
				Grille =			[0, 9, 0, 5, 6, 8, 0, 2, 0;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 5, 6, 0, 0, 0, 7, 9, 0;	...
								 3, 0, 0, 4, 0, 9, 0, 0, 7;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 4, 0, 0, 2, 0, 1, 0, 0, 8;	...
								 0, 7, 4, 0, 0, 0, 5, 1, 0;	...
								 0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 2, 0, 1, 3, 4, 0, 7, 0	]
			case '2005-08-13_4' then
				nomNiveau = 		'DIABOLIQUE 2005-08-13 Le Figaro'
				Grille =			[0, 0, 0, 4, 0, 0, 0, 0, 2;	...
								 0, 0, 4, 0, 1, 2, 0, 0, 9;	...
								 0, 7, 0, 0, 0, 8, 0, 0, 0;	...
								 0, 2, 0, 0, 9, 0, 1, 7, 0;	...
								 0, 0, 0, 0, 8, 0, 0, 0, 0;	...
								 0, 6, 1, 0, 5, 0, 0, 4, 0;	...
								 0, 0, 0, 9, 0, 0, 0, 5, 0;	...
								 6, 0, 0, 1, 2, 0, 3, 0, 0;	...
								 1, 0, 0, 0, 0, 3, 0, 0, 0	]
			case '2006-07-08_4' then
				nomNiveau = 		'DIABOLIQUE 2006-07-08 Le Figaro'
				Grille =			[0, 0, 0, 0, 1, 0, 5, 0, 0;	...
								 2, 6, 0, 0, 3, 0, 0, 0, 0;	...
								 0, 0, 7, 0, 0, 0, 0, 0, 4;	...
								 0, 8, 3, 0, 0, 0, 7, 0, 0;	...
								 0, 0, 0, 0, 5, 0, 0, 2, 0;	...
								 0, 0, 9, 0, 0, 0, 0, 0, 6;	...
								 0, 0, 0, 0, 0, 6, 0, 9, 0;	...
								 0, 0, 0, 0, 0, 2, 0, 8, 0;	...
								 3, 0, 0, 0, 7, 0, 1, 0, 0	]
		
		// NIVEAU INFERNAL
		   case '2006-07-08_5' then
				nomNiveau = 		'INFERNALE  2006-07-08 Le Figaro'
				Grille =			[0, 0, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 0, 0, 6, 5, 0, 0, 0, 7;	...
								 9, 1, 0, 0, 0, 0, 3, 0, 0;	...
								 2, 0, 0, 0, 4, 0, 8, 0, 5;	...
								 0, 0, 7, 3, 0, 0, 0, 2, 0;	...
								 6, 0, 0, 0, 0, 8, 0, 0, 9;	...
								 0, 2, 0, 0, 0, 0, 0, 0, 0;	...
								 0, 0, 0, 7, 0, 0, 4, 0, 2;	...
								 5, 0, 0, 0, 0, 1, 9, 0, 0	]
		
		// PAS DE NIVEAU CONNU
		   case '2016-08-18' then
			nomNiveau =			'Bouteille d''eau minérale 18 Août 2016'
			Grille =				[0, 6, 0, 9, 0, 0, 0, 0, 0;	...
								 0, 0, 7, 5, 0, 0, 0, 9, 1;	...
								 0, 0, 0, 0, 0, 4, 0, 0, 7;	...
								 0, 0, 3, 0, 0, 5, 0, 0, 2;	...
								 0, 2, 9, 0, 0, 0, 1, 4, 0;	...
								 1, 0, 0, 8, 0, 0, 3, 0, 0;	...
								 4, 0, 0, 1, 0, 0, 0, 0, 0;	...
								 2, 9, 0, 0, 0, 8, 6, 0, 0;	...
								 0, 0, 0, 0, 0, 6, 0, 1, 0	]
		   case '2018-04-25' then
			nomNiveau =			'Spirou 4176 ( 25 avril 2018 )'
			Grille =				[4, 0, 0, 0, 0, 6;	...
								 0, 0, 5, 0, 4, 0;	...
								 0, 3, 0, 6, 0, 0;	...
								 0, 0, 2, 0, 3, 0;	...
								 0, 2, 0, 3, 0, 0;	...
								 3, 0, 0, 0, 0, 1	]
		   case '2018-09-05' then
			nomNiveau =	 		'Spirou 4195 ( 5 Septembre 2018 )'
			Grille =				[0, 0, 6, 5, 8, 0, 0, 0, 0;	...
								 7, 0, 1, 4, 0, 0, 0, 0, 0;	...
								 0, 9, 0, 0, 1, 0, 0, 4, 6;	...
								 9, 3, 0, 0, 0, 0, 7, 0, 0;	...
								 0, 0, 7, 0, 0, 0, 8, 0, 0;	...
								 0, 0, 2, 0, 0, 0, 0, 5, 4;	...
								 5, 6, 0, 0, 2, 0, 0, 1, 0;	...
								 0, 0, 0, 0, 0, 4, 5, 0, 2;	...
								 0, 0, 0, 0, 5, 3, 6, 0, 0	]
		   case '2019-06-26' then
			nomNiveau =			'Spirou 4237 (26 Juin 2019)'
			Grille =				[0, 6, 0, 1, 0, 4, 0, 5, 0;	...
								 0, 0, 8, 3, 0, 5, 6, 0, 0;	...
								 2, 0, 0, 0, 0, 0, 0, 0, 1;	...
								 8, 0, 0, 4, 0, 7, 0, 0, 6;	...
								 0, 0, 6, 0, 0, 0, 3, 0, 0;	...
								 7, 0, 0, 9, 0, 1, 0, 0, 4;	...
								 5, 0, 0, 0, 0, 0, 0, 0, 2;	...
								 0, 0, 7, 2, 0, 6, 9, 0, 0;	...
								 6, 4, 0, 5, 0, 8, 0, 7, 0	]
	end
	
	select nomParametre
		case 'Nom'				then parametre = nomNiveau
		case 'Valeur'				then parametre = Grille
		case 'Solutions'			then parametre = nombreSolutions
	end
end

function Filtres = filtrerDirectement(Grille)
	global JEU
	
	Filtres =					ones(JEU.Taille, JEU.Taille, JEU.Taille)
	
	// FILTRAGE DIRECT PAR LIGNES
	for l = 1:JEU.Taille
		for c = 1:JEU.Taille
			for v = 1:JEU.Taille
				if (Grille(l, c) == v)
					Filtres(l, :, v) = JEU.ZerosL
					Filtres(l, c, v) = 1
				end
			end
		end
	end
	
	// FILTRAGE DIRECT PAR COLONNES
	for l = 1:JEU.Taille
		for c = 1:JEU.Taille
			for v = 1:JEU.Taille
				if (Grille(l, c) == v)
					Filtres(:, c, v) = JEU.ZerosC
					Filtres(l, c, v) = 1
				end
			end
		end
	end
	
	// FILTRAGE DIRECT PAR BLOCS
	for l = 1:JEU.Taille
		for c = 1:JEU.Taille
			lBloc = fix((l + 2)/3)
			cBloc = fix((c + 2)/3)
			lCase = [(3*lBloc - 2):(3*lBloc)]
			cCase = [(3*cBloc - 2):(3*cBloc)]
			for v = 1:JEU.Taille
				if (Grille(l, c) == v)
					Filtres(lCase, cCase, v) = JEU.ZerosB
					Filtres(l, c, v) = 1
				end
			end
		end
	end
end
function FiltresS = filtrerIndirectement(Filtres)
	global JEU
	
	FiltresS =					Filtres
	
	// FILTRAGE INDIRECT PAR LIGNES
	for l = 1:JEU.Taille,
		for c = 1:JEU.Taille,
			for v = 1:JEU.Taille,
				if (Filtres(l, c, v) == 1) & (sum(Filtres(l, :, v), 2) == 1)
					FiltresS(l, c, :) = JEU.ZerosH
					FiltresS(l, c, v) = 1
				end
			end
		end
	end
	
	// FILTRAGE INDIRECT PAR COLONNES
	for l = 1:JEU.Taille,
		for c = 1:JEU.Taille,
			for v = 1:JEU.Taille,
				if (Filtres(l, c, v) == 1) & (sum(Filtres(:, c, v), 1) == 1)
					FiltresS(l, c, :) = JEU.ZerosH
					FiltresS(l, c, v) = 1
				end
			end
		end
	end
	
	// FILTRAGE INDIRECT PAR BLOCS
	for l = 1:JEU.Taille,
		for c = 1:JEU.Taille,
			lBloc = fix((l + 2)/3)
			cBloc = fix((c + 2)/3)
			lCase = [(3*lBloc - 2):(3*lBloc)]
			cCase = [(3*cBloc - 2):(3*cBloc)]
			for v = 1:JEU.Taille
				if (Filtres(l, c, v) == 1) & (sum(Filtres(lCase, cCase, v)) == 1)
					FiltresS(l, c, :) = JEU.ZerosH
					FiltresS(l, c, v) = 1
				end
			end
		end
	end
end
function GrilleS = actualiserGrille(GrilleE, Filtres)
	global JEU
	
	GrilleS =						GrilleE
	
	for l = 1:JEU.Taille
	for c = 1:JEU.Taille
		if (sum(Filtres(l, c, :), 3) == 1) & (GrilleE(l, c) == 0)
			for v = 1:JEU.Taille
				if (Filtres(l, c, v) == 1)
					GrilleS(l, c) = v
				end
			end
		end
	end
	end
end
function Etat = evaluerCriteres(Grille1, Grille0)
	global JEU
	
	Etat =						'Jouable'
	
	Filtres =						filtrerDirectement(Grille1)
	
	// Critère de cohérence : une des cases n'a plus de possibilité restante
	//Incoherence =				or(sum(Filtres, 3))
	Incoherence =					%F
	
	// Critère de complétion : toutes les cases sont remplies
	Completion =					and(Grille1)
	
	// Critère de blocage : la grille, toujours incomplète, ne peut être améliorée
	Blocage =						(~Completion) & isequal(Grille1, Grille0)
	
	// Critère de succès : la grille est complète et il ne reste qu'une possibilité par case
	Succes =						(Completion) & isequal(sum(Filtres, 3),JEU.Uns)
	
	if (Incoherence)
		Etat =					'Incohérence'
	end
	if (Blocage)
		Etat =					'Blocage'
	end
	if (Succes)
		Etat =					'Succès'
	end		
end

function [lListe, cListe, vListe] = trouverValeurs(Filtres)
	lListe =					[]
	cListe =					[]
	vListe =					[]
	
	for l = 1:JEU.Taille
		for c = 1:JEU.Taille
			for v = 1:JEU.Taille
				if (Filtre(l, c, v) == 1)
					lListe =	[lListe, l]
					cListe =	[cListe, c]
					vListe =	[vListe, v]
				end
			end
		end
	end
end

function CellulesLibres = trouverCellulesLibres(grille)
	global JEU
	
	[l_Vide, c_Vide] =				find(grille == 0)
	
	if isempty(l_Vide) & isempty(c_Vide)
		CellulesLibres =			[0, 0]
	else
		CellulesLibres =			[l_Vide', c_Vide']
	end
end
function Validation = validerContraintes(grille, cellule)
	global JEU
	
	l_Courant =					cellule(1, 1)
	c_Courant =					cellule(1, 2)
	valeur =						grille(l_Courant, c_Courant)
	
	Validation = 					%T
	
	RedondanceColonnes =			sum(sum(grille == valeur, 1) > 1) > 0
	
	RedondanceLignes =				sum(sum(grille == valeur, 2) > 1) > 0
	
	RedondanceBlocs =				sum((sum(sum(grille(1:3, 1:3) == valeur)) > 1)	...
								  + (sum(sum(grille(1:3, 4:6) == valeur)) > 1)	...
								  + (sum(sum(grille(1:3, 7:9) == valeur)) > 1)	...
								  + (sum(sum(grille(4:6, 1:3) == valeur)) > 1)	...
								  + (sum(sum(grille(4:6, 4:6) == valeur)) > 1)	...
								  + (sum(sum(grille(4:6, 7:9) == valeur)) > 1)	...
								  + (sum(sum(grille(7:9, 1:3) == valeur)) > 1)	...
								  + (sum(sum(grille(7:9, 4:6) == valeur)) > 1)	...
								  + (sum(sum(grille(7:9, 7:9) == valeur)) > 1)	) > 0
	
	if RedondanceColonnes | RedondanceLignes | RedondanceBlocs
		Validation =				%F
	end
end
function GrilleS = filtrer(GrilleE)
	global JEU
	
	Continuer =					%T
	
	while (Continuer)
		Filtres1 =				filtrerDirectement(GrilleE)
		Grille1 =					actualiserGrille(GrilleE, Filtres1)
		
		Filtres2 =				filtrerIndirectement(Filtres1)
		Grille2 =					actualiserGrille(Grille1, Filtres2)
		
		//mettreAJourConsole
		mettreAJourDamier(Grille2)
		
		if isequal(Grille2, GrilleE)
			GrilleS =				GrilleE
			Continuer =			%F
		else
			GrilleE =				Grille2
		end
	end
end
function resoudreRecursivement(grille)	// Résolution par récursivité 
	global JEU
	
	GrilleComplete =				(sum(sum(grille == 0)) == 0)
	if GrilleComplete
		JEU.GrilleSolution =		grille
		
		JEU.GrilleResolue =			%T
	else							// Sinon l'exploration des possiblités se poursuit
		JEU.Evaluations =			JEU.Evaluations + 1
		
		grille =					filtrer(grille)
		
		GrilleComplete =			(sum(sum(grille == 0)) == 0)
		if GrilleComplete
			JEU.GrilleSolution =	grille
			
			JEU.GrilleResolue =		%T
		else						// Sinon l'exploration des possiblités se poursuit
			cellulesLibres =		trouverCellulesLibres(grille)
			l =					cellulesLibres(1, 1)
			c =					cellulesLibres(1, 2)
			
			for valeur = 1:JEU.Taille
				grille(l, c) =		valeur
				
				if validerContraintes(grille, [l, c])
					mettreAJourConsole(JEU.ETAT.RECHERCHE, grille)
					mettreAJourDamier(grille)
					
					resoudreRecursivement(grille)
				end
			end
			
			JEU.GrilleResolue =		%F
		end
	end
end

////////////////////////////////////////////////////////////////////////////////
//
//	FONCTIONS VUES
  //
  //	Initialisation des paramètres
  //
  //	Interface utilisateur
  //
  //	Console simplifiée
  //	Affichage d'une grille dans la console
  //	Affichage de deux grilles dans la console
  //	Affichage de trois grilles dans la console
//
////////////////////////////////////////////////////////////////////////////////

function affecterParametresVues()
	global JEU
	
	// Interface
		JEU.INTERFACE.Etiquette =	'Interface'
		JEU.INTERFACE.Position =		[0, 0]
		JEU.INTERFACE.Taille =		[700, 700]
		JEU.INTERFACE.CouleurRVB =	[0.8 0.8 0.8]
		JEU.INTERFACE.Titre =		'SUDOKU ' + string(JEU.Taille) + ' lignes x ' + string(JEU.Taille) + ' colonnes'
	
	// Boutons
		JEU.BOUTONS.Nombre =		5
		JEU.BOUTONS.Unites =		'normalized'
		JEU.BOUTONS.CouleurRVB =		[0.9 0.9 0.9]
		JEU.BOUTONS.TaillePolice =	15	
	
	// Damier
		TailleDamier =				(JEU.BOUTONS.Nombre - 1)/JEU.BOUTONS.Nombre
		
		JEU.DAMIER.Etiquette =		'Damier'
		JEU.DAMIER.Position =		[0, 0, TailleDamier, TailleDamier]
		JEU.DAMIER.Marges =			[0, 0, 0, 0]
		
		JEU.DAMIER.Unites =			'normalized'
		JEU.DAMIER.CouleurRVB =		[1 1 1]
		JEU.DAMIER.NombreCases =		JEU.Taille
		JEU.DAMIER.AlignementH =		'center'
		JEU.DAMIER.AlignementV =		'middle'
		JEU.DAMIER.TaillePolice =	15
	
	// Console
		JEU.CONSOLE.Marge =			'\t'
		JEU.CONSOLE.Espacement =		'\t\t'
		JEU.CONSOLE.Espace =		' '
		JEU.CONSOLE.Separateur =		' | '
		JEU.CONSOLE.SeparateurLigne =	'------+-------+------'
		JEU.CONSOLE.Saut1Ligne =		'\n'
		JEU.CONSOLE.Saut2Lignes =	'\n\n'
end

function creerInterface()
	global JEU
	
	// (figure) Interface
		interface1 =				figure('figure_position', JEU.INTERFACE.Position)
		interface1.tag =			JEU.INTERFACE.Etiquette
		
		interface1.figure_size =		JEU.INTERFACE.Taille
		interface1.auto_resize =		'on'
		interface1.figure_name =		JEU.INTERFACE.Titre
		interface1.backgroundcolor =	JEU.INTERFACE.CouleurRVB
		
		delmenu(interface1.figure_id, gettext('File'))
		delmenu(interface1.figure_id, gettext('Tools'))
		delmenu(interface1.figure_id, gettext('Edit'))
		delmenu(interface1.figure_id, gettext('?'))
		toolbar(interface1.figure_id, 'off')
	
	// (axes) Axes de la figure
		creerDamier()
	
	// (boutons) Commandes de jeu
		for bb = [1, 2, 5]
			select bb
			case 1 then BOUTON =	JEU.BOUTON1 // Résolution de la grille ( sélectionnée )
			case 2 then BOUTON =	JEU.BOUTON2 // Affichage de la base de problèmes
			case 5 then BOUTON =	JEU.BOUTON5 // Sortie
			end
			
			bouton =				uicontrol(get(JEU.INTERFACE.Etiquette), 'Style', 'pushbutton')
			bouton.Tag =			BOUTON.Etiquette
			bouton.Units =			BOUTON.Unites
			bouton.Position =		BOUTON.Position
			bouton.BackgroundColor =	BOUTON.CouleurRVB
			bouton.FontSize =		BOUTON.TaillePolice
			bouton.Relief =		BOUTON.Relief
			bouton.String =		BOUTON.Titre
			bouton.Callback =		BOUTON.Action
		end
	
	// (menus) Sélection
		for mm = [1, 2]
			select mm
			case 1 then MENU =		JEU.MENU1 // Sélection de la grille à complèter
			case 2 then MENU =		JEU.MENU2 // Sélection du nombre maximum d'itérations
			end
			menu =				uimenu(get(JEU.INTERFACE.Etiquette), 'Tag', MENU.Etiquette, 'Label', MENU.Nom)
			
			for m = 1:1:size(MENU.Choix, 1)
				nom =			MENU.Choix(m, 1)
				action =			MENU.Choix(m, 2)
								uimenu(menu, 'Label', nom, 'Callback', action)
			end
		end
end
function creerDamier()				// ! Attention au mot réservé case !
	global JEU

	damier =						newaxes(get(JEU.INTERFACE.Etiquette))
	damier.tag = 					JEU.DAMIER.Etiquette
	
	damier.axes_bounds =			JEU.DAMIER.Position
	damier.margins =				JEU.DAMIER.Marges
	
	damier.axes_visible =			"off"
	damier.x_location =				"top"
	damier.y_location =				"left"
	damier.box =					"off"
	damier.isoview =				"on"
	damier.data_bounds =			[0, 0; JEU.Taille, JEU.Taille]
	
	ZT =							zeros(1, JEU.Taille + 1)
	UT =							 ones(1, JEU.Taille + 1)
	LT =							0:1:JEU.Taille
	
	ZO =							zeros(1, JEU.Ordre + 1)
	UO =							 ones(1, JEU.Ordre + 1)
	LO =							0:JEU.Ordre:JEU.Taille
	
	xLignesCases =					[ZT,	LT; UT*JEU.Taille,	LT			]
	yLignesCases = 				[LT, ZT; LT,			UT*JEU.Taille	]
	
	cLignesCases =					 ones(1, 2*(JEU.Taille + 1))
	
	xLignesBlocs =					[ZO, LO; UO*JEU.Taille,	LO			]
	yLignesBlocs =					[LO, ZO; LO,			UO*JEU.Taille]
	
	cLignesBlocs =					 ones(1, 2*(JEU.Ordre + 1))
	
	xpolys( xLignesCases, yLignesCases, cLignesCases)
	xpolys( xLignesBlocs, yLignesBlocs, cLignesBlocs)
	objet =						gce()
	for o = 1:2*(JEU.Ordre + 1)
		objet.children(o).thickness = 2
	end
	
	
	for l = 1:JEU.Taille
	for c = 1:JEU.Taille
		xCase =					c - 1
		yCase =					JEU.Taille - 1 - (l - 1)
		etiquette =				'CaseL' + string(l) + 'C' + string(c)
		
		xstringb(xCase, yCase, '', 1, 1, 'fill')
		objet =					gce()
		objet.Tag =				etiquette
		
		JEU.CASE.Etiquettes(l, c) =	etiquette
	end
	end
	
	drawnow()
end

function mettreAJourInterface(Etat)
	global JEU
	
	if ( Etat == JEU.ETAT.RECHERCHE ) then
		set(get(JEU.BOUTON1.Etiquette), 'Enable', 'off')
		set(get(JEU.BOUTON2.Etiquette), 'Enable', 'off')
		set(get(JEU.BOUTON5.Etiquette), 'Enable', 'off')
		
		set(get(JEU.MENU1.Etiquette),   'Enable', 'off')
		set(get(JEU.MENU2.Etiquette),   'Enable', 'off')
	else
		set(get(JEU.BOUTON1.Etiquette), 'Enable', 'on')
		set(get(JEU.BOUTON2.Etiquette), 'Enable', 'on')
		set(get(JEU.BOUTON5.Etiquette), 'Enable', 'on')
		
		set(get(JEU.MENU1.Etiquette),   'Enable', 'on')
		set(get(JEU.MENU2.Etiquette),   'Enable', 'on')	
	end
end
function mettreAJourDamier(Grille)		// ! Attention au mot réservé case !
	global JEU
	
	for l = 1:JEU.Taille
	for c = 1:JEU.Taille
		if (Grille(l, c) ~= 0)
			valeur =				string(Grille(l, c))
		else
			valeur =				''
		end
		set(get(JEU.CASE.Etiquettes(l, c)), 'Text', valeur)
	end
	end
	
	drawnow()
end
function mettreAJourConsole(Etat, Grille)
	global JEU
	
	tohome
	clc
	
	message =						'SuDoKu'
	message =						message + JEU.CONSOLE.Saut1Ligne
	
	select Etat
	case JEU.ETAT.SELECTION then
		message =					message + JEU.CONSOLE.Marge
		message =					message + 'Grille à complèter : '
		message =					message + donnerNiveau(JEU.MatriculeNiveau, 'Nom')
		message =					message + JEU.CONSOLE.Saut1Ligne
		
		message =					message + typographierGrille(Grille)
	case JEU.ETAT.RECHERCHE then
		message =					message + JEU.CONSOLE.Marge
		message =					message + 'Grille à complèter : '
		message =					message + donnerNiveau(JEU.MatriculeNiveau, 'Nom')
		message =					message + JEU.CONSOLE.Saut1Ligne
		
		message =					message + JEU.CONSOLE.Marge
		message =					message + JEU.CONSOLE.Marge
		message =					message + 'Algorithme de résolution récursif avec filtrage'
		message =					message + JEU.CONSOLE.Saut1Ligne
		
		message =					message + typographier3Grilles(JEU.GrilleIncomplete, Grille, Grille - JEU.GrilleIncomplete)
		message =					message + JEU.CONSOLE.Saut1Ligne
		message =					message + JEU.CONSOLE.Saut1Ligne
		
		message =					message + JEU.CONSOLE.Marge
		message =					message + string(JEU.Evaluations) + ' évaluations'
		//message =					message + string(JEU.Evaluations) + ' évaluations sur '
		//message =					message + string(JEU.Partie.EvaluationsMAX) + ' autorisées'
	end
	
	mprintf(message)
end

function Texte = typographierGrille(Grille)
	global JEU
	
	Texte =						''
	
	for l = 1:JEU.Taille
		Texte =					Texte + JEU.CONSOLE.Marge
		
		for c = 1:JEU.Taille
			if (Grille(l, c) ~= 0)
				Texte =			Texte + string(Grille(l, c))
			else
				Texte =			Texte + ' '
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Saut1Ligne
		
		if (modulo(l, JEU.Ordre) == 0) & (modulo(l, JEU.Taille) ~= 0)
			Texte =				Texte + JEU.CONSOLE.Marge + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Saut1Ligne
		end
	end
end
function Texte = typographier2Grilles(Grille1, Grille2)
	global JEU
	
	Texte =						''
	
	for l = 1:JEU.Taille
		Texte =					Texte + JEU.CONSOLE.Marge
		
		for c = 1:JEU.Taille
			if (Grille1(l, c) ~= 0)
				Texte =			Texte + string(Grille1(l, c))
			else
				Texte =			Texte + ' '
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Espacement
		
		for c = 1:JEU.Taille
			if (Grille2(l, c) == 0)
				caractere =		' '
			end
			if (Grille2(l, c) ~= 0)
				caractere =		string(Grille2(l, c))
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Saut1Ligne
		
		if (modulo(l, JEU.Ordre) == 0) & (modulo(l, JEU.Taille) ~= 0)
			Texte =				Texte + JEU.CONSOLE.Marge      + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Espacement + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Saut1Ligne
		end
	end
end
function Texte = typographier3Grilles(Grille1, Grille2, Grille3)
	global JEU
	
	Texte =						''
	
	for l = 1:JEU.Taille
		Texte =					Texte + JEU.CONSOLE.Marge
		
		for c = 1:JEU.Taille
			if (Grille1(l, c) ~= 0)
				Texte =			Texte + string(Grille1(l, c))
			else
				Texte =			Texte + ' '
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Espacement
		
		for c = 1:JEU.Taille
			if (Grille2(l, c) ~= 0)
				Texte =			Texte + string(Grille2(l, c))
			else
				Texte =			Texte + ' '
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Espacement
		
		for c = 1:JEU.Taille
			if (Grille3(l, c) ~= 0)
				Texte =			Texte + string(Grille3(l, c))
			else
				Texte =			Texte + ' '
			end
			
			if (modulo(c, JEU.Ordre) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Espace
			end
			if (modulo(c, JEU.Ordre) == 0) & (modulo(c, JEU.Taille) ~= 0)
				Texte =			Texte + JEU.CONSOLE.Separateur
			end
		end
		
		Texte =					Texte + JEU.CONSOLE.Saut1Ligne
		
		if (modulo(l, JEU.Ordre) == 0) & (modulo(l, JEU.Taille) ~= 0)
			Texte =				Texte + JEU.CONSOLE.Marge      + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Espacement + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Espacement + JEU.CONSOLE.SeparateurLigne
			Texte =				Texte + JEU.CONSOLE.Saut1Ligne
		end
	end
end

////////////////////////////////////////////////////////////////////////////////
//
//	FONCTIONS CONTROLEURS
  //
  //	Initialisation des paramètres
  //
  // Sélection d'une grille incomplète
  // Sélection du maximum d'itérations
  //
  // Lancement de la résolution
  // Diaporama des grilles incomplètes
  // Sortie du programme
//
////////////////////////////////////////////////////////////////////////////////

function affecterParametresControleurs()
	global JEU
	
	// Menus de sélection		
		JEU.MENU1.Etiquette =		'SélectionGrilles'
		JEU.MENU1.Nom =			'Grilles incomplètes'
		JEU.MENU1.Matricules =		['2005-07-10_1';	...
								 '2005-07-27_1';	...
								 '2005-08-06_1';	...
								 '2005-08-10_1';	...
								 '2005-08-29_1';	...
								 '2005-07-10_2';	...
								 '2005-07-27_2';	...
								 '2005-08-06_2';	...
								 '2005-08-10_2';	...
								 '2005-07-10_3';	...
								 '2005-07-27_3';	...
								 '2005-08-06_3';	...
								 '2005-08-10_3';	...
								 '15-280_3';		...
								 '32_3';			...
								 '33_3';			...
								 '34_3';			...
								 '35_3';			...
								 '2005-08-06_4';	...
								 '2005-08-10_4';	...
								 '2005-08-13_4';	...
								 '2006-07-08_4';	...
								 '2006-07-08_5';	...
								 '2016-08-18';		...
								 '2018-04-25';		...
								 '2018-09-05';		...
								 '2019-06-26'		]
		
		JEU.MENU1.Choix =			[]
		for m = 1:1:size(JEU.MENU1.Matricules, 1)
			matricule =			JEU.MENU1.Matricules(m, 1)
			nom =				donnerNiveau(matricule, 'Nom')
			action =				'choisirGrille(' + '''' + matricule + '''' + ')'
			
			JEU.MENU1.Choix =		[JEU.MENU1.Choix; [nom, action]]
		end
		
		JEU.MENU2.Etiquette =		'SélectionNombreIterations'
		JEU.MENU2.Nom =			'Maximum d''itérations'
		JEU.MENU2.Matricules =		[500; 1000; 2000; 3000; 4000; 5000; 6000; 7000; 8000; 9000; 10000]
		
		JEU.MENU2.Choix =			[]
		for m = 1:1:size(JEU.MENU2.Matricules, 1)
			matricule =			JEU.MENU2.Matricules(m, 1)
			nom =				string(matricule)
			action =				'choisirMaximumIterations(' + string(matricule) + ')'
			
			JEU.MENU2.Choix =		[JEU.MENU2.Choix; [nom, action]]
		end
		
	// Boutons de contrôle
		largeurEspace =			1/JEU.BOUTONS.Nombre
		hauteurEspace =			1/JEU.BOUTONS.Nombre	
		xEspace =					((1:JEU.BOUTONS.Nombre) - 1)*largeurEspace
		yEspace =					((1:JEU.BOUTONS.Nombre) - 1)*hauteurEspace
		
		coeffMarge =				1/10
		
		xBouton =					xEspace + coeffMarge*largeurEspace
		yBouton =					yEspace + coeffMarge*hauteurEspace
		largeurBouton =			(1 - 2*coeffMarge)*largeurEspace
		hauteurBouton =			(1 - 2*coeffMarge)*hauteurEspace
		
		JEU.BOUTON1.Etiquette =		'ControleurResolution'
		JEU.BOUTON1.Unites =		JEU.BOUTONS.Unites
		JEU.BOUTON1.Position =		[xBouton($), yBouton($), largeurBouton, hauteurBouton]
		JEU.BOUTON1.CouleurRVB =		JEU.BOUTONS.CouleurRVB
		JEU.BOUTON1.TaillePolice =	JEU.BOUTONS.TaillePolice
		JEU.BOUTON1.Titre =			'Résolution'
		JEU.BOUTON1.Relief =		'raised'
		JEU.BOUTON1.Action =		'resoudreGrille'
		
		JEU.BOUTON2.Etiquette =		'ControleurAffichageBase'
		JEU.BOUTON2.Unites =		JEU.BOUTONS.Unites
		JEU.BOUTON2.Position =		[xBouton($), yBouton($ - 1), largeurBouton, hauteurBouton]
		JEU.BOUTON2.CouleurRVB =		JEU.BOUTONS.CouleurRVB
		JEU.BOUTON2.TaillePolice =	JEU.BOUTONS.TaillePolice
		JEU.BOUTON2.Titre =			'Problèmes'
		JEU.BOUTON2.Relief =		'raised'
		JEU.BOUTON2.Action =		'afficherBaseGrilles()'
		
		JEU.BOUTON3.Etiquette =		'ControleurEdition'
		JEU.BOUTON3.Unites =		JEU.BOUTONS.Unites
		JEU.BOUTON3.Position =		[xBouton($), yBouton($ - 2), largeurBouton, hauteurBouton]
		JEU.BOUTON3.CouleurRVB =		JEU.BOUTONS.CouleurRVB
		JEU.BOUTON3.TaillePolice =	JEU.BOUTONS.TaillePolice
		JEU.BOUTON3.Titre =			'Saisie'
		JEU.BOUTON3.Relief =		'raised'
		JEU.BOUTON3.Action =		''
		
		JEU.BOUTON4.Etiquette =		'ControleurResolutionManuelle'
		JEU.BOUTON4.Unites =		JEU.BOUTONS.Unites
		JEU.BOUTON4.Position =		[xBouton($), yBouton($ - 3), largeurBouton, hauteurBouton]
		JEU.BOUTON4.CouleurRVB =		JEU.BOUTONS.CouleurRVB
		JEU.BOUTON4.TaillePolice =	JEU.BOUTONS.TaillePolice
		JEU.BOUTON4.Titre =			''
		JEU.BOUTON4.Relief =		'raised'
		JEU.BOUTON4.Action =		''
		
		JEU.BOUTON5.Etiquette =		'ControleurSortie'
		JEU.BOUTON5.Unites =		JEU.BOUTONS.Unites
		JEU.BOUTON5.Position =		[xBouton($), yBouton(1), largeurBouton, hauteurBouton]
		JEU.BOUTON5.CouleurRVB =		JEU.BOUTONS.CouleurRVB
		JEU.BOUTON5.TaillePolice =	JEU.BOUTONS.TaillePolice
		JEU.BOUTON5.Titre =			'Sortie'
		JEU.BOUTON5.Relief =		'raised'
		JEU.BOUTON5.Action =		'sortir()'
	
	// États
		JEU.ETAT.SELECTION =		10 // grille incomplète sélectionnée
		JEU.ETAT.CONTRADICTOIRE =	11
		JEU.ETAT.RECHERCHE =		20 // résolution en cours
		JEU.ETAT.BLOQUE =			21 // pas de progrès dans la levée d'incertitude entre deux itérations
		JEU.ETAT.RESOLU =			22 // solution trouvée
	
	// Paramètres de la partie
		JEU.Partie.EvaluationsMAX =	100
		
		JEU.Pause =				1000
end

function choisirGrille(matricule)
	global JEU
	
	JEU.MatriculeNiveau =			matricule
	JEU.GrilleIncomplete =			donnerNiveau(matricule, 'Valeur')
	
	mettreAJourConsole(JEU.ETAT.SELECTION, JEU.GrilleIncomplete)
	mettreAJourDamier(JEU.GrilleIncomplete)
end
function choisirMaximumIterations(maximumIterations)
	global JEU
	
	JEU.Partie.EvaluationsMAX =		maximumIterations
end

function resoudreGrille()
	global JEU
	
	mettreAJourInterface(JEU.ETAT.RECHERCHE)
	mettreAJourDamier(JEU.GrilleIncomplete)
	mettreAJourConsole(JEU.ETAT.SELECTION, JEU.GrilleIncomplete)
	
	JEU.Evaluations =				0
	JEU.ProfondeurRecursive =		0
	resoudreRecursivement(JEU.GrilleIncomplete)
	
	mettreAJourInterface(JEU.ETAT.RESOLU)
	mettreAJourDamier(JEU.GrilleSolution)
	mettreAJourConsole(JEU.ETAT.RECHERCHE, JEU.GrilleSolution)
end
function afficherBaseGrilles()
	global JEU
	
	for numero = 1:size(JEU.MENU1.Matricules, 1)
		choisirGrille(JEU.MENU1.Matricules(numero, 1))
		sleep(JEU.Pause)
	end
end
function sortir()
	xdel(winsid())
end

////////////////////////////////////////////////////////////////////////////////
//
//	LANCEMENT
//
////////////////////////////////////////////////////////////////////////////////

affecterParametresModele()
affecterParametresVues()
affecterParametresControleurs()

creerInterface()