Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

DES CHIFFRES SANS LES LETTRES (WIN32)


Information sur la source

Catégorie :.Net Niveau : Initié Date de création : 18/08/2003 Date de mise à jour : 19/08/2003 03:27:34 Vu / téléchargé: 3 782 / 181

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (3)
Ajouter un commentaire et/ou une note


Description

Dans le meme style que "des chiffres et les lettres", seulement c'est seulement les chiffres ici.
le programme sort un jeu de 6 nombres ainsi qu'un nombre cible a trouver.
Si l'ordi trouve le bon resultat, il affiche tout les calculs lorsqu'on clique sur le bouton.
Si il ne trouve pas le bon resultat, il affiche les calculs du nombre le plus proche qu'il a trouvé.

Une fonction recursive essaye tout les calculs possible entre les 6 nombres avec les 4 operateurs (+-*/).
Je suis pas un pro en algo, mais ca a l'air de bien fonctionner.
Bien evidemment il n'affiche pas le calcul le plus simple, mais seulement un calcul qui permet d'atteindre le resultat.

J'ai testé une centaine de fois, et je crois qu'il n'y a plus de bug.
Merci d'avances pour les remarques/idées ou les bugs trouvés.

[UPDATE] correction du bug qui faisait que de temp en temp l'affichage du jeu de nombre + de la valeur a chercher se bloquait.
 

Source

  • #include <stdio.h>
  • #include <windows.h>
  • #include "resource.h"
  • #define CNB 6 // nombre de nombre
  • #define DIF(a,b) ((a)<(b) ? ((b)-(a)) : ((a)-(b))) // diffence entre 2 nbres, positif
  • HWND hOK, hTarget, hCalculs;
  • HWND hDialog;
  • char operateurs[4] = {'+','-','*','/'};
  • char szRes[1024]; // calculs
  • char szResult[2048]; // calculs qu'on affichera
  • int NB_Array[CNB] = {0,0,0,0,0,0};
  • int iTarget = 0;
  • int NearestDif = 9999;
  • int NearestResult = 0;
  • BOOL bInGame = FALSE; // suivant cette valeur, le bouton hOK lance une nouvelle partie ou affiche le resultat de la partie précédente
  • BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  • int CalcTarget(int iTarget, int * NB, int cNB, char * szRes);
  • int Calc(int a, int b, int iOperateur);
  • int InitGame(int * pArray);
  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  • {
  • srand(GetTickCount());
  • DialogBox(hInstance, "MainDialog", 0, AppDlgProc);
  • return 0;
  • }
  • BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  • {
  • switch(uMsg)
  • {
  • case WM_INITDIALOG:
  • hDialog = hDlg;
  • hOK = GetDlgItem(hDlg, IDC_OK);
  • hCalculs = GetDlgItem(hDlg, IDC_CALCULS);
  • return 0;
  • case WM_COMMAND:
  • switch(LOWORD(wParam))
  • {
  • case IDC_OK:
  • if(!bInGame){ // FALSE: nouveau jeu de nbre, et on fait les calculs
  • bInGame = TRUE;
  • SetWindowText(hCalculs, NULL);
  • EnableWindow(hOK, FALSE); // on desactive le bouton pendant le calcul
  • NearestDif = 9999;
  • InitGame((int*)&NB_Array);
  • memset(szRes, 0, sizeof(szRes));
  • if(0==CalcTarget(iTarget,(int*) &NB_Array, CNB, szRes)){
  • CalcTarget(NearestResult,(int*) &NB_Array, CNB, szRes);
  • strcpy(szResult, "Le résultat n'a pas été trouvé, voici le resultat le plus proche:\r\n");
  • strcat(szResult, szRes);
  • }else strcpy(szResult, szRes);
  • EnableWindow(hOK, TRUE);
  • SetWindowText(hOK, "Afficher la solution");}
  • else{ // TRUE: on affiche le resultat
  • SetDlgItemText(hDlg, IDC_CALCULS, szResult);
  • SetWindowText(hOK, "Rejouer");
  • bInGame = FALSE;}
  • return 0;
  • case IDCANCEL:
  • EndDialog(hDlg, 0);
  • }
  • }
  • return 0;
  • }
  • int CalcTarget(int iTarget, int * NB, int cNB, char * szRes)
  • {
  • int i = 0; // boucle d'un nombre de la liste
  • int j = 0; // boucle d'un autre nombre de la liste
  • int op = 0; // boucle pour les 4 types d'operateurs
  • // petite chaine pour copier le calcul courant dans la chaine qui contient tout les calculs
  • char szCalcul[64];
  • for(i=0; i<cNB-1; i++)
  • for(j=i+1; j<cNB; j++)
  • for(op=0; op<4; op++)
  • {
  • int iCResult = Calc(*(NB+i), *(NB+j), op);
  • if(!iCResult) continue;
  • // si on trouve le bon nombre, c'est fini
  • if(iCResult == iTarget){
  • sprintf(szCalcul,"%d %c %d = %d\r\n", *(NB+i), operateurs[op], *(NB+j), iTarget);
  • strcpy(szRes, szCalcul);
  • return iTarget;
  • }else{
  • // sinon, on garde une trace du resultat le + proche
  • if(DIF(iTarget, iCResult) <= NearestDif) {
  • NearestDif = DIF(iTarget, iCResult);
  • NearestResult = iCResult;}
  • }
  • sprintf(szCalcul,"%d %c %d = %d\r\n", *(NB+i), operateurs[op], *(NB+j), iCResult);
  • strcpy(szRes, szCalcul);
  • // on refais un tableau de nombre sans copier NB[i] et NB[j], mais en rajoutant iCResult
  • // puis on rappelle la fonction avec ce tableau (recursif)
  • int NB_2[CNB] = {0,0,0,0,0,0};
  • int a=0, b=0;
  • for(a=0; a<cNB; a++){
  • if(*(NB+a) == *(NB+i) || *(NB+a) == *(NB+j)) continue;
  • NB_2[b++] = *(NB+a);}
  • NB_2[b] = iCResult;
  • if(CalcTarget(iTarget,(int*) &NB_2, b+1, szRes+strlen(szRes))) return iTarget;
  • }
  • return 0;
  • }
  • // fonction qui calcule operation de base, serait mieux inline
  • int Calc(int a, int b, int iOperateur)
  • {
  • switch(iOperateur)
  • {
  • case 0: return (a+b);
  • case 1: return (a-b);
  • case 2: return (a*b);
  • case 3: if(0 == a%b) return (a/b);
  • }
  • return 0;
  • }
  • // choisi 6 nouveaux nombres + nouveau nombre a trouver
  • // affiche le tout dans les fenetres appropriées
  • int InitGame(int * pArray)
  • {
  • int i = 0; // pour les boucles
  • int i2= 0; //
  • int iValue = 0;
  • int NB_Values[14] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100}; // valeurs de depart possibles
  • for(i=0; i<6; i++) *(pArray+i) = 0; // tableau a 0
  • // nouvelles valeurs dans le tableau, et on empeche qu'une valeur se retrouve 2 fois dans le tableau
  • for(i=0; i<6; i++){
  • NewValue:
  • iValue = rand()%14;
  • for(i2=0; i2<6; i2++) if(*(pArray+i2) == NB_Values[iValue]) goto NewValue;
  • SetDlgItemInt(hDialog, IDC_NBRES+i, NB_Values[iValue], FALSE);
  • *(pArray+i) = NB_Values[iValue];}
  • iTarget = (rand()%900) + 100; // entre 100 et 999
  • SetDlgItemInt(hDialog, IDC_TARGET, iTarget, FALSE);
  • return 0;
  • }
