I. Introduction▲
Code d'un othello en pure Windows API. (Mode 2 joueurs en réseau). Avec utilisation d'un fichier ressources .rc
II. Code complet▲
ressources.rc :
Sélectionnez
#include <windows.h>
#include "resources.h"
LEMENU MENU
BEGIN
POPUP "
Fichier
"
BEGIN
MENUITEM "
Start
"
, IDM_NEW
MENUITEM "
Stop
"
, IDM_STOP
MENUITEM "
Paramètres réseau...
"
, IDM_PARAM
MENUITEM SEPARATOR
MENUITEM "
A propos...
"
, IDM_ABOUT
MENUITEM "
&Quitter
"
, IDM_QUIT
END
END
DIALOG1 DIALOGEX 30
, 60
, 210
, 120
STYLE WS_POPUP |
WS_VISIBLE |
WS_CAPTION |
WS_SYSMENU
CAPTION "
Dialog
"
FONT 8
, "
MS Shell Dlg
"
, 400
, 0
, 0x1
BEGIN
CONTROL "
Serveur
"
,IDC_RADIO1,"
Button
"
,BS_AUTORADIOBUTTON,78
,15
,41
,10
CONTROL "
Client
"
,IDC_RADIO2,"
Button
"
,BS_AUTORADIOBUTTON,27
,15
,34
,10
CONTROL ""
,IDC_IPADDRESS1,"
SysIPAddress32
"
,WS_TABSTOP,78
,39
,100
,15
LTEXT "
Adresse IP
"
,-
1
,27
,41
,36
,8
DEFPUSHBUTTON "
OK
"
,IDOK,37
,82
,50
,14
PUSHBUTTON "
Annuler
"
,IDCANCEL,121
,82
,50
,14
END
ressources.h :
Sélectionnez
#define IDM_QUIT 1
#define IDM_NEW 2
#define IDM_PARAM 3
#define IDM_ABOUT 4
#define IDM_STOP 5
#define IDD_DIALOG1 101
#define IDC_RADIO1 1000
#define IDC_RADIO2 1001
#define IDC_EDIT1 1002
#define IDC_IPADDRESS1 1003
#define IDC_BUTTON1 1004
#define IDC_BUTTON2 1005
main.c :
Sélectionnez
#include <windows.h>
#include <commctrl.h>
#include "resources.h"
#define LARG 64
#define NBC_X 8
#define NBC_Y NBC_X
#define PL_WHITE 1
#define PL_BLACK 2
#define PL_OVER 3
#define MSG_STOP 127
#define CLIENT 0
#define SERVER 1
#define GET_X_LPARAM(lp) ((int)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)HIWORD(lp))
#define WM_NETEVENT (WM_APP+1)
int
Mode; //CLIENT ou SERVER
char
IP_address[16
] =
"
127.0.0.1
"
;
WORD coord;
HINSTANCE hinst;
HANDLE hMutex;
HWND hwnd;
HWND hstb;
BOOL Connect;
LRESULT CALLBACK MainWndProc
(
HWND, UINT, WPARAM, LPARAM);
BOOL APIENTRY Dialog1Proc
(
HWND, UINT, WPARAM, LPARAM);
int
Play
(
int
tab[NBC_Y][NBC_X], int
x, int
y, int
*
joueur);
void
Init
(
int
tab[NBC_Y][NBC_X]);
/**
***************************************************************************
*/
DWORD WINAPI thread_client
(
LPVOID lpParam)
{
WSADATA WSAData;
SOCKADDR_IN sin;
char
str[256
];
WSAStartup
(
MAKEWORD
(
2
,0
), &
WSAData);
sin.sin_addr.s_addr =
inet_addr
(
IP_address);
sin.sin_family =
AF_INET;
sin.sin_port =
htons
(
6665
);
SOCKET sock =
socket
(
AF_INET, SOCK_STREAM, 0
);
if
(
connect
(
sock, (
SOCKADDR *
)&
sin, sizeof
(
sin)) ==
0
)
{
Connect =
TRUE;
wsprintf
(
str, "
Connecté : %s
"
, IP_address);
SendMessage
(
hstb, SB_SETTEXT, 2
, (
LPARAM)str);
while
(
1
)
{
WaitForSingleObject
(
hMutex, INFINITE);
int
n=
send
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
ReleaseMutex
(
hMutex);
if
(
n<=
0
) break
;
// attente des données
n=
recv
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
if
(
n>
0
)
{
int
x =
LOBYTE
(
coord);
int
y =
HIBYTE
(
coord);
if
(
x==
MSG_STOP)
{
send
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
break
;
}
SendMessage
(
hwnd, WM_NETEVENT, x, y);
}
else
break
;
}
}
Connect =
FALSE;
SendMessage
(
hstb, SB_SETTEXT, 2
, (
LPARAM)"
Déconnecté
"
);
closesocket
(
sock);
ReleaseMutex
(
hMutex);
WSACleanup
(
);
return
0
;
}
/**
***************************************************************************
*/
DWORD WINAPI thread_server
(
LPVOID lpParam)
{
WSADATA WSAData;
SOCKET socklisten;
SOCKADDR_IN sin;
SOCKADDR_IN cin;
WSAStartup
(
MAKEWORD
(
2
,0
), &
WSAData);
socklisten =
socket
(
AF_INET, SOCK_STREAM, 0
);
sin.sin_addr.s_addr =
INADDR_ANY;
sin.sin_family =
AF_INET;
sin.sin_port =
htons
(
6665
);
bind
(
socklisten, (
SOCKADDR*
)&
sin, sizeof
(
sin));
listen
(
socklisten, 0
);
int
sinsize =
sizeof
(
cin);
SendMessage
(
hstb, SB_SETTEXT, 2
, (
LPARAM)"
En attente de connexion
"
);
SOCKET sock =
accept
(
socklisten, (
SOCKADDR *
)&
cin, &
sinsize);
if
(
sock ==
INVALID_SOCKET) return
0
;
// Connexion du client...
Connect =
TRUE;
SendMessage
(
hstb, SB_SETTEXT, 2
, (
LPARAM)"
Connecté
"
);
while
(
1
)
{
int
n =
recv
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
if
(
n>
0
)
{
int
x =
LOBYTE
(
coord);
int
y =
HIBYTE
(
coord);
if
(
x==
MSG_STOP)
{
send
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
break
;
}
SendMessage
(
hwnd, WM_NETEVENT, x, y);
}
else
break
;
// Envois des données coord;
WaitForSingleObject
(
hMutex, INFINITE);
n=
send
(
sock, (
char
*
)&
coord, sizeof
(
coord), 0
);
ReleaseMutex
(
hMutex);
if
(
n<=
0
) break
;
}
Connect =
FALSE;
SendMessage
(
hstb, SB_SETTEXT, 2
, (
LPARAM)"
Déconnecté
"
);
closesocket
(
sock);
closesocket
(
socklisten);
WSACleanup
(
);
return
0
;
}
/**
***************************************************************************
*/
LRESULT CALLBACK MainWndProc
(
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static
int
tab[NBC_Y][NBC_X];
static
int
joueur;
static
HANDLE hThread;
static
int
heightstb;
switch
(
uMsg)
{
case
WM_CREATE:
{
int
part[]=
{
56
, 140
, -
1
}
;
RECT stbRect;
hstb=
CreateWindow
(
STATUSCLASSNAME, "
Status :
"
,
SBARS_SIZEGRIP|
WS_CHILD|
WS_VISIBLE, 0
, 0
, 0
, 0
, hwnd, 0
, 0
, 0
);
SendMessage
(
hstb, SB_SETPARTS, sizeof
(
part)/
sizeof
(
int
), (
LPARAM)part);
GetWindowRect
(
hstb, &
stbRect);
heightstb =
stbRect.bottom-
stbRect.top;
joueur=
PL_WHITE;
Mode =
SERVER;
hMutex =
CreateMutex
(
NULL
, FALSE, NULL
);
return
0
;
}
case
WM_COMMAND:
if
(
LOWORD
(
wParam) ==
IDM_STOP)
{
coord =
MAKEWORD
(
MSG_STOP, 0
);
ReleaseMutex
(
hMutex);
}
if
(
LOWORD
(
wParam) ==
IDM_NEW &&
Connect ==
FALSE)
{
ZeroMemory
(
tab, sizeof
(
tab));
Init
(
tab);
ReleaseMutex
(
hMutex);
joueur=
PL_WHITE;
if
(
Mode==
CLIENT)
{
WaitForSingleObject
(
hMutex, INFINITE);
SendMessage
(
hstb, SB_SETTEXT, 1
, (
LPARAM)"
Client
"
);
hThread =
CreateThread
(
NULL
, 0
, thread_client, NULL
, 0
, NULL
);
}
else
{
SendMessage
(
hstb, SB_SETTEXT, 1
, (
LPARAM)"
Serveur
"
);
hThread =
CreateThread
(
NULL
, 0
, thread_server, NULL
, 0
, NULL
);
}
InvalidateRect
(
hwnd, NULL
, FALSE);
}
if
(
LOWORD
(
wParam) ==
IDM_PARAM)
DialogBox
(
hinst, "
DIALOG1
"
, hwnd, Dialog1Proc);
if
(
LOWORD
(
wParam) ==
IDM_QUIT) PostMessage
(
hwnd, WM_CLOSE,0
,0
);
if
(
LOWORD
(
wParam) ==
IDM_ABOUT)
MessageBox
(
NULL
, "
Othello par CGi !
"
, "
A Propos !
"
, MB_OK);
return
0
;
case
WM_NETEVENT : // Jeu de l'adversaire
{
int
x =
wParam;
int
y =
lParam;
Play
(
tab, x, y, &
joueur);
WaitForSingleObject
(
hMutex, INFINITE);
InvalidateRect
(
hwnd, NULL
, FALSE);
return
0
;
}
case
WM_LBUTTONUP :
{
if
((
Connect ==
TRUE &&
Mode==
SERVER &&
joueur==
PL_BLACK) ||
(
Connect ==
TRUE &&
Mode==
CLIENT &&
joueur==
PL_WHITE))
{
int
x =
GET_X_LPARAM
(
lParam)/
LARG;
int
y =
GET_Y_LPARAM
(
lParam)/
LARG;
if
(
tab[y][x]==
1
||
tab[y][x]==
2
||
x>=
NBC_X ||
y>=
NBC_Y) return
0
;
int
result =
Play
(
tab, x, y, &
joueur);
if
(
result==
0
) return
0
;
coord =
MAKEWORD
(
x, y);
ReleaseMutex
(
hMutex);
InvalidateRect
(
hwnd, NULL
, FALSE);
}
return
0
;
}
case
WM_MOUSEMOVE:
{
if
((
Connect ==
TRUE &&
Mode==
SERVER &&
joueur==
PL_BLACK) ||
(
Connect ==
TRUE &&
Mode==
CLIENT &&
joueur==
PL_WHITE))
{
static
int
x1, y1;
int
x =
GET_X_LPARAM
(
lParam)/
LARG;
int
y =
GET_Y_LPARAM
(
lParam)/
LARG;
if
(
tab[y1][x1]==
PL_OVER) tab[y1][x1]=
0
;
x1=
x;
y1=
y;
if
(
x<
NBC_X &&
y<
NBC_Y &&
tab[y][x]==
0
) tab[y][x]=
PL_OVER;
InvalidateRect
(
hwnd, NULL
, FALSE);
}
return
0
;
}
case
WM_PAINT:
{
int
i, j;
HPEN hpen, hredpen;
HDC hdc, hdcDB;
HBITMAP bmDB;
PAINTSTRUCT ps;
RECT rect;
HBRUSH hbcase =
CreateSolidBrush
(
0x0040F040
);
hpen =
CreatePen
(
PS_SOLID, 2
, 0x00000000
);
hredpen =
CreatePen
(
PS_SOLID, 2
, 0x00000000
);
GetClientRect
(
hwnd, &
rect);
rect.bottom-=
heightstb;
hdc =
BeginPaint
(
hwnd, &
ps);
hdcDB =
CreateCompatibleDC
(
hdc);
bmDB =
CreateCompatibleBitmap
(
hdc, rect.right, rect.bottom);
SelectObject
(
hdcDB, bmDB);
SelectObject
(
hdcDB,hpen);
SelectObject
(
hdcDB, hbcase);
FillRect
(
hdcDB, &
rect, hbcase);
for
(
j=
0
; j<
NBC_Y; j++
)
for
(
i=
0
; i<
NBC_X; i++
)
{
int
value =
tab[j][i];
Rectangle
(
hdcDB, i*
LARG+
4
, j*
LARG+
4
,
i*
LARG+
LARG+
4
, j*
LARG+
LARG+
4
);
SelectObject
(
hdcDB,hredpen);
if
(
value==
PL_WHITE)
SelectObject
(
hdcDB, GetStockObject
(
WHITE_BRUSH));
if
(
value==
PL_BLACK)
SelectObject
(
hdcDB, GetStockObject
(
BLACK_BRUSH));
if
(
value==
PL_WHITE ||
value==
PL_BLACK)
Ellipse
(
hdcDB, i*
LARG+
8
, j*
LARG+
8
,
i*
LARG+
LARG-
2
, j*
LARG+
LARG-
2
);
if
(
value==
PL_OVER)
{
if
(
joueur==
PL_WHITE)
SelectObject
(
hdcDB, GetStockObject
(
WHITE_BRUSH));
else
SelectObject
(
hdcDB, GetStockObject
(
BLACK_BRUSH));
Ellipse
(
hdcDB, i*
LARG+
24
, j*
LARG+
24
,
i*
LARG+
LARG/
2
+
12
, j*
LARG+
LARG/
2
+
12
);
}
SelectObject
(
hdcDB, hbcase);
SelectObject
(
hdcDB,hpen);
}
BitBlt
(
hdc, 0
, 0
, rect.right, rect.bottom, hdcDB, 0
, 0
, SRCCOPY);
DeleteDC
(
hdcDB);
DeleteObject
(
bmDB);
EndPaint
(
hwnd, &
ps);
DeleteObject
(
hbcase);
DeleteObject
(
hpen);
DeleteObject
(
hredpen);
return
0
;
}
case
WM_ERASEBKGND:
// not drawing the background.
return
0
;
case
WM_CLOSE :
CloseHandle
(
hMutex);
WaitForSingleObject
(
hThread, 200
);
DestroyWindow
(
hwnd);
return
0
;
case
WM_DESTROY:
PostQuitMessage
(
0
);
return
0
;
default
:
return
DefWindowProc
(
hwnd, uMsg, wParam, lParam);
}
}
/**
***************************************************************************
*/
BOOL APIENTRY Dialog1Proc
(
HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch
(
uMsg)
{
case
WM_INITDIALOG:
SetDlgItemText
(
hDlg, IDC_IPADDRESS1, IP_address);
if
(
Mode ==
SERVER)
{
CheckDlgButton
(
hDlg, IDC_RADIO1, BST_CHECKED);
EnableWindow
(
GetDlgItem
(
hDlg,IDC_IPADDRESS1),FALSE);
}
else
{
CheckDlgButton
(
hDlg, IDC_RADIO2, BST_CHECKED);
EnableWindow
(
GetDlgItem
(
hDlg,IDC_IPADDRESS1),TRUE);
}
return
TRUE;
case
WM_COMMAND:
if
(
LOWORD
(
wParam) ==
IDC_RADIO2)
{
EnableWindow
(
GetDlgItem
(
hDlg,IDC_IPADDRESS1),TRUE);
return
TRUE;
}
if
(
LOWORD
(
wParam) ==
IDC_RADIO1)
{
EnableWindow
(
GetDlgItem
(
hDlg,IDC_IPADDRESS1),FALSE);
return
TRUE;
}
if
(
LOWORD
(
wParam) ==
IDOK )
{
if
(
IsDlgButtonChecked
(
hDlg, IDC_RADIO1) ==
BST_CHECKED) Mode=
SERVER;
else
Mode=
CLIENT;
GetWindowText
(
GetDlgItem
(
hDlg,IDC_IPADDRESS1), IP_address, 16
);
EndDialog
(
hDlg,0
);
return
TRUE;
}
if
(
LOWORD
(
wParam) ==
IDCANCEL)
{
EndDialog
(
hDlg,0
);
return
TRUE;
}
default
:
return
FALSE;
}
}
/**
***************************************************************************
*/
int
Play
(
int
tab[NBC_Y][NBC_X], int
x, int
y, int
*
joueur)
{
int
valide =
0
;
int
advers;
if
(*
joueur==
PL_WHITE) advers=
PL_BLACK;
else
advers=
PL_WHITE;
int
cpt=
1
;
while
(
tab[y][x+
cpt]==
advers &&
(
x+
cpt)<
7
) cpt++
;
if
(
tab[y][x+
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y][x+
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y][x-
cpt]==
advers &&
(
x-
cpt)>
0
) cpt++
;
if
(
tab[y][x-
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y][x-
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y+
cpt][x]==
advers &&
(
y+
cpt)<
7
) cpt++
;
if
(
tab[y+
cpt][x]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y+
cpt][x]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y-
cpt][x]==
advers &&
(
y-
cpt)>
0
) cpt++
;
if
(
tab[y-
cpt][x]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y-
cpt][x]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y+
cpt][x+
cpt]==
advers &&
(
x+
cpt)<
7
&&
(
y+
cpt)<
7
) cpt++
;
if
(
tab[y+
cpt][x+
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y+
cpt][x+
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y+
cpt][x-
cpt]==
advers &&
(
x-
cpt)>
0
&&
(
y+
cpt)<
7
) cpt++
;
if
(
tab[y+
cpt][x-
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y+
cpt][x-
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y-
cpt][x+
cpt]==
advers &&
(
x+
cpt)<
7
&&
(
y-
cpt)>
0
) cpt++
;
if
(
tab[y-
cpt][x+
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y-
cpt][x+
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
cpt=
1
;
while
(
tab[y-
cpt][x-
cpt]==
advers &&
(
x-
cpt)>
0
&&
(
y-
cpt)>
0
) cpt++
;
if
(
tab[y-
cpt][x-
cpt]==*
joueur &&
cpt>
1
)
{
while
(
cpt>
0
)
{
tab[y-
cpt][x-
cpt]=*
joueur;
cpt--
;
}
valide=
1
;
}
if
(
valide==
1
)
{
tab[y][x]=*
joueur;
if
(*
joueur==
PL_WHITE) *
joueur=
PL_BLACK;
else
*
joueur=
PL_WHITE;
}
return
valide;
}
/**
***************************************************************************
*/
void
Init
(
int
tab[NBC_Y][NBC_X])
{
tab[3
][3
]=
PL_WHITE;
tab[3
][4
]=
PL_BLACK;
tab[4
][3
]=
PL_BLACK;
tab[4
][4
]=
PL_WHITE;
}
/**
***************************************************************************
*/
int
WINAPI WinMain
(
HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int
nCmdShow)
{
MSG msg;
WNDCLASS wc;
hinst =
hinstance;
wc.style =
0
;
wc.lpfnWndProc =
MainWndProc;
wc.cbClsExtra =
0
;
wc.cbWndExtra =
0
;
wc.hInstance =
hinstance;
wc.hIcon =
LoadIcon
(
NULL
, IDI_APPLICATION);
wc.hCursor =
LoadCursor
(
NULL
, IDC_ARROW);
wc.hbrBackground =
(
HBRUSH)(
COLOR_WINDOW+
1
);
wc.lpszMenuName =
"
LEMENU
"
;
wc.lpszClassName =
"
WinClassMain
"
;
if
(!
RegisterClass
(&
wc)) return
FALSE;
InitCommonControls
(
);
hwnd =
CreateWindow
(
"
WinClassMain
"
, "
Othello
"
,
WS_SYSMENU |
WS_CAPTION |
WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
LARG*
NBC_X+
10
, LARG*
NBC_Y+
80
, NULL
, NULL
, hinstance, NULL
);
if
(!
hwnd) return
FALSE;
ShowWindow
(
hwnd, nCmdShow);
UpdateWindow
(
hwnd);
while
(
GetMessage
(&
msg, NULL
, 0
, 0
))
{
TranslateMessage
(&
msg);
DispatchMessage
(&
msg);
}
return
msg.wParam;
}
À vos compilateurs.