📄 map.c
字号:
/* ** housekeeper: the housekeeper game.** Copyright (C) 2002~2007 Feynman Software** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.** You should have received a copy of the GNU General Public License along** with this program; if not, write to the Free Software Foundation, Inc.,** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.*/#include "map.h"#include "data.c"ptagMap theMap; static ptagLevelCollection InitACollection(int * i);static ptagLevel InitALevel(int *i); static int LineType(int i);static inline int FindLineEnd(int j);static inline void GotoNextLine(int *i);static void DestroyCollection(ptagLevelCollection pCollection);static void DestroyLevel(ptagLevel pLevel);static void DestroyStep(void);static BOOL FindPath(int * iGoRecord, int curx, int cury, int dx, int dy, int iRow, int iCol);static int manGoInto[] = { B_SAVEMAN, B_FORBID, B_FORBID, B_FORBID, B_FORBID, B_FORBID, B_MAN };static int manLeave[] = { B_FORBID, B_NOTHING, B_FORBID, B_GOAL, B_FORBID, B_FORBID, B_FORBID }; static int boxGoInto[] = { B_TREASURE, B_FORBID, B_FORBID, B_FORBID, B_FORBID, B_FORBID,B_OBJECT };static int boxLeave[] = { B_FORBID, B_FORBID, B_NOTHING, B_FORBID, B_GOAL, B_FORBID,B_FORBID };void InitMap(void) { int i = 0; int iLength = 0; ptagLevelCollection pCollection; iLength = sizeof(level_data_level); theMap = (ptagMap)calloc(1, sizeof(Map)); theMap->iNoOfCollection = 0; theMap->head = NULL; theMap->tail = NULL; theMap->currentLevel = NULL; while( i < iLength ) { if (LineType(i) == LINE_TYPE_COLLECTION_BEGIN) { pCollection = InitACollection(&i); //Insert the struct in the doube list. if (theMap->head == NULL) { theMap->head = pCollection; theMap->tail = theMap->head; pCollection->next = pCollection; pCollection->prev = pCollection; } else { pCollection->next = theMap->tail->next; pCollection->next->prev = pCollection; pCollection->prev = theMap->tail; theMap->tail->next = pCollection; theMap->tail = pCollection; } theMap->iNoOfCollection++; } else GotoNextLine(&i); } theMap->current = theMap->head; for (i = 0; i < BACK_STEP_SIZE; i++) theMap->pSteps[i] = NULL; PlayRestart();}//align at alphabitstatic ptagLevelCollection InitACollection(int * i){ ptagLevelCollection pCollection; char * name; int iNameLength = 0; int j = *i; char a; ptagLevel pLevel; int iLevel = 1; int iType; pCollection = (ptagLevelCollection)calloc(1, sizeof(LevelCollection)); pCollection->iNoOfLevels = 0; pCollection->strName = (char *)calloc(MAX_COLLECTION_NAME, sizeof(char)); name = pCollection->strName; pCollection->head = NULL; pCollection->tail = NULL; assert (LineType(j) == LINE_TYPE_COLLECTION_BEGIN); //first get the name do { a = (char)level_data_level[j]; if((isalpha(a)) || (a == '_')){ name[iNameLength++] = a; j++; } else break; } while(1); GotoNextLine(&j); name[iNameLength] = '\0'; while(1) { iType = LineType(j); if (iType == LINE_TYPE_COLLECTION_BEGIN) break; //finished this collection if (iType == LINE_TYPE_LEVEL_BEGIN){ pLevel = InitALevel(&j); pLevel->iNo = iLevel++; if (pCollection->head == NULL) { pCollection->head = pLevel; pCollection->tail = pCollection->head; pLevel->next = pLevel; pLevel->prev = pLevel; } else { pLevel->next = pCollection->tail->next; pLevel->next->prev = pLevel; pLevel->prev = pCollection->tail; pCollection->tail->next = pLevel; pCollection->tail = pLevel; } pCollection->iNoOfLevels++; } else GotoNextLine(&j); } *i = j; pCollection->current = pCollection->head; return pCollection;}//we begin at the begin of a linestatic ptagLevel InitALevel(int *i) { ptagLevel pLevel; int j = *i; int iLineBegin = 0; int iLineEnd = 0; int iRow = 0; int iCol = 0; char a; int *pInt; int k; int b; assert (LineType(j) == LINE_TYPE_LEVEL_BEGIN); //first decide how many line rows iLineBegin = j; while(1) { //we are now at the begin of the line a = (char)level_data_level[j]; while (a != 0x0a) { if (a == '#') iLineEnd = j; a = (char)level_data_level[++j]; } if (iLineEnd == 0) //There are no '#'s in this line. break; if (iLineEnd -iLineBegin + 1 > iCol) iCol = iLineEnd - iLineBegin + 1; iRow ++; j++; iLineEnd = 0; iLineBegin = j; } //Init a structure pLevel = (ptagLevel)calloc(1, sizeof(Level)); pLevel->row = iRow; pLevel->col = iCol; pLevel->data = (int *)calloc(iRow*iCol, sizeof(int)); pInt = pLevel->data; //set value to pLevel->data j = *i; for(iRow = 0; iRow < pLevel->row; iRow++) { iLineEnd = FindLineEnd(j); for(k = 0; k <= iLineEnd; k++) { b = level_data_level[j++]; switch (b) { case '@': pLevel->manx = k; pLevel->many = iRow; pInt[iRow*iCol+k] = B_MAN; break; case '$': pInt[iRow*iCol+k] = B_OBJECT; break; case '.': pInt[iRow*iCol+k] = B_GOAL; break; case '*': pInt[iRow*iCol+k] = B_TREASURE; break; case '+': pLevel->manx = k; pLevel->many = iRow; pInt[iRow*iCol+k] = B_SAVEMAN; break; case '#': pInt[iRow*iCol+k] = B_STONE; break; default: pInt[iRow*iCol+k] = B_NOTHING; } } for ( ; k < iCol; k++) pInt[iRow*iCol+k] = B_NOTHING; GotoNextLine(&j); } *i = j; return pLevel;}static int LineType(int i){ char a; a = (char)level_data_level[i++]; while(a != 0x0a) { if (a == '#') return LINE_TYPE_LEVEL_BEGIN; if (isalpha(a)) return LINE_TYPE_COLLECTION_BEGIN; a = (char)level_data_level[i++]; } return LINE_TYPE_OTHER;}static inline int FindLineEnd(int j){ int iLineEnd = 0; int i = 0; char a; do { a = (char)level_data_level[j++]; if (a == '#') iLineEnd = i; i ++; } while (a != 0x0a); assert(iLineEnd); return iLineEnd;}static inline void GotoNextLine(int *i){ int j = *i; int a; do { a = level_data_level[j++]; } while (a != 0x0a); *i = j;}int GotoCollection(ptagLevelCollection pColl){ if (theMap->current == pColl) return 0; theMap->current = pColl; PlayRestart(); return 1;}//===============================================================================//Destroy Functions:void DestroyMap(void){ ptagLevelCollection pCollection1; ptagLevelCollection pCollection2; ptagLevelCollection pCollection3; pCollection1 = theMap->head; if (pCollection1) { pCollection2 = pCollection1->next; while ((pCollection2) && (pCollection2 != pCollection1)) { pCollection3 = pCollection2; DestroyCollection(pCollection3); pCollection2 = pCollection2->next; } DestroyCollection(pCollection1); } DestroyLevel(theMap->currentLevel); DestroyStep(); free(theMap);}static void DestroyCollection(ptagLevelCollection pCollection){ ptagLevel pLevel1; ptagLevel pLevel2; ptagLevel pLevel3; pLevel1 = pCollection->head; if (pLevel1) { pLevel2 = pLevel1->next; while ((pLevel2) && (pLevel2 != pLevel1)) { pLevel3 = pLevel2; DestroyLevel(pLevel3); pLevel2 = pLevel2->next; } DestroyLevel(pLevel1); } free(pCollection); }static void DestroyLevel(ptagLevel pLevel){ if (!pLevel) return; free(pLevel->data); free(pLevel);}static void DestroyStep(void){ int i; ptagStep * pSteps; pSteps = theMap->pSteps; for (i = 0; i < BACK_STEP_SIZE; i++){ if (pSteps[i]) { free(pSteps[i]); pSteps[i] = NULL; } } theMap->shead = -1;}//===============================================================================//Play Functions:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -