// This may look like C code, but it is really -*- C++ -*- /////////////////////////////////////////////////////////////////////////// // // AMIGA Minesweeper - Definition of the Field-object // // (c) 1992 Hubert Feyrer (c9020@rrzc1.rz.uni-regensburg.de) // /////////////////////////////////////////////////////////////////////////// #define class _class #define IntuitionBase IntuiBase #define GfxBase GraphBase extern "C" { # include # include # include # include # include # include # include # include # include } #define IntuitionBase IntuitionBase #define GfxBase GfxBase #define class class #include "mine.h" #include "field.h" Gadget *Field::lastgad=NULL; // Wird in main() auf Ergebnis // von CreateContext() gesetzt! // // Klassendefinition für ein Feld des Mine-Programmes // Field::Field(int x, int y, int i, int j){ static struct NewGadget ngad={ -1,-1,-1,-1, /* x, y, w, h */ NULL, /* ng_GadgetText */ NULL, /* font */ 0, /* gadget-id */ PLACETEXT_IN, /* flags */ NULL, /* von GetVisualInfo() */ NULL /* userdata */ }; ngad.ng_VisualInfo = vinfo; ngad.ng_TextAttr = scr->Font; (ngad.ng_GadgetText = strcpy(txt," "))[0]=BLANK; ngad.ng_LeftEdge = x; ngad.ng_TopEdge = y; ngad.ng_Width = fxs; ngad.ng_Height = fys; lastgad=_gad=CreateGadget(BUTTON_KIND,lastgad,&ngad,TAG_END); if(_gad==NULL){ fprintf(stderr,"Field::Field(%d,%d): Fehler in " "CreateGadget()!\n",x,y); shutdown(20); } _gad->Flags &= ~GFLG_SELECTED; _gad->UserData = (APTR)this; _cnt=0; // Anzahl Nachbarminen; später! _open=0; // nicht aufgedeckt _i=i; // Spalte im minefield[][] _j=j; // Zeile im minefield[][] countdown++; // 1 Feld mehr zu erforschen } Field::~Field(void) { // Nichts zu tun??? } //* //* Feld in Ausgangszustand versetzen //* void Field::clear(void) { _open=0; _gad->Flags &= ~GFLG_SELECTED; _cnt=0; txt[0]=BLANK; } //* //* Feld aufdecken //* void Field::open(int show=0) { if(!_open){ long pos = RemoveGadget(win,_gad); _open=1; if(show){ if(_cnt==-1){ _gad->Flags &= ~GFLG_SELECTED; txt[0]=BOMB; }else{ _gad->Flags |= GFLG_SELECTED; if(!isdigit(txt[0])) txt[0]=BLANK; } }else{ _gad->Flags |= GFLG_SELECTED; switch(_cnt){ case -1: txt[0] = BOMB; break; case 0: txt[0] = BLANK; break; default: txt[0] = NUM+_cnt; } } AddGadget(win,_gad,pos); RefreshGList(_gad,win,NULL,1); } } //* //* Feld überprüfen; force==1: auch markierte Felder //* GameStat Field::check(int force=0) { if(txt[0]==BLANK || force){ if(!_open){ if(_cnt==-1) return GAME_LOST; // BUMM! if(force && txt[0]==MARK && _cnt!=-1) minesleft++; open(); if(_cnt==0){ // rekursives check()en... for(int v=0;v<8;v++){ int vi=_i+validfields[v].dx; int vj=_j+validfields[v].dy; if(inminefield(vi,vj)){ Field *m=minefield[vi][vj]; if(m->cnt()!=-1 && !m->_open){ // *** Rekursion *** // minefield[vi][vj]->check(1); sprintf(tnumgad,"%04d",minesleft); if(tnumgad[0]=='0') tnumgad[0]=' '; GT_SetGadgetAttrs(numgad,win,NULL, GTTX_Text,tnumgad, TAG_END); } } } } countdown--; // 1 Feld weniger zum Sieg if(countdown==0) return GAME_WON; } } return GAME_CONT; } GameStat Field::mark(void) { if(!_open){ char *t=txt; // Markierung setzen/löschen long pos = RemoveGadget(win,_gad); *t = (*t==BLANK)?MARK:BLANK; AddGadget(win,_gad,pos); RefreshGList(_gad,win,NULL,1); minesleft+=(*t==MARK)?-1:1; sprintf(tnumgad,"%04d",minesleft); if(tnumgad[0]=='0') tnumgad[0]=' '; GT_SetGadgetAttrs(numgad,win,NULL, GTTX_Text,tnumgad, TAG_END); RefreshGList(numgad,win,NULL,1); if(_cnt==-1){ if(*t==MARK) countdown--; // 1 Feld weniger zum Sieg... else countdown++; // ...oder mehr! if(countdown==0) return GAME_WON; } } return GAME_CONT; }