📄 sudoku.cpp
字号:
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int currentNumber = 0;
int currentZone = 0;
int currentBox = 0;
int currentVal = 0;
int sudoku[9][9][10];
int mouseX, mouseY;
void dessiner( HDC );
void resetSudoku()
{
currentNumber = currentZone = currentBox = currentVal = 0;
// Initialisation du sudoku
for( int i = 0; i < 9; ++i )
for ( int j = 0; j < 9; ++j )
{
for ( int k = 0; k < 9; ++k )
sudoku[i][j][k] = k + 1;
sudoku[i][j][9] = 0;
}
}
const char* appName = "sudoku";
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
resetSudoku();
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon( hInstance, appName );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = appName ;
wndclass.hIconSm = LoadIcon( hInstance, appName );
if (!RegisterClassEx (&wndclass))
return 1;
hwnd = CreateWindow( appName, "Sudoku Helper",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
550, 486,
NULL, NULL, hInstance, NULL) ;
// Cr閍tion d'un bouton
HWND button = CreateWindow( "button", "Reset",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
463, 3, 70, 20,
hwnd, 0, 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)
{
HDC hdc ;
PAINTSTRUCT ps ;
int newNumber = 0;
switch (message)
{
case WM_COMMAND:
if ( IDYES == MessageBox( hwnd, "Are you sure ?", appName,
MB_YESNO | MB_ICONQUESTION ) )
resetSudoku();
InvalidateRect (hwnd, NULL, TRUE) ;
return 0;
case WM_LBUTTONDOWN:
mouseX = LOWORD (lParam) ;
mouseY = HIWORD (lParam) ;
if ( mouseY > 50 && mouseY < 410 && mouseX > 470 && mouseX < 520 )
{
if ( mouseX > 470 && mouseX < 495 )
newNumber = ( (mouseY-50) / 40 ) + 1;
else if ( mouseX > 495 && mouseX < 520 )
newNumber = 10 + ( (mouseY-50) / 40 ) + 1;
if ( currentNumber && newNumber == currentNumber )
currentNumber = 0;
else currentNumber = newNumber;
}
else if ( mouseY > 417 && mouseY < 438 && mouseX > 485 && mouseX < 504 )
{
if ( currentNumber == 30 ) currentNumber = 0;
else currentNumber = 30;
}
InvalidateRect (hwnd, NULL, TRUE) ;
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
dessiner( hdc );
mouseX = mouseY = 0;
EndPaint(hwnd, &ps );
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
HFONT CreateArialFont( int size )
{
LOGFONT lf ;
lf.lfHeight = -size;
lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0 ;
lf.lfWeight = 700 ;
lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = lf.lfCharSet = 0 ;
lf.lfOutPrecision = lf.lfClipPrecision = lf.lfQuality = lf.lfPitchAndFamily = 0 ;
strcpy (lf.lfFaceName, "Arial" ) ;
return CreateFontIndirect( &lf ) ;
}
void dessiner( HDC hdc )
{
// Calcule de la zone courante et box courante
currentZone = currentBox = currentVal = 0;
if ( mouseX > 0 && mouseX < 450 && mouseY > 0 && mouseY < 450 )
{
currentZone = (mouseY/150)*3 + (mouseX/150) + 1;
currentBox = (mouseY/50)*3 + (mouseX/50) + 1 - (currentZone-1)*3;
currentVal = mouseX%50 / 17 + mouseY%50 / 17 * 3 + 1;
}
// Modification du joueur
if ( currentZone && currentBox && currentNumber )
{
if ( currentNumber == 30 )
{
if ( !sudoku[currentZone-1][currentBox-1][currentVal-1] )
sudoku[currentZone-1][currentBox-1][currentVal-1] = currentVal;
else
sudoku[currentZone-1][currentBox-1][currentVal-1] = 0;
}
else
{
bool reduction = false;
if ( !sudoku[currentZone-1][currentBox-1][9] )
{
sudoku[currentZone-1][currentBox-1][9] = currentNumber;
reduction = true;
}
else
sudoku[currentZone-1][currentBox-1][9] = 0;
// R閐uction
if ( reduction )
{
// On supprime le currentNumber de la box
int number = currentNumber - (currentNumber>10?10:0);
for ( int j = 0; j < 9; ++j )
sudoku[currentZone-1][j][number-1] = 0;
// On supprime le currentNumber de la ligne
for ( int i = 3*((currentZone-1)/3); i < 3*(((currentZone-1)/3)+1); ++i )
for ( int j = 3*((currentBox-1)/3); j < 3*(((currentBox-1)/3)+1); ++j )
sudoku[i][j][number-1] = 0;
// On supprime le currentNumber de la colonne
for ( int i = (currentZone-1)%3; i < 9; i += 3 )
for ( int j = (currentBox-1)%3; j < 9; j += 3 )
sudoku[i][j][number-1] = 0;
}
}
}
HPEN gris = CreatePen( PS_SOLID, 2, RGB( 204, 204, 204 ) );
SelectObject( hdc, gris );
// Dessin des cadres internes
for ( int i = 0; i < 3*3; ++i )
{
MoveToEx( hdc, i*50, 0, 0 ); LineTo( hdc, i*50, 450 );
MoveToEx( hdc, 0, i*50, 0 ); LineTo( hdc, 450, i*50 );
}
DeleteObject( gris );
// Dessin des cadres extrenes
HPEN noir = CreatePen( PS_SOLID, 3, RGB( 0, 0, 0 ) );
SelectObject( hdc, noir );
for ( int i = 0; i < 4; ++i )
{
MoveToEx( hdc, i*150, 0, 0 ); LineTo( hdc, i*150, 450 );
MoveToEx( hdc, 0, i*150, 0 ); LineTo( hdc, 450, i*150 );
}
DeleteObject( noir );
HFONT hFont14 = CreateArialFont( 14 );
HFONT hFont38 = CreateArialFont( 38 );
// Dessin des nombres
for( int i = 0; i < 9; ++i )
for ( int j = 0; j < 9; ++j )
{
if ( sudoku[i][j][9] )
{ // Le choix a 閠
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -