diff --git a/.gitignore b/.gitignore index c34b03eb7f6731e292e2869903fa66230b4d27dd..57f030ba09fa2e5078ab0a0a4de66ad2ccd7ca1a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.exe .vs/ .gitee/ -test/ target/ MineSweeper.zip +.git/ +.vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5e33924e1937e567d6f129c7775652230079e955..0000000000000000000000000000000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.associations": { - "opt.h": "c" - } -} \ No newline at end of file diff --git a/README.md b/README.md index 8dbff164e8428884ef758bc54562ae3dac2b032d..fc858efdc9937f78b4f1cf574f4555c7f1b658bb 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,45 @@ # MineSweeper -#### 介绍 +## 介绍 + 扫雷。 -#### 软件架构 +## 软件架构 + 基于 `PainterEngine` 实现。 -#### 编译 +## 编译 + 必须使用 `Threads = win32` 下安装的 `mingw-w64` 进行编译。 在根目录下直接使用 `mingw32-make.exe` 进行编译,编译结果位于 `/MineSweeper.exe`。 -#### TODOList -~~一定会做的~~ +## 测试单元 + +使用 `mingw32-make test` 生成 `/MineSweeper_test.exe`,运行即可。 + +## 细节设计 + +### 菜单 + +菜单分为四级,在左上方: +- help,展示帮助页面 +- save-to-file,已经有自动存档的功能了,这个按钮没什么用 +- color,改变按钮的颜色 +- 写 UI 的人不让说最后这个是什么 + +### 记录 + +在胜利后如果时间能进入相同模式下前十名就会要求输入名字,名字只能是英文或数字。 + +在gamedata里会有三种不同模式的记录txt文件。 + +如果多于十条记录程序会自动覆盖最末尾的记录。 + +允许自行删除数据。在数据的末尾请不要有换行符谢谢! + +相同时间数据以先来后到的顺序计入。 + +### 排行榜 -- 基础交互 - - [ ] UI - - [x] 逻辑处理 - - [ ] 局面选项(长宽等等) - - [ ] 存档、读档 -- 高级设计 - - [ ] 高级统计 <= 这东西要是做不出来就扔了吧,都不是专业选手 \ No newline at end of file +点击排行版若无法获取本次操作的数据请重启程序。排行版最多显示单个模式下六个数据。 \ No newline at end of file diff --git a/assets/cheerpicture.traw b/assets/cheerpicture.traw new file mode 100644 index 0000000000000000000000000000000000000000..d215e60263e798f9a002b453f737fa43e781b40e Binary files /dev/null and b/assets/cheerpicture.traw differ diff --git a/assets/compass.traw b/assets/compass.traw new file mode 100644 index 0000000000000000000000000000000000000000..2e961ceaa74ef2fc13fcc0e9b2221e733678db54 Binary files /dev/null and b/assets/compass.traw differ diff --git a/assets/dividline.traw b/assets/dividline.traw new file mode 100644 index 0000000000000000000000000000000000000000..5fac0841f4187f56ef2beccae736d458be83020d Binary files /dev/null and b/assets/dividline.traw differ diff --git a/assets/easyrank.traw b/assets/easyrank.traw new file mode 100644 index 0000000000000000000000000000000000000000..459d3debd262628798f91cb42160413d69985ff8 Binary files /dev/null and b/assets/easyrank.traw differ diff --git a/assets/failpicture.traw b/assets/failpicture.traw new file mode 100644 index 0000000000000000000000000000000000000000..cfb2d6a7eaab237b46da524b62275515c7fc6b41 Binary files /dev/null and b/assets/failpicture.traw differ diff --git a/assets/flag2picture.traw b/assets/flag2picture.traw new file mode 100644 index 0000000000000000000000000000000000000000..1d6b39a18f368c2322ec7aaebbd351aa77045810 Binary files /dev/null and b/assets/flag2picture.traw differ diff --git a/assets/flag3picture.traw b/assets/flag3picture.traw new file mode 100644 index 0000000000000000000000000000000000000000..3884c4fb42827f38e8acddab295c8f976b8e8a65 Binary files /dev/null and b/assets/flag3picture.traw differ diff --git a/assets/hardrank.traw b/assets/hardrank.traw new file mode 100644 index 0000000000000000000000000000000000000000..e3365585189d89853745a28debc0711273f1d72d Binary files /dev/null and b/assets/hardrank.traw differ diff --git a/assets/helptextpic.traw b/assets/helptextpic.traw new file mode 100644 index 0000000000000000000000000000000000000000..5dd2e127f4b69c3f28dc05694c9ec15686d74342 Binary files /dev/null and b/assets/helptextpic.traw differ diff --git a/assets/helptitle.traw b/assets/helptitle.traw new file mode 100644 index 0000000000000000000000000000000000000000..0b916400f0486e72c22ecfa9af5da79170e8f7f9 Binary files /dev/null and b/assets/helptitle.traw differ diff --git a/assets/midrank.traw b/assets/midrank.traw new file mode 100644 index 0000000000000000000000000000000000000000..8d71f6f18789e730626f914d65e7e0e7f694a0ff Binary files /dev/null and b/assets/midrank.traw differ diff --git a/assets/mine2picture.traw b/assets/mine2picture.traw new file mode 100644 index 0000000000000000000000000000000000000000..ce3ec076d4fcde0b198eea1b9880d17263b75581 Binary files /dev/null and b/assets/mine2picture.traw differ diff --git a/assets/mine3picture.traw b/assets/mine3picture.traw new file mode 100644 index 0000000000000000000000000000000000000000..9d65a685dee490c69715e2e4af8570a62ad5ee95 Binary files /dev/null and b/assets/mine3picture.traw differ diff --git a/assets/modechoose_check.traw b/assets/modechoose_check.traw new file mode 100644 index 0000000000000000000000000000000000000000..fa6ee0b2fc920fe6a96fa4920c1ca27915a07168 Binary files /dev/null and b/assets/modechoose_check.traw differ diff --git a/assets/modechoose_rank_trophy.traw b/assets/modechoose_rank_trophy.traw new file mode 100644 index 0000000000000000000000000000000000000000..0e7b1c5e4bd4153cdd06f434913f9758acb94011 Binary files /dev/null and b/assets/modechoose_rank_trophy.traw differ diff --git a/assets/modechoose_rankpicture.traw b/assets/modechoose_rankpicture.traw new file mode 100644 index 0000000000000000000000000000000000000000..a6d62202ef3f8b9e3311a7dc131faed524899a75 Binary files /dev/null and b/assets/modechoose_rankpicture.traw differ diff --git a/assets/modechoosetitle.traw b/assets/modechoosetitle.traw new file mode 100644 index 0000000000000000000000000000000000000000..ad32a41f0c4ee743baa0f4a4c274271e1c00e80d Binary files /dev/null and b/assets/modechoosetitle.traw differ diff --git a/assets/rank4.traw b/assets/rank4.traw new file mode 100644 index 0000000000000000000000000000000000000000..1f1a52f8a5abdfac4ec14dbd22a76da61774ca6a Binary files /dev/null and b/assets/rank4.traw differ diff --git a/assets/rank5.traw b/assets/rank5.traw new file mode 100644 index 0000000000000000000000000000000000000000..4e7b1477206bfd733acc3e71a3e5098682654aac Binary files /dev/null and b/assets/rank5.traw differ diff --git a/assets/rank6.traw b/assets/rank6.traw new file mode 100644 index 0000000000000000000000000000000000000000..445bd2b20e99b0b43ef54537fedb7b7d5922727a Binary files /dev/null and b/assets/rank6.traw differ diff --git a/assets/ranknote2pic.traw b/assets/ranknote2pic.traw new file mode 100644 index 0000000000000000000000000000000000000000..45692427be257f8f0b271f53aa0951c0b2bb66e7 Binary files /dev/null and b/assets/ranknote2pic.traw differ diff --git a/assets/ranknotepicture.traw b/assets/ranknotepicture.traw new file mode 100644 index 0000000000000000000000000000000000000000..d0170d8853484256e443163a335c6a00c3e42ffe Binary files /dev/null and b/assets/ranknotepicture.traw differ diff --git a/assets/waiting_fordata.traw b/assets/waiting_fordata.traw new file mode 100644 index 0000000000000000000000000000000000000000..c209d42cd38549fbc4bfc68e8fd56fae3938809b Binary files /dev/null and b/assets/waiting_fordata.traw differ diff --git a/assets/what_is_this_pic.traw b/assets/what_is_this_pic.traw new file mode 100644 index 0000000000000000000000000000000000000000..3affef298a6c9c186d4bfee0a256d98376baf52c Binary files /dev/null and b/assets/what_is_this_pic.traw differ diff --git a/gamedata/Rank_easydata.txt b/gamedata/Rank_easydata.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7fe675acdba7fc06af78f04e544d8f847b6939f --- /dev/null +++ b/gamedata/Rank_easydata.txt @@ -0,0 +1,3 @@ +testdata 12.58 +Lizn 16.19 +testdata2 17.03 diff --git a/gamedata/Rank_harddata.txt b/gamedata/Rank_harddata.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/gamedata/Rank_middata.txt b/gamedata/Rank_middata.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/include/mine_map.h b/include/mine_map.h index a1e4aa396cc9c380ed1a386661785a32d69e60f3..f99697957e71dad9713fbfb6bfcf0290c79119f9 100644 --- a/include/mine_map.h +++ b/include/mine_map.h @@ -43,9 +43,7 @@ typedef struct map{ #define MY_MID 16 #define MY_HARD 30 -#define NUM_EASY 30 +#define NUM_EASY 10 #define NUM_MID 40 #define NUM_HARD 99 - - diff --git a/include/opt.h b/include/opt.h index fd1a83b776233ba55101622e0f33942d0f56141f..e855e6b589c5ae17358eff08a3e60dde885d9e50 100644 --- a/include/opt.h +++ b/include/opt.h @@ -94,7 +94,7 @@ int fnOptMidClick(int x,int y,map *m); * @param y * @param m 地图指针 */ -void fnOptAuto(int x,int y, map *m); +int fnOptAuto(int x,int y, map *m); /** * @brief 用于统计周围旗子数量 diff --git a/include/sort.h b/include/sort.h new file mode 100644 index 0000000000000000000000000000000000000000..a27638aa0e6052e2dc32fb2f372c58c9e572d85c --- /dev/null +++ b/include/sort.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include +#include +#define len 10 + +extern char name1[50]; +extern int RANKmode; +extern float duration; +bool is_topten(); +void sort(); \ No newline at end of file diff --git a/lib/PainterEngine/platform/windows/px_main.c b/lib/PainterEngine/platform/windows/px_main.c index 0d185c8d35a8249962a0a5e751a08f8d1db7be07..4b546464cc76d4f817666fd46e60e2a479e4630b 100644 --- a/lib/PainterEngine/platform/windows/px_main.c +++ b/lib/PainterEngine/platform/windows/px_main.c @@ -299,7 +299,7 @@ void setCurrentDirectory() setCurrentDirectory(); PX_srand(time(NULL)); if(!PX_ApplicationInitialize(&App,PX_GetScreenWidth(),PX_GetScreenHeight()))return 0; - if(!PX_CreateWindow(App.runtime.surface_width,App.runtime.surface_height,App.runtime.window_width,App.runtime.window_height,PX_APPLICATION_NAME)) + if(!PX_CreateWindow(App.runtime.surface_width,App.runtime.surface_height,App.runtime.window_width,App.runtime.window_height,"MineSweeper")) { return 0; } diff --git a/lib/cutest/CuTest.c b/lib/cutest/CuTest.c new file mode 100644 index 0000000000000000000000000000000000000000..8f611991a83bad949a1fdcd3618bc54d1e9ba550 --- /dev/null +++ b/lib/cutest/CuTest.c @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include +#include + +#include "CuTest.h" + +/*-------------------------------------------------------------------------* + * CuStr + *-------------------------------------------------------------------------*/ + +char* CuStrAlloc(int size) +{ + char* newStr = (char*) malloc( sizeof(char) * (size) ); + return newStr; +} + +char* CuStrCopy(const char* old) +{ + int len = strlen(old); + char* newStr = CuStrAlloc(len + 1); + strcpy(newStr, old); + return newStr; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +void CuStringInit(CuString* str) +{ + str->length = 0; + str->size = STRING_MAX; + str->buffer = (char*) malloc(sizeof(char) * str->size); + str->buffer[0] = '\0'; +} + +CuString* CuStringNew(void) +{ + CuString* str = (CuString*) malloc(sizeof(CuString)); + str->length = 0; + str->size = STRING_MAX; + str->buffer = (char*) malloc(sizeof(char) * str->size); + str->buffer[0] = '\0'; + return str; +} + +void CuStringDelete(CuString *str) +{ + if (!str) return; + free(str->buffer); + free(str); +} + +void CuStringResize(CuString* str, int newSize) +{ + str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize); + str->size = newSize; +} + +void CuStringAppend(CuString* str, const char* text) +{ + int length; + + if (text == NULL) { + text = "NULL"; + } + + length = strlen(text); + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + str->length += length; + strcat(str->buffer, text); +} + +void CuStringAppendChar(CuString* str, char ch) +{ + char text[2]; + text[0] = ch; + text[1] = '\0'; + CuStringAppend(str, text); +} + +void CuStringAppendFormat(CuString* str, const char* format, ...) +{ + va_list argp; + char buf[HUGE_STRING_LEN]; + va_start(argp, format); + vsprintf(buf, format, argp); + va_end(argp); + CuStringAppend(str, buf); +} + +void CuStringInsert(CuString* str, const char* text, int pos) +{ + int length = strlen(text); + if (pos > str->length) + pos = str->length; + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1); + str->length += length; + memcpy(str->buffer + pos, text, length); +} + +/*-------------------------------------------------------------------------* + * CuTest + *-------------------------------------------------------------------------*/ + +void CuTestInit(CuTest* t, const char* name, TestFunction function) +{ + t->name = CuStrCopy(name); + t->failed = 0; + t->ran = 0; + t->message = NULL; + t->function = function; + t->jumpBuf = NULL; +} + +CuTest* CuTestNew(const char* name, TestFunction function) +{ + CuTest* tc = CU_ALLOC(CuTest); + CuTestInit(tc, name, function); + return tc; +} + +void CuTestDelete(CuTest *t) +{ + if (!t) return; + free(t->name); + free(t); +} + +void CuTestRun(CuTest* tc) +{ + jmp_buf buf; + tc->jumpBuf = &buf; + if (setjmp(buf) == 0) + { + tc->ran = 1; + (tc->function)(tc); + } + tc->jumpBuf = 0; +} + +static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string) +{ + char buf[HUGE_STRING_LEN]; + + sprintf(buf, "%s:%d: ", file, line); + CuStringInsert(string, buf, 0); + + tc->failed = 1; + tc->message = string->buffer; + if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0); +} + +void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message) +{ + CuString string; + + CuStringInit(&string); + if (message2 != NULL) + { + CuStringAppend(&string, message2); + CuStringAppend(&string, ": "); + } + CuStringAppend(&string, message); + CuFailInternal(tc, file, line, &string); +} + +void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition) +{ + if (condition) return; + CuFail_Line(tc, file, line, NULL, message); +} + +void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + const char* expected, const char* actual) +{ + CuString string; + if ((expected == NULL && actual == NULL) || + (expected != NULL && actual != NULL && + strcmp(expected, actual) == 0)) + { + return; + } + + CuStringInit(&string); + if (message != NULL) + { + CuStringAppend(&string, message); + CuStringAppend(&string, ": "); + } + CuStringAppend(&string, "expected <"); + CuStringAppend(&string, expected); + CuStringAppend(&string, "> but was <"); + CuStringAppend(&string, actual); + CuStringAppend(&string, ">"); + CuFailInternal(tc, file, line, &string); +} + +void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + int expected, int actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected <%d> but was <%d>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + +void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + double expected, double actual, double delta) +{ + char buf[STRING_MAX]; + if (fabs(expected - actual) <= delta) return; + sprintf(buf, "expected <%f> but was <%f>", expected, actual); + + CuFail_Line(tc, file, line, message, buf); +} + +void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + void* expected, void* actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + + +/*-------------------------------------------------------------------------* + * CuSuite + *-------------------------------------------------------------------------*/ + +void CuSuiteInit(CuSuite* testSuite) +{ + testSuite->count = 0; + testSuite->failCount = 0; + memset(testSuite->list, 0, sizeof(testSuite->list)); +} + +CuSuite* CuSuiteNew(void) +{ + CuSuite* testSuite = CU_ALLOC(CuSuite); + CuSuiteInit(testSuite); + return testSuite; +} + +void CuSuiteDelete(CuSuite *testSuite) +{ + unsigned int n; + for (n=0; n < MAX_TEST_CASES; n++) + { + if (testSuite->list[n]) + { + CuTestDelete(testSuite->list[n]); + } + } + free(testSuite); + +} + +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) +{ + assert(testSuite->count < MAX_TEST_CASES); + testSuite->list[testSuite->count] = testCase; + testSuite->count++; +} + +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2) +{ + int i; + for (i = 0 ; i < testSuite2->count ; ++i) + { + CuTest* testCase = testSuite2->list[i]; + CuSuiteAdd(testSuite, testCase); + } +} + +void CuSuiteRun(CuSuite* testSuite) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + CuTestRun(testCase); + if (testCase->failed) { testSuite->failCount += 1; } + } +} + +void CuSuiteSummary(CuSuite* testSuite, CuString* summary) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + CuStringAppend(summary, testCase->failed ? "F" : "."); + } + CuStringAppend(summary, "\n\n"); +} + +void CuSuiteDetails(CuSuite* testSuite, CuString* details) +{ + int i; + int failCount = 0; + + if (testSuite->failCount == 0) + { + int passCount = testSuite->count - testSuite->failCount; + const char* testWord = passCount == 1 ? "test" : "tests"; + CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord); + } + else + { + if (testSuite->failCount == 1) + CuStringAppend(details, "There was 1 failure:\n"); + else + CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount); + + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + if (testCase->failed) + { + failCount++; + CuStringAppendFormat(details, "%d) %s: %s\n", + failCount, testCase->name, testCase->message); + } + } + CuStringAppend(details, "\n!!!FAILURES!!!\n"); + + CuStringAppendFormat(details, "Runs: %d ", testSuite->count); + CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount); + CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount); + } +} diff --git a/lib/cutest/CuTest.h b/lib/cutest/CuTest.h new file mode 100644 index 0000000000000000000000000000000000000000..8b32773d2bfede2fbf67189c2bef7cebf442ba8c --- /dev/null +++ b/lib/cutest/CuTest.h @@ -0,0 +1,116 @@ +#ifndef CU_TEST_H +#define CU_TEST_H + +#include +#include + +#define CUTEST_VERSION "CuTest 1.5" + +/* CuString */ + +char* CuStrAlloc(int size); +char* CuStrCopy(const char* old); + +#define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) + +#define HUGE_STRING_LEN 8192 +#define STRING_MAX 256 +#define STRING_INC 256 + +typedef struct +{ + int length; + int size; + char* buffer; +} CuString; + +void CuStringInit(CuString* str); +CuString* CuStringNew(void); +void CuStringRead(CuString* str, const char* path); +void CuStringAppend(CuString* str, const char* text); +void CuStringAppendChar(CuString* str, char ch); +void CuStringAppendFormat(CuString* str, const char* format, ...); +void CuStringInsert(CuString* str, const char* text, int pos); +void CuStringResize(CuString* str, int newSize); +void CuStringDelete(CuString* str); + +/* CuTest */ + +typedef struct CuTest CuTest; + +typedef void (*TestFunction)(CuTest *); + +struct CuTest +{ + char* name; + TestFunction function; + int failed; + int ran; + const char* message; + jmp_buf *jumpBuf; +}; + +void CuTestInit(CuTest* t, const char* name, TestFunction function); +CuTest* CuTestNew(const char* name, TestFunction function); +void CuTestRun(CuTest* tc); +void CuTestDelete(CuTest *t); + +/* Internal versions of assert functions -- use the public versions */ +void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message); +void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition); +void CuAssertStrEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + const char* expected, const char* actual); +void CuAssertIntEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + int expected, int actual); +void CuAssertDblEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + double expected, double actual, double delta); +void CuAssertPtrEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + void* expected, void* actual); + +/* public assert functions */ + +#define CuFail(tc, ms) CuFail_Line( (tc), __FILE__, __LINE__, NULL, (ms)) +#define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond)) +#define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond)) + +#define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) +#define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) +#define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertPtrEquals_Msg(tc,ms,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) + +#define CuAssertPtrNotNull(tc,p) CuAssert_Line((tc),__FILE__,__LINE__,"null pointer unexpected",(p != NULL)) +#define CuAssertPtrNotNullMsg(tc,msg,p) CuAssert_Line((tc),__FILE__,__LINE__,(msg),(p != NULL)) + +/* CuSuite */ + +#define MAX_TEST_CASES 1024 + +#define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST)) + +typedef struct +{ + int count; + CuTest* list[MAX_TEST_CASES]; + int failCount; + +} CuSuite; + + +void CuSuiteInit(CuSuite* testSuite); +CuSuite* CuSuiteNew(void); +void CuSuiteDelete(CuSuite *testSuite); +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); +void CuSuiteRun(CuSuite* testSuite); +void CuSuiteSummary(CuSuite* testSuite, CuString* summary); +void CuSuiteDetails(CuSuite* testSuite, CuString* details); + +#endif /* CU_TEST_H */ diff --git a/lib/cutest/license.txt b/lib/cutest/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..fd81689df465a286027864a0905f3a160acf08b3 --- /dev/null +++ b/lib/cutest/license.txt @@ -0,0 +1,38 @@ +NOTE + +The license is based on the zlib/libpng license. For more details see +http://www.opensource.org/licenses/zlib-license.html. The intent of the +license is to: + +- keep the license as simple as possible +- encourage the use of CuTest in both free and commercial applications + and libraries +- keep the source code together +- give credit to the CuTest contributors for their work + +If you ship CuTest in source form with your source distribution, the +following license document must be included with it in unaltered form. +If you find CuTest useful we would like to hear about it. + +LICENSE + +Copyright (c) 2003 Asim Jalis + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software in +a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not +be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. diff --git a/makefile b/makefile index c9bfb3d2c69f22f251b4d70b3be32dce05fb5a17..34d9593ed0817e9fa0a1275fcf99f05dde3623fb 100644 --- a/makefile +++ b/makefile @@ -1,13 +1,19 @@ #mingw32-64 makefile ##################################################### target := MineSweeper.exe +target_test := MineSweeper_test.exe project_path := src +test_path := test painterengine_path := lib\PainterEngine +cutest_path := lib\cutest ##################################################### project_build := $(wildcard $(project_path)/*.c) project_build_o := $(patsubst %.c,%.o,$(project_build)) +test_build := $(wildcard $(test_path)/*.c) +test_build_o := $(patsubst %.c,%.o,$(test_build)) + painterengine_build_core := $(wildcard $(painterengine_path)/core/*.c) painterengine_build_painterengine_o := $(patsubst %.c,%.o,$(painterengine_build_core)) @@ -23,6 +29,10 @@ painterengine_build_painterengine_o += $(patsubst %.c,%.o,$(painterengine_build_ painterengine_build_platform := $(wildcard $(painterengine_path)/platform/windows/*.cpp) painterengine_build_painterengine_o += $(patsubst %.cpp,%.o,$(painterengine_build_platform)) +cutest_build := $(wildcard $(cutest_path)/*.c) +cutest_build_o += $(patsubst %.c,%.o,$(cutest_build)) + +include_path = include all:$(project_build_o) $(painterengine_build_painterengine_o) gcc $(project_build_o) $(painterengine_build_painterengine_o) \ @@ -30,13 +40,14 @@ all:$(project_build_o) $(painterengine_build_painterengine_o) -I "$(painterengine_path)" \ -I "$(project_path)" \ -I "$(painterengine_path)\platform\windows" \ + -I "$(include_path)" \ -L. -lwinmm -ld2d1 -lws2_32 -ldsound -lcomdlg32 -std=c99 mingw32-make clean $(project_path)/%.o:$(project_path)/%.c - gcc -c $^ -o $@ -I "$(painterengine_path)" -I "$(painterengine_path)/platform/windows" -std=c99 + gcc -c $^ -o $@ -I "$(painterengine_path)" -I "$(painterengine_path)/platform/windows" -I "$(include_path)" -std=c99 $(painterengine_path)/architecture/%.o:$(painterengine_path)/architecture/%.c gcc -c $^ -o $@ -I "$(painterengine_path)" -std=c99 @@ -50,13 +61,28 @@ $(painterengine_path)/core/%.o:$(painterengine_path)/core/%.c $(painterengine_path)/platform/windows/%.o:$(painterengine_path)/platform/windows/%.c gcc -c $^ -o $@ -I "$(project_path)" -I "$(painterengine_path)" -I "$(painterengine_path)/platform/windows" -std=c99 +$(cutest_path)/%.o:$(cutest_path)/%.c + gcc -c $^ -o $@ -std=c99 + +$(test_path)/%.o:$(test_path)/%.c + gcc -c $^ -o $@ -I "$(painterengine_path)" -I "$(include_path)" -I "$(cutest_path)" -I "$(project_path)" -std=c99 .PHONY:clean clean: -# -del /s "$(painterengine_path)\core\*.o" -# -del /s "$(painterengine_path)\kernel\*.o" -# -del /s "$(painterengine_path)\architecture\*.o" -# -del /s "$(painterengine_path)\platform\windows\*.o" + -del /s "$(painterengine_path)\core\*.o" + -del /s "$(painterengine_path)\kernel\*.o" + -del /s "$(painterengine_path)\architecture\*.o" + -del /s "$(painterengine_path)\platform\windows\*.o" -del /s "$(project_path)\*.o" + -del /s "$(test_path)\*.o" - \ No newline at end of file +.PHONY:test +test:$(project_build_o) $(painterengine_build_painterengine_o) $(cutest_build_o) $(test_build_o) + gcc $(test_build_o) $(project_build_o) $(painterengine_build_painterengine_o) $(cutest_build_o) \ + -o $(project_path)\..\$(target_test) \ + -I "$(painterengine_path)" \ + -I "$(project_path)" \ + -I "$(painterengine_path)\platform\windows" \ + -I "$(include_path)" \ + -L. -lwinmm -ld2d1 -lws2_32 -ldsound -lcomdlg32 -std=c99 + mingw32-make clean \ No newline at end of file diff --git a/src/PainterEngine_Application.c b/src/PainterEngine_Application.c index 65150718759ea18c9e9f06218bbf45111f0c37f9..e645b68662117623302d39d4f851bd5ea95ae311 100644 --- a/src/PainterEngine_Application.c +++ b/src/PainterEngine_Application.c @@ -1,520 +1,1076 @@ #include "PainterEngine_Application.h" -#include -#include -#include -#include -#include"../include/map.h" -#include"../include/mine_map.h" -#include"../include/opt.h" - - +#include +#include +#include +#include +#include +#include "map.h" +#include "mine_map.h" +#include "opt.h" +#include "sort.h" PX_Application App; - - - -PX_Object* root = PX_NULL;//定义根类型 (px必须) -PX_Object* cellbutton[10][10];//定义了十个小格子的按钮 - -PX_Object* beginbutton;//开始的按钮(在welcome里面 -PX_Object* rankingbutton;//排行榜按钮(在welcome里面 -PX_Object* menubutton;//首页的菜单栏 - -PX_Object* easymode; -PX_Object* midmode; -PX_Object* hardmode; - -PX_Object* title;//标题的图片框(在welcome里面 -px_texture titlepicture;//标题的图片(在welcome里面 -PX_Object* potatoboom;//标题的图片框(在welcome里面 -px_texture potatoboompicture;//标题的图片(在welcome里面 -PX_Object* towelcomebutton;//开始的按钮(在welcome里面 - -PX_Object* firstprize;//第一的图片框(在rank里面 -px_texture firstprizepicture;//第一的图片(in rank -PX_Object* secondprize;//第一的图片框(在rank里面 -px_texture secondprizepicture;//第一的图片(in rank -PX_Object* thirdprize;//第一的图片框(在rank里面 -px_texture thirdprizepicture;//第一的图片(in rank -PX_Object* ranktitle;//第一的图片框(在rank里面 -px_texture ranktitlepicture;//第一的图片(in rank - -px_shape flag;//旗帜的图片(in game +PX_Object *root = PX_NULL; //定义根类型 (px必须) +PX_Object *cellbutton[40][40]; //定义了十个小格子的按钮 + +px_texture titlepicture; //标题的图片(在welcome里面 +px_texture potatoboompicture; //标题的图片(在welcome里面 + +px_texture firstprizepicture; //第一的图片(in rank +px_texture secondprizepicture; //第2的图片(in rank +px_texture thirdprizepicture; +px_texture rank4pic; +px_texture rank5pic; +px_texture rank6pic; +px_texture ranktitlepicture; //排行版的图片(in rank + +PX_Object *failpic; +PX_Object *recordname_message; +px_texture failpicture; //失败的图片与图片框 +px_texture cheerpicture; +px_texture modechoose_title_picture; +px_texture modechoose_check; +px_texture help_title_picture; +px_texture help_text_picture; +px_texture what_is_this_pic; +px_texture ranknote2pic; +px_texture compass; +px_texture modechoose_rank_title_picture; +px_texture modechoose_rank_trophypic; +px_texture modechoose_rank_notepic; + +px_texture easyrankpic; +px_texture midrankpic; +px_texture hardrankpic; +px_texture dividline; +px_texture waiting_fordata; + +px_shape flag; +px_shape flag2; +px_shape flag3; //旗帜的图片(in game px_shape mine; +px_shape mine2; +px_shape mine3; //雷的图片(in game 数字代表对应困难度下的图片形式,如2代表中等难度 opt_t cell[100][100]; -map* Map=NULL; -int mode=3; - -///函数声明 +map *Map = NULL; +int mode = 1; +int RANKmode = 1; +int colormode = 0; +clock_t start, stop; +float duration; // 经历的时间 +px_char *NAME; +char name1[50] = "NULL"; +//////////////////////////////函数声明///////////////////////////////// void WELCOME(); void RANK(); void Gameinit(); - +void Gamefail(); void Gamenow(); -void Lclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr); -void Rclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr); -void Mclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr); - - - +void Lclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void Rclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void Mclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +px_void *towelcomeclick(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void restart(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +px_void *towelcomeclick2(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void openall(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void openhelp(px_void *userptr); +void save_to_file(px_void *userptr); +px_void *congratulation(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +px_void *congratulation2(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +px_void *recordnameY(PX_Object *pObject, PX_Object_Event e, px_void *ptr); +void setcol_white(px_void *userptr); +void setcol_pink(px_void *userptr); +void setcol_purple(px_void *userptr); +void setcol_green(px_void *userptr); +void opencolorfulegg(px_void *userptr); ///////////////////////////////////////////////////////////// -//辅助函数(不看 -/* -px_float PX_Object_Event_GetCursorX(PX_Object_Event e); -px_float PX_Object_Event_GetCursorY(PX_Object_Event e); - -px_void(*ProcessFunc)(PX_Object*, PX_Object_Event e, px_void* ptr);//点击左/右键时运行下方函数 - -*/ ///////////////////////////////////////////////////// - - //游戏正在进行的组件 - - - - - - - - - - - - - - - - - - void Gameinit() { - ///变换界面就删除原页面的object!(由Painterengine provide)/// -//删除之前的按钮(如果有 - if (root){ - PX_ObjectDelete(root); - } //重新创建根对象 root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); ///变换界面就删除原页面的object!(由Painterengine provide)/// -//初始化map + + //初始化map Map = CreateMap(mode); //生成cellbutton - printf("debug"); - for (int i = 1; i <= Map->mx; i++) + int buttonlong, buttonmovedown; + switch (mode) + { + case MODE_EASY: + buttonlong = 50; + buttonmovedown = 0; + break; + case MODE_MID: + buttonlong = 31; + buttonmovedown = 0; + break; + case MODE_HARD: + buttonlong = 24; + buttonmovedown = 50; + break; + } //根据大小生成buttoncell,buttonlong代表button的宽度,buttonmovedone是对困难模式时按钮向下移动 + for (int i = 1; i <= Map->my; i++) { - for (int j = 1; j <= Map->my; j++) + for (int j = 1; j <= Map->mx; j++) { cell[j][i].y = i; - cell[j][i].x = j;//j行i列 x行y - cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, i * 51-51, j * 51-51, 47, 47, " ", PX_NULL); + cell[j][i].x = j; // j行i列 x行y + cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 1 + i * buttonlong - buttonlong, 5 + j * buttonlong - buttonlong + buttonmovedown, buttonlong - 1, buttonlong - 1, " ", PX_NULL); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); - //生成结束cellbutton + //生成结束cellbutton,下为根据colormode扫雷页面cellbutton的更改颜色 + if (colormode == 0) + { + ; //白色就用原来的配色,所以不管 + } + if (colormode == 1) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + } + if (colormode == 2) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + } + if (colormode == 3) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + } } - }printf("debug"); -} - - - - - + } + start = clock(); + px_int buttonx; + if (mode == 3) + { + buttonx = 730; + } + else + { + buttonx = 600; + } + PX_Object *returnwelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, buttonx, 400, 150, 40, "Return", PX_NULL); + PX_ObjectRegisterEvent(returnwelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick2, PX_NULL);//初始化时的一个return按钮。 + return; +} +int failed = 0; -void Gamenow() +void Gamenow() { - printf("debug"); - - if (root) - { - PX_ObjectDelete(root); - } - //重新创建根对象 - root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); - ///变换界面就删除原页面的object!(由Painterengine provide)/// - //printf("debug"); - for (int i = 1; i <= Map->mx; i++) + // printf("debug"); + int buttonlong, buttonmovedown; + switch (mode) { - for (int j = 1; j <= Map->my; j++) + case MODE_EASY: + buttonlong = 50; + buttonmovedown = 0; + break; + case MODE_MID: + buttonlong = 31; + buttonmovedown = 0; + break; + case MODE_HARD: + buttonlong = 24; + buttonmovedown = 50; + break; + } //根据大小生成buttoncell,buttonlong代表button的宽度,buttonmovedone是对困难模式时按钮向下移动(使得它不那么靠上) + for (int i = 1; i <= Map->my; i++) + { + for (int j = 1; j <= Map->mx; j++) { cell[j][i].y = i; - cell[j][i].x = j;//j行i列 x行y列 - - if (Map->stage[j][i] == MARKED) { - - cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, i * 51-51, j * 51-51, 47, 47, "?", PX_NULL); + cell[j][i].x = j; // j行i列 x行y列 + + if (Map->stage[j][i] == MARKED) + { + + cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 1 + i * buttonlong - buttonlong, 5 + j * buttonlong - buttonlong + buttonmovedown, buttonlong - 1, buttonlong - 1, "?", PX_NULL); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); + if (colormode == 0) + { + ; //白色就用原来的配色,所以不管 + } + if (colormode == 1) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + } + if (colormode == 2) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + } + if (colormode == 3) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + } } if (Map->stage[j][i] == FLAGED) - { - cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, i * 51-51, j * 51-51, 47, 47, " ", PX_NULL); - PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); - PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); - PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); - PX_Object_PushButtonSetShape(cellbutton[j][i], &flag); + { + cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 1 + i * buttonlong - buttonlong, 5 + j * buttonlong - buttonlong + buttonmovedown, buttonlong - 1, buttonlong - 1, " ", PX_NULL); + PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); + PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); + PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); + if (mode == MODE_EASY) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &flag); + } + if (mode == MODE_MID) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &flag2); + } + if (mode == MODE_HARD) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &flag3); + } + //不同的mode对应flag的不同大小。 + if (colormode == 0) + { + ; //白色就用原来的配色,所以不管 + } + if (colormode == 1) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + } + if (colormode == 2) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + } + if (colormode == 3) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + } } if (Map->stage[j][i] == UNCOVERED) { - //printf("uncover%d %d\n", j, i); - cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, i * 51-51, j * 51-51, 47, 47, " ", PX_NULL); + // printf("uncover%d %d\n", j, i); + cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 1 + i * buttonlong - buttonlong, 5 + j * buttonlong - buttonlong + buttonmovedown, buttonlong - 1, buttonlong - 1, " ", PX_NULL); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); - + if (colormode == 0) + { + ; //白色就用原来的配色,所以不管 + } + if (colormode == 1) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + } + if (colormode == 2) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + } + if (colormode == 3) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + } } if (Map->stage[j][i] == COVERED) { - //printf("cover%d %d\n", j, i); - cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, i * 51-51, j * 51-51, 47, 47, " ", PX_NULL); + // printf("cover%d %d\n", j, i); + cellbutton[j][i] = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 1 + i * buttonlong - buttonlong, 5 + j * buttonlong - buttonlong + buttonmovedown, buttonlong - 1, buttonlong - 1, " ", PX_NULL); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_EXECUTE, Lclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORRDOWN, Rclickcell, &cell[j][i]); PX_ObjectRegisterEvent(cellbutton[j][i], PX_OBJECT_EVENT_CURSORMDOWN, Mclickcell, &cell[j][i]); - if (opt_count(Map, j, i) == 0) { - PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(32, 255, 255, 255));;//标记为黑色按钮 - + if (opt_count(Map, j, i) == 0) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(32, 255, 255, 255)); + //标记为黑色按钮 } - else { + else + { int count = opt_count(Map, j, i); - char text[2]; + char text[2]; sprintf(text, "%d", count); - if(count) PX_Object_PushButtonSetText(cellbutton[j][i], text); + if (count) + PX_Object_PushButtonSetText(cellbutton[j][i], text); + + if (colormode == 0) + { + ; //白色就用原来的配色,所以不管 + } + if (colormode == 1) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 238, 130, 238)); + } + if (colormode == 2) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 106, 90, 205)); + } + if (colormode == 3) + { + PX_Object_PushButtonSetBorderColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + PX_Object_PushButtonSetCursorColor(cellbutton[j][i], PX_COLOR(255, 46, 139, 87)); + } } - } } } + //下为设置restart和open all 的按钮的语句 + px_int buttonx; + if (mode == 3) + { + buttonx = 730; + } + else + { + buttonx = 600; + } + PX_Object *restartbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, buttonx, 350, 150, 40, "Restart", PX_NULL); + PX_ObjectRegisterEvent(restartbutton, PX_OBJECT_EVENT_EXECUTE, restart, PX_NULL); //重开本局,相同难度模式下 + PX_Object *openallbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, buttonx, 300, 150, 40, "Open all", PX_NULL); + PX_ObjectRegisterEvent(openallbutton, PX_OBJECT_EVENT_EXECUTE, openall, PX_NULL); //打开所有格子 + PX_Object *returnwelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, buttonx, 400, 150, 40, "Return", PX_NULL); + PX_ObjectRegisterEvent(returnwelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick2, PX_NULL);//初始化时的一个return按钮。 + return; +} + +void restart(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + Gameinit(); return; - } ////////////////////////////////////////////////////////////////////////////////// -void Gamewin() { - printf("you win"); +px_void *playagain(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + printf("\nRestarting...\n"); + Gameinit(); +} //重新开始 + +px_void *towelcomeclick(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + printf("\nReturning....\n"); + WELCOME(); +} +px_void *towelcomeclick2(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + stop = clock(); + printf("\nReturning....\n"); + WELCOME(); +} +//返回欢迎页2(增加了停止计时) + +px_void *recordnameY(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + recordname_message = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxInputBox(recordname_message, "Enter your name please ", congratulation, PX_Object_MessageBoxGetInput(recordname_message), congratulation2, PX_NULL); + + return; +} //如果用户想输入名字就记录名字(因为消息对话框只能显示带有ok与cancel的界面,所以不能强制用户输入姓名) + +px_void *congratulation(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + + char *temptext = (char *)ptr; + strcpy(name1, temptext); + // printf("%s",*name1); + sort(duration); + PX_Object *winmessage3 = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertYesNo(winmessage3, "Do you want to paly again?", playagain, PX_NULL, towelcomeclick, PX_NULL); +} //为进入排行榜页面前三专门设置的祝福(免得太罗嗦,也免得输入名字的messagebox被吞掉)在recodename输入名字后调用本函数。 +px_void *congratulation2(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + + PX_Object *winmessage3 = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertYesNo(winmessage3, "Do you want to paly again?", playagain, PX_NULL, towelcomeclick, PX_NULL); +} //若用户点击取消(不输入名字) +////////////////////////////////////////////////////////////////////////////////// +void Gamewin() //游戏胜利 +{ + stop = clock(); //暂停时间 + duration = (float)(stop - start) / CLK_TCK; //获取时间 以s为单位。 + printf("you win,TIME %f", duration); + for (int i = 1; i <= Map->my; i++) + { + for (int j = 1; j <= Map->mx; j++) + { + PX_ObjectSetEnabled(cellbutton[j][i], PX_FALSE); //使得所有按钮无效,无法继续点击! + } + } + + if (is_topten(duration)) //如果能冲进前三,请求其输入名字,因为wjj还没有写函数,我就默认mode1的都进入了排行榜,会调用rank函数 + { + PX_Object *winmessage = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + const char *text[50]; + sprintf(text, "WOW!!!!!!!!!!\nYou Win!\nAND You're in the TOP TEN!!!\n It takes %.2f s\nMay I know your name?", duration); + PX_Object_MessageBoxAlertYesNo(winmessage, text, recordnameY, PX_NULL, congratulation2, PX_NULL); + } + else + { + PX_Object *winmessage = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + const char *text2[50]; + sprintf(text2, "Congradulation!\nYou Win!\nIt takes %.2f s\nDo you want to paly again?", duration); + PX_Object_MessageBoxAlertYesNo(winmessage, text2, playagain, PX_NULL, towelcomeclick, PX_NULL); + } } -void Gamefail() { - printf("debug2"); - for (int i = 1; i < Map->mx; i++) +void Gamefail() //游戏失败 +{ + stop = clock(); //暂停时间就不管了 + failed = 1; + + for (int i = 1; i <= Map->my; i++) { - for (int j = 1; j < Map->my; j++) { - if (Map->mineMap[j][i] == 1) { + for (int j = 1; j <= Map->mx; j++) + { + if (Map->mineMap[j][i] == 1) + { PX_Object_PushButtonSetText(cellbutton[j][i], " "); - PX_Object_PushButtonSetShape(cellbutton[j][i], &mine); + if (mode == 1) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &mine); + } + if (mode == 2) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &mine2); + } + if (mode == 3) + { + PX_Object_PushButtonSetShape(cellbutton[j][i], &mine3); + } + //根据mode调整雷的图片(shape)的大小 PX_Object_PushButtonSetTextColor(cellbutton[j][i], PX_COLOR(255, 255, 0, 0)); } - PX_ObjectSetEnabled(cellbutton[j][i], PX_FALSE);//使得所有按钮无效,无法继续点击! + PX_ObjectSetEnabled(cellbutton[j][i], PX_FALSE); //使得所有按钮无效,无法继续点击! } } + printf("You lose"); + if (mode == 3) + { + failpic = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 720, 20, 200, 80, &failpicture); + } + else + { + failpic = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 570, 20, 200, 80, &failpicture); + } + PX_ObjectRegisterEvent(failpic, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + px_int buttonx; + if (mode == 3) + { + buttonx = 730; + } + else + { + buttonx = 600; + } - printf("you lose"); + PX_Object *returnwelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, buttonx, 400, 150, 40, "Return", PX_NULL); + PX_ObjectRegisterEvent(returnwelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick, PX_NULL); //创建一个return按钮使得玩家可以返回主界面选择难度 + //为困难模式单独适配按钮的位置 } - - - - ////////////////////////////////////////////////////////////////////////////////// - -void Lclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr){ - if (PX_ObjectIsCursorInRegion(pObject, e)) +//左中右键的控制&open all的控制函数 +void Lclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + if (PX_ObjectIsCursorInRegion(pObject, e)) //检测鼠标操作是否在范围内 { - - opt_t* pcell = (opt_t*)ptr; + + opt_t *pcell = (opt_t *)ptr; int temp; - temp= fnOptLeftClick(pcell->x, pcell->y, Map); - - if (Map->mineMap[pcell->x][pcell->y] == 1) + temp = fnOptLeftClick(pcell->x, pcell->y, Map); + + if (temp == BOOM) { Gamefail(); - }//是雷就失败 - else if (opt_is_scuess(*Map)) { + } //是雷就失败 + else if (opt_is_scuess(*Map)) + { Gamewin(); } - else + else { - - Gamenow(); + Gamenow(); } - } } -void Rclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr) +void Rclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { if (PX_ObjectIsCursorInRegion(pObject, e)) { - - opt_t* pcell = (opt_t*)ptr; + + opt_t *pcell = (opt_t *)ptr; int temp; temp = fnOptRightClick(pcell->x, pcell->y, Map); - if(opt_is_scuess(*Map)) + if (opt_is_scuess(*Map)) { Gamewin(); } - else { + else + { Gamenow(); - } - } - } - -void Mclickcell(PX_Object* pObject, PX_Object_Event e, px_void* ptr) +void Mclickcell(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { if (PX_ObjectIsCursorInRegion(pObject, e)) { - opt_t* pcell = (opt_t*)ptr; + opt_t *pcell = (opt_t *)ptr; int temp; temp = fnOptMidClick(pcell->x, pcell->y, Map); + if (temp == BOOM) + { + Gamefail(); + } + else if (opt_is_scuess(*Map)) + { + Gamewin(); + } + else + { + Gamenow(); + } + } +} +void openall(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + if (PX_ObjectIsCursorInRegion(pObject, e)) + { + opt_t *pcell = (opt_t *)ptr; + int temp; + temp = fnTotalFlag(Map); + if (opt_is_scuess(*Map)) + { + Gamewin(); + } + else + { - Gamenow(); - + Gamefail(); + } } + return; } + ///////////////////////////////////////////////////////////////////////// -void ceasy(PX_Object* pObject, PX_Object_Event e, px_void* ptr) +//不同的模式选择函数(点击模式按钮后调用本区域函数) +void ceasy(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { if (PX_ObjectIsCursorInRegion(pObject, e)) { mode = 1; Gameinit(); - } - } -void cmid(PX_Object* pObject, PX_Object_Event e, px_void* ptr) +void cmid(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { if (PX_ObjectIsCursorInRegion(pObject, e)) { - + mode = 2; Gameinit(); - } - } -void chard(PX_Object* pObject, PX_Object_Event e, px_void* ptr) +void chard(PX_Object *pObject, PX_Object_Event e, px_void *ptr) { - - mode = 1; + if (PX_ObjectIsCursorInRegion(pObject, e)) + { + mode = 3; Gameinit(); + } +} +///////////////////////////////////////////////////// +//下为模式选择界面(进入游戏时的模式选择) +void modechoose() +{ - + //删除之前的按钮(如果有 -} -void modechoose() { - ///变换界面就删除原页面的object!(由Painterengine provide)/// -//删除之前的按钮(如果有 - if (root) - { - PX_ObjectDelete(root); - } - //重新创建根对象 root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); - ///变换界面就删除原页面的object!(由Painterengine provide)/// + //重新创建根对象 - easymode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 218, 200, 228, 64, "easy", PX_NULL); + PX_Object *easymode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 150, 228, 64, "easy", PX_NULL); PX_ObjectRegisterEvent(easymode, PX_OBJECT_EVENT_EXECUTE, ceasy, &easymode); - midmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 300, 228, 64, "middle", PX_NULL); + PX_Object *midmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 250, 228, 64, "middle", PX_NULL); PX_ObjectRegisterEvent(midmode, PX_OBJECT_EVENT_EXECUTE, cmid, &midmode); - hardmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 418, 400, 228, 64, "hard", PX_NULL); + PX_Object *hardmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 350, 228, 64, "hard", PX_NULL); PX_ObjectRegisterEvent(hardmode, PX_OBJECT_EVENT_EXECUTE, chard, &hardmode); -} - - -//////////////////////----------------------------------rank 组件 -void towelcomeclick(PX_Object* pObject, PX_Object_Event e, px_void* ptr) -{ - WELCOME(); + PX_Object *modechoose_title = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 290, 20, 300, 90, &modechoose_title_picture); + PX_ObjectRegisterEvent(modechoose_title, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *modechoose_checkpic = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 290, 450, 300, 90, &modechoose_check); + PX_ObjectRegisterEvent(modechoose_checkpic, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); } - +///////////////////////////////////////////////////// +// rank 组件 void RANK() { - ///变换界面就删除原页面的object!(由Painterengine provide)/// -//删除之前的按钮(如果有 - if (root) - { - PX_ObjectDelete(root); - } - //重新创建根对象 - root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); - ///变换界面就删除原页面的object!(由Painterengine provide)/// + root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); + ///变换界面就删除原页面的object!(由Painterengine provide)/// - towelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 400, 228, 64, "Return", PX_NULL); + PX_Object *towelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 40, 420, 160, 45, "Return", PX_NULL); PX_ObjectRegisterEvent(towelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick, &towelcomebutton); - //第一二三名排版 - firstprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 90, 90, 75, 75, &firstprizepicture); + PX_Object *firstprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, -5, 90, 75, 75, &firstprizepicture); PX_ObjectRegisterEvent(firstprize, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - secondprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 90, 190, 75, 75, &secondprizepicture); + PX_Object *secondprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, -5, 190, 75, 75, &secondprizepicture); PX_ObjectRegisterEvent(secondprize, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - thirdprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 90, 290, 75, 75, &thirdprizepicture); + PX_Object *thirdprize = PX_Object_ImageCreate(&App.runtime.mp_resources, root, -5, 290, 75, 75, &thirdprizepicture); PX_ObjectRegisterEvent(thirdprize, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - ranktitle = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 330, 20, 210, 75, &ranktitlepicture); + + PX_Object *divid_line = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 360, -35, 6, 550, &dividline); + ; + PX_ObjectRegisterEvent(divid_line, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + + PX_Object *rank4 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 370, 90, 75, 75, &rank4pic); + PX_ObjectRegisterEvent(rank4, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *rank5 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 370, 190, 75, 75, &rank5pic); + PX_ObjectRegisterEvent(rank5, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *rank6 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 370, 290, 75, 75, &rank6pic); + PX_ObjectRegisterEvent(rank6, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + + PX_Object *ranktitle = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 280, 0, 210, 75, &ranktitlepicture); PX_ObjectRegisterEvent(ranktitle, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - -} -//////////////////////----------------------------------rank 组件 + PX_Object *cheer = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 700, 415, 107, 107, &cheerpicture); + ; + PX_ObjectRegisterEvent(cheer, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *ranknote2 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 190, 400, 500, 100, &ranknote2pic); + PX_ObjectRegisterEvent(ranknote2, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + + PX_Object *easyrank; + PX_Object *midrank; + PX_Object *hardrank; + switch (RANKmode) + { + case 1: + easyrank = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 750, -12, 100, 150, &easyrankpic); + PX_ObjectRegisterEvent(easyrank, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + break; + case 2: + midrank = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 750, -12, 100, 150, &midrankpic); + PX_ObjectRegisterEvent(midrank, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + break; + case 3: + hardrank = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 750, -12, 100, 150, &hardrankpic); + PX_ObjectRegisterEvent(hardrank, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + break; + } //根据选择的排行版模式难度对应不同的提示图片(右侧标有简单困难的小旗帜) + + int valid_data = 0; + typedef struct + { + char name[50]; + float time; + } players; + players player[11]; + if (RANKmode == 1) + { + FILE *fp1; + fp1 = fopen("gamedata\\Rank_easydata.txt", "r"); + while (1) + { + if ((fscanf(fp1, "%s %f", player[valid_data + 1].name, &player[valid_data + 1].time)) == EOF) + { + break; + } + else + { + valid_data++; + } + } + } + if (RANKmode == 2) + { + FILE *fp2; + fp2 = fopen("gamedata\\Rank_middata.txt", "r"); + while (1) + { + if ((fscanf(fp2, "%s %f", player[valid_data + 1].name, &player[valid_data + 1].time)) == EOF) + { + break; + } + else + { + valid_data++; + } + } + } + if (RANKmode == 3) + { + FILE *fp3; + fp3 = fopen("gamedata\\Rank_harddata.txt", "r"); + while (1) + { + if ((fscanf(fp3, "%s %f", player[valid_data + 1].name, &player[valid_data + 1].time)) == EOF) + { + break; + } + else + { + valid_data++; + } + } + } + + //下为根据有效数据的情况判断哪些位置还没有数据,以虚位以待的图片进行代替 + + PX_Object *waiting_fordata1; + PX_Object *waiting_fordata2; + PX_Object *waiting_fordata3; + PX_Object *waiting_fordata4; + PX_Object *waiting_fordata5; + PX_Object *waiting_fordata6; + switch (valid_data) + { + case 0: + waiting_fordata1 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 70, 100, 250, 50, &waiting_fordata); + ; + PX_ObjectRegisterEvent(waiting_fordata1, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 1: + waiting_fordata2 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 70, 200, 250, 50, &waiting_fordata); + ; + PX_ObjectRegisterEvent(waiting_fordata2, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 2: + waiting_fordata3 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 70, 310, 250, 50, &waiting_fordata); + ; + PX_ObjectRegisterEvent(waiting_fordata3, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 3: + waiting_fordata4 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 440, 100, 250, 50, &waiting_fordata); + ; + PX_ObjectRegisterEvent(waiting_fordata4, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 4: + waiting_fordata5 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 440, 200, 250, 50, &waiting_fordata); + ; + PX_ObjectRegisterEvent(waiting_fordata5, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 5: + waiting_fordata6 = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 440, 310, 250, 50, &waiting_fordata); + PX_ObjectRegisterEvent(waiting_fordata6, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + default: + break; + } + PX_Object *No1; + char textno1[70]; + PX_Object *No2; + char textno2[70]; + PX_Object *No3; + char textno3[70]; + PX_Object *No4; + char textno4[70]; + PX_Object *No5; + char textno5[70]; + PX_Object *No6; + char textno6[70]; + //根据有效数据的情况判断需要展示哪些文本框 + switch (valid_data) + { + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 6: + sprintf(textno6, "NAME: %s \nTIME: %.3f s", player[6].name, player[6].time); + No6 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 480, 210, 250, 250, textno6, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No6, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 5: + sprintf(textno5, "NAME: %s \nTIME: %.3f s", player[5].name, player[5].time); + No5 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 480, 110, 250, 250, textno5, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No5, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 4: + sprintf(textno4, "NAME: %s \nTIME: %.3f s", player[4].name, player[4].time); + No4 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 480, 10, 250, 250, textno4, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No4, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 3: + sprintf(textno3, "NAME: %s \nTIME: %.3f s", player[3].name, player[3].time); + No3 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 100, 210, 250, 250, textno3, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No3, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 2: + sprintf(textno2, "NAME: %s \nTIME: %.3f s", player[2].name, player[2].time); + No2 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 100, 110, 250, 250, textno2, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No2, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 1: + sprintf(textno1, "NAME: %s \nTIME: %.3f s", player[1].name, player[1].time); + No1 = PX_Object_LabelCreate(&App.runtime.mp_resources, root, 100, 10, 250, 250, textno1, PX_NULL, PX_COLOR(140, 255, 228, 196)); + PX_ObjectRegisterEvent(No1, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + case 0: + break; + } + return; +} +///////////////////////////////////////////////////////////////////////// +//不同的模式选择函数(点击模式按钮后调用本区域函数) +void ceasy_rank(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + if (PX_ObjectIsCursorInRegion(pObject, e)) + { + RANKmode = 1; + RANK(); + } +} +void cmid_rank(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + if (PX_ObjectIsCursorInRegion(pObject, e)) + { + RANKmode = 2; + RANK(); + } +} +void chard_rank(PX_Object *pObject, PX_Object_Event e, px_void *ptr) +{ + if (PX_ObjectIsCursorInRegion(pObject, e)) + { + RANKmode = 3; + RANK(); + } +} +///////////////////////////////////////////////////// +//下为模式选择界面(进入排行时的模式选择) +void modechoose_rank() +{ + //删除之前的按钮(如果有 + root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); + //重新创建根对象 -//////////////////////----------------------------------welcome 组件 + PX_Object *easymode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 150, 228, 64, "easy", PX_NULL); + PX_ObjectRegisterEvent(easymode, PX_OBJECT_EVENT_EXECUTE, ceasy_rank, &easymode); + PX_Object *midmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 250, 228, 64, "middle", PX_NULL); + PX_ObjectRegisterEvent(midmode, PX_OBJECT_EVENT_EXECUTE, cmid_rank, &midmode); + PX_Object *hardmode = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 318, 350, 228, 64, "hard", PX_NULL); + PX_ObjectRegisterEvent(hardmode, PX_OBJECT_EVENT_EXECUTE, chard_rank, &hardmode); + PX_Object *modechoose_rank_title = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 290, 20, 290, 120, &modechoose_rank_title_picture); + PX_ObjectRegisterEvent(modechoose_rank_title, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *modechoose_rank_trophy = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 40, 360, 290, 200, &modechoose_rank_trophypic); + PX_ObjectRegisterEvent(modechoose_rank_trophy, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *modechoose_rank_note = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 150, 360, 590, 200, &modechoose_rank_notepic); + PX_ObjectRegisterEvent(modechoose_rank_note, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); +} +///////////////////////////////////////////// +// welcome 组件 -px_void beginclick(PX_Object* pObject, PX_Object_Event e, px_void* ptr)//开始按钮的跳转 +px_void beginclick(PX_Object *pObject, PX_Object_Event e, px_void *ptr) //开始按钮的跳转 { - modechoose(); - - printf("NOW begin!\n"); + modechoose(); } -px_void rankingclick(PX_Object* pObject, PX_Object_Event e, px_void* ptr)//排名按钮的跳转 +px_void rankingclick(PX_Object *pObject, PX_Object_Event e, px_void *ptr) //排名按钮的跳转 { - RANK(); + printf("Is ranking\t"); + modechoose_rank(); } - -void WELCOME()//初始化函数 +void WELCOME() //初始化函数 { - ///变换界面就删除原页面的object!(由Painterengine provide)/// + ///变换界面就删除原页面的object!(由Painterengine provide)/// //删除之前的按钮(如果有 - if (root) - { - PX_ObjectDelete(root); - } + //重新创建根对象 root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); - ///变换界面就删除原页面的object!/// - - + ///变换界面就删除原页面的object!/// //初始化两个按钮 - beginbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 145, 400, 228, 64, "begin now", PX_NULL); + PX_Object *beginbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 145, 400, 228, 64, "begin now", PX_NULL); PX_ObjectRegisterEvent(beginbutton, PX_OBJECT_EVENT_EXECUTE, beginclick, &beginbutton); - - rankingbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 490, 400, 228, 64, "RANK", PX_NULL); + PX_Object *rankingbutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 490, 400, 228, 64, "RANK", PX_NULL); PX_ObjectRegisterEvent(rankingbutton, PX_OBJECT_EVENT_EXECUTE, rankingclick, &rankingbutton); - - //初始化界面的汉字 - - //PX_FontModuleDrawText(&App.runtime.RenderSurface, PX_NULL, 395, 200, PX_ALIGN_MIDTOP, "TEXT", PX_COLOR(250, 0, 0, 0)); - //展示静态文本框 - //title=PX_Object_LabelCreate(&App.runtime.mp_ui, root, 395, 175, 256, 64, "Minesweeper", PX_NULL, PX_COLOR(255 ,106, 106, 0)); - //PX_ObjectRegisterEvent(title, PX_OBJECT_EVENT_ANY,PX_NULL, PX_NULL); - - title = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 40, -225, 800,800, &titlepicture ); + PX_Object *title = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 40, -225, 800, 800, &titlepicture); PX_ObjectRegisterEvent(title, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - potatoboom = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 2, 415, 110, 105, &potatoboompicture); + PX_Object *potatoboom = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 2, 415, 110, 105, &potatoboompicture); PX_ObjectRegisterEvent(potatoboom, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); - //这是MENU - PX_Object_Menu_Item* pItem; - menubutton=PX_Object_MenuCreate(&App.runtime.mp_ui, root,10,10,100,PX_NULL); - - pItem = PX_Object_MenuAddItem(menubutton,PX_Object_MenuGetRootItem(menubutton),"【Menu",PX_NULL,PX_NULL); - PX_Object_MenuAddItem(menubutton,pItem, "【Color", PX_NULL, PX_NULL); - - // ↑可以用一个回调函数!!!!!!必须先创建一个px_void callback(px_void* userptr)函数,【函数名可以任意取】在函数里写东西 - - + PX_Object_Menu_Item *pItem, *pItem1; + PX_Object *menubutton = PX_Object_MenuCreate(&App.runtime.mp_ui, root, 10, 10, 200, PX_NULL); + + pItem = PX_Object_MenuAddItem(menubutton, PX_Object_MenuGetRootItem(menubutton), "_______< M e N u >_______", PX_NULL, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem, "[ H E L P ]", openhelp, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem, "[ Save to file ]", save_to_file, PX_NULL); + pItem1 = PX_Object_MenuAddItem(menubutton, pItem, "[ Color ]", PX_NULL, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem1, "[ white ]", setcol_white, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem1, "[ pink ]", setcol_pink, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem1, "[ purple ]", setcol_purple, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem1, "[ green ]", setcol_green, PX_NULL); + PX_Object_MenuAddItem(menubutton, pItem, "[ What is this?????? ]", opencolorfulegg, PX_NULL); + + // ↑可以用一个回调函数!!!!!!必须先创建一个px_void callback(px_void* userptr)函数,【函数名可以任意取】在函数里写东西 +} +////////////////////////////////////////////////////////////// +//下为menu的返回函数 +//下为颜色返回函数 +void setcol_white(px_void *userptr) +{ + colormode = 0; + PX_Object *setcolor = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertOk(setcolor, "The cells' color has changed to WHITE.It will take effect in the game interface", PX_NULL, PX_NULL); + return; +} +void setcol_pink(px_void *userptr) +{ + colormode = 1; + PX_Object *setcolor = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertOk(setcolor, "The cells' color has changed to PINK.It will take effect only in the game interface", PX_NULL, PX_NULL); +} +void setcol_purple(px_void *userptr) +{ + colormode = 2; + PX_Object *setcolor = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertOk(setcolor, "The cells' color has changed to PURPLE.It will take effect only in the game interface", PX_NULL, PX_NULL); } +void setcol_green(px_void *userptr) +{ + colormode = 3; + PX_Object *setcolor = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertOk(setcolor, "The cells' color has changed to GREEN.It will take effect only in the game interface", PX_NULL, PX_NULL); +} +//下为帮助界面 +void openhelp(px_void *userptr) +{ + //重新创建根对象 + root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); + ///变换界面就删除原页面的object!/// + PX_Object *towelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 370, 450, 128, 32, "Return", PX_NULL); + PX_ObjectRegisterEvent(towelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick, &towelcomebutton); -/// ///////////////////////////////////////-----------------------welcome组件 + PX_Object *helptitle = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 330, 10, 210, 75, &help_title_picture); + PX_ObjectRegisterEvent(helptitle, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *helptext = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 90, -100, 700, 700, &help_text_picture); + PX_ObjectRegisterEvent(helptext, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + PX_Object *compasspic = PX_Object_ImageCreate(&App.runtime.mp_resources, root, 710, 345, 108, 108, &compass); + ; //第一的图片框(在rank里面 + PX_ObjectRegisterEvent(compasspic, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + return; +} +void opencolorfulegg(px_void *userptr) +{ + //重新创建根对象 + root = PX_ObjectCreate(&App.runtime.mp_ui, PX_NULL, 0, 0, 0, 0, 0, 0); + ///变换界面就删除原页面的object!/// + PX_Object *towelcomebutton = PX_Object_PushButtonCreate(&App.runtime.mp_ui, root, 370, 450, 128, 32, "Return", PX_NULL); + PX_ObjectRegisterEvent(towelcomebutton, PX_OBJECT_EVENT_EXECUTE, towelcomeclick, &towelcomebutton); + PX_Object *what_is_this = PX_Object_ImageCreate(&App.runtime.mp_resources, root, -60, -250, 1000, 1000, &what_is_this_pic); + PX_ObjectRegisterEvent(what_is_this, PX_OBJECT_EVENT_ANY, PX_NULL, PX_NULL); + return; +} +void save_to_file(px_void *userptr) +{ + PX_Object *save_to_file_message = PX_Object_MessageBoxCreate(&App.runtime.mp_ui, root, PX_NULL); + PX_Object_MessageBoxAlertOk(save_to_file_message, " We automatically save it when win.\nYou can check it in the gamedata folder.\nWe only record the top ten of each mode", PX_NULL, PX_NULL); + return; +} +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// 以下为painterengine专门的函数请尽量不要更改!!! // +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// -px_bool PX_ApplicationInitialize(PX_Application* pApp, px_int screen_width, px_int screen_height)//初始化函数(px内部) +px_bool PX_ApplicationInitialize(PX_Application *pApp, px_int screen_width, px_int screen_height) //初始化函数(px内部) { + SetConsoleTitle("MineSweeper_info"); PX_ApplicationInitializeDefault(&pApp->runtime, screen_width, screen_height); - //PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &titlepicture, "titlepicture.traw");//加载图片!! - //PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &shape_mine, "mine.traw");//加载图片!! - //PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &shape_mine, "mine.traw");//加载图片!! - - //以下为欢迎页图片 - - PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &titlepicture, "assets\\titlepicture2.traw");//加载图片!! + + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &titlepicture, "assets\\titlepicture2.traw"); //加载图片!! PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &potatoboompicture, "assets\\potatoboom.traw"); -//注意文件地址!放在project里面,为何不能用相对地址??? ↑ -//以下为排行版页图片 - PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &firstprizepicture, "assets\\firstprize.traw");//加载图片!! + //注意文件地址! + //以下为排行版页图片 + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &firstprizepicture, "assets\\firstprize.traw"); //加载图片!! PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &secondprizepicture, "assets\\secondprize.traw"); PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &thirdprizepicture, "assets\\thirdprize.traw"); PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &ranktitlepicture, "assets\\ranktitlepicture.traw"); - - - - + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &failpicture, "assets\\failpicture.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &cheerpicture, "assets\\cheerpicture.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &modechoose_title_picture, "assets\\modechoosetitle.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &modechoose_check, "assets\\modechoose_check.traw"); + + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &help_title_picture, "assets\\helptitle.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &help_text_picture, "assets\\helptextpic.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &what_is_this_pic, "assets\\what_is_this_pic.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &modechoose_rank_title_picture, "assets\\modechoose_rankpicture.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &modechoose_rank_trophypic, "assets\\modechoose_rank_trophy.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &modechoose_rank_notepic, "assets\\ranknotepicture.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &ranknote2pic, "assets\\ranknote2pic.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &compass, "assets\\compass.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &easyrankpic, "assets\\easyrank.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &midrankpic, "assets\\midrank.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &hardrankpic, "assets\\hardrank.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &dividline, "assets\\dividline.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &waiting_fordata, "assets\\waiting_fordata.traw"); + + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &rank4pic, "assets\\rank4.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &rank5pic, "assets\\rank5.traw"); + PX_LoadTextureFromFile(&pApp->runtime.mp_resources, &rank6pic, "assets\\rank6.traw"); PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &flag, "assets\\flagpicture.traw"); + PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &flag2, "assets\\flag2picture.traw"); + PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &flag3, "assets\\flag3picture.traw"); PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &mine, "assets\\minepicture.traw"); - - - WELCOME();//直接前往welcome函数 + PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &mine2, "assets\\mine2picture.traw"); + PX_LoadShapeFromFile(&pApp->runtime.mp_resources, &mine3, "assets\\mine3picture.traw"); + + WELCOME(); //直接前往welcome函数 return PX_TRUE; } -px_void PX_ApplicationUpdate(PX_Application* pApp, px_dword elpased) +px_void PX_ApplicationUpdate(PX_Application *pApp, px_dword elpased) { - } -px_void PX_ApplicationRender(PX_Application* pApp, px_dword elpased) +px_void PX_ApplicationRender(PX_Application *pApp, px_dword elpased) { - px_surface* pRenderSurface = &pApp->runtime.RenderSurface; + px_surface *pRenderSurface = &pApp->runtime.RenderSurface; PX_RuntimeRenderClear(&pApp->runtime, PX_OBJECT_UI_DEFAULT_BACKGROUNDCOLOR); PX_ObjectRender(pRenderSurface, root, elpased); - - - } -px_void PX_ApplicationPostEvent(PX_Application* pApp, PX_Object_Event e) +px_void PX_ApplicationPostEvent(PX_Application *pApp, PX_Object_Event e) { PX_ApplicationEventDefault(&pApp->runtime, e); PX_ObjectPostEvent(root, e); - } diff --git a/src/PainterEngine_Startup.c b/src/PainterEngine_Startup.c index fcb28f0791057bb736e436aed9aec3a0f4e1ab26..cf58759cd21512dcfc6001a78625dc12ba4b8486 100644 --- a/src/PainterEngine_Startup.c +++ b/src/PainterEngine_Startup.c @@ -16,8 +16,8 @@ px_bool PX_ApplicationInitializeDefault(PX_Runtime *runtime, px_int screen_width surface_width=(px_int)(surface_height*wdh); - window_width=screen_width/2; - window_height=screen_height/2; + window_width=screen_width/1.6; + window_height=screen_height/1.6; if(!PX_RuntimeInitialize(runtime,surface_width,surface_height,window_width,window_height,PX_ApplicationRuntime,sizeof(PX_ApplicationRuntime),PX_APPLICATION_MEMORYPOOL_UI_SIZE,PX_APPLICATION_MEMORYPOOL_RESOURCES_SIZE,PX_APPLICATION_MEMORYPOOL_GAME_SIZE)) diff --git a/src/PainterEngine_Startup.h b/src/PainterEngine_Startup.h index d2019f64d7b4c911ad61a8ca57464cc35852e2b3..b95628475a8fabcfee94650feecc25140598f2a3 100644 --- a/src/PainterEngine_Startup.h +++ b/src/PainterEngine_Startup.h @@ -5,7 +5,7 @@ //Configures #include "platform/modules/px_file.h" -#define PX_APPLICATION_NAME "PainterEngine" +#define PX_APPLICATION_NAME "MineSweeper" #define PX_APPLICATION_SURFACE_SIZE 680 #define PX_APPLICATION_MEMORYPOOL_UI_SIZE 1024*1024*16 diff --git a/src/map.c b/src/map.c index c2ca6a91f8a58f154f22b01af482d7704e68c497..5227f9f826027c8e2128ab040dc4edaf311fdc1c 100644 --- a/src/map.c +++ b/src/map.c @@ -30,6 +30,7 @@ map *CreateMap(int mode) default: break; } + Map -> mode = mode; Map -> generated = false; return Map; } diff --git a/src/opt.c b/src/opt.c index 6b45af95a91bf5b726e6c6bbb6c4fa26534737c1..9c6ad53604f4b81b460694fb4152da6435bf5a26 100644 --- a/src/opt.c +++ b/src/opt.c @@ -2,8 +2,9 @@ #include "../include/opt.h" #include "../include/map.h" #include -#include - +#include +#include +#define OPT_DEBUG 0 int opt(map *m, opt_t opt) { /** @@ -79,7 +80,8 @@ int opt_flag_count(map *map, int x, int y) int fnOptLeftClick(int x, int y, map *m) { - if(!m -> generated) Setmine(m, x, y, (unsigned int)time(NULL)); + if (!m->generated) + Setmine(m, x, y, (unsigned int)time(NULL)); /** * @brief 地图当前状态 * @@ -92,7 +94,7 @@ int fnOptLeftClick(int x, int y, map *m) * */ bool map_mine; - map_mine = (m->mineMap[x][y] == 1) ? true : false; + map_mine = (m->mineMap[x][y] == 1) ? true : false; // ? /** * @brief 左键实现 * 如果当前格子被标记或者已经打开 @@ -109,7 +111,7 @@ int fnOptLeftClick(int x, int y, map *m) m->stage[x][y] = COVERED; if (opt_count(m, x, y) == 0) - fnOptAuto(x, y, m); + return fnOptAuto(x, y, m); return ALLOWED; } @@ -141,6 +143,7 @@ int fnOptRightClick(int x, int y, map *m) return ALLOWED; break; } + return ALLOWED; } int fnOptMidClick(int x, int y, map *m) @@ -155,14 +158,18 @@ int fnOptMidClick(int x, int y, map *m) return UNALLOWED; if (opt_count(m, x, y) != opt_flag_count(m, x, y)) return UNALLOWED; - fnOptAuto(x, y, m); - return ALLOWED; + return fnOptAuto(x, y, m); } -void fnOptAuto(int x, int y, map *m) +int fnOptAuto(int x, int y, map *m) { + #if OPT_DEBUG + printf("\nAuto\n"); + #endif + int flag = 0; if (m->autobook[x][y] == 1) - return; + return ALLOWED; + m->autobook[x][y] = 1; for (int i = -1; i <= 1; i++) { @@ -177,11 +184,14 @@ void fnOptAuto(int x, int y, map *m) { m->stage[fx][fy] = COVERED; if (opt_count(m, fx, fy) == 0) - fnOptAuto(fx, fy, m); + if (fnOptAuto(fx, fy, m) == BOOM) + flag = 1; + if (m->mineMap[fx][fy] == 1) + flag = 1; } } } - return; + return flag ? BOOM : ALLOWED; } bool opt_is_scuess(map m) diff --git a/src/sort.c b/src/sort.c new file mode 100644 index 0000000000000000000000000000000000000000..2b4b3fa43c82b9744bd753da0ab904f1773f1e5f --- /dev/null +++ b/src/sort.c @@ -0,0 +1,157 @@ +#include +#include +#include +#define len 10 + +extern float duration; +extern int RANKmode; +//定义结构体 +typedef struct +{ + float time; + char name[50]; +}players; + +players player[len]; + +players tmp; + +extern char name1[50]; + + +//判断时间是否能冲进前十 +bool is_topten(){ + //定义一个有效数据的个数 + int valid_data; + FILE *fp1,*fp2,*fp3; + //定义三个文件指针 + fp1 = fopen("gamedata\\Rank_easydata.txt","r"); + fp2 = fopen("gamedata\\Rank_middata.txt","r"); + fp3 = fopen("gamedata\\Rank_harddata.txt","r"); + //选择模式 + for(valid_data = 0;valid_data duration) + break; + else continue; + } +//只在文件中存len(10)个有效数据 +//数据已满 + if(valid_data == len){ + if(j == len-1){ + player[len].time = duration; + strcpy(player[len].name,name1); + } + else{ + for(int h = valid_data-1;h > j;h --){ + player[h] = player[h-1]; + } + player[j].time = duration; + strcpy(player[j].name,name1); + } + for(int count = 0;count < valid_data;count++){ + fprintf(fp4,"%s %.2f\n",player[count].name,player[count].time); + } + return; + } + + for(int h = valid_data;h > j;h --){ + player[h] = player[h-1]; + } + player[j].time = duration; + strcpy(player[j].name,name1); + + for(int count = 0;count <= valid_data;count++){ + fprintf(fp4,"%s %.2f\n",player[count].name,player[count].time); + } + + + fclose(fp1); + fclose(fp2); + fclose(fp3); + fclose(fp4); + + return; +} + + diff --git a/test/AllTest.c b/test/AllTest.c new file mode 100644 index 0000000000000000000000000000000000000000..ee5d4229d864ae3c2cbabe2d7d851009de7d76ad --- /dev/null +++ b/test/AllTest.c @@ -0,0 +1,20 @@ +#include "../lib/cutest/CuTest.h" + +void RunAllTests(void) { + CuString *output = CuStringNew(); + CuSuite* suite = CuSuiteNew(); + + CuSuiteAddSuite(suite, MapGetSuite()); + CuSuiteAddSuite(suite, OptGetSuite()); + CuSuiteAddSuite(suite, UIGetSuite()); + CuSuiteAddSuite(suite, SortGetSuite()); + + CuSuiteRun(suite); + CuSuiteSummary(suite, output); + CuSuiteDetails(suite, output); + printf("%s\n", output->buffer); +} + +int main(void) { + RunAllTests(); +} \ No newline at end of file diff --git a/test/MapTest.c b/test/MapTest.c new file mode 100644 index 0000000000000000000000000000000000000000..f2a92c979ce8eaff107056fa3b98fa1a81e3b75b --- /dev/null +++ b/test/MapTest.c @@ -0,0 +1,47 @@ +#include +#include "../lib/cutest/CuTest.h" +#include "../include/map.h" +#include "../include/mine_map.h" + +void TestCreateMap(CuTest *tc) { + map* Map = CreateMap(MODE_EASY); + CuAssertIntEquals_Msg(tc, "X size in easy mode", MX_EASY, Map -> mx); + CuAssertIntEquals_Msg(tc, "Y size in easy mode", MY_EASY, Map -> my); + CuAssertIntEquals_Msg(tc, "cnt in easy mode", NUM_EASY, Map -> cnt); + CuAssertIntEquals_Msg(tc, "mode in easy mode", MODE_EASY, Map -> mode); + CuAssertIntEquals_Msg(tc, "generated in easy mode", 0, Map -> generated); + Map = CreateMap(MODE_MID); + CuAssertIntEquals_Msg(tc, "X size in mid mode", MX_MID, Map -> mx); + CuAssertIntEquals_Msg(tc, "Y size in mid mode", MY_MID, Map -> my); + CuAssertIntEquals_Msg(tc, "cnt in mid mode", NUM_MID, Map -> cnt); + CuAssertIntEquals_Msg(tc, "mode in mid mode", MODE_MID, Map -> mode); + CuAssertIntEquals_Msg(tc, "generated in mid mode", 0, Map -> generated); + Map = CreateMap(MODE_HARD); + CuAssertIntEquals_Msg(tc, "X size in hard mode", MX_HARD, Map -> mx); + CuAssertIntEquals_Msg(tc, "Y size in hard mode", MY_HARD, Map -> my); + CuAssertIntEquals_Msg(tc, "cnt in hard mode", NUM_HARD, Map -> cnt); + CuAssertIntEquals_Msg(tc, "mode in hard mode", MODE_HARD, Map -> mode); + CuAssertIntEquals_Msg(tc, "generated in hard mode", 0, Map -> generated); +} + +void TestSetMine(CuTest *tc) { + srand((int)time(NULL)); + for(int testCases=0;testCases<30;testCases++) { + map* Map = CreateMap(testCases / 10 + 1); // 10 * [easy, mid, hard] + int x = rand() % Map -> mx + 1, y = rand() % Map -> my + 1; + Setmine(Map, x, y, rand()); + for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) + CuAssertIntEquals_Msg(tc, "no mine around first click pos", 0, Map -> mineMap[x + i][y + j]); + int cnt = 0; + for(int i=1;i<=Map->mx;i++) for(int j=1;j<=Map->my;j++) + cnt += Map -> mineMap[i][j]; + CuAssertIntEquals_Msg(tc, "cnt in the map", Map -> cnt, cnt); + } +} + +CuSuite* MapGetSuite() { + CuSuite* suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, TestCreateMap); + SUITE_ADD_TEST(suite, TestSetMine); + return suite; +} \ No newline at end of file diff --git a/test/OptTest.c b/test/OptTest.c new file mode 100644 index 0000000000000000000000000000000000000000..47f93aa03d05206b2a412c4b65b5691d8b9bae2a --- /dev/null +++ b/test/OptTest.c @@ -0,0 +1,81 @@ +#include +#include "../lib/cutest/CuTest.h" +#include "../include/map.h" +#include "../include/mine_map.h" +#include "../include/opt.h" + +void TestOptCount(CuTest *tc) { + for(int i=10;i<40;i++) { + map *Map = CreateMap(i / 10); // 10 * [easy, mid, hard] + Setmine(Map, rand() % Map -> mx + 1, rand() % Map -> my + 1, rand()); + for(int x=1;x<=Map->mx;x++) + for(int y=1;y<=Map->my;y++) { + int cnt = 0; + for(int dx=-1;dx<=1;dx++) + for(int dy=-1;dy<=1;dy++) { + if(dx == 0 && dy == 0) continue; + int tx = x + dx, ty = y + dy; + if(1 <= tx && tx <= Map -> mx && 1 <= ty && ty <= Map -> my) cnt += Map -> mineMap[tx][ty]; + } + CuAssertIntEquals_Msg(tc, "opt_count", cnt, opt_count(Map, x, y)); + } + } +} + +void TestFnOptLeftClick(CuTest *tc) { + for(int testcases=10;testcases<40;testcases++) { + map *Map = CreateMap(testcases / 10); // 10 * [easy, mid, hard] + Setmine(Map, rand() % Map -> mx + 1, rand() % Map -> my + 1, rand()); + for(int i=1;i<=20;i++) { + int x = rand() % Map -> mx + 1, y = rand() % Map -> my + 1, preStage = Map -> stage[x][y]; + int result = fnOptLeftClick(x, y, Map); + if(Map -> mineMap[x][y]) CuAssertIntEquals_Msg(tc, "left click boom", preStage, result); + else CuAssertIntEquals_Msg(tc, "left click safe", BOOM, !result); + } + } +} + +void TestFnOptRightClick(CuTest *tc) { + for(int testcases=10;testcases<40;testcases++) { + map *Map = CreateMap(testcases / 10); // 10 * [easy, mid, hard] + Setmine(Map, rand() % Map -> mx + 1, rand() % Map -> my + 1, rand()); + for(int i=1;i<=20;i++) { + int x = rand() % Map -> mx + 1, y = rand() % Map -> my + 1, preStage = Map -> stage[x][y]; + int result = fnOptRightClick(x, y, Map); + CuAssertIntEquals_Msg(tc, "right click allowed", ALLOWED, result); + CuAssertIntEquals_Msg(tc, "right click change stage", true, preStage != Map -> stage[x][y]); + } + } +} + +void TestFnOptMidClick(CuTest *tc) { + // stage -> UNCOVERED COVERED FLAGED + // testcase definition + map Map; + Map.mx = Map.my = 3; + int testMaps[][3] = {{5, 0, 5}, {7, 0, 0}, {7, 0, 0}, {7, 0, 0}, {3, 0, 2}}; + int testStages[][3] = {{202, 10, 202}, {222, 10, 110}, {220, 210, 110}, {220, 10, 110}, {22, 10, 20}}; + int expectedResults[] = {ALLOWED, ALLOWED, BOOM, UNALLOWED, ALLOWED}; + int expcetedStages[][3] = {{212, 111, 212}, {222, 111, 111}, {221, 211, 111}, {220, 10, 110}, {122, 111, 121}}; + int pow10[] = {1, 10, 100}; + // test + for(int i=0;i<5;i++) { + for(int x=1;x<=3;x++) for(int y=1;y<=3;y++) + Map.mineMap[x][y] = !!(testMaps[i][x-1] & (1 << (y-1))), // !!x -> (bool) x + Map.stage[x][y] = testStages[i][x-1] / pow10[y-1] % 10, + Map.autobook[x][y] = 0; // wtf is this + CuAssertIntEquals_Msg(tc, "mid click result", expectedResults[i], fnOptMidClick(2, 2, &Map)); + for(int x=1;x<=3;x++) for(int y=1;y<=3;y++) + CuAssertIntEquals_Msg(tc, "mid click stage", expcetedStages[i][x-1] / pow10[y-1] % 10, Map.stage[x][y]); + } +} + +CuSuite* OptGetSuite() { + srand((int)time(NULL)); + CuSuite* suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, TestOptCount); + SUITE_ADD_TEST(suite, TestFnOptLeftClick); + SUITE_ADD_TEST(suite, TestFnOptRightClick); + SUITE_ADD_TEST(suite, TestFnOptMidClick); + return suite; +} \ No newline at end of file diff --git a/test/SortTest.c b/test/SortTest.c new file mode 100644 index 0000000000000000000000000000000000000000..4ca7858d5ae98d16a5d53dc14c43830aa9e1d961 --- /dev/null +++ b/test/SortTest.c @@ -0,0 +1,20 @@ +#include +#include "../lib/cutest/CuTest.h" +#include "../include/map.h" +#include "../include/mine_map.h" +#include "../include/sort.h" // 讲道理,我应该在这个东西写定之前给他来一次 code review,这个命名让我感觉很抽象,为什么这东西直接就被推到远端了。 + +CuSuite* SortGetSuite() { + CuSuite* suite = CuSuiteNew(); + // ?从个人角度来说,我觉得 Sort 运行时能不出 bug 就已经不错了。 + // 这个代码太离奇了,我姑且只能摸清楚运行逻辑,我写不出适合它的单元测试。 + // 现在是 12/29 23:55,报告都还没写,没时间做 code review 然后修改了,那么这个 Test 姑且就不写了。 + + // 我真的忍不住看这个代码,为什么排行榜的数据逻辑要显式暴露为结构体数组并且还不提供任何操作函数啊。 + // 我根本不可能在没有说明或者仔细阅读源码前理解这个模块的使用方法。 + // 从 OOP 角度来说这完全是在逆向完成封装的要求。 + // 如果能让我提早一天看到这个代码,它绝对活不过两个小时。 + + // 原来这个 Sort 是 12/26 被 push 到远端的,那确实是我看代码不及时了,我有错。 + return suite; +} \ No newline at end of file diff --git a/test/UITest.c b/test/UITest.c new file mode 100644 index 0000000000000000000000000000000000000000..4a869b5ab50668e26149b855e5170691794bbe25 --- /dev/null +++ b/test/UITest.c @@ -0,0 +1,10 @@ +#include +#include "../lib/cutest/CuTest.h" +#include "../include/map.h" +#include "../include/mine_map.h" + +CuSuite* UIGetSuite() { + CuSuite* suite = CuSuiteNew(); + // 这要测?这能测?这咋测? + return suite; +} \ No newline at end of file