⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glpuzzle.cxx

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    puzzle->backptr->solnptr = puzzle;    puzzle = puzzle->backptr;  }  sprintf(buf, "%d moves to complete!", i);  glutSetWindowTitle(buf);}intaddConfig(Config config, struct puzzle *back){  unsigned hashvalue;  struct puzzle *newpiece;  struct puzzlelist *newlistentry;  hashvalue = hash(config);  newpiece = hashtable[hashvalue % HASHSIZE];  while (newpiece != NULL) {    if (newpiece->hashvalue == hashvalue) {      int i, j;      for (i = 0; i < WIDTH; i++) {        for (j = 0; j < HEIGHT; j++) {          if (convert[config[j][i]] !=            convert[newpiece->pieces[j][i]])            goto nomatch;        }      }      return 0;    }  nomatch:    newpiece = newpiece->next;  }  newpiece = (struct puzzle *) malloc(sizeof(struct puzzle));  newpiece->next = hashtable[hashvalue % HASHSIZE];  newpiece->hashvalue = hashvalue;  memcpy(newpiece->pieces, config, HEIGHT * WIDTH);  newpiece->backptr = back;  newpiece->solnptr = NULL;  hashtable[hashvalue % HASHSIZE] = newpiece;  newlistentry = (struct puzzlelist *) malloc(sizeof(struct puzzlelist));  newlistentry->puzzle = newpiece;  newlistentry->next = NULL;  if (lastentry) {    lastentry->next = newlistentry;  } else {    puzzles = newlistentry;  }  lastentry = newlistentry;  if (back == NULL) {    startPuzzle = newpiece;  }  if (solution(config)) {    solidifyChain(newpiece);    return 1;  }  return 0;}/* Checks if a space can move */intcanmove0(Config pieces, int x, int y, int dir, Config newpieces){  char piece;  int xadd, yadd;  int l, m;  xadd = xadds[dir];  yadd = yadds[dir];  if (x + xadd < 0 || x + xadd >= WIDTH ||    y + yadd < 0 || y + yadd >= HEIGHT)    return 0;  piece = pieces[y + yadd][x + xadd];  if (piece == 0)    return 0;  memcpy(newpieces, pieces, HEIGHT * WIDTH);  for (l = 0; l < WIDTH; l++) {    for (m = 0; m < HEIGHT; m++) {      if (newpieces[m][l] == piece)        newpieces[m][l] = 0;    }  }  xadd = -xadd;  yadd = -yadd;  for (l = 0; l < WIDTH; l++) {    for (m = 0; m < HEIGHT; m++) {      if (pieces[m][l] == piece) {        int newx, newy;        newx = l + xadd;        newy = m + yadd;        if (newx < 0 || newx >= WIDTH ||          newy < 0 || newy >= HEIGHT)          return 0;        if (newpieces[newy][newx] != 0)          return 0;        newpieces[newy][newx] = piece;      }    }  }  return 1;}/* Checks if a piece can move */intcanmove(Config pieces, int x, int y, int dir, Config newpieces){  int xadd, yadd;  xadd = xadds[dir];  yadd = yadds[dir];  if (x + xadd < 0 || x + xadd >= WIDTH ||    y + yadd < 0 || y + yadd >= HEIGHT)    return 0;  if (pieces[y + yadd][x + xadd] == pieces[y][x]) {    return canmove(pieces, x + xadd, y + yadd, dir, newpieces);  }  if (pieces[y + yadd][x + xadd] != 0)    return 0;  return canmove0(pieces, x + xadd, y + yadd, (dir + 2) % 4, newpieces);}intgenerateNewConfigs(struct puzzle *puzzle){  int i, j, k;  Config pieces;  Config newpieces;  memcpy(pieces, puzzle->pieces, HEIGHT * WIDTH);  for (i = 0; i < WIDTH; i++) {    for (j = 0; j < HEIGHT; j++) {      if (pieces[j][i] == 0) {        for (k = 0; k < 4; k++) {          if (canmove0(pieces, i, j, k, newpieces)) {            if (addConfig(newpieces, puzzle))              return 1;          }        }      }    }  }  return 0;}voidfreeSolutions(void){  struct puzzlelist *nextpuz;  struct puzzle *puzzle, *next;  int i;  while (puzzles) {    nextpuz = puzzles->next;    free((char *) puzzles);    puzzles = nextpuz;  }  lastentry = NULL;  for (i = 0; i < HASHSIZE; i++) {    puzzle = hashtable[i];    hashtable[i] = NULL;    while (puzzle) {      next = puzzle->next;      free((char *) puzzle);      puzzle = next;    }  }  startPuzzle = NULL;}intcontinueSolving(void){  struct puzzle *nextpuz;  int i, j;  int movedPiece;  int movedir;  int fromx, fromy;  int tox, toy;  if (startPuzzle == NULL)    return 0;  if (startPuzzle->solnptr == NULL) {    freeSolutions();    return 0;  }  nextpuz = startPuzzle->solnptr;  movedPiece = 0;  movedir = 0;  for (i = 0; i < HEIGHT; i++) {    for (j = 0; j < WIDTH; j++) {      if (startPuzzle->pieces[i][j] != nextpuz->pieces[i][j]) {        if (startPuzzle->pieces[i][j]) {          movedPiece = startPuzzle->pieces[i][j];          fromx = j;          fromy = i;          if (i < HEIGHT - 1 && nextpuz->pieces[i + 1][j] == movedPiece) {            movedir = 3;          } else {            movedir = 2;          }          goto found_piece;        } else {          movedPiece = nextpuz->pieces[i][j];          if (i < HEIGHT - 1 &&            startPuzzle->pieces[i + 1][j] == movedPiece) {            fromx = j;            fromy = i + 1;            movedir = 1;          } else {            fromx = j + 1;            fromy = i;            movedir = 0;          }          goto found_piece;        }      }    }  }  glutSetWindowTitle("What!  No change?");  freeSolutions();  return 0;found_piece:  if (!movingPiece) {    movingPiece = movedPiece;    move_x = fromx;    move_y = fromy;  }  move_x += xadds[movedir] * MOVE_SPEED;  move_y += yadds[movedir] * MOVE_SPEED;  tox = fromx + xadds[movedir];  toy = fromy + yadds[movedir];  if (move_x > tox - MOVE_SPEED / 2 && move_x < tox + MOVE_SPEED / 2 &&    move_y > toy - MOVE_SPEED / 2 && move_y < toy + MOVE_SPEED / 2) {    startPuzzle = nextpuz;    movingPiece = 0;  }  memcpy(thePuzzle, startPuzzle->pieces, HEIGHT * WIDTH);  changeState();  return 1;}intsolvePuzzle(void){  struct puzzlelist *nextpuz;  char buf[256];  int i;  if (solution(thePuzzle)) {    glutSetWindowTitle("Puzzle already solved!");    return 0;  }  addConfig(thePuzzle, NULL);  i = 0;  while (puzzles) {    i++;    if (generateNewConfigs(puzzles->puzzle))      break;    nextpuz = puzzles->next;    free((char *) puzzles);    puzzles = nextpuz;  }  if (puzzles == NULL) {    freeSolutions();    sprintf(buf, "I can't solve it! (%d positions examined)", i);    glutSetWindowTitle(buf);    return 1;  }  return 1;}intselectPiece(int mousex, int mousey){  long hits;  GLuint selectBuf[1024];  GLuint closest;  GLuint dist;  glSelectBuffer(1024, selectBuf);  (void) glRenderMode(GL_SELECT);  glInitNames();  /* Because LoadName() won't work with no names on the stack */  glPushName(0);  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  gluPickMatrix(mousex, H - mousey, 4, 4, viewport);  gluPerspective(45, viewport[2]*1.0/viewport[3], 0.1, 100.0);  drawAll();  hits = glRenderMode(GL_RENDER);  if (hits <= 0) {    return 0;  }  closest = 0;  dist = 0xFFFFFFFFU; //2147483647;  while (hits) {    if (selectBuf[(hits - 1) * 4 + 1] < dist) {      dist = selectBuf[(hits - 1) * 4 + 1];      closest = selectBuf[(hits - 1) * 4 + 3];    }    hits--;  }  return closest;}voidnukePiece(int piece){  int i, j;  for (i = 0; i < HEIGHT; i++) {    for (j = 0; j < WIDTH; j++) {      if (thePuzzle[i][j] == piece) {        thePuzzle[i][j] = 0;      }    }  }}voidmultMatrices(const GLfloat a[16], const GLfloat b[16], GLfloat r[16]){  int i, j;  for (i = 0; i < 4; i++) {    for (j = 0; j < 4; j++) {      r[i * 4 + j] =        a[i * 4 + 0] * b[0 * 4 + j] +        a[i * 4 + 1] * b[1 * 4 + j] +        a[i * 4 + 2] * b[2 * 4 + j] +        a[i * 4 + 3] * b[3 * 4 + j];    }  }}voidmakeIdentity(GLfloat m[16]){  m[0 + 4 * 0] = 1;  m[0 + 4 * 1] = 0;  m[0 + 4 * 2] = 0;  m[0 + 4 * 3] = 0;  m[1 + 4 * 0] = 0;  m[1 + 4 * 1] = 1;  m[1 + 4 * 2] = 0;  m[1 + 4 * 3] = 0;  m[2 + 4 * 0] = 0;  m[2 + 4 * 1] = 0;  m[2 + 4 * 2] = 1;  m[2 + 4 * 3] = 0;  m[3 + 4 * 0] = 0;  m[3 + 4 * 1] = 0;  m[3 + 4 * 2] = 0;  m[3 + 4 * 3] = 1;}/*   ** inverse = invert(src) */intinvertMatrix(const GLfloat src[16], GLfloat inverse[16]){  int i, j, k, swap;  double t;  GLfloat temp[4][4];  for (i = 0; i < 4; i++) {    for (j = 0; j < 4; j++) {      temp[i][j] = src[i * 4 + j];    }  }  makeIdentity(inverse);  for (i = 0; i < 4; i++) {    /*        ** Look for largest element in column */    swap = i;    for (j = i + 1; j < 4; j++) {      if (fabs(temp[j][i]) > fabs(temp[i][i])) {        swap = j;      }    }    if (swap != i) {      /*          ** Swap rows. */      for (k = 0; k < 4; k++) {        t = temp[i][k];        temp[i][k] = temp[swap][k];        temp[swap][k] = t;        t = inverse[i * 4 + k];        inverse[i * 4 + k] = inverse[swap * 4 + k];        inverse[swap * 4 + k] = t;      }    }    if (temp[i][i] == 0) {      /*          ** No non-zero pivot.  The matrix is singular, which         shouldn't ** happen.  This means the user gave us a         bad matrix. */      return 0;    }    t = temp[i][i];    for (k = 0; k < 4; k++) {      temp[i][k] /= t;      inverse[i * 4 + k] /= t;    }    for (j = 0; j < 4; j++) {      if (j != i) {        t = temp[j][i];        for (k = 0; k < 4; k++) {          temp[j][k] -= temp[i][k] * t;          inverse[j * 4 + k] -= inverse[i * 4 + k] * t;        }      }    }  }  return 1;}/*   ** This is a screwball function.  What it does is the following:   ** Given screen x and y coordinates, compute the corresponding object space    **   x and y coordinates given that the object space z is 0.9 + OFFSETZ.   ** Since the tops of (most) pieces are at z = 0.9 + OFFSETZ, we use that    **   number. */intcomputeCoords(int piece, int mousex, int mousey,  GLfloat * selx, GLfloat * sely){  GLfloat modelMatrix[16];  GLfloat projMatrix[16];  GLfloat finalMatrix[16];  GLfloat in[4];  GLfloat a, b, c, d;  GLfloat top, bot;  GLfloat z;  GLfloat w;  GLfloat height;  if (piece == 0)    return 0;  height = zsize[piece] - 0.1 + OFFSETZ;  glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);  glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);  multMatrices(modelMatrix, projMatrix, finalMatrix);  if (!invertMatrix(finalMatrix, finalMatrix))    return 0;  in[0] = (2.0 * (mousex - viewport[0]) / viewport[2]) - 1;  in[1] = (2.0 * ((H - mousey) - viewport[1]) / viewport[3]) - 1;  a = in[0] * finalMatrix[0 * 4 + 2] +    in[1] * finalMatrix[1 * 4 + 2] +    finalMatrix[3 * 4 + 2];  b = finalMatrix[2 * 4 + 2];  c = in[0] * finalMatrix[0 * 4 + 3] +    in[1] * finalMatrix[1 * 4 + 3] +    finalMatrix[3 * 4 + 3];  d = finalMatrix[2 * 4 + 3];  /*      ** Ok, now we need to solve for z: **   (a + b z) / (c + d      z) = height. ** ("height" is the height in object space we      want to solve z for) ** ** ==>  a + b z = height c +     height d z **      bz - height d z = height c - a ** z =     (height c - a) / (b - height d) */  top = height * c - a;  bot = b - height * d;  if (bot == 0.0)    return 0;  z = top / bot;  /* 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -