|
- /* * * * * * * * * * * * * * * * * * * * * *
- // Project: Light(点灯)
- // Author: problue
- // Date: 15:49 11/09/2013
- * * * * * * * * * * * * * * * * * * * * * */
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include "pcc32.h"
- // 定义地图的最尺寸及坐标
- #define MAP_ROW_MIN 5
- #define MAP_COL_MIN 5
- #define MAP_ROW_MAX 20
- #define MAP_COL_MAX 20
- #define MAP_BASE_X 10
- #define MAP_BASE_Y 4
- #define TIME_POS_X (MAP_BASE_X+20)
- #define TIME_POS_Y (MAP_BASE_Y-3)
- #define STEP_POS_X (MAP_BASE_X)
- #define STEP_POS_Y (TIME_POS_Y)
- #define TIME_COLOR WHITE
- #define STEP_COLOR WHITE
- #define CursorToInMap(x, y) gotoTextPos(MAP_BASE_X+(x)*2, MAP_BASE_Y+(y)*1)
- #define Beep() putchar(7)
- typedef struct _POINT2D
- {
- uint8 x, y;
- }POINT2D, *PPOINT2D;
- // 定义灯的状态[关|开]
- typedef enum {OFF = 0, ON = 1}LIGHT;
- // 灯地图
- typedef struct
- {
- uint8 row, col;
- LIGHT map[MAP_ROW_MAX][MAP_COL_MAX];
- }LMAP;
- // 定义灯两种状态对应的形状及颜色,顺序同上
- char* LightSharps[] = {"□", "■"};
- PCCOLOR LightColors[] = {DARK_GRAY, YELLOW};
- void drawLight(uint8 x, uint8 y, LIGHT lt);
- void showStep(uint32 stepNum);
- void showTime(uint32 appSTime);
- void drawMap(LMAP map);
- void fillMap(LMAP* map, LIGHT lt);
- void loadMap(LMAP* map);
- void editMap();
- void changeSurround(LMAP* map, POINT2D center);
- bool isAllOn(LMAP map);
- void doGame(LMAP map);
- int main()
- {
- int choice;
- LMAP myMap;
- setConsoleTitle("Light by Problue.");
-
- while (true)
- {
- clearText();
- gotoTextPos(0, 6);
- setTextColor(LIGHT_BLUE);
- puts("\t1.New game");
- puts("\t2.Load map");
- puts("\t3.Edit map");
- puts("\t4.Quit");
- gotoTextPos(8, 10);
- do
- {
- choice = getch();
- } while ( !strchr("1234", choice));
- clearText();
- switch (choice)
- {
- case '1':
- myMap.row = MAP_ROW_MIN * 2;
- myMap.col = MAP_COL_MIN * 2;
- fillMap(&myMap, OFF);
- doGame(myMap);
- break;
- case '2':
- loadMap(&myMap);
- doGame(myMap);
- break;
- case '3':
- editMap();
- break;
- case '4':
- exit(EXIT_SUCCESS);
- }
- }
- return 0;
- }
- void doGame(LMAP map)
- {
- bool isOver = false;
- bool isWin = false;
- uint8 key = 8;
- int stepNum = 0;
- POINT2D select = {0, 0};
- long pauseTime, playTime = clock();
- drawMap(map);
- showStep(stepNum);
- CursorToInMap(select.x, select.y);
- while (!isOver)
- {
- if (jkHasKey())
- {
- switch (jkGetKey())
- {
- case JK_UP:
- if (select.y > 0)
- select.y--;
- else
- select.y = map.row - 1;
- break;
- case JK_DOWN:
- if (select.y < map.row - 1)
- select.y++;
- else
- select.y = 0;
- break;
- case JK_LEFT:
- if (select.x > 0)
- select.x--;
- else
- select.x = map.col - 1;
- break;
- case JK_RIGHT:
- if (select.x < map.col - 1)
- select.x++;
- else
- select.x = 0;
- break;
- case JK_ENTER:
- case JK_SPACE:
- changeSurround(&map, select);
- showStep(++stepNum);
- isOver = isWin = isAllOn(map);
- break;
- case JK_ESC:
- isOver = true;
- break;
- default:
- Beep();
- break;
- }
- if (isWin)
- {
- clearText();
- gotoTextPos(MAP_BASE_X, MAP_BASE_Y);
- setTextColor(WHITE);
- puts("Congratulations! ");
- printf("\tPress any key to Menu...");
- jkGetKey();
- }
- else if (isOver)
- {
- pauseTime = clock();
- CursorToInMap(0, MAP_BASE_Y + 5);
- setTextColor(TIME_COLOR);
- puts("\nGame is Paused. Press Enter Key to Exit, any other to Resume.");
- key = getch();
- if (key != JK_ENTER)
- {
- isOver = false;
- playTime += (clock() - pauseTime);
- clearText();
- drawMap(map);
- showStep(stepNum);
- showTime(playTime);
- }
- }
- CursorToInMap(select.x, select.y);
- }
-
- showTime(playTime);
- }
- }
- void drawMap(LMAP map)
- {
- setCursorVisible(0);
- int i, j;
- for (i = 0; i < map.row; i++)
- for (j = 0; j < map.col; j++)
- drawLight(j, i, map.map[i][j]);
- setCursorVisible(1);
- }
- void drawLight(uint8 x, uint8 y, LIGHT lt)
- {
- CursorToInMap(x, y);
- setTextColor(LightColors[lt]);
- printf("%s", LightSharps[lt]);
- }
- void showStep(uint32 stepNum)
- {
- gotoTextPos(STEP_POS_X, STEP_POS_Y);
- setTextColor(STEP_COLOR);
- printf("Step: %d", stepNum);
- }
- void showTime(uint32 appSTime)
- {
- static uint32 appTime1S = 0;
- uint8 cx = getCursorX(), cy = getCursorY();
- if (clock() - appSTime > appTime1S*1000)
- {
- gotoTextPos(TIME_POS_X, TIME_POS_Y);
- setTextColor(TIME_COLOR);
- printf("Time: %lds", appTime1S);
- appTime1S++;
- gotoTextPos(cx, cy);
- }
- }
- void changeSurround(LMAP* map, POINT2D cpt)
- {
- map->map[cpt.y][cpt.x] = 1 - map->map[cpt.y][cpt.x];
- if (cpt.y-1 >= 0)
- map->map[cpt.y-1][cpt.x] = 1 - map->map[cpt.y-1][cpt.x];
- if (cpt.y+1 < map->row)
- map->map[cpt.y+1][cpt.x] = 1 - map->map[cpt.y+1][cpt.x];
- if (cpt.x-1 >= 0)
- map->map[cpt.y][cpt.x-1] = 1 - map->map[cpt.y][cpt.x-1];
- if (cpt.x+1 < map->col)
- map->map[cpt.y][cpt.x+1] = 1 - map->map[cpt.y][cpt.x+1];
- drawMap(*map);
- }
- bool isAllOn(LMAP map)
- {
- int i, j;
- for (i = 0; i < map.row; i++)
- for (j = 0; j < map.col; j++)
- if (map.map[i][j] != ON)
- return false;
- return true;
- }
- void fillMap(LMAP* map, LIGHT lt)
- {
- int i, j;
- for (i = 0; i < map->row; i++)
- for (j = 0; j < map->col; j++)
- map->map[i][j] = lt;
- }
- void loadMap(LMAP* map)
- {
- char filename[BUFSIZ];
- FILE* fp = NULL;
- bool exist = false;
- // check file exist
- while (true)
- {
- printf("Enter map file path:");
- fgets(filename, BUFSIZ, stdin);
- *strchr(filename, '\n') = '\0';
- fp = fopen(filename, "r");
- exist = fp != NULL;
- if (!exist)
- {
- puts("not fountd the file.");
- }
- else
- break;
- }
- clearText();
- // read map
- int i, j;
- char c;
- fscanf(fp, "%d*%d\n", &map->row, &map->col);
- for (i = 0; i < map->row; i++)
- {
- for (j = 0; j < map->col; j++)
- {
- if ((c = fgetc(fp)) != '\n')
- map->map[i][j] = c - '0';
- else
- --j;
- }
- }
- fclose(fp);
- }
- void editMap()
- {
- int getInt();
- LMAP map;
- // way of initialize map
- int choice;
- printf("\n");
- puts("1.New map");
- puts("2.Old map");
- do
- {
- choice = getch();
- } while ( !strchr("12", choice));
- clearText();
- if (choice == '1')
- {
- // from input
- while (true)
- {
- clearText();
- puts("Enter size of the map.");
- printf("Row(%d~%d):", MAP_ROW_MIN - 1, MAP_ROW_MAX + 1);
- map.row = getInt();
- printf("Column(%d~%d):", MAP_COL_MIN - 1, MAP_COL_MAX + 1);
- map.col = getInt();
- if ((MAP_ROW_MIN <= map.row && map.row <= MAP_ROW_MAX) &&
- (MAP_COL_MIN <= map.col && map.col <= MAP_COL_MAX))
- break;
- }
- fillMap(&map, OFF);
- }
- else if (choice == '2')
- {
- // from file
- loadMap(&map);
- }
- clearText();
- // set light on the map
- puts("Save: S");
- puts("On-Off: Enter/Space");
- POINT2D select = {0, 0};
- bool isFix = false;
- drawMap(map);
- CursorToInMap(select.x, select.y);
- while (!isFix)
- {
- if (jkHasKey())
- {
- switch (jkGetKey())
- {
- case JK_UP:
- if (select.y > 0)
- select.y--;
- else
- select.y = map.row - 1;
- break;
- case JK_DOWN:
- if (select.y < map.row - 1)
- select.y++;
- else
- select.y = 0;
- break;
- case JK_LEFT:
- if (select.x > 0)
- select.x--;
- else
- select.x = map.col - 1;
- break;
- case JK_RIGHT:
- if (select.x < map.col - 1)
- select.x++;
- else
- select.x = 0;
- break;
- case JK_ENTER:
- case JK_SPACE:
- map.map[select.y][select.x] = 1 - map.map[select.y][select.x];
- drawLight(select.x, select.y, map.map[select.y][select.x]);
- break;
- case 'S':
- case 's':
- isFix = true;
- break;
- default:
- break;
- }
- CursorToInMap(select.x, select.y);
- }
- }
- // save as text file
- char filename[BUFSIZ];
- gotoTextPos(0, MAP_BASE_Y+map.row+1);
- setTextColor(WHITE);
- printf("Save as. Enter map file name:");
- fgets(filename, BUFSIZ - 5, stdin);
- strcpy(strchr(filename, '\n'), ".txt");
- FILE* fp = fopen(filename, "w");
- fprintf(fp, "%d*%d\n", map.row, map.col);
- int i, j;
- for (i = 0; i < map.row; i++)
- {
- for (j = 0; j < map.col; j++)
- fprintf(fp, "%d", map.map[i][j]);
- fputc('\n', fp);
- }
- fclose(fp);
- }
- int getInt()
- {
- long integer = 0;
- int digit = 0;
- char key;
- while ((key = getch()) != 13)
- {
- if (isdigit(key))
- {
- putchar(key);
- integer = integer * 10+(key-'0');
- digit++;
- }
- else if (key == 8)
- {
- if (digit > 0)
- {
- printf("\b\40\b");
- integer /= 10;
- --digit;
- }
- }
- }
- putchar('\n');
- return integer;
- }
复制代码
这是个非常简单的小游戏,你的目标是点亮所有灯泡(■)。使用键盘按键上下左右来定位,回车或空格来开关灯泡(会影响到这个灯泡周围至多4个灯泡状态反转开或关),可以在游戏进行中ESC来暂停~
以下是菜单和游戏开始的运行截图:
菜单中的功能说明
New game
使用10*10的默认地图开始游戏。
Load map
玩已有地图。输入已有的地图文件所在的路径就可以开始游戏。
Edit map
编辑地图。加载已有的或是创建新地图,编辑好"灯泡布局",然后输入地图文件名,即可生成一个地图文件。
Quit
退出游戏。
源码及程序下载:
Text Game.Light.rar
(10.17 KB, 下载次数: 243)
|
|