#include <stdio.h>
#include <windows.h>
#include "resource.h"

#define CNB 6 // nombre de nombre
#define DIF(a,b) ((a)<(b) ? ((b)-(a)) : ((a)-(b))) // diffence entre 2 nbres, positif

HWND hOK, hTarget, hCalculs;
HWND hDialog;
char operateurs[4] = {'+','-','*','/'};
char szRes[1024];    // calculs
char szResult[2048]; // calculs qu'on affichera
int NB_Array[CNB] = {0,0,0,0,0,0};
int iTarget = 0;
int NearestDif = 9999;
int NearestResult = 0;
BOOL bInGame = FALSE; // suivant cette valeur, le bouton hOK lance une nouvelle partie ou affiche le resultat de la partie précédente

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CalcTarget(int iTarget, int * NB, int cNB, char * szRes);
int Calc(int a, int b, int iOperateur);
int InitGame(int * pArray);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
srand(GetTickCount());
DialogBox(hInstance, "MainDialog", 0, AppDlgProc);
return 0;
}

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) 
	{
	case WM_INITDIALOG:
		hDialog = hDlg;
		hOK = GetDlgItem(hDlg, IDC_OK);
		hCalculs = GetDlgItem(hDlg, IDC_CALCULS);
	return 0;
	case WM_COMMAND:
		switch(LOWORD(wParam)) 
		{
		case IDC_OK:
			if(!bInGame){ // FALSE: nouveau jeu de nbre, et on fait les calculs
				bInGame = TRUE;
				SetWindowText(hCalculs, NULL);
				EnableWindow(hOK, FALSE); // on desactive le bouton pendant le calcul
				NearestDif = 9999;
				InitGame((int*)&NB_Array);
				memset(szRes, 0, sizeof(szRes));
				if(0==CalcTarget(iTarget,(int*) &NB_Array, CNB, szRes)){
					CalcTarget(NearestResult,(int*) &NB_Array, CNB, szRes);
					strcpy(szResult, "Le résultat n'a pas été trouvé, voici le resultat le plus proche:\r\n");
					strcat(szResult, szRes);
				}else strcpy(szResult, szRes);
				EnableWindow(hOK, TRUE);
				SetWindowText(hOK, "Afficher la solution");}
			else{ // TRUE: on affiche le resultat
				SetDlgItemText(hDlg, IDC_CALCULS, szResult);
				SetWindowText(hOK, "Rejouer");
				bInGame = FALSE;}
		return 0;
		case IDCANCEL: 
			EndDialog(hDlg, 0);
		}
	}
return 0;
}

int CalcTarget(int iTarget, int * NB, int cNB, char * szRes)
{
	int i = 0;  // boucle d'un nombre de la liste
	int j = 0;  // boucle d'un autre nombre de la liste
	int op = 0; // boucle pour les 4 types d'operateurs 
	// petite chaine pour copier le calcul courant dans la chaine qui contient tout les calculs
	char szCalcul[64]; 

	for(i=0; i<cNB-1; i++)
		for(j=i+1; j<cNB; j++)
			for(op=0; op<4; op++)
			{
				int iCResult = Calc(*(NB+i), *(NB+j), op);
				if(!iCResult) continue;
				// si on trouve le bon nombre, c'est fini
				if(iCResult == iTarget){
					sprintf(szCalcul,"%d %c %d = %d\r\n", *(NB+i), operateurs[op], *(NB+j), iTarget);
					strcpy(szRes, szCalcul);
					return iTarget;
				}else{
					// sinon, on garde une trace du resultat le + proche
					if(DIF(iTarget, iCResult) <= NearestDif) {
						NearestDif = DIF(iTarget, iCResult);
						NearestResult = iCResult;}
				}
				sprintf(szCalcul,"%d %c %d = %d\r\n", *(NB+i), operateurs[op], *(NB+j), iCResult);
				strcpy(szRes, szCalcul);

				// on refais un tableau de nombre sans copier NB[i] et NB[j], mais en rajoutant iCResult
				// puis on rappelle la fonction avec ce tableau (recursif)
				int NB_2[CNB] = {0,0,0,0,0,0};
				int a=0, b=0;
				for(a=0; a<cNB; a++){
					if(*(NB+a) == *(NB+i) || *(NB+a) == *(NB+j)) continue;
					NB_2[b++] = *(NB+a);}
				NB_2[b] = iCResult;
				if(CalcTarget(iTarget,(int*) &NB_2, b+1, szRes+strlen(szRes))) return iTarget;
			}
return 0;
}
// fonction qui calcule operation de base, serait mieux inline
int Calc(int a, int b, int iOperateur)
{
	switch(iOperateur)
	{
	case 0: return (a+b);
	case 1: return (a-b);
	case 2: return (a*b);
	case 3: if(0 == a%b) return (a/b);
	}
return 0;
}

// choisi 6 nouveaux nombres + nouveau nombre a trouver
// affiche le tout dans les fenetres appropriées
int InitGame(int * pArray) 
{
	int i = 0; // pour les boucles
	int i2= 0; //
	int iValue = 0;
	int NB_Values[14] = {1,2,3,4,5,6,7,8,9,10,25,50,75,100}; // valeurs de depart possibles
	for(i=0; i<6; i++) *(pArray+i) = 0; // tableau a 0
	// nouvelles valeurs dans le tableau, et on empeche qu'une valeur se retrouve 2 fois dans le tableau
	for(i=0; i<6; i++){
NewValue:
		iValue = rand()%14;
		for(i2=0; i2<6; i2++) if(*(pArray+i2) == NB_Values[iValue]) goto NewValue;
		SetDlgItemInt(hDialog, IDC_NBRES+i, NB_Values[iValue], FALSE);
		*(pArray+i) = NB_Values[iValue];}
	iTarget = (rand()%900) + 100; // entre 100 et 999
	SetDlgItemInt(hDialog, IDC_TARGET, iTarget, FALSE);
return 0;
}

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de BruNews le 18/08/2003 20:41:53 administrateur CS

Salut,
on pourrait peut-etre reunir les 2 morceaux. Si t'es OK j'ecris les ajouts et suppressions de mots qui manquent au mien.

signaler à un administrateur
Commentaire de aardman le 18/08/2003 20:57:50

Cette source n'est pas vraiment optimisée, et je suis pas encore sur d'avoir trouvé tout les bugs, mais si ca te convient il n'y a aucun probleme pour faire les chiffres et les lettres en complet.

signaler à un administrateur
Commentaire de virlix le 20/08/2003 06:45:55

Dans ton choix des chiffre tu ne gere pas la probabilite. On a autant de chance d'avoir un 1 qu'un 10. Or dans le vrai jeu c'est faux

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,250 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.