home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume15
/
xdemineur
/
part01
/
main.c
next >
Wrap
C/C++ Source or Header
|
1993-01-27
|
18KB
|
484 lines
/* ********************************************************************** */
/* */
/* xdemineur - Jeu de reflexion sous X, version 1.0 */
/* */
/* Copyright : Marc Baudoin (baudoin@ensta.fr) */
/* */
/* |\ */
/* |\| \ */
/* |// ) */
/* |\ / / /\/\_ */
/* |// / /. . / */
/* |\ / / ___/ |_ */
/* |// / (____/ /_/\_ */
/* |__| (_____/ __ > */
/* /| ___ ________ _< \ \__ > */
/* \|| __\| _|_ _/ \\ \___\/ */
/* | __\____ | |/ _ \\ > */
/* /||___\_____|___/ \_\\ _> */
/* \|____ ____ \| */
/* \ \_________/ / */
/* \ _ _ / */
/* \_// //_____/ */
/* (_ \ (_ _\ */
/* |/\| \/ */
/* */
/* Ecole Nationale Superieure de Techniques Avancees (ENSTA) */
/* 32, boulevard Victor - 75015 Paris - France */
/* */
/* Vous avez le droit d'utiliser et de distribuer xdemineur et sa */
/* documentation pourvu que cette notice de copyright apparaisse sur */
/* toutes les copies et que vous ne tiriez aucun profit de mon programme. */
/* */
/* ********************************************************************** */
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "demineur.h"
#include "xdemineur.h"
#include "bitmaps/xdemineur.bm"
extern struct jeu **tableau ;
extern int nb_lig , nb_col , nb_mines ;
extern time_t temps ;
extern BOOLEAN perdu , gagne , jeu , ouvre ;
Display *display ;
int screen ;
Window window ;
GC gc ;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Programme principal ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
main ( argc , argv )
int argc ;
char *argv [ ] ;
{
int i ;
char *display_name = NULL ;
Bool option_m = False ;
char *window_title = "Demineur" , *icon_title = "Demineur" ;
XTextProperty window_name , icon_name ;
Pixmap icon_bitmap ;
XSizeHints size_hints ;
XWMHints wm_hints ;
XClassHint class_hint ;
Atom protocol [ 1 ] ;
time_t ref , courant , ancien ;
XEvent event ;
int lig , col , l , c , bouton = 0 ;
enum { CASE , DOUBLE_CLIC , ICONE , RIEN } quoi ;
Bool focus = False ;
Region region ;
XRectangle rectangle ;
nb_mines = NB_MINES ;
/* arguments de la ligne de commande */
for ( i = 1 ; i < argc ; i ++ )
{
if ( strcmp ( argv [ i ] , "-display" ) == 0 )
{
display_name = argv [ ++ i ] ;
}
else if ( strcmp ( argv [ i ] , "-l" ) == 0 )
{
nb_lig = atoi ( argv [ ++ i ] ) ;
if ( nb_lig < 5 )
{
nb_lig = 5 ;
}
if ( ! option_m )
{
nb_mines = NB_MINES ;
}
}
else if ( strcmp ( argv [ i ] , "-c" ) == 0 )
{
nb_col = atoi ( argv [ ++ i ] ) ;
if ( nb_col < 10 )
{
nb_col = 10 ;
}
if ( ! option_m )
{
nb_mines = NB_MINES ;
}
}
else if ( strcmp ( argv [ i ] , "-m" ) == 0 )
{
option_m = True ;
nb_mines = atoi ( argv [ ++ i ] ) ;
if ( nb_mines >= nb_lig * nb_col )
{
nb_mines = NB_MINES ;
}
}
else if ( strcmp ( argv [ i ] , "-ouvre" ) == 0 )
{
ouvre = TRUE ;
}
else
{
fprintf ( stderr ,
"Usage: xdemineur [-display display] [-l lignes] [-c colonnes] [-m mines]\n" ) ;
fprintf ( stderr ,
" [-ouvre]\n" ) ;
exit ( 1 ) ;
}
}
/* initialisation de X */
if ( ( display = XOpenDisplay ( display_name ) ) == NULL )
{
fprintf ( stderr , "%s : impossible de se connecter au serveur X.\n" ,
argv [ 0 ] ) ;
exit ( 1 ) ;
}
screen = DefaultScreen ( display ) ;
while ( HAUTEUR_FEN > DisplayHeight ( display , screen ) )
{
nb_lig -- ;
if ( ! option_m )
{
nb_mines = NB_MINES ;
}
}
while ( LARGEUR_FEN > DisplayWidth ( display , screen ) )
{
nb_col -- ;
if ( ! option_m )
{
nb_mines = NB_MINES ;
}
}
window = XCreateSimpleWindow ( display , RootWindow ( display , screen ) ,
X_FEN , Y_FEN , LARGEUR_FEN , HAUTEUR_FEN , 2 ,
BlackPixel ( display , screen ) ,
WhitePixel ( display , screen ) ) ;
XSelectInput ( display , window , ButtonPressMask | ButtonReleaseMask |
FocusChangeMask | ExposureMask ) ;
XStringListToTextProperty ( &window_title , 1 , &window_name ) ;
XStringListToTextProperty ( &icon_title , 1 , &icon_name ) ;
icon_bitmap = XCreateBitmapFromData ( display , RootWindow ( display , screen ) ,
xdemineur_bits ,
xdemineur_width , xdemineur_height ) ;
size_hints . flags = USPosition | PSize | PMinSize | PMaxSize ;
size_hints . min_width = size_hints . max_width = LARGEUR_FEN ;
size_hints . min_height = size_hints . max_height = HAUTEUR_FEN ;
wm_hints . flags = InputHint | StateHint | IconPixmapHint ;
wm_hints . input = True ;
wm_hints . initial_state = NormalState ;
wm_hints . icon_pixmap = icon_bitmap ;
class_hint . res_name = argv [ 0 ] ;
class_hint . res_class = "XDemineur" ;
XSetWMProperties ( display , window ,
&window_name , &icon_name ,
argv , argc ,
&size_hints , &wm_hints , &class_hint ) ;
protocol [ 0 ] = XInternAtom ( display , "WM_DELETE_WINDOW" , False ) ;
XSetWMProtocols ( display , window , protocol , 1 ) ;
gc = XCreateGC ( display , window , 0 , NULL ) ;
XSetForeground ( display , gc , BlackPixel ( display , screen ) ) ;
XSetBackground ( display , gc , WhitePixel ( display , screen ) ) ;
cree_pixmaps ( ) ;
XMapWindow ( display , window ) ;
/* initialisation du jeu */
/* on rajoute deux rangees supplementaires pour ne pas avoir a s'occuper *
* des effets de bord lors du comptage du nombre de mines adjacentes */
tableau = ( struct jeu ** ) malloc ( ( nb_lig + 2 ) *
sizeof ( struct jeu * ) ) ;
for ( i = 0 ; i < nb_lig + 2 ; i ++ )
{
tableau [ i ] = ( struct jeu * ) malloc ( ( nb_col + 2 ) *
sizeof ( struct jeu ) );
}
remplis_et_compte ( ) ;
/* le jeu */
region = XCreateRegion ( ) ;
while ( True )
{
while ( XPending ( display ) )
{
XNextEvent ( display , &event ) ;
switch ( event . type )
{
case ButtonPress :
bouton ++ ;
if ( event . xbutton . y >= Y_ICONE &&
event . xbutton . y <= Y_ICONE + HAUT_ICONE &&
event . xbutton . x >= X_ICONE &&
event . xbutton . x <= X_ICONE + LARG_ICONE &&
event . xbutton . button == Button1 &&
bouton == 1 ) /* nouveau jeu */
{
quoi = ICONE ;
icone_activee ( ) ;
}
else if ( event . xbutton . x > X_JEU &&
event . xbutton . x < X_JEU + LARG_JEU &&
event . xbutton . y > Y_JEU &&
event . xbutton . y < Y_JEU + HAUT_JEU &&
! perdu && ! gagne )
{
if ( ( event . xbutton . x - X_JEU ) % ( LARG_CASE + 1 ) == 0 ||
( event . xbutton . y - Y_JEU ) % ( HAUT_CASE + 1 ) == 0 )
{
quoi = RIEN ; /* on a clique sur une ligne donc on ne fait rien */
}
else
{
icone_joue ( ) ;
lig = 1 + ( event . xbutton . y - Y_JEU ) / ( HAUT_CASE + 1 ) ;
col = 1 + ( event . xbutton . x - X_JEU ) / ( LARG_CASE + 1 ) ;
if ( event . xbutton . button == Button1 &&
tableau [ lig ] [ col ] . etat != DECOUVERTE &&
tableau [ lig ] [ col ] . etat != MARQUEE &&
bouton == 1 )
{
quoi = CASE ;
case_vide ( lig , col ) ;
}
else if ( tableau [ lig ] [ col ] . etat == DECOUVERTE &&
bouton == 2 )
{
quoi = DOUBLE_CLIC ;
cases_vides ( lig , col ) ;
}
else if ( event . xbutton . button == Button3 &&
tableau [ lig ] [ col ] . etat != DECOUVERTE &&
bouton == 1 )
{
quoi = CASE ;
marque ( lig , col ) ;
if ( ! jeu && ! gagne && ! perdu )
{
jeu = TRUE ;
ancien = ref = time ( 0 ) ;
}
}
else
{
quoi = RIEN ;
}
}
}
else
{
quoi = RIEN ;
}
break ;
case ButtonRelease :
bouton -- ;
if ( bouton != 0 )
{
break ;
}
if ( event . xbutton . y >= Y_ICONE &&
event . xbutton . y <= Y_ICONE + HAUT_ICONE &&
event . xbutton . x >= X_ICONE &&
event . xbutton . x <= X_ICONE + LARG_ICONE &&
event . xbutton . button == Button1 &&
quoi == ICONE ) /* nouveau jeu */
{
remplis_et_compte ( ) ;
affiche_jeu ( ) ;
}
else if ( quoi == ICONE )
{
icone_perdu_gagne ( ) ;
}
if ( ( event . xbutton . y < Y_JEU ||
event . xbutton . y > Y_JEU + HAUT_JEU ||
event . xbutton . x < X_JEU ||
event . xbutton . x > X_JEU + LARG_JEU ) &&
quoi == CASE )
{
affiche_case ( lig , col ) ;
}
else if ( event . xbutton . x > X_JEU &&
event . xbutton . x < X_JEU + LARG_JEU &&
event . xbutton . y > Y_JEU &&
event . xbutton . y < Y_JEU + HAUT_JEU &&
! perdu && ! gagne &&
event . xbutton . button == Button1 &&
quoi == CASE )
{
if ( ( event . xbutton . y - Y_JEU ) % ( HAUT_CASE + 1 ) == 0 ||
( event . xbutton . x - X_JEU ) % ( LARG_CASE + 1 ) == 0 )
{
affiche_case ( lig , col ) ; /* on a clique sur une ligne donc on ne fait rien */
}
else
{
l = 1 + ( event . xbutton . y - Y_JEU ) / ( HAUT_CASE + 1 ) ;
c = 1 + ( event . xbutton . x - X_JEU ) / ( LARG_CASE + 1 ) ;
if ( tableau [ lig ] [ col ] . etat != DECOUVERTE &&
tableau [ lig ] [ col ] . etat != MARQUEE &&
lig == l && col == c )
{
joue ( lig , col ) ;
if ( ! jeu && !gagne && ! perdu )
{
jeu = TRUE ;
ancien = ref = time ( 0 ) ;
}
}
else
{
affiche_case ( lig , col ) ;
}
}
}
else if ( ( event . xbutton . y < Y_JEU ||
event . xbutton . y > Y_JEU + HAUT_JEU ||
event . xbutton . x < X_JEU ||
event . xbutton . x > X_JEU + LARG_JEU ) &&
quoi == DOUBLE_CLIC )
{
affiche_bloc ( lig , col ) ;
}
else if ( event . xbutton . x > X_JEU &&
event . xbutton . x < X_JEU + LARG_JEU &&
event . xbutton . y > Y_JEU &&
event . xbutton . y < Y_JEU + HAUT_JEU &&
! perdu && ! gagne &&
quoi == DOUBLE_CLIC )
{
if ( ( event . xbutton . y - Y_JEU ) % ( HAUT_CASE + 1 ) == 0 ||
( event . xbutton . x - X_JEU ) % ( LARG_CASE + 1 ) == 0 )
{
affiche_bloc ( lig , col ) ; /* on a clique sur une ligne donc on ne fait rien */
}
else
{
l = 1 + ( event . xbutton . y - Y_JEU ) / ( HAUT_CASE + 1 ) ;
c = 1 + ( event . xbutton . x - X_JEU ) / ( LARG_CASE + 1 ) ;
if ( tableau [ lig ] [ col ] . etat == DECOUVERTE &&
tableau [ lig ] [ col ] . nombre ==
nombre_de_drapeaux ( lig , col ) &&
lig == l && col == c )
{
double_clic ( lig , col ) ;
}
else
{
affiche_bloc ( lig , col ) ;
}
}
}
icone_perdu_gagne ( ) ;
break ;
case FocusIn :
focus = True ;
ref = time ( 0 ) - temps ;
break ;
case FocusOut :
focus = False ;
break ;
case Expose :
rectangle . x = ( short ) event . xexpose . x ;
rectangle . y = ( short ) event . xexpose . y ;
rectangle . width = ( unsigned short ) event . xexpose . width ;
rectangle . height = ( unsigned short ) event . xexpose . height ;
XUnionRectWithRegion ( &rectangle , region , region ) ;
if ( event . xexpose . count == 0 )
{
XSetRegion ( display , gc , region ) ;
affiche_jeu ( ) ;
XSetClipMask ( display , gc , None ) ;
XDestroyRegion ( region ) ;
region = XCreateRegion ( ) ;
}
break ;
case ClientMessage :
if ( event . xclient . data . l [ 0 ] == protocol [ 0 ] )
{
for ( i = 0 ; i < nb_lig + 2 ; i ++ )
{
free ( tableau [ i ] ) ;
}
free ( tableau ) ;
detruit_pixmaps ( ) ;
XDestroyWindow ( display , window ) ;
XCloseDisplay ( display ) ;
exit ( 0 ) ;
}
break ;
}
}
if ( jeu && focus )
{
courant = time ( 0 ) ;
if ( ancien != courant )
{
ancien = courant ;
temps = courant - ref ;
if ( temps > 999 )
{
temps %= 1000 ;
}
chronometre ( ) ;
}
}
}
}
int nombre_de_drapeaux ( lig , col )
int lig , col ;
{
return ( drapeau01 ( lig - 1 , col - 1 ) +
drapeau01 ( lig - 1 , col ) +
drapeau01 ( lig - 1 , col + 1 ) +
drapeau01 ( lig , col - 1 ) +
drapeau01 ( lig , col + 1 ) +
drapeau01 ( lig + 1 , col - 1 ) +
drapeau01 ( lig + 1 , col ) +
drapeau01 ( lig + 1 , col + 1 ) ) ;
}
int drapeau01 ( lig , col )
int lig , col ;
{
return ( ( tableau [ lig ] [ col ] . etat == MARQUEE ) ? 1 : 0 ) ;
}