/********************************************************************* PROGRAM: WCDBRK2.C PURPOSE: Code Break game AUTHOR: Ken Fogel Omnibus Systems 8108 Norfolk Road Cote St-Luc, Qu‚bec Canada H4X 1A3 (514) 487-1565 CompuServe: 74646,2157 REVISION: June 1, 1991 - Version 2 Full Colour/Bitmaps April 22, 1991 - Version 1.01 April 15, 1991 - Version 1 *********************************************************************/ #include /* required for all Windows applications */ #include #include #include #include #include "wcdbrk2.h" /* specific to this program */ HANDLE hInst; /* current instance */ HWND hGameGrid[10][4]; /* array of buttons */ int board[10][4]; /* array of guesses */ int code[4]; /* secret code */ char clues[10][4]; /* array of clues */ int cur_round; /* current row */ int cur_column; /* current column */ char str[80]; /* general purpose string */ HWND DidIGetItRight; BOOL Setup; BITMAP Bitmap; HBITMAP hOldBitmap; HBITMAP hBoardmap; HBITMAP hBlclpegmap; HBITMAP hWhclpegmap; HBITMAP hPegBoardmap; LPSTR lpPegs[8] = {"Bluepeg","Dkpupeg","Grenpeg","Ltblpeg", "Oranpeg","Purppeg","Redpeg","Yellpeg"}; HBITMAP hPegs[8]; int iXpos,iYpos; int curcolour = 0; int prevcolour = -1; int winstate; /*********************************************************************/ int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) HANDLE hInstance; /* current instance */ HANDLE hPrevInstance; /* previous instance */ LPSTR lpCmdLine; /* command line */ int nCmdShow; /* show-window type (open/icon) */ { MSG msg; /* message */ Setup = FALSE; if (!hPrevInstance) /* Other instances of app running? */ if (!InitApplication(hInstance)) /* Initialize shared things */ return (FALSE); /* Exits if unable to initialize */ /* Perform initializations that apply to a specific instance */ if (!InitInstance(hInstance, nCmdShow)) return (FALSE); /* Aquire and dispatch messages until a WM_QUIT message is recieved */ while (GetMessage(&msg, /* message structure */ NULL, /* handle of window recieving the message */ NULL, /* lowest message to examine */ NULL)) /* highest message to examine */ { TranslateMessage(&msg); /* Translates virtual key codes */ DispatchMessage(&msg); /* Dispatches message to window */ } return(msg.wParam); /* Returns the value from PostQuitMessage */ } /*********************************************************************/ BOOL InitApplication(hInstance) HANDLE hInstance; /* current instance */ { WNDCLASS wc; /* Fill in window class structure with parameters that describe the */ /* main window. */ wc.style = CS_DBLCLKS; /* Class style(s). */ wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for */ /* windows of this class */ wc.cbClsExtra = 0; /* No per-class extra data */ wc.cbWndExtra = 0; /* No per-window extra data */ wc.hInstance = hInstance; /* Application that owns the class. */ wc.hIcon = LoadIcon(hInstance, "Wcdbrk2"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "WndCdBrkMenu"; /* Name of menu resource in .RC file */ wc.lpszClassName = "WndCdBrkWClass";/* Name used in call to CreateWindow */ /* Register the window class and return success/failure code */ return (RegisterClass(&wc)); } /*********************************************************************/ BOOL InitInstance(hInstance, nCmdShow) HANDLE hInstance; /* Current instance identifier */ int nCmdShow; /* Param for first ShowWindow() call */ { HWND hWnd; /* Main window handle */ hInst = hInstance; /* Create a main window for this application instance */ hWnd = CreateWindow( "WndCdBrkWClass", /* See RegisterClass() call */ "Code Breaker II", /* Text for window title bar */ /* The following line creates a window which can be */ /* minimized to an icon and moved but not re-sized */ WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, 120, /* Initial column */ 30, /* Initial row */ 230, /* Width */ 435, /* Height */ NULL, /* Overlapped windows have no parent */ NULL, /* Use the window class menu */ hInstance, /* This instance owns this window */ NULL /* Pointer not needed */ ); /* If window could not be created, return "failure" */ if (!hWnd) return (FALSE); /* Make the window visible; update its client area; and return "success" */ ShowWindow(hWnd, nCmdShow); /* Show the window */ UpdateWindow(hWnd); /* Sends WM_PAINT message */ return (TRUE); /* Returns the value from POSTQUITMESSAGE */ } /*********************************************************************/ long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam) HWND hWnd; /* window handle */ unsigned message; /* type of message */ WORD wParam; /* additional information */ LONG lParam; /* additional information */ { FARPROC lpProcAbout; /* pointer to the "About" function */ int x,y; switch (message) { case WM_CREATE: if (!Setup) /* Do this only once */ { hBoardmap = LoadBitmap(hInst,"Board"); hPegBoardmap = LoadBitmap(hInst,"Pegboard"); hBlclpegmap = LoadBitmap(hInst,"Blclpeg"); hWhclpegmap = LoadBitmap(hInst,"Whclpeg"); for (x=0;x<8;x++) hPegs[x] = LoadBitmap(hInst,lpPegs[x]); if(!bMakeGameButtons(hWnd)) { MessageBox(hWnd,"Failure to create buttons!",NULL, MB_OK | MB_ICONHAND); } Setup = TRUE; } vInitialize(); vMakecode(); break; case WM_LBUTTONUP: /* Mouse button was pressed */ iXpos = LOWORD(lParam); iYpos = HIWORD(lParam); if (bCheckPosition(hWnd)) { board[cur_round][cur_column] = curcolour; vPutPeg(hWnd,curcolour,cur_round,cur_column); } break; case WM_PAINT: /* Time to repaint */ vBasicScreen(hWnd); vMarkColour(hWnd); for (x=0;x<=cur_round;x++) { for (y=0;y<4;y++) vPutPeg(hWnd,board[x][y],x,y); vDoClues(hWnd,x); } if (winstate == 1) vDoWin(hWnd); else if (winstate == 2) vDoLoose(hWnd); break; case WM_COMMAND: /* message: command from application menu */ switch(wParam) { case DIDIGETITRIGHT: if (!winstate) /* If won or lost ignore commands */ { if (!bCheckfill()) break; if (bCheckguess(cur_round)) { vDoWin(hWnd); break; } else { vDoClues(hWnd,cur_round); cur_round++; if (cur_round == 10) /* You loose */ vDoLoose(hWnd); } } break; case IDM_ABOUT: lpProcAbout = MakeProcInstance(About, hInst); DialogBox(hInst, /* current instance */ "AboutBox", /* resource to use */ hWnd, /* parent handle */ lpProcAbout); /* About() instance address */ FreeProcInstance(lpProcAbout); break; case IDM_NEW: /* Let's play again */ InvalidateRect(hWnd, NULL, TRUE); SendMessage(hWnd,WM_CREATE,NULL,NULL); break; case IDM_GIVEUP: vDoLoose(hWnd); break; case IDM_HELP: lpProcAbout = MakeProcInstance(About, hInst); DialogBox(hInst, /* current instance */ "HelpBox", /* resource to use */ hWnd, /* parent handle */ lpProcAbout); /* About() instance address */ FreeProcInstance(lpProcAbout); break; default: /* Lets Windows process it */ return (DefWindowProc(hWnd, message, wParam, lParam)); } break; case WM_DESTROY: /* message: window being destroyed */ DeleteObject(hBoardmap); DeleteObject(hPegBoardmap); DeleteObject(hBlclpegmap); DeleteObject(hWhclpegmap); for (x=0;x<8;x++) DeleteObject(hPegs[x]); PostQuitMessage(0); break; default: /* Passes it on if unprocessed */ return (DefWindowProc(hWnd, message, wParam, lParam)); } return (NULL); } /*********************************************************************/ BOOL FAR PASCAL About(hDlg, message, wParam, lParam) HWND hDlg; /* window handle of the dialog box */ unsigned message; /* type of message */ WORD wParam; /* message-specific information */ LONG lParam; { switch (message) { case WM_INITDIALOG: /* message: initialize dialog box */ return (TRUE); case WM_COMMAND: /* message: received a command */ if (wParam == IDOK || /* "OK" box selected ? */ wParam == IDCANCEL) /* System menu close command ? */ { EndDialog(hDlg, TRUE); /* Exits the dialog box */ return (TRUE); } break; } return (FALSE); } /*****************/ /* Clear the board and the clues for a new game */ void vInitialize(void) { int x,y; for(x=0;x<=9;x++) for(y=0;y<=3;y++) { board[x][y] = -1; clues[x][y] = ' '; } cur_round = 0; winstate = 0; return; } /*****************/ /* Scramble the position of clues */ void vScrambleclues(int round) { int x,y=0,signal=1; char tempclues[4]={'\0','\0','\0','\0'}; while (signal) { x=(rand() % 4); if (tempclues[x]=='\0') { tempclues[x] = clues[round][y]; y++; if (y>3) signal = 0; } } for(x=0;x <=3;x++) clues[round][x]=tempclues[x]; return; } /*****************/ /* Check the guess for clues or win */ BOOL bCheckguess(int round) { int x,y=0; int tempcode[4], temp[4]; for(x=0;x<=3;x++) /* prepare temporary arrays */ { temp[x]=board[round][x]; tempcode[x]=code[x]; clues[round][x] = ' '; } for(x=0;x<=3;x++) /* check for perfect match */ if (temp[x] == tempcode[x]) { clues[round][x]='1'; temp[x]=0; tempcode[x]=-1; y++; } if (y==4) return(TRUE); for(x=0;x<=3;x++) /* check for right colour */ for(y=0;y<=3;y++) /* wrong position */ { if (tempcode[x]==temp[y]) { clues[round][y] = '0'; temp[y] = 0; tempcode[x] = -1; break; } } vScrambleclues(round); return(FALSE); } /*****************/ /* Make sure all the buttons were clicked */ BOOL bCheckfill(void) { int x; for(x=0;x<=3;x++) if (board[cur_round][x] == -1) return(FALSE); return(TRUE); } /*****************/ /* Generate the secret code */ void vMakecode(void) { int x; time_t t; srand((unsigned) time(&t)); for(x=0;x<=3;x++) code[x]= (rand() % 8); return; } /***********************/ /* Create the buttons on screen */ BOOL bMakeGameButtons(HWND hWnd) { if (DidIGetItRight != NULL) DestroyWindow(DidIGetItRight); DidIGetItRight = CreateWindow("Button", "Did I Get It Right?", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 350, 168, 20, hWnd, DIDIGETITRIGHT, hInst, NULL); if (!DidIGetItRight) return(FALSE); ShowWindow(DidIGetItRight, SW_SHOW); UpdateWindow(DidIGetItRight); return(TRUE); } /*******************************/ /* The basic game board setup */ /*******************************/ void vBasicScreen(HWND hWnd) { HDC hDC,hMemoryDC; PAINTSTRUCT ps; int x,y; hDC = BeginPaint(hWnd, &ps); hMemoryDC = CreateCompatibleDC(hDC); hOldBitmap = SelectObject(hMemoryDC,hBoardmap); /* Game board */ GetObject(hBoardmap, sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,10,10,Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); hOldBitmap = SelectObject(hMemoryDC,hPegBoardmap); /* Peg board */ GetObject(hPegBoardmap, sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,190,154,Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); y = 158; for (x=0;x<8;x++) /* Pegs */ { hOldBitmap=SelectObject(hMemoryDC,hPegs[x]); GetObject(hPegs[x], sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,194,y,Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); y += 23; } SelectObject(hMemoryDC, hOldBitmap); DeleteDC(hMemoryDC); ReleaseDC(hWnd, hDC); EndPaint(hWnd, &ps); return; } /***************************************/ /* Check where mouse was clicked and */ /* decide if a peg was selected or a */ /* position on the board was selected. */ /***************************************/ BOOL bCheckPosition(HWND hWnd) { int x,y,z,row=-1; BOOL recX = FALSE; BOOL recY = FALSE; if ((iYpos<=344-(cur_round*30)) && (iYpos>=314-(cur_round*30))) { recY = TRUE; z = 0; for(x=16;x<=118;x+=27) { if ((iXpos>=x) && (iXpos<=(x+27))) { recX = TRUE; break; } z++; } } if ((recX) && (recY)) { cur_column = z; return(TRUE); } else { for(y=0;y<=7;y++) { if ((iYpos>=(y*23+158)) && (iYpos<=(y*23+181))) { row = y; break; } } if ((row > -1) && ((iXpos>=194) && (iXpos<=218))) { curcolour = row; vMarkColour(hWnd); } } return(FALSE); } /********************************/ /* Place the selected peg at the*/ /* appropriate position */ /********************************/ void vPutPeg(HWND hWnd, int colour, int round, int column) { HDC hDC,hMemoryDC; if (board[round][column] == -1) return; hDC = GetDC(hWnd); hMemoryDC = CreateCompatibleDC(hDC); hOldBitmap = SelectObject(hMemoryDC,hPegs[colour]); GetObject(hPegs[colour], sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,column*27+16,314-round*30,Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); DeleteDC(hMemoryDC); ReleaseDC(hWnd, hDC); return; } /**************************/ /* Display the secret code*/ /**************************/ void vShowCode(HWND hWnd) { int x; HDC hDC,hMemoryDC; hDC = GetDC(hWnd); hMemoryDC = CreateCompatibleDC(hDC); for (x=0;x<4;x++) { hOldBitmap = SelectObject(hMemoryDC,hPegs[code[x]]); GetObject(hPegs[code[x]], sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,x*27+16,15,Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); } DeleteDC(hMemoryDC); ReleaseDC(hWnd, hDC); return; } /***************************/ /* Winner's routine */ /***************************/ void vDoWin(HWND hWnd) { HDC hDC; vShowCode(hWnd); hDC = GetDC(hWnd); SetTextColor(hDC,RGB(0,255,0)); SetBkMode(hDC,TRANSPARENT); strcpy(str,"WIN!"); TextOut(hDC,130,18,str,strlen(str)); ReleaseDC(hWnd, hDC); winstate = 1; return; } /***************************/ /* Looser's routine */ /***************************/ void vDoLoose(HWND hWnd) { HDC hDC; vShowCode(hWnd); hDC = GetDC(hWnd); SetTextColor(hDC,RGB(255,0,0)); SetBkMode(hDC,TRANSPARENT); strcpy(str,"LOOSE!"); TextOut(hDC,125,18,str,strlen(str)); ReleaseDC(hWnd, hDC); winstate = 2; return; } /*************************/ /* Display the clue pegs */ /*************************/ void vDoClues(HWND hWnd, int round) { int x,y=0; HDC hDC,hMemoryDC; hDC = GetDC(hWnd); hMemoryDC = CreateCompatibleDC(hDC); for (x=0;x<4;x++) { if (clues[round][x] == '1') { hOldBitmap = SelectObject(hMemoryDC,hWhclpegmap); GetObject(hWhclpegmap, sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,y*12+125,320-(round*30),Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); y++; } else if (clues[round][x] =='0') { hOldBitmap = SelectObject(hMemoryDC,hBlclpegmap); GetObject(hBlclpegmap, sizeof(BITMAP), (LPSTR) &Bitmap); BitBlt(hDC,y*12+125,320-(round*30),Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC,0,0,SRCCOPY); y++; } } DeleteDC(hMemoryDC); ReleaseDC(hWnd, hDC); return; } /*******************************/ /* Mark the selected colour */ /*******************************/ void vMarkColour(HWND hWnd) { HDC hDC; hDC = GetDC(hWnd); if (prevcolour != -1) { SetTextColor(hDC,GetBkColor(hDC)); SetBkMode(hDC,TRANSPARENT); strcpy(str,"*"); TextOut(hDC,220,prevcolour*23+165,str,strlen(str)); } SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); strcpy(str,"*"); TextOut(hDC,220,curcolour*23+165,str,strlen(str)); prevcolour = curcolour; ReleaseDC(hWnd, hDC); return; }