JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=8b825ba6887b1374649f6793d31f9bb4Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Sudoku

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Held vom Erdbeerfeld
Mini JLI'ler



Anmeldedatum: 21.06.2006
Beiträge: 17

Medaillen: Keine

BeitragVerfasst am: 09.12.2006, 19:54    Titel: Sudoku Antworten mit Zitat

Hi,
ich will ein Programm schreiben, bei dem man die vorgegeben Zahlen eines Sudokus eingeben kann und der Rest automatisch ausgefüllt wird. Um einen Algorithmus entwerfen zu können will ich mit der graphischen Oberfläche anfangen, damit ich überprüfen kann, ob er funktioniert.
Ich habe mir gedacht, 9*9 Childfenster zu erstellen, in denen jeweils eine Zahl eingelesen/ausgegeben und in einem zweidimensionalen Array gespeichert wird. Der Code ist bisher ziemlich simpel und bedarf hoffentlich keiner weiteren Erläuterung.
CPP:
/*--------------------------------------------------------
   Sudoku Solver by Jonas Peter
  --------------------------------------------------------*/



#include <windows.h>

#define DIVISIONS 9
static HWND hwndChild[DIVISIONS][DIVISIONS];
static TCHAR  szEingabe[2];
static int           cxBlock, cyBlock, x, y;
static int xf, yf, iZahlen[DIVISIONS] [DIVISIONS];

