游戏开发论坛

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

点灯游戏

[复制链接]

2

主题

2

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2013-9-15 00:40:02 | 显示全部楼层 |阅读模式
  1. /* * * * * * * * * * * * * * * * * * * * * *
  2. // Project: Light(点灯)
  3. // Author:  problue
  4. // Date:    15:49 11/09/2013
  5. * * * * * * * * * * * * * * * * * * * * * */
  6. #include <stdio.h>
  7. #include <assert.h>
  8. #include <stdlib.h>
  9. #include <stdbool.h>
  10. #include "pcc32.h"

  11. // 定义地图的最尺寸及坐标
  12. #define MAP_ROW_MIN  5
  13. #define MAP_COL_MIN  5
  14. #define MAP_ROW_MAX  20
  15. #define MAP_COL_MAX  20
  16. #define MAP_BASE_X   10
  17. #define MAP_BASE_Y   4

  18. #define TIME_POS_X   (MAP_BASE_X+20)
  19. #define TIME_POS_Y   (MAP_BASE_Y-3)
  20. #define STEP_POS_X   (MAP_BASE_X)
  21. #define STEP_POS_Y   (TIME_POS_Y)

  22. #define TIME_COLOR   WHITE
  23. #define STEP_COLOR   WHITE

  24. #define CursorToInMap(x, y) gotoTextPos(MAP_BASE_X+(x)*2, MAP_BASE_Y+(y)*1)
  25. #define Beep()  putchar(7)

  26. typedef struct _POINT2D
  27. {
  28.   uint8 x, y;
  29. }POINT2D, *PPOINT2D;

  30. // 定义灯的状态[关|开]
  31. typedef enum {OFF = 0, ON = 1}LIGHT;

  32. // 灯地图
  33. typedef struct
  34. {
  35.   uint8 row, col;
  36.   LIGHT map[MAP_ROW_MAX][MAP_COL_MAX];
  37. }LMAP;

  38. // 定义灯两种状态对应的形状及颜色,顺序同上
  39. char*   LightSharps[] = {"□", "■"};
  40. PCCOLOR LightColors[] = {DARK_GRAY, YELLOW};

  41. void drawLight(uint8 x, uint8 y, LIGHT lt);
  42. void showStep(uint32 stepNum);
  43. void showTime(uint32 appSTime);
  44. void drawMap(LMAP map);
  45. void fillMap(LMAP* map, LIGHT lt);
  46. void loadMap(LMAP* map);
  47. void editMap();
  48. void changeSurround(LMAP* map, POINT2D center);
  49. bool isAllOn(LMAP map);
  50. void doGame(LMAP map);

  51. int main()
  52. {
  53.   int choice;
  54.   LMAP myMap;

  55.   setConsoleTitle("Light by Problue.");
  56.   
  57.   while (true)
  58.   {
  59.     clearText();
  60.     gotoTextPos(0, 6);
  61.     setTextColor(LIGHT_BLUE);
  62.     puts("\t1.New  game");
  63.     puts("\t2.Load map");
  64.     puts("\t3.Edit map");
  65.     puts("\t4.Quit");
  66.     gotoTextPos(8, 10);

  67.     do
  68.     {
  69.       choice = getch();
  70.     } while ( !strchr("1234", choice));
  71.     clearText();

  72.     switch (choice)
  73.     {
  74.       case '1':
  75.         myMap.row = MAP_ROW_MIN * 2;
  76.         myMap.col = MAP_COL_MIN * 2;
  77.         fillMap(&myMap, OFF);
  78.         doGame(myMap);
  79.         break;
  80.       case '2':
  81.         loadMap(&myMap);
  82.         doGame(myMap);
  83.         break;
  84.       case '3':
  85.         editMap();
  86.         break;
  87.       case '4':
  88.         exit(EXIT_SUCCESS);
  89.     }
  90.   }
  91.   return 0;
  92. }

  93. void doGame(LMAP map)
  94. {
  95.   bool isOver = false;
  96.   bool isWin = false;
  97.   uint8 key = 8;
  98.   int stepNum = 0;
  99.   POINT2D select = {0, 0};
  100.   long pauseTime, playTime = clock();

  101.   drawMap(map);
  102.   showStep(stepNum);
  103.   CursorToInMap(select.x, select.y);

  104.   while (!isOver)
  105.   {
  106.     if (jkHasKey())
  107.     {
  108.       switch (jkGetKey())
  109.       {
  110.         case JK_UP:
  111.           if (select.y > 0)
  112.             select.y--;
  113.           else
  114.             select.y = map.row - 1;
  115.           break;
  116.         case JK_DOWN:
  117.           if (select.y < map.row - 1)
  118.             select.y++;
  119.           else
  120.             select.y = 0;
  121.           break;
  122.         case JK_LEFT:
  123.           if (select.x > 0)
  124.             select.x--;
  125.           else
  126.             select.x = map.col - 1;
  127.           break;
  128.         case JK_RIGHT:
  129.           if (select.x < map.col - 1)
  130.             select.x++;
  131.           else
  132.             select.x = 0;
  133.           break;
  134.         case JK_ENTER:
  135.         case JK_SPACE:
  136.           changeSurround(&map, select);
  137.           showStep(++stepNum);
  138.           isOver = isWin = isAllOn(map);
  139.           break;
  140.         case JK_ESC:
  141.           isOver = true;
  142.           break;
  143.         default:
  144.           Beep();
  145.           break;
  146.       }

  147.       if (isWin)
  148.       {
  149.         clearText();
  150.         gotoTextPos(MAP_BASE_X, MAP_BASE_Y);
  151.         setTextColor(WHITE);
  152.         puts("Congratulations! ");
  153.         printf("\tPress any key to Menu...");
  154.         jkGetKey();
  155.       }
  156.       else if (isOver)
  157.       {
  158.         pauseTime = clock();
  159.         CursorToInMap(0, MAP_BASE_Y + 5);
  160.         setTextColor(TIME_COLOR);
  161.         puts("\nGame is Paused. Press Enter Key to Exit, any other to Resume.");
  162.         key = getch();
  163.         if (key != JK_ENTER)
  164.         {
  165.           isOver = false;
  166.           playTime += (clock() - pauseTime);
  167.           clearText();
  168.           drawMap(map);
  169.           showStep(stepNum);
  170.           showTime(playTime);
  171.         }
  172.       }

  173.       CursorToInMap(select.x, select.y);
  174.     }
  175.    
  176.     showTime(playTime);
  177.   }

  178. }

  179. void drawMap(LMAP map)
  180. {
  181.   setCursorVisible(0);
  182.   int i, j;
  183.   for (i = 0; i < map.row; i++)
  184.     for (j = 0; j < map.col; j++)
  185.       drawLight(j, i, map.map[i][j]);
  186.   setCursorVisible(1);
  187. }

  188. void drawLight(uint8 x, uint8 y, LIGHT lt)
  189. {
  190.   CursorToInMap(x, y);
  191.   setTextColor(LightColors[lt]);
  192.   printf("%s", LightSharps[lt]);
  193. }

  194. void showStep(uint32 stepNum)
  195. {
  196.   gotoTextPos(STEP_POS_X, STEP_POS_Y);
  197.   setTextColor(STEP_COLOR);
  198.   printf("Step: %d", stepNum);
  199. }

  200. void showTime(uint32 appSTime)
  201. {
  202.   static uint32 appTime1S = 0;
  203.   uint8 cx = getCursorX(), cy = getCursorY();
  204.   if (clock() - appSTime > appTime1S*1000)
  205.   {
  206.     gotoTextPos(TIME_POS_X, TIME_POS_Y);
  207.     setTextColor(TIME_COLOR);
  208.     printf("Time: %lds", appTime1S);
  209.     appTime1S++;
  210.     gotoTextPos(cx, cy);
  211.   }
  212. }

  213. void changeSurround(LMAP* map, POINT2D cpt)
  214. {
  215.     map->map[cpt.y][cpt.x] = 1 - map->map[cpt.y][cpt.x];
  216.   if (cpt.y-1 >= 0)
  217.     map->map[cpt.y-1][cpt.x] = 1 - map->map[cpt.y-1][cpt.x];
  218.   if (cpt.y+1 < map->row)
  219.     map->map[cpt.y+1][cpt.x] = 1 - map->map[cpt.y+1][cpt.x];
  220.   if (cpt.x-1 >= 0)
  221.     map->map[cpt.y][cpt.x-1] = 1 - map->map[cpt.y][cpt.x-1];
  222.   if (cpt.x+1 < map->col)
  223.     map->map[cpt.y][cpt.x+1] = 1 - map->map[cpt.y][cpt.x+1];

  224.   drawMap(*map);
  225. }

  226. bool isAllOn(LMAP map)
  227. {
  228.   int i, j;
  229.   for (i = 0; i < map.row; i++)
  230.     for (j = 0; j < map.col; j++)
  231.       if (map.map[i][j] != ON)
  232.         return false;
  233.   return true;
  234. }

  235. void fillMap(LMAP* map, LIGHT lt)
  236. {
  237.   int i, j;
  238.   for (i = 0; i < map->row; i++)
  239.     for (j = 0; j < map->col; j++)
  240.       map->map[i][j] = lt;
  241. }

  242. void loadMap(LMAP* map)
  243. {
  244.   char filename[BUFSIZ];
  245.   FILE* fp = NULL;
  246.   bool exist = false;

  247.   // check file exist
  248.   while (true)
  249.   {
  250.     printf("Enter map file path:");
  251.     fgets(filename, BUFSIZ, stdin);
  252.     *strchr(filename, '\n') = '\0';
  253.     fp = fopen(filename, "r");
  254.     exist = fp != NULL;
  255.     if (!exist)
  256.     {
  257.       puts("not fountd the file.");
  258.     }
  259.     else
  260.       break;
  261.   }
  262.   clearText();

  263.   // read map
  264.   int i, j;
  265.   char c;
  266.   fscanf(fp, "%d*%d\n", &map->row, &map->col);
  267.   for (i = 0; i < map->row; i++)
  268.   {
  269.     for (j = 0; j < map->col; j++)
  270.     {
  271.       if ((c = fgetc(fp)) != '\n')
  272.         map->map[i][j] = c - '0';
  273.       else
  274.         --j;
  275.     }
  276.   }

  277.   fclose(fp);
  278. }

  279. void editMap()
  280. {
  281.   int getInt();

  282.   LMAP map;

  283.   // way of initialize map

  284.   int choice;
  285.   printf("\n");
  286.   puts("1.New map");
  287.   puts("2.Old map");
  288.   do
  289.   {
  290.     choice = getch();
  291.   } while ( !strchr("12", choice));
  292.   clearText();

  293.   if (choice == '1')
  294.   {
  295.     // from input
  296.     while (true)
  297.     {
  298.       clearText();
  299.       puts("Enter size of the map.");
  300.       printf("Row(%d~%d):", MAP_ROW_MIN - 1, MAP_ROW_MAX + 1);
  301.       map.row = getInt();
  302.       printf("Column(%d~%d):", MAP_COL_MIN - 1, MAP_COL_MAX + 1);
  303.       map.col = getInt();
  304.       if ((MAP_ROW_MIN <= map.row && map.row <= MAP_ROW_MAX) &&
  305.           (MAP_COL_MIN <= map.col && map.col <= MAP_COL_MAX))
  306.         break;
  307.     }
  308.     fillMap(&map, OFF);
  309.   }
  310.   else if (choice == '2')
  311.   {
  312.     // from file
  313.     loadMap(&map);
  314.   }
  315.   clearText();

  316.   // set light on the map

  317.   puts("Save: S");
  318.   puts("On-Off: Enter/Space");
  319.   POINT2D select = {0, 0};
  320.   bool isFix = false;
  321.   drawMap(map);
  322.   CursorToInMap(select.x, select.y);
  323.   while (!isFix)
  324.   {
  325.     if (jkHasKey())
  326.     {
  327.       switch (jkGetKey())
  328.       {
  329.         case JK_UP:
  330.           if (select.y > 0)
  331.             select.y--;
  332.           else
  333.             select.y = map.row - 1;
  334.           break;
  335.         case JK_DOWN:
  336.           if (select.y < map.row - 1)
  337.             select.y++;
  338.           else
  339.             select.y = 0;
  340.           break;
  341.         case JK_LEFT:
  342.           if (select.x > 0)
  343.             select.x--;
  344.           else
  345.             select.x = map.col - 1;
  346.           break;
  347.         case JK_RIGHT:
  348.           if (select.x < map.col - 1)
  349.             select.x++;
  350.           else
  351.             select.x = 0;
  352.           break;
  353.         case JK_ENTER:
  354.         case JK_SPACE:
  355.           map.map[select.y][select.x] = 1 - map.map[select.y][select.x];
  356.           drawLight(select.x, select.y, map.map[select.y][select.x]);
  357.           break;
  358.         case 'S':
  359.         case 's':
  360.           isFix = true;
  361.           break;
  362.         default:
  363.           break;
  364.       }
  365.       CursorToInMap(select.x, select.y);
  366.     }
  367.   }

  368.   // save as text file

  369.   char filename[BUFSIZ];
  370.   gotoTextPos(0, MAP_BASE_Y+map.row+1);
  371.   setTextColor(WHITE);
  372.   printf("Save as. Enter map file name:");
  373.   fgets(filename, BUFSIZ - 5, stdin);
  374.   strcpy(strchr(filename, '\n'), ".txt");
  375.   FILE* fp = fopen(filename, "w");
  376.   fprintf(fp, "%d*%d\n", map.row, map.col);
  377.   int i, j;
  378.   for (i = 0; i < map.row; i++)
  379.   {
  380.     for (j = 0; j < map.col; j++)
  381.       fprintf(fp, "%d", map.map[i][j]);
  382.     fputc('\n', fp);
  383.   }
  384.   fclose(fp);
  385. }

  386. int getInt()
  387. {
  388.   long integer = 0;
  389.   int digit = 0;
  390.   char key;

  391.   while ((key = getch()) != 13)
  392.   {
  393.     if (isdigit(key))
  394.     {
  395.       putchar(key);
  396.       integer = integer * 10+(key-'0');
  397.       digit++;
  398.     }
  399.     else if (key == 8)
  400.     {
  401.       if (digit > 0)
  402.       {
  403.         printf("\b\40\b");
  404.         integer /= 10;
  405.         --digit;
  406.       }
  407.     }
  408.   }
  409.   putchar('\n');

  410.   return integer;
  411. }

复制代码

  这是个非常简单的小游戏,你的目标是点亮所有灯泡(■)。使用键盘按键上下左右来定位,回车或空格来开关灯泡(会影响到这个灯泡周围至多4个灯泡状态反转开或关),可以在游戏进行中ESC来暂停~
以下是菜单和游戏开始的运行截图:
QQ图片20130915004529.jpg QQ图片20130915004456.jpg

菜单中的功能说明
New game
使用10*10的默认地图开始游戏。
Load map
玩已有地图。输入已有的地图文件所在的路径就可以开始游戏。
Edit map
编辑地图。加载已有的或是创建新地图,编辑好"灯泡布局",然后输入地图文件名,即可生成一个地图文件。
Quit
退出游戏。

源码及程序下载: Text Game.Light.rar (10.17 KB, 下载次数: 243)




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

本版积分规则

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

GMT+8, 2025-2-26 08:39

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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