/****************/ /* tictac.cpp */ /****************/ // Esimerkki pelistä jossa piirretään nappuloita. // Projektiin tictac.cpp, tictac.rc // Vesa Lappalainen 4.11.1996-6.11.1996 // Muutoksia: 7.11.1996 ix<->iy taulukoissa // Buttoneita käyttävä toteutus. Edullinen jos nappulat piirretään .RC:ssä // - ongelma oli monen WM_COMMANDin käsittely. MFC:ssä olisi ollut // ON_COMMAND_RANGE // Tehtäviä: // 1) Voittajan tarkistus // 2) Muuta ohjelma sellaiseksi, että on vain yksi "pitkä" bittikartta, // josta "poimitaan" Draw-metodissa nappulan "oikea" kuva. #include #include #include "tictac.rh" const int MAX_NX = 9; const int MAX_NY = 9; const int MAX_PELAAJIA = 2; #define NAPPIID(ix,iy) (1000*(iy)+(ix)+1000) //------------------------------------------------------------------------------ // Luokka, joka osaa muttua ID <-> x,y ja ix,iy class TId { int ix,iy; // index x,y (0-3) static int koko; static TPoint origo; public: TId(int aix,int aiy) { ix = aix; iy = aiy; } TId(int n) { ix = (n-1000)%1000; iy = (n-1000)/1000; } operator int() const { return 1000*iy+ix+1000; } int OK(int nx=10,int ny=10) const { return (0<=ix && ixSize().cx,b->Size().cy,SRCCOPY); } void SetType(int t) { type = t; Invalidate(); } int Type() { return type; } }; //------------------------------------------------------------------------------ class TLauta { int nx,ny; TNappi *lauta[MAX_NX][MAX_NY]; TBitmap *bmps[MAX_PELAAJIA+1]; TWindow *Wnd; int pelaaja; protected: void CreateButtons(); void DeleteButtons(); public: TLauta(TWindow *awnd,int anx=3,int any=3); ~TLauta(); void uusi(int unx=0,int uny=0) { DeleteButtons(); if ( unx != 0 && uny != 0 ) { nx = unx; ny = uny; } CreateButtons(); } int Draw(TDC &dc,int id) { TId bid(id); if ( !bid.OK(nx,ny) ) return -1; lauta[bid.iny()][bid.inx()]->Draw(dc); return 0; } int Hit(int id) { TId bid(id); if ( !bid.OK(nx,ny) ) return -1; TNappi *nap=lauta[bid.iny()][bid.inx()]; if ( nap->Type() != 0 ) return 0; nap->SetType(pelaaja+1); pelaaja++; if ( pelaaja >= MAX_PELAAJIA ) pelaaja = 0; return 0; } }; TLauta::TLauta(TWindow *awnd,int anx,int any) : nx(anx), ny(any), Wnd(awnd) { pelaaja = 0; const TModule &module(*Wnd->GetModule()); for (int i=0; i= MAX_NX ) nx = MAX_NX-1; if ( ny >= MAX_NY ) ny = MAX_NY-1; for (int iy=0; iyCreateChildren(); // Jos tämä on täällä, ei saa kutsua konstruktorissa } // jollei ole, PITÄÄ kutsua!!! void TLauta::DeleteButtons() { for (int iy=0; iyuusi(); } void Cm3x3() { lauta->uusi(3,3); } void Cm4x4() { lauta->uusi(4,4); } void EvDrawItem(uint ctrlId, DRAWITEMSTRUCT far& drawInfo) { lauta->Draw(TDC(drawInfo.hDC),ctrlId); } void Hit(WPARAM id) { lauta->Hit(id); } // Määritellään koko WM_COMMAND -viestinkäsittely uudelleen!!! virtual TResult EvCommand(uint id, THandle hWndCtl, uint notifyCode) { if ( notifyCode == 0 && lauta->Hit(id) == 0 ) return 0; return TDialog::EvCommand(id,hWndCtl,notifyCode); } DECLARE_RESPONSE_TABLE(TTicTacDialog); }; DEFINE_RESPONSE_TABLE1(TTicTacDialog, TDialog) EV_COMMAND(CM_GAMEEXIT ,CmExit), EV_COMMAND(CM_GAMENEW ,CmNew), EV_COMMAND(CM_GAME_3x3 ,Cm3x3), EV_COMMAND(CM_GAME_4x4 ,Cm4x4), // EV_COMMAND_AND_ID(NAPPIID(0,0) ,Hit), // Tämä olisi liian työlästä!!! // EV_COMMAND_AND_ID(NAPPIID(1,0) ,Hit), // EV_COMMAND_AND_ID(NAPPIID(3,3) ,Hit), EV_WM_DRAWITEM, END_RESPONSE_TABLE; //------------------------------------------------------------------------------ class TTicTacApp : public TApplication { public: TTicTacApp(const char *title) : TApplication(title) {} void InitMainWindow() { TDecoratedFrame *fw = new TDecoratedFrame(0, Name, new TTicTacDialog(0, IDD_TICTAC) ); fw->SetFlag(wfShrinkToClient); fw->AssignMenu(IDM_PAAMENU); fw->SetIcon(this, IDI_IKONI); fw->SetIconSm(this, IDI_IKONI); SetMainWindow(fw); } }; /********************* Pääohjelma *********************************************/ int OwlMain(int ,char far * []) { return TTicTacApp("TicTacToe").Run(); }