PUZZLE.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:
Windows编程
开发平台:
Visual C++
- /**************************************************************************
- *
- * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- * PURPOSE.
- *
- * Copyright (C) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
- *
- **************************************************************************/
- #define STRICT
- #include <windows.h>
- #include <mmsystem.h>
- #include <stdlib.h>
- #include "puzzle.h"
- #define MEM_COPY( hpd, hps, size ) memcpy( hpd, hps, size )
- #define DATA_PTR BYTE *
- #define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
- #define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((int)(bi).biWidth * (int)(bi).biBitCount)
- //
- // Initialize the puzzle, and optionally simulate 1000 clicks on the puzzle
- //
- void InitPuzzle(
- LPPUZZLE p,
- BOOL fScramble)
- {
- int i,j;
- // Set the puzzle to a "solved" state
- for (i = 0; i < PSIZE; i++)
- for (j = 0; j < PSIZE; j++)
- p->a[i][j] = i + j * PSIZE;
- // Put the "hole" in the lower right corner.
- p->a[PSIZE-1][PSIZE-1] = -1;
- p->hx = PSIZE - 1;
- p->hy = PSIZE - 1;
- if(fScramble) {
- // Make things really be random
- srand((unsigned int) timeGetTime());
- for (i = 0; i < 1000; i++) {
- // Click on a random square
- int r = rand() % PSIZE;
- int s = rand() % PSIZE;
- ClickPuzzle(p, r, s);
- }
- }
- }
- //
- // Given a puzzle, and x & y in puzzle coordinates, move squares around
- // or not as appropriate, given how such puzzles work.
- //
- void ClickPuzzle(
- LPPUZZLE p,
- int x,
- int y)
- {
- int i;
- if (x < 0 || x >= PSIZE)
- return;
- if (y < 0 || y >= PSIZE)
- return;
- if (x == p->hx) {
- if (y < p->hy) {
- for (i = p->hy; i > y; i--)
- p->a[x][i] = p->a[x][i-1];
- } else if (y > p->hy) {
- for (i = p->hy; i < y; i++)
- p->a[x][i] = p->a[x][i+1];
- }
- p->hy = y;
- p->a[x][y] = -1;
- } else if (y == p->hy) {
- if (x < p->hx) {
- for (i = p->hx; i > x; i--)
- p->a[i][y] = p->a[i-1][y];
- } else if (x > p->hx) {
- for (i = p->hx; i < x; i++)
- p->a[i][y] = p->a[i+1][y];
- }
- p->hx = x;
- p->a[x][y] = -1;
- }
- // We could potentially see if the puzzle was solved here.
- // If we do that, the prototype should change to
- // BOOL ClickPuzzle(LPPUZZLE p, int x, int y, BOOL fCheckSolved)
- // where we would pass TRUE for fCheckSolved if the call was
- // a result of the user really clicking, and not a call from
- // InitPuzzle() or something....
- }
- //
- // Given a puzzle, map the input picture to the output picture with squares
- // rearranged.
- //
- // Works on any RGB DIB. Doesn't work on bitmaps, probably, so could be a
- // problem with Todd's new DrawDib.
- //
- void MixPicture(
- LPPUZZLE p,
- LPBITMAPINFOHEADER lpbi,
- LPBYTE lpIn,
- LPBYTE lpOut)
- {
- int i,j;
- int y;
- char achHack[1024] = {0};
- int dx = ((int) lpbi->biWidth / PSIZE) * ((int) lpbi->biBitCount / 8);
- int dy = (int) lpbi->biHeight / PSIZE;
- LONG lRowBytes = DIBWIDTHBYTES(*lpbi);
- DATA_PTR lpI;
- DATA_PTR lpO;
- for (i = 0; i < PSIZE; i++) {
- for (j = 0; j < PSIZE; j++) {
- // Get pointer to square we're copying into
- lpO = (DATA_PTR) lpOut + (PSIZE - 1 - j) * dy * lRowBytes + dx * i;
- if (p->a[i][j] >= 0) {
- // Get pointer to square we're copying from
- lpI = (DATA_PTR) lpIn +
- (PSIZE - 1 - (p->a[i][j] / PSIZE)) * dy * lRowBytes +
- dx * (p->a[i][j] % PSIZE);
- // do the copy
- for (y = 0; y < dy; y++) {
- MEM_COPY(lpO, lpI, dx);
- lpO += lRowBytes;
- lpI += lRowBytes;
- }
- } else {
- // clear the square to zeroes
- for (y = 0; y < dy; y++) {
- MEM_COPY(lpO, achHack, dx);
- lpO += lRowBytes;
- }
- }
- }
- }
- }