游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3848|回复: 0

C语言控制台小游戏-拼图

[复制链接]

2

主题

2

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2013-9-2 16:35:49 | 显示全部楼层 |阅读模式
游戏目标

移动小块的拼图零件使它恢复成原始图片。



操作说明

用方向键上、下、左、右来控制周围某个小图案往空白图案移动。


程序源码
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * *
  2. // Project: puzzle(拼图)
  3. // Author:  problue
  4. // Date:    13:14 26/08/2013
  5. * * * * * * * * * * * * * * * * * * * * * * * * * */

  6. #include <stdio.h>
  7. #include "pcc32.h" //from ROCoder

  8. // 定义控制台窗口尺寸
  9. #define APP_WIDTH      40
  10. #define APP_HEIGHT     20
  11. // 定义拼图坐标及最大尺寸
  12. #define PUZ_BASE_X     (APP_WIDTH/2-5)
  13. #define PUZ_BASE_Y     5
  14. #define PUZ_ROW_MAX    5
  15. #define PUZ_COL_MAX    5
  16. // 定义空白图片的编号
  17. #define BLANK_NO       (puzzleSize.r*puzzleSize.c)

  18. typedef struct
  19. {
  20.   uint8 r, c;
  21. }POINT2D, *PPOINT2D;

  22. // 拼图零件
  23. typedef struct
  24. {
  25.   int no;
  26.   char pic[4];
  27. }PIECE;

  28. // 游戏等级数据: 拼图尺寸、拼图图片
  29. POINT2D myLevelSizes[] =
  30. {
  31.   {3,3}, {4,4}, {5,5}
  32. };
  33. static char myLevelGraphs[][PUZ_ROW_MAX * PUZ_COL_MAX][4] =
  34. {
  35.   {"╔","╦","╗","╠","╬","╣","╚","╩","╝"},
  36.   {"△","▽","○","◇","□","☆","▲","▼","●","◆","★","◎","⊙","Θ","¤","  "},
  37.   {"A ","B ","C ","D ","E ","F ","G ","H ","I ","J ","K ","L ","M ","N ","O ","P ","Q ","R ","S ","T ","U ","V ","W ","X ","Y "}
  38. };

  39. int levelNo;
  40. POINT2D puzzleSize;
  41. POINT2D blankPos;
  42. PIECE puzzle[PUZ_ROW_MAX][PUZ_COL_MAX];

  43. int moves = 0;
  44. long appTime, playTimeS = 1;

  45. void drawPuzzle();
  46. void drawPiece(int r, int c);
  47. void movePiece(POINT2D fromPos);
  48. void swapPiece(PIECE* pa, PIECE* pb);
  49. void randPuzzle();
  50. int isFull();
  51. void printScore();
  52. void gameStart();
  53. void gameOver();

  54. int main()
  55. {
  56.   int isOver = 0;
  57.   POINT2D select;

  58.   fixConsoleSize(APP_WIDTH, APP_HEIGHT);
  59.   setCursorVisible(0);
  60.   setConsoleTitle("Puzzle by problue.");
  61.   gameStart();
  62.   randPuzzle();
  63.   drawPuzzle();
  64.   appTime = clock();

  65.   while (!isOver)
  66.   {
  67.     printScore();

  68.     select = blankPos;
  69.     if (jkHasKey())
  70.     {
  71.       switch (jkGetKey())
  72.       {
  73.         case JK_UP:
  74.           if (blankPos.r < puzzleSize.r - 1)
  75.             select.r = blankPos.r + 1;
  76.           break;
  77.         case JK_DOWN:
  78.           if (blankPos.r > 0)
  79.             select.r = blankPos.r - 1;
  80.           break;
  81.         case JK_LEFT:
  82.           if (blankPos.c < puzzleSize.c - 1)
  83.             select.c = blankPos.c + 1;
  84.           break;
  85.         case JK_RIGHT:
  86.           if (blankPos.c > 0)
  87.             select.c = blankPos.c - 1;
  88.           break;
  89.         case JK_ESC:
  90.           isOver = 1;
  91.           break;
  92.         default:
  93.           break;
  94.       }
  95.       movePiece(select);
  96.       if (!isOver);
  97.         isOver = isFull();
  98.     }
  99.   }
  100.   gameOver();
  101.   jkGetKey();
  102.   return 0;
  103. }

  104. void movePiece(POINT2D fromPos)
  105. {
  106.   swapPiece(&puzzle[fromPos.r][fromPos.c], &puzzle[blankPos.r][blankPos.c]);
  107.   drawPiece(fromPos.r, fromPos.c);
  108.   drawPiece(blankPos.r, blankPos.c);
  109.   blankPos = fromPos;
  110.   moves++;
  111.   return;
  112. }

  113. void randPuzzle()
  114. {
  115.   int i, j;
  116.   for (i = 0;i < puzzleSize.r; i++)
  117.   {
  118.     for (j = 0;j < puzzleSize.c; j++)
  119.     {
  120.       puzzle[i][j].no = i * puzzleSize.c + j + 1;
  121.       strcpy(puzzle[i][j].pic, myLevelGraphs[levelNo][ i * puzzleSize.c + j ]);
  122.     }
  123.   }
  124.   srand((uint32)time(NULL));
  125.   for (i = 0; i < puzzleSize.r; i++)
  126.     for (j = 0; j < puzzleSize.c; j++)
  127.       swapPiece(&puzzle[i][j], &puzzle[i][ rand() % puzzleSize.c ]);

  128.   for (i = 0; i < puzzleSize.r; i++)
  129.     for (j = 0; j < puzzleSize.c; j++)
  130.       if (puzzle[i][j].no == BLANK_NO)
  131.         goto BREAK;
  132.   BREAK:
  133.   blankPos.r = i;
  134.   blankPos.c = j;
  135.   strcpy(puzzle[blankPos.r][blankPos.c].pic, "\40\40");
  136. }

  137. void swapPiece(PIECE* pa, PIECE* pb)
  138. {
  139.   PIECE temp = *pa;
  140.   *pa = *pb;
  141.   *pb = temp;
  142. }

  143. int isFull()
  144. {
  145.   if (puzzle[puzzleSize.r-1][puzzleSize.c-1].no != BLANK_NO)
  146.     return 0;
  147.   int i, j;
  148.   for (i = 0;i < puzzleSize.r; i++)
  149.     for (j = 0;j < puzzleSize.c - 1; j++)
  150.       if ( (puzzle[i][j].no - puzzle[i][j+1].no) != -1)
  151.         return 0;
  152.   return 1;
  153. }

  154. void drawPiece(int r, int c)
  155. {
  156.   gotoTextPos(PUZ_BASE_X + c * 2, PUZ_BASE_Y + r);
  157.   printf("%2s", puzzle[r][c].pic);
  158. }

  159. void drawPuzzle()
  160. {
  161.   int i, j;

  162.   clearText();
  163.   for (i = 0; i < puzzleSize.r; i++)
  164.     for (j = 0; j < puzzleSize.c; j++)
  165.       drawPiece(i, j);

  166.   for (i = 0; i < puzzleSize.r; i++)
  167.   {
  168.     for (j = 0; j < puzzleSize.c; j++)
  169.     {
  170.       gotoTextPos((APP_WIDTH - puzzleSize.c * 2) + j * 2, APP_HEIGHT - puzzleSize.r + i - 1);
  171.       printf("%2s", myLevelGraphs[levelNo][ i * puzzleSize.c + j ]);
  172.     }
  173.   }
  174. }

  175. void printScore()
  176. {
  177.   gotoTextPos(0, 0);
  178.   printf("Step: %d", moves);
  179.   if (clock() - appTime > playTimeS*1000)
  180.   {
  181.     gotoTextPos(20, 0);
  182.     printf("Time: %ld", playTimeS);
  183.     playTimeS++;
  184.   }
  185. }

  186. void gameStart()
  187. {
  188.   int choice;
  189.   puts("请选择游戏等级:");
  190.   puts("1.简单");
  191.   puts("2.普通");
  192.   puts("3.困难");
  193.   do
  194.   {
  195.     choice = getch();
  196.   } while (! ('1' <= choice &&  choice <= '3'));

  197.   levelNo = choice - '0' - 1;
  198.   puzzleSize = myLevelSizes[levelNo];
  199. }

  200. void gameOver()
  201. {
  202.   gotoTextPos(PUZ_BASE_X - 6 , PUZ_BASE_Y + puzzleSize.r + 2);
  203.   setTextColor(YELLOW);
  204.   printf("完成拼图!");
  205. }
复制代码
运行效果截图:
hard.jpg


完整程序及源码(包含库pcc32):
控制台游戏.拼图.rar (7.98 KB, 下载次数: 266)




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-26 14:09

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表