LRESULT CALLBACK WndProc   (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szChildClass[] = TEXT ("SSChild") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Sudoku Solver") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {    // UNICODE-Compilierung ist die einzige realistische Fehlermöglichkeit
          MessageBox (NULL, TEXT ("Programm arbeitet mit Unicode und setzt Windows NT voraus!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     wndclass.lpfnWndProc   = ChildWndProc ;
     wndclass.cbWndExtra    = sizeof (long) ;
     wndclass.hIcon         = NULL ;
     wndclass.lpszClassName = szChildClass ;

     RegisterClass (&wndclass) ;
     
     hwnd = CreateWindow (szAppName, TEXT ("Sudoku Solver"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     
     switch (message)
     {
     case WM_CREATE :
          for (x = 0 ; x < DIVISIONS ; x++)
               for (y = 0 ; y < DIVISIONS ; y++)
                    hwndChild[x][y] = CreateWindow (szChildClass, NULL,
                              WS_CHILDWINDOW | WS_VISIBLE,
                              0, 0, 0, 0,
                              hwnd, (HMENU) (y << 8 | x),
                              (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                              NULL) ;
          return 0 ;
               
     case WM_SIZE :
          cxBlock = LOWORD (lParam) / DIVISIONS ;
          cyBlock = HIWORD (lParam) / DIVISIONS ;

          for (x = 0 ; x < DIVISIONS ; x++)
                for (y = 0 ; y < DIVISIONS ; y++)
                    MoveWindow (hwndChild[x][y],
                                x * cxBlock, y * cyBlock,
                                cxBlock, cyBlock, TRUE) ;
          return 0 ;

     case WM_LBUTTONDOWN :
          MessageBeep (0) ;
          return 0 ;
         
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message,
                               WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     switch (message)
     {
     case WM_CREATE :
          SetWindowLong (hwnd, 0, 0) ;
          return 0 ;
         
     case WM_LBUTTONDOWN :
        //Feststellen, in welchem Fenster geklickt wurde
        xf=LOWORD (lParam)/cxBlock;
        yf=LOWORD (lParam)/cyBlock;
        return 0 ;
         
    case WM_CHAR:
       switch (wParam){
         case '0' :
            iZahlen[xf][yf]=0;
            szEingabe[0]=0;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '1' :
            iZahlen[xf][yf]=1;
            szEingabe[0]=1;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '2' :
            iZahlen[xf][yf]=2;
            szEingabe[0]=2;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '3' :
            iZahlen[xf][yf]=3;
            szEingabe[0]=3;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '4' :
            iZahlen[xf][yf]=4;
            szEingabe[0]=4;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '5' :
            iZahlen[xf][yf]=5;
            szEingabe[0]=5;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '6' :
            iZahlen[xf][yf]=6;
            szEingabe[0]=6;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '7' :
            iZahlen[xf][yf]=7;
            szEingabe[0]=7;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '8' :
            iZahlen[xf][yf]=8;
            szEingabe[0]=8;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '9' :
            iZahlen[xf][yf]=9;
            szEingabe[0]=9;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;
         }
       return 0;

    case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;
         
        TextOut(hdc, 0, 0, szEingabe[0], 1);
         
          EndPaint (hwnd, &ps) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}



Beim Kompilieren erhalte ich folgende Fehlermeldung: ------ Build started: Project: SudokuSolver, Configuration: Debug Win32 ------
Compiling...
SudokuSolver.cpp
d:\1programmieren\c++programme\sudokusolver\sudokusolver\sudokusolver.cpp(66) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data
d:\1programmieren\c++programme\sudokusolver\sudokusolver\sudokusolver.cpp(82) : warning C4312: 'type cast' : conversion from 'int' to 'HMENU' of greater size
d:\1programmieren\c++programme\sudokusolver\sudokusolver\sudokusolver.cpp(82) : warning C4312: 'type cast' : conversion from 'LONG' to 'HINSTANCE' of greater size
d:\1programmieren\c++programme\sudokusolver\sudokusolver\sudokusolver.cpp(203) : error C2664: 'TextOutW' : cannot convert parameter 4 from 'TCHAR' to 'LPCWSTR'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Build log was saved at "file://d:\1Programmieren\C++Programme\SudokuSolver\SudokuSolver\Debug\BuildLog.htm"
SudokuSolver - 1 error(s), 3 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Ich würde mich über Hilfe sehr freuen. Auch über grundsätzliche Design Vorschläge, da das mein erstes Winapi Programm ist und ich bezweifle, dass das die eleganteste Lösungsmöglichkeit ist.

HeldvomErdbeerfeld

Edit by Kampfhund: code durch cpp-Tags ersetzt.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 09.12.2006, 21:31    Titel: Antworten mit Zitat

CPP:
TextOut(hdc, 0, 0, szEingabe, 1);
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 09.12.2006, 22:27    Titel: Antworten mit Zitat

öhm, ich hatte auch mal angefangen und ich habe konsole benutz. Das einlesen ging über Textdateien und zum darstellen hatte ich eine einfache Funktion. Das ging fürs erste eigneltich wunderbar nur dann war irgendwo ein Bug drinne und ich hatte keinen Bock mehr zu suchen...
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Held vom Erdbeerfeld
Mini JLI'ler



Anmeldedatum: 21.06.2006
Beiträge: 17

Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 10:34    Titel: Antworten mit Zitat

@Maxim
Danke, ein Hinweis was falsch ist hätte auch geholfen, aber ich habs jetzt selbst rausgefunden.

Mein Programm lässt sich jetzt zwar kompilieren, aber ich bin immer noch weit davon entfernt davon, dass es macht was ich will. Also, falls ihr grundsätzliche Tipps habt würde ich mich freuen, wenn ihr sie Postet.
Danke
Held vom Erdbeerfeld
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 10:55    Titel: Antworten mit Zitat

Ok, meine Überlegungen waren erstmal die folgenden:
Es wird jedes Feld durchgegangen, ob es ller ist.
Bei einem leeren Feld testest du wie viele Zahlen du einsetzen könntest. Wenn du nur eine einzige Zahl einsetzen kannst, dann kommt ide logischerweise da rein.
Dann kannste noch testen, ob in einer Reihe, Spalte und Rechteck eine bestimmte Zahl nur in ein Feld rein kann. Dann muss die auch darein, obwohl evtl. auch andere Zahlen passen würden, aber da diese Zahl ja auf jeden Fall vorkommen muss, kommt die darein.
Du schreibst dir also für jedes leere Feld eine Liste möglicher Zahlen. Und testest das dann entsprechend damit.

Damit dürftest du schon sehr weit kommen, nur bei den schwereren Sudokus musste dann halt auch manchmal raten. Logischerweise solltest du dann dafür halt ein Feld nehmen wo es nicht so viele möglichkeiten bgibt udn das ganze dann rekursiv ablaufen lassen.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Held vom Erdbeerfeld
Mini JLI'ler



Anmeldedatum: 21.06.2006
Beiträge: 17

Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 11:23    Titel: Antworten mit Zitat

Sorry, ich hab mich wohl unklar ausgedrückt. Ich hab erstmal nach Hilfe zu graphischen Oberfläche gefragt.
Zum Lösen will ich dann einen Backtracking Algorithmus verwenden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 12:03    Titel: Re: Sudoku Antworten mit Zitat

Held vom Erdbeerfeld hat Folgendes geschrieben:

Code ist bisher ziemlich simpel und bedarf hoffentlich keiner weiteren Erläuterung.


kann schon sein, aber ein paar kommentare wäre schön, denn nicht jeder hat zeit und lust sich sich in die gedanken des programmierers reinzuversetzen

schreib doch erst mal was du überhaupt sehen willst und was nicht
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 12:27    Titel: Antworten mit Zitat

CPP:
         case '5' :
            iZahlen[xf][yf]=5;
            szEingabe[0]=5;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;

         case '6' :
            iZahlen[xf][yf]=6;
            szEingabe[0]=6;
            InvalidateRect (hwnd, NULL, FALSE);
            return 0;
            break;


äh...
wie wärs damit? :
CPP:
            iZahlen[xf][yf]=wParam;
            szEingabe[0]=wParam;
            InvalidateRect (hwnd, NULL, FALSE);

Nur eine kleine Schönheitskorektur^^
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Held vom Erdbeerfeld
Mini JLI'ler



Anmeldedatum: 21.06.2006
Beiträge: 17

Medaillen: Keine

BeitragVerfasst am: 10.12.2006, 14:42    Titel: Antworten mit Zitat

Okay, dann erklär ich mal, was ich will.
Es soll ein Sudokufeld mit 9*9 Feldern dargestellt werden. Der Benutzer klickt in ein Feld (WM_LBUTTONDOWN). Dabei wird festgestellt, in welches Feld geklickt wurde und das ganze in den Variablen xf und yf gespeichert.
CPP:
xf=LOWORD (lParam)/cxBlock;
        yf=LOWORD (lParam)/cyBlock;

Ich weiß nicht ob man das auch mit dem Handle des Fensters erledigen kann. Wenn dann eine der Tasten 1-9 gedrückt wurde("WM_CHAR") wird der Wert in das Feld an der stelle iZahlen[xf][yf] gespeichert. Dannach wird das Rechteck als ungültich deklariert und bei WM_PAINT wird der wert von szEingabe ausgegeben.
Das ist erstmal alles. Ich will also, dass man auf einem 9*9 Feld eine Zahl von 1-9 eingeben kann und diese dann gleich sieht. Die Zahlen müssen dabei auch unter angabe ihrer Position in ein Feld gespeichert werden. xf gibt an in welcher spalte und yf gibt an in welcher Reihe.

@Jonathan_Klein
Ich will, dass nur die Zahlen bearbeitet werden, also keine Buchstaben eingegeben werden können.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum