PUZZLE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9.  *
  10.  **************************************************************************/
  11. #define  STRICT
  12. #include <windows.h>
  13. #include <mmsystem.h>
  14. #include <stdlib.h>
  15. #include "puzzle.h"
  16. #define MEM_COPY( hpd, hps, size ) memcpy( hpd, hps, size )
  17. #define DATA_PTR BYTE *
  18. #define WIDTHBYTES(i)     ((unsigned)((i+31)&(~31))/8)  /* ULONG aligned ! */
  19. #define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((int)(bi).biWidth * (int)(bi).biBitCount)
  20. //
  21. // Initialize the puzzle, and optionally simulate 1000 clicks on the puzzle
  22. //
  23. void InitPuzzle(
  24. LPPUZZLE p,
  25. BOOL fScramble)
  26. {
  27.         int i,j;
  28.         // Set the puzzle to a "solved" state
  29.         for (i = 0; i < PSIZE; i++)
  30.                 for (j = 0; j < PSIZE; j++)
  31.                         p->a[i][j] = i + j * PSIZE;
  32.         // Put the "hole" in the lower right corner.
  33.         p->a[PSIZE-1][PSIZE-1] = -1;
  34.         p->hx = PSIZE - 1;
  35.         p->hy = PSIZE - 1;
  36.         if(fScramble) {
  37.                 // Make things really be random
  38.                 srand((unsigned int) timeGetTime());
  39.                 for (i = 0; i < 1000; i++) {
  40.                         // Click on a random square
  41.                         int r = rand() % PSIZE;
  42.                         int s = rand() % PSIZE;
  43.                         ClickPuzzle(p, r, s);
  44.                 }
  45.         }
  46. }
  47. //
  48. // Given a puzzle, and x & y in puzzle coordinates, move squares around
  49. // or not as appropriate, given how such puzzles work.
  50. //
  51. void ClickPuzzle(
  52. LPPUZZLE p,
  53. int x,
  54. int y)
  55. {
  56.         int i;
  57.         if (x < 0 || x >= PSIZE)
  58.                 return;
  59.         if (y < 0 || y >= PSIZE)
  60.                 return;
  61.         if (x == p->hx) {
  62.                 if (y < p->hy) {
  63.                         for (i = p->hy; i > y; i--)
  64.                                 p->a[x][i] = p->a[x][i-1];
  65.                 } else if (y > p->hy) {
  66.                         for (i = p->hy; i < y; i++)
  67.                                 p->a[x][i] = p->a[x][i+1];
  68.                 }
  69.                 p->hy = y;
  70.                 p->a[x][y] = -1;
  71.         } else if (y == p->hy) {
  72.                 if (x < p->hx) {
  73.                         for (i = p->hx; i > x; i--)
  74.                                 p->a[i][y] = p->a[i-1][y];
  75.                 } else if (x > p->hx) {
  76.                         for (i = p->hx; i < x; i++)
  77.                                 p->a[i][y] = p->a[i+1][y];
  78.                 }
  79.                 p->hx = x;
  80.                 p->a[x][y] = -1;
  81.         }
  82.         // We could potentially see if the puzzle was solved here.
  83.         // If we do that, the prototype should change to
  84.         // BOOL ClickPuzzle(LPPUZZLE p, int x, int y, BOOL fCheckSolved)
  85.         // where we would pass TRUE for fCheckSolved if the call was
  86.         // a result of the user really clicking, and not a call from
  87.         // InitPuzzle() or something....
  88. }
  89. //
  90. // Given a puzzle, map the input picture to the output picture with squares
  91. // rearranged.
  92. //
  93. // Works on any RGB DIB.  Doesn't work on bitmaps, probably, so could be a
  94. // problem with Todd's new DrawDib.
  95. //
  96. void MixPicture(
  97. LPPUZZLE p,
  98. LPBITMAPINFOHEADER lpbi,
  99. LPBYTE lpIn,
  100. LPBYTE lpOut)
  101. {
  102.         int i,j;
  103.         int y;
  104.         char achHack[1024] = {0};
  105.         int dx = ((int) lpbi->biWidth / PSIZE) * ((int) lpbi->biBitCount / 8);
  106.         int dy = (int) lpbi->biHeight / PSIZE;
  107.         LONG lRowBytes = DIBWIDTHBYTES(*lpbi);
  108.         DATA_PTR lpI;
  109.         DATA_PTR lpO;
  110.         for (i = 0; i < PSIZE; i++) {
  111.                 for (j = 0; j < PSIZE; j++) {
  112.                         // Get pointer to square we're copying into
  113.                         lpO = (DATA_PTR) lpOut + (PSIZE - 1 - j) * dy * lRowBytes + dx * i;
  114.                         if (p->a[i][j] >= 0) {
  115.                                 // Get pointer to square we're copying from
  116.                                 lpI = (DATA_PTR) lpIn +
  117.                                                 (PSIZE - 1 - (p->a[i][j] / PSIZE)) * dy * lRowBytes +
  118.                                                 dx * (p->a[i][j] % PSIZE);
  119.                                 // do the copy
  120.                                 for (y = 0; y < dy; y++) {
  121.                                         MEM_COPY(lpO, lpI, dx);
  122.                                         lpO += lRowBytes;
  123.                                         lpI += lRowBytes;
  124.                                 }
  125.                         } else {
  126.                                 // clear the square to zeroes
  127.                                 for (y = 0; y < dy; y++) {
  128.                                         MEM_COPY(lpO, achHack, dx);
  129.                                         lpO += lRowBytes;
  130.                                 }
  131.                         }
  132.                 }
  133.         }
  134. }