From 60aa7641ce7ee7ee23d727697b716a57808e907c Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 9 Mar 2021 21:27:16 +0800 Subject: [PATCH 01/19] running letter --- level1/p01_runningLetter/level1.1.cpp | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 level1/p01_runningLetter/level1.1.cpp diff --git a/level1/p01_runningLetter/level1.1.cpp b/level1/p01_runningLetter/level1.1.cpp new file mode 100644 index 00000000..1c06c9a8 --- /dev/null +++ b/level1/p01_runningLetter/level1.1.cpp @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +int main() +{ + system("mode con cols=50 lines=25 "); + char a[100]={0}; + int i,j,p; + gets(a); + for(i=0;i<50-strlen(a);i++) + { + for(j=0;j0;p--) + { + for(int j=0;j +//#include +//#include +//#include +//#include +//int main() +//{ +//struct winsize size; +//ioctl(STDIN_FILENO,TIOCGWINSZ,&size); +//printf("%d\n",size.ws_col); +//printf("%d\n",size.ws_row); +//return 0; +//} From 2cdeb66ab96bb9059ae05dedafdf98514b904428 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 9 Mar 2021 21:42:29 +0800 Subject: [PATCH 02/19] level1.2-1.6 --- level1/p02_isPrime/level1.2.cpp | 18 +++++++ level1/p03_Diophantus/README.md | 6 ++- level1/p03_Diophantus/level1.3.cpp | 16 ++++++ level1/p04_ narcissus/level1.4.cpp | 24 +++++++++ level1/p05_allPrimes/level1.5.cpp | 86 ++++++++++++++++++++++++++++++ level1/p06_Goldbach/level1.6.cpp | 70 ++++++++++++++++++++++++ level1/p08_hanoi/README.md | 3 +- 7 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 level1/p02_isPrime/level1.2.cpp create mode 100644 level1/p03_Diophantus/level1.3.cpp create mode 100644 level1/p04_ narcissus/level1.4.cpp create mode 100644 level1/p05_allPrimes/level1.5.cpp create mode 100644 level1/p06_Goldbach/level1.6.cpp diff --git a/level1/p02_isPrime/level1.2.cpp b/level1/p02_isPrime/level1.2.cpp new file mode 100644 index 00000000..ea355e30 --- /dev/null +++ b/level1/p02_isPrime/level1.2.cpp @@ -0,0 +1,18 @@ +#include +int main() +{ + int n,i; + scanf("%d",&n); + for(i=2;i + +int main() +{ + int m=0,i=0,k; + do + { + i++; + if(i%12==0&&i%7==0&&(i/6+i/12+i/7+5+i/2+4)==i)//直接用循环解方程除法取整后会得到错误结果,先要保证年龄是6,12,7的公倍数 + { + m=i; + } + } + while(m!=i); + printf("儿子死时丢番图的年龄是%d",m-4); +} diff --git a/level1/p04_ narcissus/level1.4.cpp b/level1/p04_ narcissus/level1.4.cpp new file mode 100644 index 00000000..7d6abf56 --- /dev/null +++ b/level1/p04_ narcissus/level1.4.cpp @@ -0,0 +1,24 @@ +#include +#include +int main() +{ + int m,s,t=0,k,i; + printf("三位的水仙花数有:"); + for(m=100;m<1000;m++) + { + k=m; + s=0;//s,i,k都要初始化,注意初始化的位置应该在循环内还是外 + for(i=0;k>0;i++) + { + t=k%10; + s+=pow(t,3); + k=k/10; + } + if(m==s) + { + printf("%d\t",m); + } + } + + return 0; +} diff --git a/level1/p05_allPrimes/level1.5.cpp b/level1/p05_allPrimes/level1.5.cpp new file mode 100644 index 00000000..9440b2eb --- /dev/null +++ b/level1/p05_allPrimes/level1.5.cpp @@ -0,0 +1,86 @@ +/*节省时间: +- break; +- 只用奇数,排除偶数,n+=2 +- i +#include +#include +void isprime_1() +{ + int x=0,isprime,n=3,a[1000]={2,0}; + + while(n<1000) + { + isprime=1; + for(int i=0;a[i] +#include + +void prime(int a[]);//先做一个 数组存放100以内的质数 +int isprime(int q,int a[]);//与质数表比对判断是不是质数 + +//n减去一个质数判断是否有差值为质数,若有,则得证 +int main() +{ + int t,n=4; + int p[100]={0}; + prime(p); + while(n<=100) + { + for(int i=0;p[i]>0;i++) + { + if(isprime(n-p[i],p)) + { + printf("%d=%d+%d\n",n,p[i],n-p[i]); + break; + } + if(p[i]==0) + { + printf("Error"); + } + } + n+=2; + } + printf("If there is no error,Goldbach conjecture has been proved."); + return 0; + +} + +void prime(int a[]) +{ + int x=0,isprime,n=3; + while(n<100) + { + isprime=1; + a[0]=2; + for(int i=0;a[i]0;i++) + { + if(q==a[i]) + { + isprime=1; + } + } + return isprime; +} diff --git a/level1/p08_hanoi/README.md b/level1/p08_hanoi/README.md index 859be942..69186db7 100755 --- a/level1/p08_hanoi/README.md +++ b/level1/p08_hanoi/README.md @@ -2,4 +2,5 @@ 1.姹夎濉旓細姹夎濉旓紙鍙堢О娌冲唴濉旓級闂鏄簮浜庡嵃搴︿竴涓彜鑰佷紶璇寸殑鐩婃櫤鐜╁叿銆傚ぇ姊靛ぉ鍒涢犱笘鐣岀殑鏃跺欏仛浜嗕笁鏍归噾鍒氱煶鏌卞瓙锛屽湪涓鏍规煴瀛愪笂浠庝笅寰涓婃寜鐓уぇ灏忛『搴忔憺鐫64鐗囬粍閲戝渾鐩樸傚ぇ姊靛ぉ鍛戒护濠嗙綏闂ㄦ妸鍦嗙洏浠庝笅闈㈠紑濮嬫寜澶у皬椤哄簭閲嶆柊鎽嗘斁鍦ㄥ彟涓鏍规煴瀛愪笂銆傚苟涓旇瀹氾紝鍦ㄥ皬鍦嗙洏涓婁笉鑳芥斁澶у渾鐩橈紝鍦ㄤ笁鏍规煴瀛愪箣闂翠竴娆″彧鑳界Щ鍔ㄤ竴涓渾鐩樸 -![](./hanoi.jpg) \ No newline at end of file +![](./hanoi.jpg) + From 3df8768b7019879827a540a573aedaea470b9eea Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Wed, 10 Mar 2021 11:33:20 +0800 Subject: [PATCH 03/19] level 1.1-1.6 --- README.md | 4 ++++ {level1/p01_runningLetter => homework}/level1.1.cpp | 0 {level1/p02_isPrime => homework}/level1.2.cpp | 0 {level1/p03_Diophantus => homework}/level1.3.cpp | 0 {level1/p04_ narcissus => homework}/level1.4.cpp | 0 {level1/p05_allPrimes => homework}/level1.5.cpp | 0 {level1/p06_Goldbach => homework}/level1.6.cpp | 2 +- 7 files changed, 5 insertions(+), 1 deletion(-) rename {level1/p01_runningLetter => homework}/level1.1.cpp (100%) rename {level1/p02_isPrime => homework}/level1.2.cpp (100%) rename {level1/p03_Diophantus => homework}/level1.3.cpp (100%) rename {level1/p04_ narcissus => homework}/level1.4.cpp (100%) rename {level1/p05_allPrimes => homework}/level1.5.cpp (100%) rename {level1/p06_Goldbach => homework}/level1.6.cpp (99%) diff --git a/README.md b/README.md index 837adcf4..457fe342 100755 --- a/README.md +++ b/README.md @@ -78,3 +78,7 @@ ### 鍏朵粬 [鍏嶈垂鐨勮绠楁満缂栫▼绫讳腑鏂囦功绫峕(https://github.com/wwj718/free-programming-books-zh_CN) + +github鎵撲笉寮 + +鎵撳紑CMD杩愯濡備笅鍛戒护 ipconfig /flushdns \ No newline at end of file diff --git a/level1/p01_runningLetter/level1.1.cpp b/homework/level1.1.cpp similarity index 100% rename from level1/p01_runningLetter/level1.1.cpp rename to homework/level1.1.cpp diff --git a/level1/p02_isPrime/level1.2.cpp b/homework/level1.2.cpp similarity index 100% rename from level1/p02_isPrime/level1.2.cpp rename to homework/level1.2.cpp diff --git a/level1/p03_Diophantus/level1.3.cpp b/homework/level1.3.cpp similarity index 100% rename from level1/p03_Diophantus/level1.3.cpp rename to homework/level1.3.cpp diff --git a/level1/p04_ narcissus/level1.4.cpp b/homework/level1.4.cpp similarity index 100% rename from level1/p04_ narcissus/level1.4.cpp rename to homework/level1.4.cpp diff --git a/level1/p05_allPrimes/level1.5.cpp b/homework/level1.5.cpp similarity index 100% rename from level1/p05_allPrimes/level1.5.cpp rename to homework/level1.5.cpp diff --git a/level1/p06_Goldbach/level1.6.cpp b/homework/level1.6.cpp similarity index 99% rename from level1/p06_Goldbach/level1.6.cpp rename to homework/level1.6.cpp index dfe5ca3b..9fcc195e 100644 --- a/level1/p06_Goldbach/level1.6.cpp +++ b/homework/level1.6.cpp @@ -27,7 +27,7 @@ int main() } n+=2; } - printf("If there is no error,Goldbach conjecture has been proved."); + printf("If there is no error,Goldbach conjecture has been proved.") return 0; } From 93f42f4e4f4b836c2ce65f3fc2ae3386d2fd6e73 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Sun, 14 Mar 2021 14:55:55 +0800 Subject: [PATCH 04/19] level 1.7-1.8 --- ...4\344\272\232\345\257\206\347\240\201.pdf" | Bin 0 -> 173199 bytes homework/level1.7.cpp | 113 ++++++++++++++++++ homework/level1.8.cpp | 26 ++++ 3 files changed, 139 insertions(+) create mode 100644 "homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" create mode 100644 homework/level1.7.cpp create mode 100644 homework/level1.8.cpp diff --git "a/homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" "b/homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..9afadcb0e18cbea5df885432eb2a60a230e88ac6 GIT binary patch literal 173199 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

caXb_wE)g_mReiYx&4_|sW+NT9thl+o#pBz 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 literal 0 HcmV?d00001 diff --git a/homework/level1.7.cpp b/homework/level1.7.cpp new file mode 100644 index 00000000..e0b4e6e7 --- /dev/null +++ b/homework/level1.7.cpp @@ -0,0 +1,113 @@ +//维吉尼亚密码 +//找ASC的规律,用ASC相加最后减掉a的ASC97就可,注意相乘ASC溢出的时候要减一轮字母26 +//加密和解密时的限制条件,限制在大写字母或小写字母的范围内即可,不在就-+26 +#include +#include + +#define _CRT_SECURE_NO_WARNINGS + +void encrypt(); +void change(char* k, char* c); +void decrypt(); + +int main() +{ + int n; + printf("Hello!This program has two functions:encrypt and decrypt.\n"); + printf("If you want to encrypt,please input 0,if you want to decrypt,please input 1\n"); + scanf("%d", &n);//scanf输入完之后要清空stdin,不然\t就会记入下一次的输入中 + fflush(stdin); + if (n) + decrypt(); + else + encrypt(); + + return 0; +} + +void encrypt() +{ + char M[1000] = { '\0' }, C[1000] = { '\0' }, K[1000] = { '\0' }; + printf("please input your secret key.for example:CompleteVictory\n"); + gets(K); + printf("please input the text that you want to encrypt.for example:Wherethereisawillthereisaway\n"); + gets(C); + change(K, C); + + for (int i = 0;C[i] != '\0';i++) + { + if (C[i] < 91) + { + if (C[i] + K[i] < 189) + { + M[i] = C[i] + K[i] - 97; + } + else + { + M[i] = C[i] + K[i] - 97 - 26; + } + } + else + { + if (C[i] + K[i] < 220) + { + M[i] = C[i] + K[i] - 97; + } + else + { + M[i] = C[i] + K[i] - 97 - 26; + } + } + + } + puts(M); +} + +void decrypt() +{ + char M[1000] = { '\0' }, C[1000] = { '\0' }, K[1000] = { '\0' }; + printf("please input your secret key.for example:CompleteVictory\n"); + gets(K); + printf("please input the text that you want to decrypt.for example:Yvqgpxaimmklongnzfwpvxmniytm\n"); + gets(M); + change(K, M); + for (int i = 0;M[i] != '\0';i++) + { + if (M[i] < 91) + { + if (64 < M[i] - K[i] + 97 && M[i] - K[i] + 97 < 91) + { + C[i] = M[i] + 97 - K[i]; + } + else + { + C[i] = M[i] - K[i] + 97 + 26; + } + } + else + { + if (96 < M[i] - K[i] + 97 && M[i] - K[i] + 97 < 123) + { + C[i] = M[i] - K[i] + 97; + } + else + { + C[i] = M[i] - K[i] + 97 + 26; + } + } + } + puts(C); +} + +//为了多次使用秘钥 ,拷贝 ,将秘钥转换成小写 + void change(char* k, char* c) +{ + strncat(k, k, strlen(c)); + for (int i = 0;k[i] != '\0';i++) + { + if (k[i] < 97) + { + k[i] = k[i] + 32; + } + } +} diff --git a/homework/level1.8.cpp b/homework/level1.8.cpp new file mode 100644 index 00000000..34e95105 --- /dev/null +++ b/homework/level1.8.cpp @@ -0,0 +1,26 @@ +#include + +void move(int n, char a, char b, char c); + +int main() +{ + int n; + printf("please input the number of your disks:"); + scanf("%d", &n); + move(n, 'A', 'B', 'C'); + + +} +void move(int m, char a, char b, char c)//move函数的作用是把m块盘子移到目标柱 +{ + if(1==m) + printf("move disk %d from %c to %c\n", m, a, c); //递归截止条件 + else + { + move(m-1,a,c,b);//将 m-1个盘子先放到中间柱(对于第m块)上,(对于m-1块)此时起始柱是a,目标柱是b + printf("move disk %d from %c to %c\n", m, a, c);//将A座上地剩下的一个盘移动到C盘上 + move(m-1,b,a,c);//将m-1个盘从中间柱移动到目标柱上 + } + + + From 82d718161c3e901d1b927edf53d389df66b981ed Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 16 Mar 2021 18:34:33 +0800 Subject: [PATCH 05/19] revise 1.2and1.5 --- homework/level1.2.c | 15 ++++++++ homework/level1.2.cpp | 18 --------- homework/level1.5.c | 84 ++++++++++++++++++++++++++++++++++++++++++ homework/level1.5.cpp | 86 ------------------------------------------- 4 files changed, 99 insertions(+), 104 deletions(-) create mode 100644 homework/level1.2.c delete mode 100644 homework/level1.2.cpp create mode 100644 homework/level1.5.c delete mode 100644 homework/level1.5.cpp diff --git a/homework/level1.2.c b/homework/level1.2.c new file mode 100644 index 00000000..21e5ca68 --- /dev/null +++ b/homework/level1.2.c @@ -0,0 +1,15 @@ +#include +int main() +{ + int n, i; + scanf_s("%d", &n); + for (i = 2;i < n;i++) + { + if (0==n%i)break; + } + if (i == n) + printf("%d是素数", n); + else + printf("%d不是素数", n); + return 0; +} \ No newline at end of file diff --git a/homework/level1.2.cpp b/homework/level1.2.cpp deleted file mode 100644 index ea355e30..00000000 --- a/homework/level1.2.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -int main() -{ - int n,i; - scanf("%d",&n); - for(i=2;i +#include +#include +void isprime_1() +{ + int x = 0, isprime, n = 3, a[1000] = { 2,0 }; + + while (n < 1000) + { + isprime = 1; + for (int i = 0;a[i] < sqrt(n);i++) + { + if (n % a[i] == 0) + { + isprime = 0; + break; + } + } + if (isprime) + { + a[x + 1] = n; + x += 1; + } + n += 2; + } + + + for (int i = 0;i <= x;i++) + { + printf("%d\t", a[i]); + if ((i + 1) % 10 == 0) + { + printf("\n"); + } + } + printf("\n"); + +} + +void isprime_2() +{ + int n = 0, i, j, isprime; + for (i = 2;i <= 1000; i++) + { + isprime = 1; + for (j = 2; j <= sqrt(i); j++) + if (i % j == 0) + { + isprime = 0; + break; + } + if (isprime) + { + n++; + if (n % 10 == 0) printf("%d\n", i); + else printf("%d\t", i); + } + } +} + +int main() +{ + clock_t start_t, finish_t; + double total_t; + + start_t = clock(); + isprime_1(); + finish_t = clock(); + total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; + printf("\n璐ㄦ暟鏁扮粍娉曡繍琛屾绘椂闂存槸%f 绉抃n", total_t); + + start_t = clock(); + isprime_2(); + finish_t = clock(); + total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; + printf("\n鐩存帴寰幆鍙栦綑绋嬪簭杩愯鎬绘椂闂存槸%f 绉抃n", total_t); + return 0; +} \ No newline at end of file diff --git a/homework/level1.5.cpp b/homework/level1.5.cpp deleted file mode 100644 index 9440b2eb..00000000 --- a/homework/level1.5.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*节省时间: -- break; -- 只用奇数,排除偶数,n+=2 -- i -#include -#include -void isprime_1() -{ - int x=0,isprime,n=3,a[1000]={2,0}; - - while(n<1000) - { - isprime=1; - for(int i=0;a[i] Date: Tue, 16 Mar 2021 18:56:13 +0800 Subject: [PATCH 06/19] revise level1.2and1.5 --- homework/level1.2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homework/level1.2.c b/homework/level1.2.c index 21e5ca68..8baa5bb8 100644 --- a/homework/level1.2.c +++ b/homework/level1.2.c @@ -8,8 +8,8 @@ int main() if (0==n%i)break; } if (i == n) - printf("%d是素数", n); + printf(" %d 是素数 ", n); else - printf("%d不是素数", n); + printf(" %d 不是素数 ", n); return 0; } \ No newline at end of file From 73bc22f4ee639bfa8618a9f65b828c27f93cef6b Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 16 Mar 2021 19:25:05 +0800 Subject: [PATCH 07/19] revise level 1.2 and 1.5 --- homework/level1.2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homework/level1.2.c b/homework/level1.2.c index 8baa5bb8..2f044541 100644 --- a/homework/level1.2.c +++ b/homework/level1.2.c @@ -1,4 +1,4 @@ -#include +锘#include int main() { int n, i; @@ -8,8 +8,8 @@ int main() if (0==n%i)break; } if (i == n) - printf(" %d 是素数 ", n); + printf(" %d 鏄礌鏁", n); else - printf(" %d 不是素数 ", n); + printf(" %d 涓嶆槸绱犳暟", n); return 0; } \ No newline at end of file From 5316511f0ba335ab198cc2527fccf827705559b0 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 23 Mar 2021 19:33:40 +0800 Subject: [PATCH 08/19] nibolan --- homework/level1.5.c | 47 ++++---- level1/p11_linkedList/README.md | 2 +- .../nibolan.h" | 32 ++++++ .../\351\200\206\346\263\242\345\205\260.c" | 107 ++++++++++++++++++ 4 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 "\350\257\276\345\240\202\347\273\203\344\271\240/nibolan.h" create mode 100644 "\350\257\276\345\240\202\347\273\203\344\271\240/\351\200\206\346\263\242\345\205\260.c" diff --git a/homework/level1.5.c b/homework/level1.5.c index d02804e4..dbd06b4a 100644 --- a/homework/level1.5.c +++ b/homework/level1.5.c @@ -4,11 +4,35 @@ - i #include #include + +void isprime_1(); +void isprime_2(); + +int main() +{ + clock_t start_t, finish_t; + double total_t; + + start_t = clock(); + isprime_1(); + finish_t = clock(); + total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; + printf("\n璐ㄦ暟鏁扮粍娉曡繍琛屾绘椂闂存槸%f 绉抃n", total_t); + + start_t = clock(); + isprime_2(); + finish_t = clock(); + total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; + printf("\n鐩存帴寰幆鍙栦綑绋嬪簭杩愯鎬绘椂闂存槸%f 绉抃n", total_t); + return 0; +} + void isprime_1() -{ +{ int x = 0, isprime, n = 3, a[1000] = { 2,0 }; while (n < 1000) @@ -16,7 +40,7 @@ void isprime_1() isprime = 1; for (int i = 0;a[i] < sqrt(n);i++) { - if (n % a[i] == 0) + if (n % a[i]==0) { isprime = 0; break; @@ -62,23 +86,4 @@ void isprime_2() else printf("%d\t", i); } } -} - -int main() -{ - clock_t start_t, finish_t; - double total_t; - - start_t = clock(); - isprime_1(); - finish_t = clock(); - total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; - printf("\n璐ㄦ暟鏁扮粍娉曡繍琛屾绘椂闂存槸%f 绉抃n", total_t); - - start_t = clock(); - isprime_2(); - finish_t = clock(); - total_t = (double)(finish_t - start_t) / CLOCKS_PER_SEC; - printf("\n鐩存帴寰幆鍙栦綑绋嬪簭杩愯鎬绘椂闂存槸%f 绉抃n", total_t); - return 0; } \ No newline at end of file diff --git a/level1/p11_linkedList/README.md b/level1/p11_linkedList/README.md index 0bce4a53..cd6935f9 100755 --- a/level1/p11_linkedList/README.md +++ b/level1/p11_linkedList/README.md @@ -11,4 +11,4 @@ ### 鎶鑳藉己鍖栵紙褰诲簳鎼炲畾鎸囬拡锛夛細 娆㈣繋澶х浠兘鍘荤帺鐜╄繖涓細 -[Level2-瀹炵幇 SkipList 绠楁硶](../../level2/SkipList/Readme.md) +[Level2-瀹炵幇 SkipList 绠楁硶](../../level2/SkipList/Readme.md) \ No newline at end of file diff --git "a/\350\257\276\345\240\202\347\273\203\344\271\240/nibolan.h" "b/\350\257\276\345\240\202\347\273\203\344\271\240/nibolan.h" new file mode 100644 index 00000000..09eb43fb --- /dev/null +++ "b/\350\257\276\345\240\202\347\273\203\344\271\240/nibolan.h" @@ -0,0 +1,32 @@ +#pragma once +#include +#include +#include +#include +#define N 100 + +struct stack +{ + int dataS[N]; + int top; +}; +typedef struct stack S; + +struct queue +{ + char dataQ[N]; + int front; + int rear; +}; +typedef struct queue Q; + +void initQueue(Q* myqueue); +void Qappend(Q* myqueue, char y); +char Qpop(Q* myqueue); + +void initStack(S* mystack); +void Sappend(S* mystack, int z); +int Spop(S* mystack); + +void input(Q* myqueue); +int calculate(char p1, int p2, int p3); diff --git "a/\350\257\276\345\240\202\347\273\203\344\271\240/\351\200\206\346\263\242\345\205\260.c" "b/\350\257\276\345\240\202\347\273\203\344\271\240/\351\200\206\346\263\242\345\205\260.c" new file mode 100644 index 00000000..99b263fd --- /dev/null +++ "b/\350\257\276\345\240\202\347\273\203\344\271\240/\351\200\206\346\263\242\345\205\260.c" @@ -0,0 +1,107 @@ +#include "nibolan.h" +int main() +{ + Q Q1; + S S1; + char m1; + int m2 = 0, m3 = 0, m4 = 0, m = 0; + initQueue(&Q1); + initStack(&S1); + input(&Q1); + do + { + m1 = Qpop(&Q1);//m1要同时储存符号和数字 + if (m1 == 0) break; + else + { + if (m1 >= '0' && m1 <= '9') + { + m = (int)(m1 - '0'); + Sappend(&S1, m); + } + else + { + //不仅要跳出while循环,还要让不再执行下面的else,所以前面加上='\0' + m2 = Spop(&S1); + m3 = Spop(&S1); + m4 = calculate(m1, m2, m3); + Sappend(&S1, m4); + } + } + + } while (m); + printf("%d", m4); +} + +void input(Q* myqueue) +{ + char str[100] = { '\0' }; + gets(str); + for (int i = 0;str[i] != '\0';i++) + Qappend(myqueue, str[i]); +} + +int calculate(char p1, int p2, int p3) +{ + int p = 0; + + switch (p1) + { + case '+': p = p3 + p2; break; + case '-': p = p3 - p2; break; + case '*': p = p3 * p2; break; + case '/': p = p3 / p2; break; + case '%': p = p3 % p2; break; + case '^': p = pow(p3, p2);break; + } + return p; +} + +void initQueue(Q* myqueue) +{ + myqueue->front = myqueue->rear = 0; +} + +void Qappend(Q* myqueue, char y) +{ + if (myqueue->rear == N) + printf("失败"); + else + { + myqueue->dataQ[myqueue->rear] = y; + myqueue->rear += 1; + } +} + +char Qpop(Q* myqueue) +{ + if (myqueue->front == myqueue->rear) + return 0; + else + { + myqueue->front += 1; + return (myqueue->dataQ[myqueue->front - 1]); + } +} + +void initStack(S* mystack) +{ + mystack->top = -1; +} +void Sappend(S* mystack, int z) +{ + if (mystack->top == N - 1) + printf("Error"); + mystack->top++; + mystack->dataS[mystack->top] = z; +} +int Spop(S* mystack) +{ + int q; + if (mystack->top == -1) + printf("Error"); + //利用传出参数传出栈顶元素 + q = mystack->dataS[mystack->top]; + mystack->top--; + return q; +} \ No newline at end of file From 535806e38d9162300787c59880659483976e4fd8 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Sun, 28 Mar 2021 18:07:11 +0800 Subject: [PATCH 09/19] level1.9-1.11 --- homework/level1.10pushbox.c | 372 +++++++++++++++++++++++++++++++++ homework/level1.11linkedList.c | 143 +++++++++++++ homework/level1.11linkedList.h | 19 ++ homework/level1.8.cpp | 2 - homework/level1.9.c | 226 ++++++++++++++++++++ 5 files changed, 760 insertions(+), 2 deletions(-) create mode 100644 homework/level1.10pushbox.c create mode 100644 homework/level1.11linkedList.c create mode 100644 homework/level1.11linkedList.h create mode 100644 homework/level1.9.c diff --git a/homework/level1.10pushbox.c b/homework/level1.10pushbox.c new file mode 100644 index 00000000..d5c35860 --- /dev/null +++ b/homework/level1.10pushbox.c @@ -0,0 +1,372 @@ +/* +墙会被推动->空格长度和标记长度不一样 +判断前面的情况 +记录步数 +读入文件,记录关卡 +*/ +#include +#include +#include +#include +#define Length 10//游戏界面的长和宽 + +int x = 0, y = 0; +int walkcnt = 0; +int score = 0; + +int map[Length][Length] = { 0 };// 定义的游戏界面模型 + +int count1(); +int count2(); +void CursorGoto(int x, int y);//光标定位 +void up(); +void down(); +void left(); +void right(); +void ChooseLevel(); +void GetMap(FILE*fp); +void DrawMap(); +int find(); +void HomeScreen(); +void EndScreen(); +int grade(); +void SaveGrade(); + +int main() +{ + int n, m; + system("title 推箱子游戏~"); + system("color F3"); + + HomeScreen(); + ChooseLevel(); + + getchar(); + + system("cls"); + + n = count1(); + + while (1) + { + system("cls"); + DrawMap(); + m = count2(); + walkcnt++; + + switch (getchar()) + { + case 'w':up(); break; + case 's':down(); break; + case 'a':left(); break; + case 'd':right(); break; + default:printf("请重新输入");break; + } + + if (n == m) + { + EndScreen(); + SaveGrade(); + return 0; + } + } +} + +// 按w的时候的输出结果 +void up() +{ + find(); + switch (map[x - 1][y])//判断人前面是什么 + { + case 0://空 + { + map[x - 1][y] = 3; + map[x][y] = 0; + break; + } + case 1:break;//墙 + case 2://箱子 + { + if (map[x - 2][y] == 0)//箱子前面空,箱子和人一起动 + { + map[x - 2][y] = 2; + map[x - 1][y] = 3; + map[x][y] = 0; + } + else + { + if (map[x - 2][y] == 4)//箱子前面是目标 + { + map[x][y] = 0; + map[x - 1][y] = 3; + map[x - 2][y] = 5; + } + } + break; + } + } +} + +//按d的时候的输出结果 +void down() +{ + find(); + switch (map[x + 1][y]) + { + case 0: + { + map[x + 1][y] = 3; + map[x][y] = 0; + break; + } + case 1:break; + case 2: + { + if (map[x + 2][y] == 0) + { + map[x + 2][y] = 2; + map[x + 1][y] = 3; + map[x][y] = 0; + } + else + { + if (map[x + 2][y] == 4) + { + map[x][y] = 0; + map[x + 1][y] = 3; + map[x + 2][y] = 5; + } + } + break; + } + } +} + +//按a的时候的输出结果 +void left() +{ + find(); + switch (map[x][y - 1]) + { + case 0: + { + map[x][y - 1] = 3; + map[x][y] = 0; + break; + } + case 1:break; + case 2: + { + if (map[x][y - 2] == 0) + { + map[x][y - 2] = 2; + map[x][y - 1] = 3; + map[x][y] = 0; + } + else + { + if (map[x][y - 2] == 4) + { + map[x][y] = 0; + map[x][y - 1] = 3; + map[x][y - 2] = 5; + } + } + break; + } + } +} + +//按d的时候的输出结果 +void right() +{ + find(); + switch (map[x][y + 1]) + { + case 0://空 + { + map[x][y + 1] = 3; + map[x][y] = 0; + break; + } + case 1:break; + case 2: + { + if (map[x][y + 2] == 0) + { + map[x][y + 2] = 2; + map[x][y + 1] = 3; + map[x][y] = 0; + } + else + { + if (map[x][y + 2] == 4) + { + map[x][y] = 0; + map[x][y + 1] = 3; + map[x][y + 2] = 5; + } + } + break; + } + } +} + +void DrawMap() +{ + for (x = 0; x < Length; x++) + { + for (y = 0; y < Length; y++) + { + if (map[x][y] == 1) + printf("■"); //输出砖块的样子 + if (map[x][y] == 3) + printf("♀"); //输出自己的位置 + if (map[x][y] == 2) + printf("□"); //输出箱子 + if (map[x][y] == 4) + printf("☆"); //输出箱子要到的位置 + if (map[x][y] == 0) + printf(" "); //输出空白 + if (map[x][y] == 5) + printf("★"); //输出箱子到了该到的位置 + } + printf("\n"); + } +} +//找到自己的位置 +int find()//用break只能跳出内层循环,不能跳出两层 +{ + for (x = 0; x < Length; x++) + for (y = 0; y < Length; y++) + { + if (map[x][y] == 3)return 0; + } + return 0; +} +//箱子要到的位置的个数 +int count1() +{ + int n = 0; + for (x = 0; x < Length; x++) + for (y = 0; y < Length; y++) + { + if (map[x][y] == 4) + n++; + } + return n; +} +//箱子到了位置的个数 +int count2() +{ + int m = 0; + for (x = 0; x < Length; x++) + for (y = 0; y < Length; y++) + { + if (map[x][y] == 5) + m++; + } + return m; +} +//制作主界面 +void HomeScreen() +{ + system("cls"); + CursorGoto(39, 8); + printf("欢迎来到超级有趣的推箱子游戏"); + CursorGoto(34, 10); + printf("游戏规则"); + CursorGoto(34, 12); + printf("按wsad控制小人上下左右移动,按回车键结束输入"); + CursorGoto(34, 14); + printf("输入0 退出游戏"); + CursorGoto(34, 16); + printf("输入1-4 选择关卡"); +} +//记录得分 +int grade() +{ + score = 1000 / walkcnt; + return score; +} + +void ChooseLevel() +{ + int n; + scanf_s("%d", &n); + FILE* fp; + fp = NULL; + switch (n) + { + case 0: + { + system("cls"); //退出游戏则输出提示信息 + CursorGoto(34, 12); + printf("欢迎下次光临"); + exit(0); + } + case 1: + { + fp = fopen("D:/tmp/pushbox/level1.txt", "a+"); + GetMap(fp); + break; + } + case 2: + { + fp = fopen("D:/tmp/pushbox/level2.txt", "a+"); + GetMap(fp); + break; + } + case 3: + { + fp = fopen("D:/tmp/pushbox/level3.txt", "a+"); + GetMap(fp); + break; + } + case 4: + { + fp = fopen("D:/tmp/pushbox/level4.txt", "a+"); + GetMap(fp); + break; + } + } + fclose(fp); +} + +void GetMap(FILE*fp) +{ + for (int i = 0;i < Length;i++) + { + for (int j = 0;j < Length;j++) + fscanf_s(fp, "%d", &map[i][j]); + } +} + +void SaveGrade() +{ + FILE* fp; + fp = NULL; + fp = fopen("D:/tmp/pushbox/level1.txt", "a+"); + fprintf(fp, "\n您第本关的得分是%d\n", score); + fprintf(fp, "%s\r\t", __DATE__); + fprintf(fp, "%s\r\n", __TIME__); + fclose(fp); +} + +void EndScreen() +{ + system("cls"); + CursorGoto(39, 8); + printf("$¥游戏胜利¥$~\n"); + CursorGoto(39, 10); + printf("您走过的步数是%d\n", walkcnt); + score = grade(score); + CursorGoto(39, 12); + printf("您本关卡得分%d\n", score); + system("pause"); +} +void CursorGoto(int x, int y) //光标定位 +{ + COORD pos = { x,y }; + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); +} \ No newline at end of file diff --git a/homework/level1.11linkedList.c b/homework/level1.11linkedList.c new file mode 100644 index 00000000..fe87caa2 --- /dev/null +++ b/homework/level1.11linkedList.c @@ -0,0 +1,143 @@ +#include +#include "linkedList.h" +int main() +{ + List list; + int number; + int isfound; + Node* head = NULL; + list.head = NULL; + do + { + scanf_s("%d", &number); + add(&list,number); + } while (number != -1); + reverse(&list); + isfound = search(&list, 5); + isfound = searchAgain(&list, isfound, 5); + //deleteNode(&list, 5); + //isfound=search(&list, 5)+1;//方法二 + freeList(&list); + + return 0; + +} + +void add(List* plist, int number) +{ + if (number != -1) + { + //add a new node + Node* p = (Node*)malloc(sizeof(Node)); + p->value = number; + p->next = NULL; + //find the last + plist-> tail = plist->head; + if (plist->tail) + { + while (plist->tail->next) + plist->tail = plist->tail->next;//last和last->next都是指向Node的指针,last指向下一个 + //attach + plist->tail->next=p; + } + else + plist->head = p; + } +} + + +int search(List* plist, int aim) +{ + int i=0; + Node* p; + for (Node* p = plist->head;p ;p = p->next) + { + if (p->value == aim) + { + printf("The sequence of aimed node is %d(from 0)\n", i); + return i; + break; + } + i++; + } + return-1; +} + +void deleteNode(List* plist,int number) +{ + Node* p; + Node* q; + for (p = plist->head,q=NULL;p;p = p->next,q=p) + { + if (q) + plist->head = p->next; + else + { + if (number == p->value) + { + q = p->next; + free(p); + } + } + } +} + +void reverse(List* plist) +{ + Node* p; + Node* q; + Node* r; + plist->tail = plist->head; + p = plist->head; + q = NULL; + do + { + r = p->next; + p->next = q; + q = p; + p = r; + } while (p->next); + p->next = q; + plist->head = p; + for (p = plist->head; p; p = p->next) + printf("%d\t", p->value); +} + +void reverse(List* plist) +{ + Node* p; + plist->tail->next = plist->head; + p = plist->head; + plist->head = plist->head->next; + p = NULL; +} + + + +int searchAgain(List* plist,int isfound,int aim) +{ + Node* p; + p = plist->head; + int i; + for (i = 0; i <= isfound; i++) + p = p->next; + for (i;p;i++,p=p->next) + { + if (p->value == aim) + { + printf("The sequence of the next aimed node is %d(from 0)\n", i); + return i; + break; + } + } +} +void freeList(List* plist) +{ + Node* p; + Node* q; + for (p = plist->head;p;p = q) + { + q = p->next; + free(p); + } +} \ No newline at end of file diff --git a/homework/level1.11linkedList.h b/homework/level1.11linkedList.h new file mode 100644 index 00000000..3f61351d --- /dev/null +++ b/homework/level1.11linkedList.h @@ -0,0 +1,19 @@ +#pragma once +typedef struct node{ + int value; + struct node* next; + struct node* last; +}Node; + +typedef struct list { + Node* head; + Node* tail; +}List; + +void add(List* plist, int number); +int search(List* plist, int aim); +int searchAgain(List* plist, int isfound, int aim); +void reverse(List* plist); +void deleteNode(List* plist, int number); +void freeList(List* plist); + diff --git a/homework/level1.8.cpp b/homework/level1.8.cpp index 34e95105..f6d5a13a 100644 --- a/homework/level1.8.cpp +++ b/homework/level1.8.cpp @@ -8,8 +8,6 @@ int main() printf("please input the number of your disks:"); scanf("%d", &n); move(n, 'A', 'B', 'C'); - - } void move(int m, char a, char b, char c)//move函数的作用是把m块盘子移到目标柱 { diff --git a/homework/level1.9.c b/homework/level1.9.c new file mode 100644 index 00000000..a523f520 --- /dev/null +++ b/homework/level1.9.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include + + +//地图长度L,包括迷宫主体20,外侧的包围的墙体2,最外侧包围路径2(之后会解释) +#define L 24 + +//墙和路径的标识 +#define WALL 0 +#define ROUTE 1 + +//控制迷宫的复杂度,数值越大越简单,最小值为0 +int Rank ; +//小人的位置坐标 +int x; +int y; +//记录出口的位置 +int z; + +void CreateMaze(int** maze, int x, int y);//生成迷宫 +void DrawMaze(int** maze);//画迷宫 +void Move(int** maze);//移动小人 +void HomeScreen();//主菜单 +void CursorGoto(int x, int y);//光标定位 +int main(void) +{ + system("color F2"); + srand((unsigned)time(NULL)); + HomeScreen(); + system("cls"); + + int** Maze = (int**)malloc(L * sizeof(int*)); + for (int i = 0; i < L; i++) + { + Maze[i] = (int*)calloc(L, sizeof(int)); + } + + x = 2; + y = 1; + //创造迷宫,(2,2)为起点 + CreateMaze(Maze, 2, 2); + DrawMaze(Maze); + + Move(Maze); + + for (int i = 0; i < L; i++) free(Maze[i]); + free(Maze); + + system("pause"); + return 0; +} + +void CreateMaze(int** maze, int x, int y) +{ + maze[x][y] = ROUTE; + + //最外围层设为路径的原因,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿 + for (int i = 0; i < L; i++) + { + maze[i][0] = ROUTE; + maze[0][i] = ROUTE; + maze[i][L - 1] = ROUTE; + maze[L - 1][i] = ROUTE; + } + + //确保四个方向随机 + int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } }; + for (int i = 0; i < 4; i++) + { + int r = rand() % 4; + int temp = direction[0][0]; + direction[0][0] = direction[r][0]; + direction[r][0] = temp; + + temp = direction[0][1]; + direction[0][1] = direction[r][1]; + direction[r][1] = temp; + } + + //向四个方向开挖 + for (int i = 0; i < 4; i++) + { + int dx = x; + int dy = y; + + //控制挖的距离,由Rank来调整大小 + int range = 1 + (Rank == 0 ? 0 : rand() % Rank); + while (range > 0) + { + dx += direction[i][0]; + dy += direction[i][1]; + + //排除掉回头路 + if (maze[dx][dy] == ROUTE) + { + break; + } + + //判断是否挖穿路径 + int count = 0; + for (int j = dx - 1; j < dx + 2; j++) + { + for (int k = dy - 1; k < dy + 2; k++) + { + //abs(j - dx) + abs(k - dy) == 1 确保只判断九宫格的四个特定位置 + if (abs(j - dx) + abs(k - dy) == 1 && maze[j][k] == ROUTE) + count++; + } + } + + if (count > 1) break; + + //确保不会挖穿时,前进 + --range; + maze[dx][dy] = ROUTE; + } + + //没有挖穿危险,以此为节点递归 + if (range <= 0) + CreateMaze(maze, dx, dy); + } + + //画迷宫的入口和出口 + maze[2][1] = ROUTE; + + //由于算法随机性,出口有一定概率不在(L-3,L-2)处,此时需要寻找出口 + for (int i = L - 3; i >= 0; i--) { + if (maze[i][L - 3] == ROUTE) { + maze[i][L - 2] = ROUTE; + z = i; + break; + } + } +} + +void DrawMaze(int** maze) +{ + for (int i = 0; i < L; i++) + { + for (int j = 0; j < L; j++) + { + if (maze[i][j] == ROUTE) + { + if(i==x&&j==y) + printf("♀"); + else + printf(" "); + } + else + { + printf("▓"); + } + } + printf("\n"); + } + printf("a:向左移动\td:向右移动\n"); + printf("w:向上移动\ts:向下移动\n"); + printf("按回车结束输入"); +} + +void Move(int** maze) +{ + fflush(stdin);//多次使用getchar需要清空stdin,pause按任意键继续,这时会读入一个字符,所以也要清空 + char m; + m = getchar(); + if(m=='\n') + m = getchar(); + fflush(stdin); + switch (m) + { + case 'a': + if (maze[x][y - 1] == WALL) + Move(maze); + else + y = y - 1; + break; + case 'w': + if (maze[x - 1][y] == WALL) + Move(maze); + else + x = x - 1; + break; + case 's': + if (maze[x + 1][y] == WALL) + Move(maze); + else + x = x + 1; + break; + case 'd': + if (maze[x][y + 1] == WALL) + Move(maze); + else + y = y + 1; + break; + default: + printf("请输入w,a,s,d"); + Move(maze); + break; + } + system("cls"); + DrawMaze(maze); + fflush(stdin); + if (x == z && y == L-2) + printf("恭喜您已经走出迷宫"); + else + Move(maze); +} + +void HomeScreen() +{ + system("cls"); + CursorGoto(39, 8); + printf("欢迎来到迷宫游戏"); + CursorGoto(39, 10); + printf("请按0-4选择难度等级\n"); + scanf_s("%d", &Rank); +} + +void CursorGoto(int x, int y) +{ + COORD pos = { x,y }; + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); +} \ No newline at end of file From 6ffd164f84b848ce6514e96af6ed2f9b9d48778a Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Mon, 29 Mar 2021 19:26:54 +0800 Subject: [PATCH 10/19] the map of pushbox --- homework/pushboxmap/level1.txt | 12 ++++++++++++ homework/pushboxmap/level2.txt | 10 ++++++++++ homework/pushboxmap/level3.txt | 10 ++++++++++ homework/pushboxmap/level4.txt | 10 ++++++++++ 4 files changed, 42 insertions(+) create mode 100644 homework/pushboxmap/level1.txt create mode 100644 homework/pushboxmap/level2.txt create mode 100644 homework/pushboxmap/level3.txt create mode 100644 homework/pushboxmap/level4.txt diff --git a/homework/pushboxmap/level1.txt b/homework/pushboxmap/level1.txt new file mode 100644 index 00000000..26358eee --- /dev/null +++ b/homework/pushboxmap/level1.txt @@ -0,0 +1,12 @@ +0 0 1 1 1 0 0 0 0 0 +0 0 1 4 1 0 0 0 0 0 +0 0 1 2 1 1 1 1 0 0 +1 1 1 0 0 2 4 1 0 0 +1 4 0 2 3 1 1 1 0 0 +1 1 1 1 2 1 0 0 0 0 +0 0 0 1 4 1 0 0 0 0 +0 0 0 1 1 1 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +您第本关的得分是1 +Mar 28 2021 17:33:50 diff --git a/homework/pushboxmap/level2.txt b/homework/pushboxmap/level2.txt new file mode 100644 index 00000000..b1edddad --- /dev/null +++ b/homework/pushboxmap/level2.txt @@ -0,0 +1,10 @@ +0 0 1 1 1 0 0 0 0 0 +0 0 1 4 1 1 0 0 0 0 +0 0 1 2 0 1 1 1 0 0 +1 1 1 0 2 0 4 1 1 0 +1 4 0 2 3 1 1 1 1 0 +1 1 1 1 2 1 1 0 0 0 +0 0 0 1 0 1 0 0 0 0 +0 0 0 1 0 1 0 0 0 0 +0 0 0 1 4 1 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 diff --git a/homework/pushboxmap/level3.txt b/homework/pushboxmap/level3.txt new file mode 100644 index 00000000..89ca4f5b --- /dev/null +++ b/homework/pushboxmap/level3.txt @@ -0,0 +1,10 @@ +1 4 1 1 1 1 0 0 0 0 +1 0 1 1 4 1 0 0 0 0 +1 0 0 1 0 1 1 1 1 1 +1 0 2 0 0 2 4 1 0 1 +1 0 0 2 3 0 1 0 0 1 +1 1 0 0 0 0 0 2 0 1 +0 0 1 1 1 1 0 1 0 1 +0 0 0 0 0 1 0 0 0 1 +0 0 0 0 0 1 1 0 4 1 +0 0 0 0 0 0 1 1 1 0 diff --git a/homework/pushboxmap/level4.txt b/homework/pushboxmap/level4.txt new file mode 100644 index 00000000..c0c75cb5 --- /dev/null +++ b/homework/pushboxmap/level4.txt @@ -0,0 +1,10 @@ +0 1 1 1 1 1 1 1 1 0 +1 0 0 0 4 1 0 1 0 1 +1 0 0 1 1 1 0 1 0 1 +1 1 2 0 0 0 0 1 4 1 +1 0 0 0 3 0 0 1 0 1 +4 0 0 0 2 0 0 2 0 1 +1 2 0 0 1 1 0 0 0 1 +1 0 0 1 1 0 1 0 0 1 +1 0 0 0 0 0 0 0 1 1 +0 1 1 1 1 1 1 4 1 0 \ No newline at end of file From db86f8693ae53134e32da35428e4dd7c1c74e33e Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 6 Apr 2021 21:03:02 +0800 Subject: [PATCH 11/19] finished warehouse --- homework/level1.12link (1).c | 154 +++++++++++++++++++++++++++++++++ homework/level1.12link (1).h | 25 ++++++ homework/level1.12warehouse.c | 29 +++++++ homework/pushboxmap/level1.txt | 5 +- 4 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 homework/level1.12link (1).c create mode 100644 homework/level1.12link (1).h create mode 100644 homework/level1.12warehouse.c diff --git a/homework/level1.12link (1).c b/homework/level1.12link (1).c new file mode 100644 index 00000000..c2e87a72 --- /dev/null +++ b/homework/level1.12link (1).c @@ -0,0 +1,154 @@ +#include "link.h" +void HomeScreen() +{ + int n; + int i, j = 1; + gotoxy(43, 18); + color(11); + printf("进销存小程序"); + color(14); //黄色边框 + for (i = 20; i <= 26; i++) //输出上下边框┅ + { + for (j = 27; j <= 74; j++) //输出左右边框┇ + { + gotoxy(j, i); + if (i == 20 || i == 26) + { + printf("-"); + } + else if (j == 27 || j == 74) + { + printf("|"); + } + } + } + color(10); + gotoxy(35, 22); + printf("显示存货请按1"); + gotoxy(55, 22); + printf("出库请按3"); + gotoxy(35, 24); + printf("列表入库请按2"); + gotoxy(55, 24); + printf("退出程序请按4\n"); +} + +void importdata() +{ + char buf[BUFSIZE] = { '\0' }; + char charthead[BUFSIZE] = { '\0' }; + head = NULL; + fopen_s(&fp, "D:/tmp/warehouse.txt", "r"); + if (fp == NULL) + printf("Cannot open file!\n"); + fgets(charthead, BUFSIZE, fp); + do + { + Node* p = (Node*)malloc(sizeof(Node)); + p->next = NULL; + fgets(buf, BUFSIZE, fp); //一次读取一行 + sscanf(buf, "%s\t%d\t%d", &(p->name), &(p->type), &(p->quantity)); + Node* last = head; + if (head) + { + while (last->next) + last = last->next; + last->next = p; + } + else + head = p; + } while (!feof(fp)); + fclose(fp); +} + +void ShowList() +{ + printf("name\ttype\tquantity\n"); + for (Node* q = head;q;q = q->next) + printf("%s\t%d\t%d\n", q->name, q->type, q->quantity); +} + +void Input() +{ + int issame = 1; + Node* p = (Node*)malloc(sizeof(Node)); + p->next = NULL; + printf("请要入库的‘货物名称 货物数量’\n"); + scanf("%s %d", &(p->name), &(p->quantity)); + fflush(stdin); + for (Node* q = head;q->next;q = q->next) + { + if (!strcmp(p->name, q->name)) + { + q->quantity += p->quantity; + issame = 0; + update(); + break; + } + } + if (issame) + { + Node* last = head; + if (head) + { + while (last->next) + last = last->next; + last->next = p; + } + else + head = p; + update(); + } + printf("\n恭喜老板,出库成功!\n"); +} + +void Output() +{ + char outname[100]; + int outcnt, isfound = 1; + color(11); + printf("请输入要出库的‘货物名称 货物数量’:\n"); + scanf("%s %d", &outname, &outcnt); + for (Node* q = head;q->next;q = q->next) + { + if (!strcmp(outname, q->name)) + { + q->quantity -= outcnt; + printf("\n恭喜老板,出库成功!\n"); + if (q->quantity < 0) + printf("存货数量不够\n"); + else + { + update(); + isfound = 0; + } + } + } + if (isfound) + printf("没有该货物的储存记录,无法出库\n"); +} + +void update() +{ + fp = fopen("D:/tmp/warehouse2.txt", "w+"); + fprintf(fp, "*%s\r\n", __DATE__); + for (Node* q = head;q;q = q->next) + fprintf(fp, "\n%s\t%d\t%d", q->name, q->type, q->quantity); + fclose(fp); +} + + +void color(int c) +{ + //SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数 + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); + //更改背景颜色 +} + +void gotoxy(int x, int y) +{ + COORD c; + c.X = x; + c.Y = y; + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); +} diff --git a/homework/level1.12link (1).h b/homework/level1.12link (1).h new file mode 100644 index 00000000..23a6b1cd --- /dev/null +++ b/homework/level1.12link (1).h @@ -0,0 +1,25 @@ +#pragma once +#include +#include +#include +#define BUFSIZE 1000 + +typedef struct node +{ + char name[20]; + int type; + int quantity; + struct node* next; +}Node; + +Node* head; +FILE* fp; + +void HomeScreen(); +void importdata(); +void ShowList(); +void Input(); +void Output(); +void update(); +void color(int c); +void gotoxy(int x, int y); diff --git a/homework/level1.12warehouse.c b/homework/level1.12warehouse.c new file mode 100644 index 00000000..4126875a --- /dev/null +++ b/homework/level1.12warehouse.c @@ -0,0 +1,29 @@ +#include "link.h" +int main() +{ + int n; + while (1) + { + HomeScreen(); + importdata(); + scanf_s("%d", &n); + fflush stdin; + system("cls"); + switch (n) + { + case 1:ShowList();break; + case 2:Input();break; + case 3:Output();break; + case 4:exit(0);break; + } + printf("再次运行程序请按1,退出程序请按0"); + scanf_s("%d", &n); + switch (n) + { + case 1:system("cls");break; + case 2:exit(0); + } + } + return 0; +} + diff --git a/homework/pushboxmap/level1.txt b/homework/pushboxmap/level1.txt index 26358eee..6ed81b42 100644 --- a/homework/pushboxmap/level1.txt +++ b/homework/pushboxmap/level1.txt @@ -6,7 +6,4 @@ 1 1 1 1 2 1 0 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - -您第本关的得分是1 -Mar 28 2021 17:33:50 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 From 24e8d10335dd5bd6b5fad8ecc2f81e8e608e1b52 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 13 Apr 2021 22:20:16 +0800 Subject: [PATCH 12/19] revise warehouse --- homework/level1.13link.c | 165 ++++++++++++++++++++++++++++++++++ homework/level1.13link.h | 25 ++++++ homework/level1.13warehouse.c | 30 +++++++ homework/level1.8.cpp | 24 ----- homework/level1.8hanoi.c | 32 +++++++ 5 files changed, 252 insertions(+), 24 deletions(-) create mode 100644 homework/level1.13link.c create mode 100644 homework/level1.13link.h create mode 100644 homework/level1.13warehouse.c delete mode 100644 homework/level1.8.cpp create mode 100644 homework/level1.8hanoi.c diff --git a/homework/level1.13link.c b/homework/level1.13link.c new file mode 100644 index 00000000..a650f111 --- /dev/null +++ b/homework/level1.13link.c @@ -0,0 +1,165 @@ +#include "link.h" +void HomeScreen() +{ + int n; + int i, j = 1; + gotoxy(43, 18); + color(11); + printf("进销存小程序"); + color(14); //黄色边框 + for (i = 20; i <= 26; i++) //输出上下边框┅ + { + for (j = 27; j <= 74; j++) //输出左右边框┇ + { + gotoxy(j, i); + if (i == 20 || i == 26) + { + printf("-"); + } + else if (j == 27 || j == 74) + { + printf("|"); + } + } + } + color(10); + gotoxy(35, 22); + printf("显示存货请按1"); + gotoxy(55, 22); + printf("出库请按3"); + gotoxy(35, 24); + printf("列表入库请按2"); + gotoxy(55, 24); + printf("退出程序请按4\n"); +} + +void importdata() +{ + char buf[BUFSIZE] = { '\0' }; + char charthead[BUFSIZE] = { '\0' }; + head = NULL; + fopen_s(&fp, "D:/tmp/warehouse.txt", "r"); + if (fp == NULL) + printf("Cannot open file!\n"); + fgets(charthead, BUFSIZE, fp); + do + { + Node* p = (Node*)malloc(sizeof(Node)); + p->next = NULL; + fgets(buf, BUFSIZE, fp); //一次读取一行 + sscanf(buf, "%s\t%d\t%d", &(p->name), &(p->type), &(p->quantity)); + Node* last = head; + if (head) + { + while (last->next) + last = last->next; + last->next = p; + } + else + head = p; + } while (!feof(fp)); + fclose(fp); +} + +void ShowList() +{ + printf("name\ttype\tquantity\n"); + for (Node* q = head;q;q = q->next) + printf("%s\t%d\t%d\n", q->name, q->type, q->quantity); +} + +void Input() +{ + int issame = 1; + Node* p = (Node*)malloc(sizeof(Node)); + p->next = NULL; + printf("请要入库的‘货物名称 货物数量’\n"); + scanf("%s %d", &(p->name), &(p->quantity)); + fflush(stdin); + for (Node* q = head;q->next;q = q->next) + { + if (!strcmp(p->name, q->name)) + { + q->quantity += p->quantity; + issame = 0; + update(); + break; + } + } + if (issame) + { + Node* last = head; + if (head) + { + while (last->next) + last = last->next; + last->next = p; + } + else + head = p; + update(); + } + printf("\n恭喜老板,入库成功!\n"); +} + +void Output() +{ + char outname[100]; + int outcnt, isfound = 1; + color(11); + printf("请输入要出库的‘货物名称 货物数量’:\n"); + scanf("%s %d", &outname, &outcnt); + Node* r; + Node* q; + for (q = head, r = NULL;q;q = q->next, r = q) + { + if (!strcmp(outname, q->name)) + { + q->quantity -= outcnt; + if (q->quantity < 0) + { + printf("存货数量不够\n"); + isfound = 0; + } + else + { + if (q->quantity = 0) + { + r = q->next; + free(q); + } + update(); + isfound = 0; + printf("\n恭喜老板,出库成功!\n"); + } + } + } + if (isfound) + printf("没有该货物的储存记录,无法出库\n"); +} + +void update() +{ + fp = fopen("D:/tmp/warehouse.txt", "w+"); + fprintf(fp, "name\ttype\tnumber\n"); + for (Node* q = head;q;q = q->next) + fprintf(fp, "\n%s\t%d\t%d", q->name, q->type, q->quantity); + fclose(fp); +} + + +void color(int c) +{ + //SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数 + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); + //更改背景颜色 +} + +void gotoxy(int x, int y) +{ + COORD c; + c.X = x; + c.Y = y; + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); +} + diff --git a/homework/level1.13link.h b/homework/level1.13link.h new file mode 100644 index 00000000..23a6b1cd --- /dev/null +++ b/homework/level1.13link.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include +#include +#define BUFSIZE 1000 + +typedef struct node +{ + char name[20]; + int type; + int quantity; + struct node* next; +}Node; + +Node* head; +FILE* fp; + +void HomeScreen(); +void importdata(); +void ShowList(); +void Input(); +void Output(); +void update(); +void color(int c); +void gotoxy(int x, int y); diff --git a/homework/level1.13warehouse.c b/homework/level1.13warehouse.c new file mode 100644 index 00000000..3534dd4e --- /dev/null +++ b/homework/level1.13warehouse.c @@ -0,0 +1,30 @@ +#include "link.h" +int main() +{ + int n; + int t; + while (t=1) + { + HomeScreen(); + importdata(); + scanf_s("%d", &n); + fflush stdin; + system("cls"); + switch (n) + { + case 1:ShowList();break; + case 2:Input();break; + case 3:Output();break; + case 4:exit(0);break; + } + printf("再次运行程序请按1,退出程序请按0"); + scanf_s("%d", &n); + switch (n) + { + case 1:system("cls");break; + case 0:exit(0);break; + } + } + return 0; +} + diff --git a/homework/level1.8.cpp b/homework/level1.8.cpp deleted file mode 100644 index f6d5a13a..00000000 --- a/homework/level1.8.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -void move(int n, char a, char b, char c); - -int main() -{ - int n; - printf("please input the number of your disks:"); - scanf("%d", &n); - move(n, 'A', 'B', 'C'); -} -void move(int m, char a, char b, char c)//move函数的作用是把m块盘子移到目标柱 -{ - if(1==m) - printf("move disk %d from %c to %c\n", m, a, c); //递归截止条件 - else - { - move(m-1,a,c,b);//将 m-1个盘子先放到中间柱(对于第m块)上,(对于m-1块)此时起始柱是a,目标柱是b - printf("move disk %d from %c to %c\n", m, a, c);//将A座上地剩下的一个盘移动到C盘上 - move(m-1,b,a,c);//将m-1个盘从中间柱移动到目标柱上 - } - - - diff --git a/homework/level1.8hanoi.c b/homework/level1.8hanoi.c new file mode 100644 index 00000000..48d327b5 --- /dev/null +++ b/homework/level1.8hanoi.c @@ -0,0 +1,32 @@ +#include +void hanoi(int n, char A, char B, char C);//解决汉诺塔问题的函数 +void move(int i, char A, char B);//表示移动 + +int main() +{ + int n, t; + char a='a', c='c', b='b'; + printf("please input the number of diskes that you want to move\n"); + scanf_s("%d", &n); + hanoi(n, a, b, c); + return 0; +} + +void hanoi(int n, char A, char B, char C) +//A是起始柱,B是中间临时放置的柱子,C是目标柱 +{ + int t = n; + if (t > 0) + //递归终止的条件,注意递归不用循环来写,层层进入的过程是计算机来完成的 + { + //解决n个盘子的问题分三步 + hanoi(t - 1, A, C, B);//把n-1个盘子从起始柱移动到中间柱 + move(t, A, C);//最大的盘子(第n个)从起始柱移动到目标柱 + hanoi(t - 1, B, A, C);//把n-1个盘子从中间柱移动到目标柱 + t--; + } +} +void move(int i, char A, char B) +{ + printf("move disk %d from %c to %c\n", i, A, B); +} \ No newline at end of file From 9e2e68426fc80362cab0e7afd4efcafd419cd5bf Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Tue, 27 Apr 2021 21:40:05 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=9E=81=E5=A4=A7=E5=80=BC=E6=9E=81?= =?UTF-8?q?=E5=B0=8F=E5=80=BC=E6=90=9C=E7=B4=A2=E7=AE=97=E6=B3=95=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/warehouse.txt | 6 + "\345\256\236\351\252\214/draft.c" | 62 +++ "\345\256\236\351\252\214/go.h" | 39 ++ "\345\256\236\351\252\214/main.c" | 0 "\345\256\236\351\252\214/max-min.c" | 158 +++++++ ...\344\272\224\345\255\220\346\243\2131.0.c" | 415 ++++++++++++++++++ 6 files changed, 680 insertions(+) create mode 100644 homework/warehouse.txt create mode 100644 "\345\256\236\351\252\214/draft.c" create mode 100644 "\345\256\236\351\252\214/go.h" create mode 100644 "\345\256\236\351\252\214/main.c" create mode 100644 "\345\256\236\351\252\214/max-min.c" create mode 100644 "\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" diff --git a/homework/warehouse.txt b/homework/warehouse.txt new file mode 100644 index 00000000..a46beb60 --- /dev/null +++ b/homework/warehouse.txt @@ -0,0 +1,6 @@ +name type number +A 5 8 +B 3 2 +C 4 0 +D 1 19 +E 17 6 \ No newline at end of file diff --git "a/\345\256\236\351\252\214/draft.c" "b/\345\256\236\351\252\214/draft.c" new file mode 100644 index 00000000..74815ac5 --- /dev/null +++ "b/\345\256\236\351\252\214/draft.c" @@ -0,0 +1,62 @@ +/* +int PD[21][15] = { {0},{0} };//principle diagonal +int BD[21][15] = { {0},{0} };//back diagonal +void flat() +{ + for (int i = 0;i < 11;i++) + for (int j = 0;j < L-i;j++) + { + PD[i][j] = board[i + j][j]; + PD[10 + i][j] = board[j][i + j]; + } + for (int i = 0;i < 11;i++) + for (int j = 0;j < L - i;j++) + { + BD[i][j] = board[i + j][L - j]; + BD[10 + i][j] = board[j][L - i - j]; + } +} + +void testflat() +{ + for(int i=0;i<21;i++) + for(int j=0;j<21;j++) + printf("%d\t", PD[i][j]); + for (int i = 0;i < 21;i++) + for (int j = 0;j < 21;j++) + printf("%d\t", BD[i][j]); +} +*/ //c语言平面化可能并不方便 +/* + for(int j=0;j<15;j++) + for (int i = 0;i < 21;i++) + { + if (PD[i][j] == 1) + { + k = 0; + int t = i; + while (PD[t][j] == 1) + t++;k++; + if (PD[i-1][j] == 2 || PD[t+1][j] == 2)//判断不是边界 + k--; + if (PD[i-1][j] == 2 && PD[t+1][j] == 2) + k = -1;//区分死棋和死一 + if (k >= 0) + human_score = human_score + pow(10, k); + + } + + } +#define ONE 10//live one +#define TWO 100 +#define THREE 1000 +#define FOUR 100000 +#define FIVE 10000000 +#define BLOCKED_ONE 1 +#define BLOCKED_TWO 10 +#define BLOCKED_THREE 100 +#define BLOCKED_FOUR 10000 +#define TWO_THREE +#define BLOCK_FOUR +#define FOUR_THREE + */ diff --git "a/\345\256\236\351\252\214/go.h" "b/\345\256\236\351\252\214/go.h" new file mode 100644 index 00000000..20a2a8db --- /dev/null +++ "b/\345\256\236\351\252\214/go.h" @@ -0,0 +1,39 @@ + +#pragma once +#include +#include +#include +#include +#include +#include +#define N 65 +#define L 15 +#define red 1 +#define white 2 +#define wall 3 +#define col 4 +#define row 2 + +int** board; + +int AI_regrex, AI_regrey, man_regrex, man_regrey; + +int AI_x, AI_y; +int AI_x2, AI_y2; +int man_x, man_y; +int man_x2, man_y2; + +void BackGround(unsigned int ForeColor, unsigned int BackGroundColor); +void gotoxy(int x, int y); +void chess_menu(); +void chess_board();//打印棋盘 +void board_array(); +void man_move();//红子棋移动光标 +void machine_move(); +void convert(int x, int y, int x2, int y2); +void man_machine();//人机对战 +int judge_chess(int x, int y);//判断这个位置是否下过 +int judge_winner(int x, int y, int temp);//判断输赢 +void Regret();//悔棋函数 +void welcome(); +char Gametips(); \ No newline at end of file diff --git "a/\345\256\236\351\252\214/main.c" "b/\345\256\236\351\252\214/main.c" new file mode 100644 index 00000000..e69de29b diff --git "a/\345\256\236\351\252\214/max-min.c" "b/\345\256\236\351\252\214/max-min.c" new file mode 100644 index 00000000..2aaf1bb0 --- /dev/null +++ "b/\345\256\236\351\252\214/max-min.c" @@ -0,0 +1,158 @@ +#include "go.h" +int evaluate(int me, int others); +void generator(int me, int others); + +//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 + + +int evaluate(int me,int others) +{ + int k=0, score=0; + int T = me, F = others; + + for (int i = 1;i < L + 1;i++)//检查横向 + for (int j = 1;j < L + 1;j++) + { + if (board[i][j] == T) + { + + k = 1; + int t = j;//用t暂时存储j,方便之后检查前面的情况,然后j++,避免重复检查 + j++; + while (board[i][j] == T) + { + j++; + k++; + } + if (board[i][j] == F || board[i][t - 1] == F || board[i][j] == wall || board[i][t - 1] == wall) + k--; + if ((board[i][j] == F && board[i][t - 1] == F) || (board[i][j] == wall && board[i][t - 1] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + j = t; + } + } + + for (int i = 1;i < L + 1;i++)//竖向检查 + for (int j = 1;j < L + 1;j++) + { + if (board[i][j] == T) + { + k = 1; + int t = i; + i++; + while (board[i][j] == T)//i=16,这里经过一次i++后,i已经在连棋的后面一格了 + { + i++; + k++; + } + if (board[t - 1][j] == F || board[i][j] == F || board[t - 1][j] == wall || board[i][j] == wall) + k--; + if ((board[t - 1][j] == F && board[i][j] == F )|| (board[t - 1][j] == wall && board[i + 1][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t; + } + } + + for (int i = 1;i < L + 1;i += 1)//检查主对角线 + for (int j = 1;j < L + 1;j += 1) + { + if (board[i][j] == T) + { + k = 1; + int t1 = i, t2 = j; + i++; + j++; + while (board[i][j] == T) + { + i++; + j++; + k++; + } + if (board[t1 - 1][t2 - 1] == F || board[i][j] == F || board[t1 - 1][t2 - 1] == wall || board[i][j] == wall) + //判断不是边界 + k--; + if ((board[t1 - 1][t2 - 1] == F && board[i][j] == F )|| (board[t1 - 1][t2 - 1] == wall && board[i][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t1; + j = t2; + } + } + + for (int i = 1;i < L + 1;i += 1)//检查反对角线 + for (int j = 1;j < L + 1;j += 1) + { + if (board[i][j] == T) + { + k = 1; + int t1 = i, t2 = j; + i += 1; + j -= 1; + while (board[i][j] == T) + { + i += 1; + j -= 1; + k++; + } + if (board[t1 - 1][t2 + 1] == F || board[i][j] == F || board[i][j] == wall || board[i][j] == wall) + k--;//遇到边界也相当于是死棋 + if ((board[t1 - 1][t2 + 1] == F && board[i][j] == F )|| (board[i][j] == wall && board[i][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t1; + j = t2; + } + } + return score; +} + +void generator(int me,int others)//先不管邻居,直接遍历 +{ + int my_score = 0; + int t = 0; + int m, n; + for (int i = 1;i < L + 1;i += 1) + for (int j = 1;j < L + 1;j += 1) + { + if (!board[i][j])//决策树,评估这个点下了棋之后的得分 + { + board[i][j] = me; + t=evaluate(me, others)- evaluate(others, me); + n = evaluate(me, others); + m = evaluate(others, me); + board[i][j] = 0; + } + if (t > my_score) + { + board[i][j] = me; + my_score = t; + AI_x = j;//坐标表示和数组索引表示是反的 + AI_y = i; + } + } +} + +//用什么数据结构储存有邻居的位置 +/* +void neighbor() +{ + for (int i = 0;i < 15;i++) + for (int j = 0;j < 15;j++) + { + if (!board[i][j]) + { + + } + + } + + +} +*/ + diff --git "a/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" new file mode 100644 index 00000000..a1c77d92 --- /dev/null +++ "b/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" @@ -0,0 +1,415 @@ +#include "go.h" +//判断输赢,判断是否下过 +int flag = 0;//判断输赢 +int count = 0;//计算棋子数量 + +void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 +{ + HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 + SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 +} + +void gotoxy(int x, int y) //光标函数 +{ + HANDLE handle; + COORD coord; //获取坐标轴结构体 + coord.X = x; + coord.Y = y; + handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11 + SetConsoleCursorPosition(handle, coord); //移动光标到x,y处 +} + +void chess_board()//打印棋盘 +{ + int i,j; + for(i=1;i<=30;i++) + for(j=0;j<=60;j+=4) + { + gotoxy(j, i); + printf("|"); + } + for(i=1;i<=31;i+=2) + for(j=1;j<=57;j+=4) + { + gotoxy(j,i); + printf("---"); + } +} + +void chess_menu()//打印棋盘旁的菜单 +{ + int i,j; + for(i=1;i<=29;i++) + { + gotoxy(67,i); + printf("||"); + } + for(i=1;i<=29;i++) + { + gotoxy(89,i); + printf("||"); + } + gotoxy(69,1); + printf("--------------------"); + gotoxy(69,29); + printf("--------------------"); + gotoxy(75,3); + printf("模 式"); + gotoxy(75,20); + printf("提 示"); +} + +void board_array() +{ + board = (int**)malloc(L * sizeof(int*)); + for (int i = 0;i < L+2;i++) + board[i] = (int*)calloc(L, sizeof(int)); + for (int i = 0;i < L+2;i++) + for (int j = 0;j < L+2;j++)//解决边界问题,加一个边界,边界=3 + //1-15是棋盘 + { + if (i != 0 && i != L+1 && j != 0 && j != L+1) + board[i][j] = 0; + else + board[i][j] = 3; + } +} + +void man_move()//白棋移动光标 +{ + loop1:gotoxy(4*man_x,2*man_y+1); + char key='y'; + while(key!='0') + { + key=_getch(); + switch(key) + { + case 72: + man_y--; + if(man_y<=1) + man_y=1; + break; + case 80: + man_y++; + if(man_y>=15) + man_y=15; + break; + case 75: + man_x--; + if(man_x<=1) + man_x=1; + break; + case 77: + man_x++; + if(man_x>=15) + man_x=15; + break; + case 'B': + case 'b': + { + int message=MessageBox(NULL,TEXT("是否确定悔棋?"),TEXT("友情提示"),MB_OKCANCEL); + if(IDCANCEL==message) + break; + if(IDOK==message) + { + Regret(); + break; + } + } + } + //convert(man_x, man_y, man_x2, man_y2); + gotoxy(4 * man_x, 2 * man_y + 1); + } + if (board[man_y][man_x]) + { + gotoxy(70, 22); + BackGround(4, 0); + printf("这里已经被人下过了"); + goto loop1; + } + else + { + board[man_y][man_x] = white; + BackGround(7, 0); + man_regrex = man_x; + man_regrey = man_y; + printf("●"); + } +} + +void machine_move()//机器用红子,玩家用白子 +{ + generator(red, white); + //convert(AI_x, AI_y, AI_x2, AI_y2); + gotoxy(4*AI_x, 2*AI_y+1);//坐标和数组的顺序是反的 + BackGround(4, 0); + AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 + AI_regrey = AI_y; + printf("●"); +} +/* +void convert(int* px,int* py,int* qx,int* qy) +{ + *qx = 4 * (*px); + *qy = 2 * (*qy) + 1; +}//打印出的棋盘和数组模拟棋盘之间索引需要转换 +*/ + +int judge_chess(int x,int y)//判断这个地方是否有棋子 +{ + if(board[x][y]==0) + return 0; + else + return 1; +} +/* +int judge_winner(int x,int y,int temp)//判断输赢 +{ + int i,j,n1,n2; + n1=n2=0; + for(i=x,j=y+4;j<=58;j+=4)//右 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x,j=y;j>=2;j-=4)//左 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x,j=y;i>=1;i-=2)//上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x+2,j=y;i<=30;i+=2)//下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x-2,j=y+4;i>=1&&j<=58;i-=2,j+=4)//右上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x,j=y;i<=30&&j>=2;i+=2,j-=4)//左下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x,j=y;i>=0&&j>=0;i-=2,j-=4)//左上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x+2,j=y+4;i<=30&&j<=58;i+=2,j+=4)//右下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + return 0; +} + +*/ + +void man_machine()//人机对战模式 +{ + loop6:system("cls"); + char key; + int control; + gotoxy(2, 3); + printf("1.玩 家 先 手"); + + gotoxy(2, 5); + printf("2.电 脑 先 手"); + + gotoxy(2, 7); + printf("玩家为白子,电脑为红子(输入相应序号选择)"); + key=_getch(); + system("cls"); + if(key=='1') + control=1; + else if(key=='2') + { + control=-1; + } + else + goto loop6; + gotoxy(70,5); + printf(" 人 机 对 战 "); + man_y=7; + man_x=8; + chess_board(); + board_array(); + chess_menu(); + while(flag==0) + { + if(control==1) + { + gotoxy(70,22); + BackGround(6,0); + printf(" 玩 家 执 手 "); + man_move(); + //flag=judge_winner(direct[1],direct[0],1); + } + else + { + gotoxy(70,22); + BackGround(6,0); + printf(" 电 脑 执 手 "); + machine_move(); + //flag=judge_winner(direct[1],direct[0],2); + } + control=-control; + } + gotoxy(8,18); + if(flag==1) + { + BackGround(7,0); + MessageBox(NULL,TEXT("太厉害了,您竟然战胜了电脑!"),TEXT("五子棋游戏"),MB_OK); + } + if(flag==2) + { + MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); + } + if(count>=225) + { + MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); + } +} + +void Regret()//悔棋函数 +{ + gotoxy(man_x2,man_y2); + BackGround(0,0); + printf(" "); + board[man_y][man_x]=0; + gotoxy(AI_y2,AI_x2); + BackGround(0,0); + printf(" "); + board[AI_y][AI_x]=0; +} + +void welcome()//游戏菜单 +{ + int k; + char choose; + system("cls"); + for(k=2;k<=16;k+=2)//游戏菜单 + { + gotoxy(5,k); + printf("|-----------------|"); + } + gotoxy(5, 3); + printf("| 五 子 棋 游 戏 |"); + + gotoxy(5, 5); + printf("| 菜 单 |"); + + gotoxy(5, 7); + printf("| 1.人 人 对 战 |"); + + gotoxy(5, 9); + printf("| 2.人 机 对 战 |"); + + gotoxy(5, 11); + printf("| 3.游 戏 帮 助 |"); + + gotoxy(5, 13); + printf("| 4.更 新 日 志 |"); + + gotoxy(5, 15); + printf("| 5.退 出 游 戏 |"); + + gotoxy(5, 18); + printf("温馨提示:输入菜单对应序号进行操作"); + + gotoxy(5, 20); + printf("祝您游戏愉快!"); + + gotoxy(13, 20); +} + +char Gametips()//游戏帮助 +{ + char choose; + int key; + + system("cls"); + + gotoxy(2, 3); + printf("游戏操作:"); + + gotoxy(4, 5); + printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); + + gotoxy(4, 7); + printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); + + gotoxy(2, 19); + printf("(按E键返回,按其它任意键退出)"); + + return _getch(); +} + + +int main() +{ + system("title 五子棋"); + system("mode con cols=92 lines=33"); + char choose, temp; +loop:welcome(); + choose = _getch(); + switch (choose) + { + case '1': + + break; + case '2': + man_machine(); + break; + case '3': + temp = Gametips(); + if (temp == 'E' || temp == 'e') + goto loop; + break; + case '4': + case '5': + { + int message = MessageBox(NULL, TEXT("是否退出?"),TEXT( "友情提示"), MB_OKCANCEL); + if (IDCANCEL == message) + goto loop; + if (IDOK == message) + { + break; + } + } + } +} From 1b9a445767520095fe9b324b68107ac1d5692d34 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Fri, 14 May 2021 19:12:45 +0800 Subject: [PATCH 14/19] =?UTF-8?q?[=E4=B8=80=E5=B1=82=E5=86=B3=E7=AD=96,?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\345\256\236\351\252\214/BetaGo/BetaGo.sln" | 31 + .../BetaGo/BetaGo.vcxproj" | 154 ++++ .../BetaGo/BetaGo.vcxproj.filters" | 36 + .../BetaGo/BetaGo.vcxproj.user" | 4 + "\345\256\236\351\252\214/BetaGo/GUI.c" | 90 ++ "\345\256\236\351\252\214/BetaGo/draft.c" | 158 ++++ .../BetaGo/go.h" | 16 +- "\345\256\236\351\252\214/BetaGo/max-min.c" | 117 +++ .../\344\272\224\345\255\220\346\243\213.c" | 771 ++++++++++++++++++ ...\344\272\224\345\255\220\346\243\2131.0.c" | 286 +++++++ "\345\256\236\351\252\214/README.md" | 17 - "\345\256\236\351\252\214/draft.c" | 62 -- "\345\256\236\351\252\214/main.c" | 0 "\345\256\236\351\252\214/max-min.c" | 158 ---- ...\344\272\224\345\255\220\346\243\2131.0.c" | 415 ---------- 15 files changed, 1654 insertions(+), 661 deletions(-) create mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.sln" create mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" create mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" create mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" create mode 100644 "\345\256\236\351\252\214/BetaGo/GUI.c" create mode 100644 "\345\256\236\351\252\214/BetaGo/draft.c" rename "\345\256\236\351\252\214/go.h" => "\345\256\236\351\252\214/BetaGo/go.h" (75%) create mode 100644 "\345\256\236\351\252\214/BetaGo/max-min.c" create mode 100644 "\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" create mode 100644 "\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" delete mode 100644 "\345\256\236\351\252\214/README.md" delete mode 100644 "\345\256\236\351\252\214/draft.c" delete mode 100644 "\345\256\236\351\252\214/main.c" delete mode 100644 "\345\256\236\351\252\214/max-min.c" delete mode 100644 "\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.sln" "b/\345\256\236\351\252\214/BetaGo/BetaGo.sln" new file mode 100644 index 00000000..54ba4057 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.sln" @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31112.23 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BetaGo", "BetaGo.vcxproj", "{3932EE5E-DA7A-46C4-9A62-742C7FE25302}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x64.ActiveCfg = Debug|x64 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x64.Build.0 = Debug|x64 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x86.ActiveCfg = Debug|Win32 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x86.Build.0 = Debug|Win32 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x64.ActiveCfg = Release|x64 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x64.Build.0 = Release|x64 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x86.ActiveCfg = Release|Win32 + {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9FC45EAA-8058-4628-977E-C3026065F929} + EndGlobalSection +EndGlobal diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" new file mode 100644 index 00000000..46e201b9 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {3932ee5e-da7a-46c4-9a62-742c7fe25302} + BetaGo + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + D:\Documents\c璇█\C璇█璇剧▼\BetaGo;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" new file mode 100644 index 00000000..8829cfd1 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" @@ -0,0 +1,36 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 澶存枃浠 + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" new file mode 100644 index 00000000..88a55094 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/GUI.c" "b/\345\256\236\351\252\214/BetaGo/GUI.c" new file mode 100644 index 00000000..6e4361ef --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/GUI.c" @@ -0,0 +1,90 @@ +#include "go.h" + +void welcome()//游戏菜单 +{ + int k; + char choose; + system("cls"); + for (k = 2;k <= 12;k += 2)//游戏菜单 + { + gotoxy(5, k); + printf("|-----------------|"); + } + gotoxy(5, 3); + printf("| 五 子 棋 游 戏 |"); + + gotoxy(5, 5); + printf("| 菜 单 |"); + + gotoxy(5, 7); + printf("| 1.人 机 对 战 |"); + + gotoxy(5, 9); + printf("| 2.游 戏 帮 助 |"); + + gotoxy(5, 11); + printf("| 3.退 出 游 戏 |"); + + gotoxy(5, 15); + printf("温馨提示:输入菜单对应序号进行操作"); + + gotoxy(5, 20); + printf("祝您游戏愉快!"); + + gotoxy(13, 20); +} + +char Gametips()//游戏帮助 +{ + char choose; + int key; + + system("cls"); + + gotoxy(2, 3); + printf("游戏操作:"); + + gotoxy(4, 5); + printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); + + gotoxy(4, 7); + printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); + + gotoxy(2, 19); + printf("(按E键返回,按其它任意键退出)"); + + return _getch(); +} + +void chess_board()//打印棋盘 +{ + int i, j; + for (i = 1;i <= 30;i++) + for (j = 0;j <= 60;j += 4) + { + gotoxy(j, i); + printf("|"); + } + for (i = 1;i <= 31;i += 2) + for (j = 1;j <= 57;j += 4) + { + gotoxy(j, i); + printf("---"); + } +} + +void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 +{ + HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 + SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 +} + +void gotoxy(int x, int y) //光标函数 +{ + HANDLE handle; + COORD coord; //获取坐标轴结构体 + coord.X = x; + coord.Y = y; + handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11 + SetConsoleCursorPosition(handle, coord); //移动光标到x,y处 +} \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/draft.c" "b/\345\256\236\351\252\214/BetaGo/draft.c" new file mode 100644 index 00000000..a1681c0e --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/draft.c" @@ -0,0 +1,158 @@ +/* +int PD[21][15] = { {0},{0} };//principle diagonal +int BD[21][15] = { {0},{0} };//back diagonal +void flat() +{ + for (int i = 0;i < 11;i++) + for (int j = 0;j < L-i;j++) + { + PD[i][j] = board[i + j][j]; + PD[10 + i][j] = board[j][i + j]; + } + for (int i = 0;i < 11;i++) + for (int j = 0;j < L - i;j++) + { + BD[i][j] = board[i + j][L - j]; + BD[10 + i][j] = board[j][L - i - j]; + } +} + +void testflat() +{ + for(int i=0;i<21;i++) + for(int j=0;j<21;j++) + printf("%d\t", PD[i][j]); + for (int i = 0;i < 21;i++) + for (int j = 0;j < 21;j++) + printf("%d\t", BD[i][j]); +} +*/ //c语言平面化可能并不方便 +/* + for(int j=0;j<15;j++) + for (int i = 0;i < 21;i++) + { + if (PD[i][j] == 1) + { + k = 0; + int t = i; + while (PD[t][j] == 1) + t++;k++; + if (PD[i-1][j] == 2 || PD[t+1][j] == 2)//判断不是边界 + k--; + if (PD[i-1][j] == 2 && PD[t+1][j] == 2) + k = -1;//区分死棋和死一 + if (k >= 0) + human_score = human_score + pow(10, k); + + } + + } +#define ONE 10//live one +#define TWO 100 +#define THREE 1000 +#define FOUR 100000 +#define FIVE 10000000 +#define BLOCKED_ONE 1 +#define BLOCKED_TWO 10 +#define BLOCKED_THREE 100 +#define BLOCKED_FOUR 10000 +#define TWO_THREE +#define BLOCK_FOUR +#define FOUR_THREE + */ + + /* + k = 1; + int t = j;//用t暂时存储j,方便之后检查前面的情况,然后j++,避免重复检查 + j++; + while (board[i][j] == T) + { + j++; + k++; + } + if (board[i][j] == F || board[i][t - 1] == F || board[i][j] == wall || board[i][t - 1] == wall) + k--; + if ((board[i][j] == F && board[i][t - 1] == F) || (board[i][j] == wall && board[i][t - 1] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + j = t; + } + } + + for (int i = 1;i < L + 1;i++)//竖向检查 + for (int j = 1;j < L + 1;j++) + { + if (board[i][j] == T) + { + k = 1; + int t = i; + i++; + while (board[i][j] == T)//i=16,这里经过一次i++后,i已经在连棋的后面一格了 + { + i++; + k++; + } + if (board[t - 1][j] == F || board[i][j] == F || board[t - 1][j] == wall || board[i][j] == wall) + k--; + if ((board[t - 1][j] == F && board[i][j] == F )|| (board[t - 1][j] == wall && board[i + 1][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t; + } + } + + for (int i = 1;i < L + 1;i += 1)//检查主对角线 + for (int j = 1;j < L + 1;j += 1) + { + if (board[i][j] == T) + { + k = 1; + int t1 = i, t2 = j; + i++; + j++; + while (board[i][j] == T) + { + i++; + j++; + k++; + } + if (board[t1 - 1][t2 - 1] == F || board[i][j] == F || board[t1 - 1][t2 - 1] == wall || board[i][j] == wall) + //判断不是边界 + k--; + if ((board[t1 - 1][t2 - 1] == F && board[i][j] == F )|| (board[t1 - 1][t2 - 1] == wall && board[i][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t1; + j = t2; + } + } + + for (int i = 1;i < L + 1;i += 1)//检查反对角线 + for (int j = 1;j < L + 1;j += 1) + { + if (board[i][j] == T) + { + k = 1; + int t1 = i, t2 = j; + i += 1; + j -= 1; + while (board[i][j] == T) + { + i += 1; + j -= 1; + k++; + } + if (board[t1 - 1][t2 + 1] == F || board[i][j] == F || board[i][j] == wall || board[i][j] == wall) + k--;//遇到边界也相当于是死棋 + if ((board[t1 - 1][t2 + 1] == F && board[i][j] == F )|| (board[i][j] == wall && board[i][j] == wall)) + k = -1;//区分死棋和死一 + if (k >= 0) + score = score + pow(10, k); + i = t1; + j = t2; + } + } + */ diff --git "a/\345\256\236\351\252\214/go.h" "b/\345\256\236\351\252\214/BetaGo/go.h" similarity index 75% rename from "\345\256\236\351\252\214/go.h" rename to "\345\256\236\351\252\214/BetaGo/go.h" index 20a2a8db..da26ec6f 100644 --- "a/\345\256\236\351\252\214/go.h" +++ "b/\345\256\236\351\252\214/BetaGo/go.h" @@ -1,4 +1,3 @@ - #pragma once #include #include @@ -14,14 +13,14 @@ #define col 4 #define row 2 -int** board; - -int AI_regrex, AI_regrey, man_regrex, man_regrey; +extern int board[17][17]; +extern int AI_regrex, AI_regrey, man_regrex, man_regrey; -int AI_x, AI_y; -int AI_x2, AI_y2; -int man_x, man_y; -int man_x2, man_y2; +extern int AI_x, AI_y; +extern int AI_x2, AI_y2; +extern int man_x, man_y; +extern int man_x2, man_y2; +extern int dir[][2]; void BackGround(unsigned int ForeColor, unsigned int BackGroundColor); void gotoxy(int x, int y); @@ -32,7 +31,6 @@ void board_array(); void machine_move(); void convert(int x, int y, int x2, int y2); void man_machine();//人机对战 -int judge_chess(int x, int y);//判断这个位置是否下过 int judge_winner(int x, int y, int temp);//判断输赢 void Regret();//悔棋函数 void welcome(); diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214/BetaGo/max-min.c" new file mode 100644 index 00000000..6e969ae6 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/max-min.c" @@ -0,0 +1,117 @@ +#include "go.h" +int evaluate(int me, int others); +void generator(int me, int others); + +//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 +typedef struct node +{ + int x, y; +}Node; + +int dfs(int x, int y,int T,int F,int vis[][17]) +{ + int value = 0; + int maxdir = 0; + for (int i = 0;i < 8;i++)//i表示八个方向 + for (int j = 1;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j*dir[i][0]; + int dy = y + j*dir[i][1]; + if (board[dx][dy] != T) + { + if (j > value) + { + value = j;//记录最大连子数和最大的方向 + maxdir = i; + } + break; + } + } + + //特殊情况优先 + + //标记已经搜索且在最大路径上的节点,避免重复搜索 + for (int j = 0;j <= value;j++) + { + int dx = x + j * dir[maxdir][0]; + int dy = y + j * dir[maxdir][1]; + vis[dx][dy] = 1; + } + + //判断连子的死活 + int dx1 = x + value * dir[maxdir][0]; + int dy1 = y + value * dir[maxdir][1]; + int dx2 = x - dir[maxdir][0]; + int dy2 = y - dir[maxdir][1]; + if(dx1<0||dy1<0) + value--; + else + if (board[dx1][dy1] == F || board[dx1][dy1] == wall) + value--; + if (board[dx2][dy2] == F || board[dx2][dy2] == wall) + value--; + return value; +} + +int evaluate(int me,int others)//全局评估某一方的分数 +{ + int k=0, score=0; + int T = me, F = others; + int value = 0; + int vis[17][17] = { {0},{0} }; + + //遍历找到我方棋子开始dfs + for (int i = 1;i < L + 1;i++) + for (int j = 1;j < L + 1;j++) + { + if (board[i][j] == T && (!vis[i][j]))//是我方且没有被搜索过 + { + value = dfs(i, j, T, F, vis); + score = score + pow(10, value); + } + } + return score; +} + +void generator()//生成AI的棋子的函数 +{ + int my_score = -100; + int t = -1000; + int m, n; + for (int i = 1;i < L + 1;i += 1) + for (int j = 1;j < L + 1;j += 1) + { + int is_nei = neighbor(i, j);//棋子附近两步之内有棋子 + if (board[i][j]==0 && is_nei)//决策树,评估这个点下了棋之后的得分 + { + board[i][j] = red; + t=evaluate(red, white)- evaluate(white, red); + board[i][j] = 0; + } + if (t > my_score) + { + my_score = t; + AI_x = j;//坐标表示和数组索引表示是反的 + AI_y = i; + } + } +} + + +int neighbor(int x,int y) +{ + for (int di = 0;di < 8;di++)//i表示八个方向 + for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 + { + int dx = x + dj * dir[di][0]; + int dy = y + dj * dir[di][1]; + if (dx > 0 && dx < L + 1 && dy>0 && dy < L + 1) + if (board[dx][dy] == red || board[dx][dy] == white) + return 1; + } + return 0; +} + + + + diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" new file mode 100644 index 00000000..bc2ea03a --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" @@ -0,0 +1,771 @@ +/*界面文字和系统文字重叠 +悔棋擦不干净 +弹窗上的字是乱码*/ +/* +#include +#include +#include +#include +#include +#define N 65 +#define size 60 +#define L 3 + +int status[N][N]={{0},{0}};//记录棋盘情况,0无,1红棋/玩家,2为白棋/电脑 +int flag=0;//判断输赢 +int direct[2];//方向 +int Value1[N][N]={{0},{0}};//计算权值 +int Value2[N][N]={{0},{0}};//计算权值 +int regrex,regrey,regrex1,regrey1; +int count=0;//计算棋子数量 + +void chess_board();//打印棋盘 +void red_movexy();//红子棋移动光标 +void white_movexy();//白棋移动光标 +void red_chess(int x,int y);//红棋 +void white_chess(int x,int y);//白棋 +void man_man(); +void man_machine();//人机对战 +int judge_chess(int x,int y);//判断这个位置是否下过 +int judge_winner(int x,int y,int temp);//判断输赢 +void machine_attack();//电脑进攻权值 +void machine_defend();//电脑防守权值 +void find_position();//寻找最佳权值 +void Regret();//悔棋函数 + +void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 +{ + HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 + SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 +} + +void gotoxy(int x, int y) //光标函数 +{ + HANDLE handle; + COORD coord; //获取坐标轴结构体 + coord.X = x; + coord.Y = y; + handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11 + SetConsoleCursorPosition(handle, coord); //移动光标到x,y处 +} + +void chess_board()//打印棋盘 +{ + int i,j; + BackGround(1, 3); + for (i = 0;i <= size / L;i++) + for(j=0;j<=size;j+=L) + { + gotoxy(j,i); + printf("|"); + } + for(i=0;i<= size / L;i++) + for(j=1;j<=size;j+=L) + { + gotoxy(j,i); + printf("--"); + } +} + +void chess_menu()//打印棋盘旁的菜单 +{ + int i,j; + for(i=1;i<=size/L;i++) + { + gotoxy(67,i); + printf("||"); + } + for(i=1;i<= size / L;i++) + { + gotoxy(67,i); + printf("||"); + } + gotoxy(69,1); + printf("--------------------"); + gotoxy(69, size / L); + printf("--------------------"); + gotoxy(75,3); + printf("模 式"); + gotoxy(75,15); + printf("提 示"); +} + +void red_movexy()//红棋移动光标 +{ + loop2:gotoxy(direct[0],direct[1]); + char key='y'; + int temp; + while(key!=' ') + { + key=_getch(); + switch(key) + { + case 'W': + case 'w': + direct[1]-=1; + if(direct[1]<=1) + direct[1]=1; + break; + case 's': + case 'S': + direct[1]+=1; + if(direct[1]>=size/L) + direct[1]= size / L; + break; + case 'a': + case 'A': + direct[0]-=L; + if(direct[0]<=2) + direct[0]=2; + break; + case 'd': + case 'D': + direct[0]+=L; + if(direct[0]>=size) + direct[0]=size; + break; + case 'q': + case 'Q': + { + int message=MessageBox(NULL,TEXT("是否确定悔棋?"),TEXT("友情提示"),MB_OKCANCEL); + if(IDCANCEL==message) + break; + if(IDOK==message) + { + Regret(); + break; + } + } + } + gotoxy(direct[0],direct[1]); + } + temp=judge_chess(direct[1],direct[0]); + if(temp==1) + { + gotoxy(70,22); + BackGround(4, 0); + printf("这里已经被人下过了"); + goto loop2; + } +} + +void white_movexy()//白棋移动光标 +{ + loop1:gotoxy(direct[0],direct[1]); + char key='y'; + int temp; + while(key!='0') + { + key=_getch(); + switch(key) + { + case 72: + direct[1]-=1; + if(direct[1]<=1) + direct[1]=1; + break; + case 80: + direct[1]+=1; + if(direct[1]>= size / L) + direct[1]= size / L; + break; + case 75: + direct[0]-=L; + if(direct[0]<=2) + direct[0]=2; + break; + case 77: + direct[0]+=L; + if(direct[0]>= size) + direct[0]= size; + break; + case 'B': + case 'b': + { + int message=MessageBox(NULL, TEXT("是否确定悔棋?"), TEXT("友情提示"),MB_OKCANCEL); + if(IDCANCEL==message)break; + if(IDOK==message)Regret();break; + } + } + gotoxy(direct[0],direct[1]); + } + temp=judge_chess(direct[1],direct[0]); + if(temp==1) + { + gotoxy(70,22); + BackGround(4, 0); + printf("这里已经被人下过了"); + goto loop1; + } +} + +void red_chess(int x,int y)//打印红棋 +{ + BackGround(4,3); + regrex=x;//记录上一落子的位置 ,方便悔棋 + regrey=y; + count++; + printf("●"); + status[x][y]=1; +} + +void white_chess(int x,int y)//打印白棋 +{ + BackGround(7,3); + regrex1=x; + regrey1=y; + printf("●"); + count++; + status[x][y]=2; +} + +void machine_chess(int x,int y)//电脑落子 +{ + BackGround(7,3); + status[x][y]=2; + regrex1=x; + regrey1=y; + count++; + gotoxy(y,x); + printf("●"); +} + +int judge_chess(int x,int y)//判断这个地方是否有棋子 +{ + if(status[x][y]==0) + return 0; + else + return 1; +} + +int judge_winner(int x,int y,int temp)//判断输赢 +{ + int i,j,n1,n2; + n1=n2=0; + for(i=x,j=y+4;j<=58;j+=4)//右 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x,j=y;j>=2;j-=4)//左 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x,j=y;i>=1;i-=2)//上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x+2,j=y;i<=30;i+=2)//下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x-2,j=y+4;i>=1&&j<=58;i-=2,j+=4)//右上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x,j=y;i<=30&&j>=2;i+=2,j-=4)//左下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + n1=n2=0; + for(i=x,j=y;i>=0&&j>=0;i-=2,j-=4)//左上 + { + if(status[i][j]==temp) + n1++; + else + break; + } + for(i=x+2,j=y+4;i<=30&&j<=58;i+=2,j+=4)//右下 + { + if(status[i][j]==temp) + n2++; + else + break; + } + if(n1+n2>=5) + return temp; + return 0; +} + +void machine_attack()//电脑进攻权值 +{ + int i1,j1; + int k1,k2,k; + for(int i=1;i<=30;i+=2) + { + for(int j=2;j<=58;j+=4) + { + if(status[i][j]) + Value1[i][j]=0; + if(status[i][j]==0) + { + k1=k2=0; + for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k1++; + else + break; + } + for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k2++; + else + break; + } + k=k1>k2? k1:k2; + k1=k2=0; + for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k1++; + else + break; + } + for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1? k:k1; + k1=k2=0; + for(i1=i-2,j1=j-4;i1>=0&&j1>=0;i1-=2,j1-=4)//往左上数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k1++; + else + break; + } + for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找电脑棋子数 + { + if(status[i1][j1]==2 ) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1?k:k1; + k1=k2=0; + for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k1++; + else + break; + } + for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找电脑棋子数 + { + if(status[i1][j1]==2) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1?k:k1; + switch(k) + { + case 3: + Value1[i][j]=15;break; + case 4: + Value1[i][j]=25;break; + default: + Value1[i][j]=3+2*k;break; + } + } + } + } +} + +void machine_defend()//防守权值 +{ + int i1, j1; + int k1,k2,k; + for(int i=1;i<=30;i+=2) + { + for(int j=2;j<=58;j+=4) + { + if(status[i][j]) + Value2[i][j]=0; + if(status[i][j]==0) + { + k1=k2=0; + for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k1++; + else + break; + } + for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k2++; + else + break; + } + k=k1>k2? k1:k2; + k1=k2=0; + for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k1++; + else + break; + } + for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1?k:k1; + k1=k2=0; + for(i1=i-2,j1=j-4;i1>=1&&j1>=2;i1-=2,j1-=4)//往左上数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k1++; + else + break; + } + for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1?k:k1; + k1=k2=0; + for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k1++; + else + break; + } + for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找玩家棋子数 + { + if(status[i1][j1]==1) + k2++; + else + break; + } + k1=k1>k2? k1:k2; + k=k>k1?k:k1; + switch(k) + { + case 3: + Value2[i][j]=10;break; + case 4: + Value2[i][j]=20;break; + default: + Value2[i][j]=2+k*2; + } + } + } + } +} + +void find_position()//找到最有价值的位置 +{ + int k1=0, k2=0; + int i, j, max=0; + for( i=1;i<=30;i+=2) + for( j=2;j<=58;j+=4) + { + if(max<=Value1[i][j]) + { + max=Value1[i][j]; + k1=i; + k2=j; + } + } + for( i=1;i<=30;i+=2) + for( j=2;j<=58;j+=4) + { + if(max<=Value2[i][j]) + { + max=Value2[i][j]; + k1=i; + k2=j; + } + } + direct[1]=k1; //将找到的位置传给光标 + direct[0]=k2; +} + +void man_man()//人人对战模式 +{ + loop5:system("cls"); + char key; + int control; + gotoxy(2, 3); + printf("1.红 子 先 手"); + + gotoxy(2, 5); + printf("2.白 子 先 手"); + + gotoxy(2, 7); + printf("(输入相应序号选择)"); + key=_getch(); + system("cls"); + if(key=='1') + control=1; + else if(key=='2') + control=-1; + else + goto loop5; + gotoxy(70,5); + printf(" 人 人 对 战 "); + direct[1]=15; + direct[0]=30; + chess_menu(); + chess_board(); + while(flag==0) + { + if(control==1) + { + gotoxy(70,22); + BackGround(6,0); + printf(" 红 子 执 手 "); + red_movexy(); + red_chess(direct[1],direct[0]); + flag=judge_winner(direct[1],direct[0],1); + } + else + { + gotoxy(70,22); + BackGround(6,0); + printf(" 白 子 执 手 "); + white_movexy(); + white_chess(direct[1],direct[0]); + flag=judge_winner(direct[1],direct[0],2); + } + control=-control; + } + if(flag==1) + { + BackGround(7,0); + MessageBox(NULL,TEXT("游戏结束,红子胜利"),TEXT("五子棋游戏"),MB_OK); + } + if(flag==2) + { + MessageBox(NULL,TEXT("游戏结束,白子胜利"),TEXT("五子棋游戏"),MB_OK); + } + if(count>=225) + { + MessageBox(NULL,TEXT("游戏结束,平局"),TEXT("五子棋游戏"),MB_OK); + } +} + +void man_machine()//人机对战模式 +{ + loop6:system("cls"); + char key; + int control; + gotoxy(2, 3); + printf("1.玩 家 先 手(玩家为红子)"); + + gotoxy(2, 5); + printf("2.电 脑 先 手(电脑为白子)"); + + gotoxy(2, 7); + printf("(输入相应序号选择)"); + key=_getch(); + system("cls"); + if(key=='1') + control=1; + else if(key=='2') + { + control=1; + machine_chess(13,26); + } + else + goto loop6; + gotoxy(70,5); + printf(" 人 机 对 战 "); + direct[1]=15; + direct[0]=30; + chess_menu(); + chess_board(); + while(flag==0) + { + if(control==1) + { + gotoxy(70,size/L-5); + BackGround(6,0); + printf(" 玩 家 执 手 "); + red_movexy(); + red_chess(direct[1],direct[0]); + flag=judge_winner(direct[1],direct[0],1); + } + else + { + gotoxy(70,size/L-5); + BackGround(6,0); + printf(" 电 脑 执 手 "); + machine_defend(); + machine_attack(); + find_position(); + machine_chess(direct[1],direct[0]); + flag=judge_winner(direct[1],direct[0],2); + } + control=-control; + } + gotoxy(8,18); + if(flag==1) + { + BackGround(7,0); + MessageBox(NULL,TEXT("太厉害了,您战胜了电脑!"),TEXT("五子棋游戏"),MB_OK); + } + if(flag==2) + { + MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); + } + if(count>=225) + { + MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); + } +} + +void Regret()//悔棋函数 +{ + gotoxy(regrey,regrex); + BackGround(0,0); + printf(" "); + status[regrex][regrey]=0; + gotoxy(regrey1,regrex1); + BackGround(0,0); + printf(" "); + status[regrex1][regrey1]=0; + count-=2; +} + +void welcome()//游戏菜单 +{ + int k; + char choose; + system("cls"); + for(k=2;k<=16;k+=2)//游戏菜单 + { + gotoxy(5,k); + printf("|-----------------|"); + } + gotoxy(5, 3); + printf("| 五 子 棋 游 戏 |"); + + gotoxy(5, 5); + printf("| 菜 单 |"); + + gotoxy(5, 7); + printf("| 1.人 人 对 战 |"); + + gotoxy(5, 9); + printf("| 2.人 机 对 战 |"); + + gotoxy(5, 11); + printf("| 3.游 戏 帮 助 |"); + + gotoxy(5, 13); + printf("| 4.更 新 日 志 |"); + + gotoxy(5, 15); + printf("| 5.退 出 游 戏 |"); + + gotoxy(5, 18); + printf("温馨提示:输入菜单对应序号进行操作"); + + gotoxy(5, 20); + printf("祝您游戏愉快!"); + + gotoxy(20, 20); +} + +char Gametips()//游戏帮助 +{ + char choose; + int key; + + system("cls"); + + gotoxy(2, 3); + printf("游戏操作:"); + + gotoxy(4, 5); + printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); + + gotoxy(4, 7); + printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); + + gotoxy(2, 19); + printf("(按E键返回,按其它任意键退出)"); + + return _getch(); +} + + +int main() +{ + system("title 五子棋"); + system("mode con cols=92 lines=33"); + system("color F0"); + char choose,temp; + loop:welcome(); + choose=_getch(); + switch(choose) + { + case '1': + man_man(); + break; + case '2': + man_machine(); + break; + case '3': + temp=Gametips(); + if(temp=='E'||temp=='e') + goto loop; + break; + case '5': + { + int message = MessageBox(NULL, "是否退出?", "友情提示", MB_OKCANCEL); + if (IDCANCEL == message) + goto loop; + if (IDOK == message)break; + } + + } +} + +*/ diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" new file mode 100644 index 00000000..af213a3f --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" @@ -0,0 +1,286 @@ +#include "go.h" + +int board[17][17]; + +int AI_regrex, AI_regrey, man_regrex, man_regrey; + +int AI_x, AI_y; +int AI_x2, AI_y2; +int man_x, man_y;//man_y=i,man_x=j +int man_x2, man_y2; +int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//八向的常量数组 +//判断输赢,判断是否下过 +int flag = 0;//判断输赢 +int count = 0;//计算棋子数量 + +void chess_menu()//打印棋盘旁的菜单 +{ + int i,j; + for(i=1;i<=29;i++) + { + gotoxy(67,i); + printf("||"); + } + for(i=1;i<=29;i++) + { + gotoxy(89,i); + printf("||"); + } + gotoxy(69,1); + printf("--------------------"); + gotoxy(69,29); + printf("--------------------"); + gotoxy(75,3); + printf("模 式"); + gotoxy(75,20); + printf("提 示"); +} + +void board_array() +{ + for (int i = 0;i < L+2;i++) + for (int j = 0;j < L+2;j++)//解决边界问题,加一个边界,边界=3 + //1-15是棋盘 + { + if (i != 0 && i != L+1 && j != 0 && j != L+1) + board[i][j] = 0; + else + board[i][j] = 3; + } +} + +void man_move()//白棋移动光标 +{ + loop1:gotoxy(4*man_x,2*man_y+1); + char key='y'; + while(key!='0') + { + key=_getch(); + switch(key) + { + case 72: + man_y--; + if(man_y<=1) + man_y=1; + break; + case 80: + man_y++; + if(man_y>=15) + man_y=15; + break; + case 75: + man_x--; + if(man_x<=1) + man_x=1; + break; + case 77: + man_x++; + if(man_x>=15) + man_x=15; + break; + case 'B': + case 'b': + { + int message=MessageBox(NULL,TEXT("是否确定悔棋?"),TEXT("友情提示"),MB_OKCANCEL); + if(IDCANCEL==message) + break; + if(IDOK==message) + { + Regret(); + break; + } + } + } + gotoxy(4 * (man_x-1), 2 * (man_y-1) + 1); + } + if (board[man_y][man_x]) + { + gotoxy(70, 22); + BackGround(4, 0); + printf("这里已经被下过了"); + goto loop1; + } + else + { + board[man_y][man_x] = white; + BackGround(7, 0); + man_regrex = man_x; + man_regrey = man_y; + printf("●"); + } +} + +void test_board()//调试输出代码 +{ + gotoxy(1, 1); + for (int i = 1;i < L + 1;i++) + { + for (int j = 1;j < L + 1;j++) + printf("%d\t", board[i][j]); + printf("\n"); + } +} + +void machine_move()//打印AI的棋子的函数,机器用红子,玩家用白子 +{ + generator(); + board[AI_y][AI_x] = red; + gotoxy(4*(AI_x-1), 2*(AI_y-1)+1);//坐标和数组的顺序是反的 + BackGround(4, 0); + AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 + AI_regrey = AI_y; + printf("●"); +} + +int judge_winner(int x, int y, int me)//判断输赢,要向两个方向搜索 +{ + int n1 = 0, n2 = 0; + int flag = 0; + for (int i = 0;i < 4;i++)//i表示八个方向 + { + for (int j = 0;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j * dir[i][0]; + int dy = y + j * dir[i][1]; + if (board[dy][dx] == me)//AI_x,AI_y都是坐标上的x,y,表示数组要反过来 + n1++; + else + break; + } + for (int j = 0;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j * dir[7 - i][0]; + int dy = y + j * dir[7 - i][1]; + if (board[dy][dx] == me) + n2++; + else + break; + } + if (n1 + n2 >= 6) + { + flag = me; + return flag; + } + n1 = 0; + n2 = 0; + } + return flag; +} + +void man_machine()//人机对战模式 +{ + loop6:system("cls"); + char key; + int control; + gotoxy(2, 3); + printf("1.玩 家 先 手"); + + gotoxy(2, 5); + printf("2.电 脑 先 手"); + + gotoxy(2, 7); + printf("玩家为白子,电脑为红子(输入相应序号选择)"); + key=_getch(); + system("cls"); + control = 1; + if(key!='1'&& key!='2') + { + printf("请重新输入"); + goto loop6; + } + gotoxy(70,5); + printf(" 人 机 对 战 "); + man_y=7; + man_x=8; + chess_board(); + board_array(); + chess_menu(); + if (key == '2') + { + AI_x = 7; + AI_y = 8; + gotoxy(4 * (AI_x - 1), 2 * (AI_y - 1) + 1);//机器第一次下在中间位置 + BackGround(4, 0); + AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 + AI_regrey = AI_y; + board[AI_y][AI_x] = 1; + printf("●"); + } + while(flag==0) + { + if(control==1) + { + gotoxy(70,22); + BackGround(6,0); + printf(" 玩 家 执 手 "); + man_move(); + flag=judge_winner(man_x,man_y,white); + } + else + { + gotoxy(70,22); + BackGround(6,0); + printf(" 电 脑 执 手 "); + machine_move(); + flag=judge_winner(AI_x,AI_y,red); + } + control=-control; + } + gotoxy(8,18); + if(flag==white) + { + BackGround(7,0); + MessageBox(NULL,TEXT("太厉害了,您战胜了电脑!"),TEXT("五子棋游戏"),MB_OK); + } + if(flag==red) + { + MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); + } + if(count>=225) + { + MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); + } +} + +void Regret()//悔棋函数 +{ + gotoxy(man_x2,man_y2); + BackGround(0,0); + printf(" "); + board[man_y][man_x]=0; + gotoxy(AI_y2,AI_x2); + BackGround(0,0); + printf(" "); + board[AI_y][AI_x]=0; +} + + +int main() +{ + system("title 五子棋"); + system("mode con cols=92 lines=33"); + char choose, temp; +loop:welcome(); + choose = _getch(); + switch (choose) + { + case '1': + man_machine(); + break; + case '2': + temp = Gametips(); + if (temp == 'E' || temp == 'e') + goto loop; + break; + case '3': + { + int message = MessageBox(NULL, TEXT("是否退出?"),TEXT( "友情提示"), MB_OKCANCEL); + if (IDCANCEL == message) + goto loop; + if (IDOK == message) + { + break; + } + } + } +} diff --git "a/\345\256\236\351\252\214/README.md" "b/\345\256\236\351\252\214/README.md" deleted file mode 100644 index 92a492e8..00000000 --- "a/\345\256\236\351\252\214/README.md" +++ /dev/null @@ -1,17 +0,0 @@ -## 瀹為獙棰樼洰锛堜换閫変竴椤癸級锛 - -1. 鎵撻鏈烘父鎴忥細 - -2. 浜斿瓙妫婣I锛 - - 娉細浜斿瓙妫婣I鏄惁浣跨敤鍥惧舰鐣岄潰锛岃闅忔剰锛 - -## GUI -- [EasyX](https://easyx.cn/) -- [SFML](https://www.sfml-dev.org/) -- [raylib](https://github.com/raysan5/raylib) - -## 鍙傝 - -- [浜斿瓙妫婣I绠楁硶](https://blog.csdn.net/lihongxun945/category_6089493.html) -- [鏂版父鎴忚璁℃ā寮廍CS](https://zhuanlan.zhihu.com/p/30538626) \ No newline at end of file diff --git "a/\345\256\236\351\252\214/draft.c" "b/\345\256\236\351\252\214/draft.c" deleted file mode 100644 index 74815ac5..00000000 --- "a/\345\256\236\351\252\214/draft.c" +++ /dev/null @@ -1,62 +0,0 @@ -/* -int PD[21][15] = { {0},{0} };//principle diagonal -int BD[21][15] = { {0},{0} };//back diagonal -void flat() -{ - for (int i = 0;i < 11;i++) - for (int j = 0;j < L-i;j++) - { - PD[i][j] = board[i + j][j]; - PD[10 + i][j] = board[j][i + j]; - } - for (int i = 0;i < 11;i++) - for (int j = 0;j < L - i;j++) - { - BD[i][j] = board[i + j][L - j]; - BD[10 + i][j] = board[j][L - i - j]; - } -} - -void testflat() -{ - for(int i=0;i<21;i++) - for(int j=0;j<21;j++) - printf("%d\t", PD[i][j]); - for (int i = 0;i < 21;i++) - for (int j = 0;j < 21;j++) - printf("%d\t", BD[i][j]); -} -*/ //c语言平面化可能并不方便 -/* - for(int j=0;j<15;j++) - for (int i = 0;i < 21;i++) - { - if (PD[i][j] == 1) - { - k = 0; - int t = i; - while (PD[t][j] == 1) - t++;k++; - if (PD[i-1][j] == 2 || PD[t+1][j] == 2)//判断不是边界 - k--; - if (PD[i-1][j] == 2 && PD[t+1][j] == 2) - k = -1;//区分死棋和死一 - if (k >= 0) - human_score = human_score + pow(10, k); - - } - - } -#define ONE 10//live one -#define TWO 100 -#define THREE 1000 -#define FOUR 100000 -#define FIVE 10000000 -#define BLOCKED_ONE 1 -#define BLOCKED_TWO 10 -#define BLOCKED_THREE 100 -#define BLOCKED_FOUR 10000 -#define TWO_THREE -#define BLOCK_FOUR -#define FOUR_THREE - */ diff --git "a/\345\256\236\351\252\214/main.c" "b/\345\256\236\351\252\214/main.c" deleted file mode 100644 index e69de29b..00000000 diff --git "a/\345\256\236\351\252\214/max-min.c" "b/\345\256\236\351\252\214/max-min.c" deleted file mode 100644 index 2aaf1bb0..00000000 --- "a/\345\256\236\351\252\214/max-min.c" +++ /dev/null @@ -1,158 +0,0 @@ -#include "go.h" -int evaluate(int me, int others); -void generator(int me, int others); - -//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 - - -int evaluate(int me,int others) -{ - int k=0, score=0; - int T = me, F = others; - - for (int i = 1;i < L + 1;i++)//检查横向 - for (int j = 1;j < L + 1;j++) - { - if (board[i][j] == T) - { - - k = 1; - int t = j;//用t暂时存储j,方便之后检查前面的情况,然后j++,避免重复检查 - j++; - while (board[i][j] == T) - { - j++; - k++; - } - if (board[i][j] == F || board[i][t - 1] == F || board[i][j] == wall || board[i][t - 1] == wall) - k--; - if ((board[i][j] == F && board[i][t - 1] == F) || (board[i][j] == wall && board[i][t - 1] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - j = t; - } - } - - for (int i = 1;i < L + 1;i++)//竖向检查 - for (int j = 1;j < L + 1;j++) - { - if (board[i][j] == T) - { - k = 1; - int t = i; - i++; - while (board[i][j] == T)//i=16,这里经过一次i++后,i已经在连棋的后面一格了 - { - i++; - k++; - } - if (board[t - 1][j] == F || board[i][j] == F || board[t - 1][j] == wall || board[i][j] == wall) - k--; - if ((board[t - 1][j] == F && board[i][j] == F )|| (board[t - 1][j] == wall && board[i + 1][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t; - } - } - - for (int i = 1;i < L + 1;i += 1)//检查主对角线 - for (int j = 1;j < L + 1;j += 1) - { - if (board[i][j] == T) - { - k = 1; - int t1 = i, t2 = j; - i++; - j++; - while (board[i][j] == T) - { - i++; - j++; - k++; - } - if (board[t1 - 1][t2 - 1] == F || board[i][j] == F || board[t1 - 1][t2 - 1] == wall || board[i][j] == wall) - //判断不是边界 - k--; - if ((board[t1 - 1][t2 - 1] == F && board[i][j] == F )|| (board[t1 - 1][t2 - 1] == wall && board[i][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t1; - j = t2; - } - } - - for (int i = 1;i < L + 1;i += 1)//检查反对角线 - for (int j = 1;j < L + 1;j += 1) - { - if (board[i][j] == T) - { - k = 1; - int t1 = i, t2 = j; - i += 1; - j -= 1; - while (board[i][j] == T) - { - i += 1; - j -= 1; - k++; - } - if (board[t1 - 1][t2 + 1] == F || board[i][j] == F || board[i][j] == wall || board[i][j] == wall) - k--;//遇到边界也相当于是死棋 - if ((board[t1 - 1][t2 + 1] == F && board[i][j] == F )|| (board[i][j] == wall && board[i][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t1; - j = t2; - } - } - return score; -} - -void generator(int me,int others)//先不管邻居,直接遍历 -{ - int my_score = 0; - int t = 0; - int m, n; - for (int i = 1;i < L + 1;i += 1) - for (int j = 1;j < L + 1;j += 1) - { - if (!board[i][j])//决策树,评估这个点下了棋之后的得分 - { - board[i][j] = me; - t=evaluate(me, others)- evaluate(others, me); - n = evaluate(me, others); - m = evaluate(others, me); - board[i][j] = 0; - } - if (t > my_score) - { - board[i][j] = me; - my_score = t; - AI_x = j;//坐标表示和数组索引表示是反的 - AI_y = i; - } - } -} - -//用什么数据结构储存有邻居的位置 -/* -void neighbor() -{ - for (int i = 0;i < 15;i++) - for (int j = 0;j < 15;j++) - { - if (!board[i][j]) - { - - } - - } - - -} -*/ - diff --git "a/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" deleted file mode 100644 index a1c77d92..00000000 --- "a/\345\256\236\351\252\214/\344\272\224\345\255\220\346\243\2131.0.c" +++ /dev/null @@ -1,415 +0,0 @@ -#include "go.h" -//判断输赢,判断是否下过 -int flag = 0;//判断输赢 -int count = 0;//计算棋子数量 - -void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 -{ - HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 - SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 -} - -void gotoxy(int x, int y) //光标函数 -{ - HANDLE handle; - COORD coord; //获取坐标轴结构体 - coord.X = x; - coord.Y = y; - handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11 - SetConsoleCursorPosition(handle, coord); //移动光标到x,y处 -} - -void chess_board()//打印棋盘 -{ - int i,j; - for(i=1;i<=30;i++) - for(j=0;j<=60;j+=4) - { - gotoxy(j, i); - printf("|"); - } - for(i=1;i<=31;i+=2) - for(j=1;j<=57;j+=4) - { - gotoxy(j,i); - printf("---"); - } -} - -void chess_menu()//打印棋盘旁的菜单 -{ - int i,j; - for(i=1;i<=29;i++) - { - gotoxy(67,i); - printf("||"); - } - for(i=1;i<=29;i++) - { - gotoxy(89,i); - printf("||"); - } - gotoxy(69,1); - printf("--------------------"); - gotoxy(69,29); - printf("--------------------"); - gotoxy(75,3); - printf("模 式"); - gotoxy(75,20); - printf("提 示"); -} - -void board_array() -{ - board = (int**)malloc(L * sizeof(int*)); - for (int i = 0;i < L+2;i++) - board[i] = (int*)calloc(L, sizeof(int)); - for (int i = 0;i < L+2;i++) - for (int j = 0;j < L+2;j++)//解决边界问题,加一个边界,边界=3 - //1-15是棋盘 - { - if (i != 0 && i != L+1 && j != 0 && j != L+1) - board[i][j] = 0; - else - board[i][j] = 3; - } -} - -void man_move()//白棋移动光标 -{ - loop1:gotoxy(4*man_x,2*man_y+1); - char key='y'; - while(key!='0') - { - key=_getch(); - switch(key) - { - case 72: - man_y--; - if(man_y<=1) - man_y=1; - break; - case 80: - man_y++; - if(man_y>=15) - man_y=15; - break; - case 75: - man_x--; - if(man_x<=1) - man_x=1; - break; - case 77: - man_x++; - if(man_x>=15) - man_x=15; - break; - case 'B': - case 'b': - { - int message=MessageBox(NULL,TEXT("是否确定悔棋?"),TEXT("友情提示"),MB_OKCANCEL); - if(IDCANCEL==message) - break; - if(IDOK==message) - { - Regret(); - break; - } - } - } - //convert(man_x, man_y, man_x2, man_y2); - gotoxy(4 * man_x, 2 * man_y + 1); - } - if (board[man_y][man_x]) - { - gotoxy(70, 22); - BackGround(4, 0); - printf("这里已经被人下过了"); - goto loop1; - } - else - { - board[man_y][man_x] = white; - BackGround(7, 0); - man_regrex = man_x; - man_regrey = man_y; - printf("●"); - } -} - -void machine_move()//机器用红子,玩家用白子 -{ - generator(red, white); - //convert(AI_x, AI_y, AI_x2, AI_y2); - gotoxy(4*AI_x, 2*AI_y+1);//坐标和数组的顺序是反的 - BackGround(4, 0); - AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 - AI_regrey = AI_y; - printf("●"); -} -/* -void convert(int* px,int* py,int* qx,int* qy) -{ - *qx = 4 * (*px); - *qy = 2 * (*qy) + 1; -}//打印出的棋盘和数组模拟棋盘之间索引需要转换 -*/ - -int judge_chess(int x,int y)//判断这个地方是否有棋子 -{ - if(board[x][y]==0) - return 0; - else - return 1; -} -/* -int judge_winner(int x,int y,int temp)//判断输赢 -{ - int i,j,n1,n2; - n1=n2=0; - for(i=x,j=y+4;j<=58;j+=4)//右 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x,j=y;j>=2;j-=4)//左 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x,j=y;i>=1;i-=2)//上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x+2,j=y;i<=30;i+=2)//下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x-2,j=y+4;i>=1&&j<=58;i-=2,j+=4)//右上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x,j=y;i<=30&&j>=2;i+=2,j-=4)//左下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x,j=y;i>=0&&j>=0;i-=2,j-=4)//左上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x+2,j=y+4;i<=30&&j<=58;i+=2,j+=4)//右下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - return 0; -} - -*/ - -void man_machine()//人机对战模式 -{ - loop6:system("cls"); - char key; - int control; - gotoxy(2, 3); - printf("1.玩 家 先 手"); - - gotoxy(2, 5); - printf("2.电 脑 先 手"); - - gotoxy(2, 7); - printf("玩家为白子,电脑为红子(输入相应序号选择)"); - key=_getch(); - system("cls"); - if(key=='1') - control=1; - else if(key=='2') - { - control=-1; - } - else - goto loop6; - gotoxy(70,5); - printf(" 人 机 对 战 "); - man_y=7; - man_x=8; - chess_board(); - board_array(); - chess_menu(); - while(flag==0) - { - if(control==1) - { - gotoxy(70,22); - BackGround(6,0); - printf(" 玩 家 执 手 "); - man_move(); - //flag=judge_winner(direct[1],direct[0],1); - } - else - { - gotoxy(70,22); - BackGround(6,0); - printf(" 电 脑 执 手 "); - machine_move(); - //flag=judge_winner(direct[1],direct[0],2); - } - control=-control; - } - gotoxy(8,18); - if(flag==1) - { - BackGround(7,0); - MessageBox(NULL,TEXT("太厉害了,您竟然战胜了电脑!"),TEXT("五子棋游戏"),MB_OK); - } - if(flag==2) - { - MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); - } - if(count>=225) - { - MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); - } -} - -void Regret()//悔棋函数 -{ - gotoxy(man_x2,man_y2); - BackGround(0,0); - printf(" "); - board[man_y][man_x]=0; - gotoxy(AI_y2,AI_x2); - BackGround(0,0); - printf(" "); - board[AI_y][AI_x]=0; -} - -void welcome()//游戏菜单 -{ - int k; - char choose; - system("cls"); - for(k=2;k<=16;k+=2)//游戏菜单 - { - gotoxy(5,k); - printf("|-----------------|"); - } - gotoxy(5, 3); - printf("| 五 子 棋 游 戏 |"); - - gotoxy(5, 5); - printf("| 菜 单 |"); - - gotoxy(5, 7); - printf("| 1.人 人 对 战 |"); - - gotoxy(5, 9); - printf("| 2.人 机 对 战 |"); - - gotoxy(5, 11); - printf("| 3.游 戏 帮 助 |"); - - gotoxy(5, 13); - printf("| 4.更 新 日 志 |"); - - gotoxy(5, 15); - printf("| 5.退 出 游 戏 |"); - - gotoxy(5, 18); - printf("温馨提示:输入菜单对应序号进行操作"); - - gotoxy(5, 20); - printf("祝您游戏愉快!"); - - gotoxy(13, 20); -} - -char Gametips()//游戏帮助 -{ - char choose; - int key; - - system("cls"); - - gotoxy(2, 3); - printf("游戏操作:"); - - gotoxy(4, 5); - printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); - - gotoxy(4, 7); - printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); - - gotoxy(2, 19); - printf("(按E键返回,按其它任意键退出)"); - - return _getch(); -} - - -int main() -{ - system("title 五子棋"); - system("mode con cols=92 lines=33"); - char choose, temp; -loop:welcome(); - choose = _getch(); - switch (choose) - { - case '1': - - break; - case '2': - man_machine(); - break; - case '3': - temp = Gametips(); - if (temp == 'E' || temp == 'e') - goto loop; - break; - case '4': - case '5': - { - int message = MessageBox(NULL, TEXT("是否退出?"),TEXT( "友情提示"), MB_OKCANCEL); - if (IDCANCEL == message) - goto loop; - if (IDOK == message) - { - break; - } - } - } -} From 90b9af93e61f4a193b786fc5518a04c81fd32ee4 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Sat, 22 May 2021 14:47:15 +0800 Subject: [PATCH 15/19] =?UTF-8?q?[=E4=BA=94=E5=AD=90=E6=A3=8B2.0=E5=9B=9B?= =?UTF-8?q?=E5=B1=82min-max+Alpha-Beta=E5=89=AA=E6=9E=9D]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BetaGo/BetaGo.vcxproj" | 3 +- .../BetaGo/BetaGo.vcxproj.filters" | 3 + "\345\256\236\351\252\214/BetaGo/draft.c" | 44 ++++- "\345\256\236\351\252\214/BetaGo/go.h" | 11 +- "\345\256\236\351\252\214/BetaGo/max-min.c" | 146 +++++++++++---- "\345\256\236\351\252\214/BetaGo/minmaxAB.c" | 173 ++++++++++++++++++ ...\344\272\224\345\255\220\346\243\2131.0.c" | 28 +-- 7 files changed, 349 insertions(+), 59 deletions(-) create mode 100644 "\345\256\236\351\252\214/BetaGo/minmaxAB.c" diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" index 46e201b9..d3c0f9fa 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" @@ -85,7 +85,7 @@ Level3 - true + false WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true D:\Documents\c璇█\C璇█璇剧▼\BetaGo;%(AdditionalIncludeDirectories) @@ -143,6 +143,7 @@ + diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" index 8829cfd1..d45942d9 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" @@ -27,6 +27,9 @@ 婧愭枃浠 + + 婧愭枃浠 + diff --git "a/\345\256\236\351\252\214/BetaGo/draft.c" "b/\345\256\236\351\252\214/BetaGo/draft.c" index a1681c0e..70ae65b6 100644 --- "a/\345\256\236\351\252\214/BetaGo/draft.c" +++ "b/\345\256\236\351\252\214/BetaGo/draft.c" @@ -155,4 +155,46 @@ void testflat() j = t2; } } - */ + + int DFS(int me, int others, int depth)//dfs遍历四层决策树 +{ + int my_score = -100; + int t = -1000; + int temp; + int cnt; + int empty_p[100][2] = { {0},{0} }; + int a[4] = { 0 }; + int i = 0; + int best_position = 0; + if (depth==0)//超过预定层数,结束递归,返回分数 + { + t = evaluate(red, white) - evaluate(white, red); + if (t > my_score) + { + my_score = t; + best_position = a[0]; + } + return best_position; + } + else + { + cnt = generator(empty_p); + for (int k = 0;k < cnt;k++) + { + int tree_x = empty_p[k][0]; + int tree_y = empty_p[k][1]; + board[tree_x][tree_y] = me; + a[i] = k; + i++; + temp = me;//交换敌方和己方 + me = others; + others = temp; + DFS(me, others, depth--); + board[tree_x][tree_y] = me;//(回到上一步)清除标记 + + } + + } +} + + */ diff --git "a/\345\256\236\351\252\214/BetaGo/go.h" "b/\345\256\236\351\252\214/BetaGo/go.h" index da26ec6f..f7f0698d 100644 --- "a/\345\256\236\351\252\214/BetaGo/go.h" +++ "b/\345\256\236\351\252\214/BetaGo/go.h" @@ -13,13 +13,11 @@ #define col 4 #define row 2 -extern int board[17][17]; +extern int board[L+2][L+2]; extern int AI_regrex, AI_regrey, man_regrex, man_regrey; extern int AI_x, AI_y; -extern int AI_x2, AI_y2; extern int man_x, man_y; -extern int man_x2, man_y2; extern int dir[][2]; void BackGround(unsigned int ForeColor, unsigned int BackGroundColor); @@ -29,9 +27,12 @@ void chess_menu(); void board_array(); void man_move();//红子棋移动光标 void machine_move(); -void convert(int x, int y, int x2, int y2); + void man_machine();//人机对战 int judge_winner(int x, int y, int temp);//判断输赢 void Regret();//悔棋函数 void welcome(); -char Gametips(); \ No newline at end of file +char Gametips(); +int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2]); +int minMax_AB(int deep, int me, int Alpha, int Beta, int tmp_board[][L + 2]); +int evaluate(int me, int copy[][L + 2]); \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214/BetaGo/max-min.c" index 6e969ae6..5e64335a 100644 --- "a/\345\256\236\351\252\214/BetaGo/max-min.c" +++ "b/\345\256\236\351\252\214/BetaGo/max-min.c" @@ -1,23 +1,37 @@ + #include "go.h" -int evaluate(int me, int others); -void generator(int me, int others); - -//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 -typedef struct node +typedef struct { - int x, y; -}Node; + int Alpha; + int Beta; + int X; + int Y; +}Tree; +//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 -int dfs(int x, int y,int T,int F,int vis[][17]) +int search(int x, int y,int me,int vis[][L+2],int copy[][L+2])//搜索有多少颗连子 { int value = 0; int maxdir = 0; + int T, F; + + if (me == 1) + { + T = red; + F = white; + } + else + { + F = red; + T = white; + } + for (int i = 0;i < 8;i++)//i表示八个方向 for (int j = 1;j <= 5;j++)//j表示沿这个方向走了几步 { int dx = x + j*dir[i][0]; int dy = y + j*dir[i][1]; - if (board[dx][dy] != T) + if (copy[dx][dy] != T) { if (j > value) { @@ -46,59 +60,123 @@ int dfs(int x, int y,int T,int F,int vis[][17]) if(dx1<0||dy1<0) value--; else - if (board[dx1][dy1] == F || board[dx1][dy1] == wall) + if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) value--; - if (board[dx2][dy2] == F || board[dx2][dy2] == wall) + if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) value--; return value; } -int evaluate(int me,int others)//全局评估某一方的分数 +int evaluate(int me,int copy[][L+2])//全局评估某一方的分数,turn=1评估red,a=2评估white { int k=0, score=0; - int T = me, F = others; int value = 0; int vis[17][17] = { {0},{0} }; - - //遍历找到我方棋子开始dfs + + //遍历找到我方棋子开始search 连子 for (int i = 1;i < L + 1;i++) for (int j = 1;j < L + 1;j++) { - if (board[i][j] == T && (!vis[i][j]))//是我方且没有被搜索过 + if (copy[i][j] == me && (!vis[i][j]))//是我方且没有被搜索过 { - value = dfs(i, j, T, F, vis); + value = search(i, j, me, vis, copy); + //计分方式:n连子,10^n,有一边死了n-1 score = score + pow(10, value); } } return score; } -void generator()//生成AI的棋子的函数 + +int generator(int *empty[][2])//产生空子序列 { - int my_score = -100; - int t = -1000; - int m, n; + + int empty_cnt = 0; for (int i = 1;i < L + 1;i += 1) for (int j = 1;j < L + 1;j += 1) - { - int is_nei = neighbor(i, j);//棋子附近两步之内有棋子 - if (board[i][j]==0 && is_nei)//决策树,评估这个点下了棋之后的得分 - { - board[i][j] = red; - t=evaluate(red, white)- evaluate(white, red); - board[i][j] = 0; - } - if (t > my_score) + { + if (neighbor(i, j)) { - my_score = t; - AI_x = j;//坐标表示和数组索引表示是反的 - AI_y = i; + empty[empty_cnt][0] = i; + empty[empty_cnt][1] = j; + empty_cnt++; } } + return empty_cnt; } +int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) +//分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF +{ + int i, j; + int c[L+2][L+2]; + int minmax; + int rival; + Tree tree; + tree.Alpha = Alpha; + tree.Beta = Beta; + tree.X = 0; + tree.Y = 0; + if (me == 1) + rival = 2; + else + rival = 1; + if (depth == 0||judge_winner(tree.X,tree.Y,me)==me) + return evaluate(me, tmp_board)-evaluate(rival,tmp_board); + if (depth % 2)//判断是min层还是max层,奇数是min层 + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!tmp_board[i][j]&& neighbor(i, j) && tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + c[i][j] = 0; + if (minmax < tree.Beta) + { + tree.Beta = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Alpha;//α剪枝,抛弃后续节点 + } + } + } + return tree.Beta; + } + else + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L); + //用一个新的数组表示棋盘,以免破坏原棋盘 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); + c[i][j] = 0; + if (minmax > tree.Alpha) + { + tree.Alpha = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Beta;//α剪枝,抛弃后续节点 + } + } + } + AI_x = tree.X; + AI_y = tree.Y; + return tree.Alpha; + } + +} -int neighbor(int x,int y) + +int neighbor(int x,int y)//判断空位置两步之内是否有邻居 { for (int di = 0;di < 8;di++)//i表示八个方向 for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 diff --git "a/\345\256\236\351\252\214/BetaGo/minmaxAB.c" "b/\345\256\236\351\252\214/BetaGo/minmaxAB.c" new file mode 100644 index 00000000..c0c7f312 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/minmaxAB.c" @@ -0,0 +1,173 @@ +/* +#include "go.h" +typedef struct +{ + int Alpha; + int Beta; + int X; + int Y; +}Tree; +//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 + +int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2])//搜索有多少颗连子 +{ + int value = 0; + int maxdir = 0; + int T, F; + + if (me == 1) + { + T = red; + F = white; + } + else + { + F = red; + T = white; + } + + for (int i = 0;i < 8;i++)//i表示八个方向 + for (int j = 1;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j * dir[i][0]; + int dy = y + j * dir[i][1]; + if (copy[dx][dy] != T) + { + if (j > value) + { + value = j;//记录最大连子数和最大的方向 + maxdir = i; + } + break; + } + } + + //特殊情况优先 + + //标记已经搜索且在最大路径上的节点,避免重复搜索 + for (int j = 0;j <= value;j++) + { + int dx = x + j * dir[maxdir][0]; + int dy = y + j * dir[maxdir][1]; + vis[dx][dy] = 1; + } + + //判断连子的死活 + int dx1 = x + value * dir[maxdir][0]; + int dy1 = y + value * dir[maxdir][1]; + int dx2 = x - dir[maxdir][0]; + int dy2 = y - dir[maxdir][1]; + if (dx1 < 0 || dy1 < 0) + value--; + else + if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) + value--; + if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) + value--; + return value; +} + +int evaluate(int me, int copy[][L + 2])//全局评估某一方的分数,turn=1评估red,a=2评估white +{ + int k = 0, score = 0; + int value = 0; + int vis[17][17] = { {0},{0} }; + + //遍历找到我方棋子开始search 连子 + for (int i = 1;i < L + 1;i++) + for (int j = 1;j < L + 1;j++) + { + if (copy[i][j] == me && (!vis[i][j]))//是我方且没有被搜索过 + { + value = search(i, j, me, vis, copy); + //计分方式:n连子,10^n,有一边死了n-1 + score = score + pow(10, value); + } + } + return score; +} + +int minMax_AB(int depth, int me, int Alpha, int Beta) +//分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF +{ + int i, j; + int c[L + 2][L + 2]; + int minmax; + int rival; + Tree tree; + tree.Alpha = Alpha; + tree.Beta = Beta; + tree.X = 0; + tree.Y = 0; + if (me == 1) + rival = 2; + else + rival = 1; + if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) + return evaluate(me); + if (depth % 2 == 0)//判断是min层还是max层,偶数是min层 + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + { + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta); + c[i][j] = 0; + if (minmax < tree.Beta) + { + tree.Beta = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Alpha;//α剪枝,抛弃后续节点 + } + } + } + return tree.Beta; + } + else + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + { + //用一个新的数组表示棋盘,以免破坏原棋盘 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta); + c[i][j] = 0; + if (minmax > tree.Alpha) + { + tree.Alpha = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Beta;//α剪枝,抛弃后续节点 + } + } + } + AI_x = tree.X; + AI_y = tree.Y; + return tree.Alpha; + } + +} + + +int neighbor(int x, int y)//判断空位置两步之内是否有邻居 +{ + for (int di = 0;di < 8;di++)//i表示八个方向 + for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 + { + int dx = x + dj * dir[di][0]; + int dy = y + dj * dir[di][1]; + if (dx > 0 && dx < L + 1 && dy>0 && dy < L + 1) + if (board[dx][dy] == red || board[dx][dy] == white) + return 1; + } + return 0; +} + +*/ diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" index af213a3f..623759ea 100644 --- "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" +++ "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" @@ -1,15 +1,16 @@ #include "go.h" +#define PTIF 2147483647//正无穷,Beta +#define NGIF -2147483648//负无穷,Alpha -int board[17][17]; +int board[L+2][L+2]; int AI_regrex, AI_regrey, man_regrex, man_regrey; int AI_x, AI_y; -int AI_x2, AI_y2; int man_x, man_y;//man_y=i,man_x=j -int man_x2, man_y2; +//board[i][j]与position之间的关系gotoxy(4 * (man_x-1), 2 * (man_y-1) + 1) int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//八向的常量数组 -//判断输赢,判断是否下过 + int flag = 0;//判断输赢 int count = 0;//计算棋子数量 @@ -51,7 +52,7 @@ void board_array() void man_move()//白棋移动光标 { - loop1:gotoxy(4*man_x,2*man_y+1); + loop1:gotoxy(4 * (man_x - 1), 2 * (man_y - 1) + 1); char key='y'; while(key!='0') { @@ -110,20 +111,11 @@ void board_array() } } -void test_board()//调试输出代码 -{ - gotoxy(1, 1); - for (int i = 1;i < L + 1;i++) - { - for (int j = 1;j < L + 1;j++) - printf("%d\t", board[i][j]); - printf("\n"); - } -} + void machine_move()//打印AI的棋子的函数,机器用红子,玩家用白子 { - generator(); + minMax_AB(4, red, NGIF, PTIF,board); board[AI_y][AI_x] = red; gotoxy(4*(AI_x-1), 2*(AI_y-1)+1);//坐标和数组的顺序是反的 BackGround(4, 0); @@ -244,11 +236,11 @@ void board_array() void Regret()//悔棋函数 { - gotoxy(man_x2,man_y2); + gotoxy(4 * (man_x - 1), 2 * (man_y - 1) + 1); BackGround(0,0); printf(" "); board[man_y][man_x]=0; - gotoxy(AI_y2,AI_x2); + gotoxy(4 * (AI_x - 1), 2 * (AI_y - 1) + 1); BackGround(0,0); printf(" "); board[AI_y][AI_x]=0; From e93a869f432d4440427ca6bcd3bf2dce0c3f077e Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Sun, 6 Jun 2021 20:29:46 +0800 Subject: [PATCH 16/19] =?UTF-8?q?[=E4=BF=AE=E6=94=B9GUI=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=BE=B9=E7=95=8Cbug]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BetaGo/BetaGo.vcxproj" | 1 + .../BetaGo/BetaGo.vcxproj.filters" | 3 + "\345\256\236\351\252\214/BetaGo/GUI.c" | 91 ++++++++++-- "\345\256\236\351\252\214/BetaGo/draft.c" | 29 ++++ "\345\256\236\351\252\214/BetaGo/go.h" | 10 +- "\345\256\236\351\252\214/BetaGo/max-min.c" | 57 +++++--- "\345\256\236\351\252\214/BetaGo/minmaxAB.c" | 136 ++++-------------- "\345\256\236\351\252\214/BetaGo/priority.c" | 0 ...\344\272\224\345\255\220\346\243\2131.0.c" | 89 +++++------- 9 files changed, 218 insertions(+), 198 deletions(-) create mode 100644 "\345\256\236\351\252\214/BetaGo/priority.c" diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" index d3c0f9fa..223f6971 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" @@ -144,6 +144,7 @@ + diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" index d45942d9..9805b9e1 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" @@ -30,6 +30,9 @@ 婧愭枃浠 + + 婧愭枃浠 + diff --git "a/\345\256\236\351\252\214/BetaGo/GUI.c" "b/\345\256\236\351\252\214/BetaGo/GUI.c" index 6e4361ef..9e5adcba 100644 --- "a/\345\256\236\351\252\214/BetaGo/GUI.c" +++ "b/\345\256\236\351\252\214/BetaGo/GUI.c" @@ -20,7 +20,7 @@ printf("| 1.人 机 对 战 |"); gotoxy(5, 9); - printf("| 2.游 戏 帮 助 |"); + printf("| 2.游 戏 规 则 |"); gotoxy(5, 11); printf("| 3.退 出 游 戏 |"); @@ -45,13 +45,13 @@ printf("游戏操作:"); gotoxy(4, 5); - printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); + printf("电脑执红子,玩家执白子"); gotoxy(4, 7); - printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); + printf("玩家按↑↓←→移动光标选择下棋位置,按空格确认,按B悔棋"); gotoxy(2, 19); - printf("(按E键返回,按其它任意键退出)"); + printf("(按E键返回,按其它任意键退出,祝您游戏愉快)"); return _getch(); } @@ -59,18 +59,93 @@ void chess_board()//打印棋盘 { int i, j; - for (i = 1;i <= 30;i++) - for (j = 0;j <= 60;j += 4) + for (i = 1;i <= 29;i++) + for (j = 4;j <= 60;j += 4) { gotoxy(j, i); printf("|"); } - for (i = 1;i <= 31;i += 2) - for (j = 1;j <= 57;j += 4) + for (i = 1;i <= 29;i += 2) + for (j = 5;j <= 57;j += 4) { gotoxy(j, i); printf("---"); } + for (j = 5;j <= 57;j += 4) + { + gotoxy(j, 0); + printf("——"); + gotoxy(j, 30); + printf("——"); + } +} + +void chess_menu()//打印棋盘旁的菜单 +{ + int i, j; + for (i = 1;i <= 29;i++) + { + gotoxy(67, i); + printf("||"); + } + for (i = 1;i <= 29;i++) + { + gotoxy(89, i); + printf("||"); + } + gotoxy(69, 1); + printf("--------------------"); + gotoxy(69, 29); + printf("--------------------"); + gotoxy(75, 3); + printf("模 式"); + gotoxy(75, 20); + printf("提 示"); +} + +void location(int x, int y,int color) // 定位 +{ + if (color == red) + BackGround(4, 0); + else + BackGround(7, 0); + //如果传给光标移动函数的是负数,光标就不移动,范围判断,边界不输出定位框,且不能是负数 + if (x > 1 && y > 1) + { + gotoxy(x * 4 - 2, y * 2 - 2);puts("┛"); + } + if (x < 15 && y > 1) + { + gotoxy(x * 4 + 2, y * 2 - 2);puts("┗"); + } + if (x > 1 && y < 15) + { + gotoxy(x * 4 - 2, y * 2);puts("┓"); + } + if (x < 15 && y < 15) + { + gotoxy(x * 4 + 2, y * 2);puts("┏"); + } +} + +void clearlocation(int x, int y) //清除定位 +{ + if (x > 1 && y > 1) + { + gotoxy(x * 4 - 2, y * 2 - 2);puts(" "); + } + if (x < 15 && y > 1) + { + gotoxy(x * 4 + 2, y * 2 - 2);puts(" "); + } + if (x > 1 && y < 15) + { + gotoxy(x * 4 - 2, y * 2);puts(" "); + } + if (x < 15 && y < 15) + { + gotoxy(x * 4 + 2, y * 2);puts(" "); + } } void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 diff --git "a/\345\256\236\351\252\214/BetaGo/draft.c" "b/\345\256\236\351\252\214/BetaGo/draft.c" index 70ae65b6..552f30dc 100644 --- "a/\345\256\236\351\252\214/BetaGo/draft.c" +++ "b/\345\256\236\351\252\214/BetaGo/draft.c" @@ -197,4 +197,33 @@ void testflat() } } +#include "go.h" +int priority() +{ + int i, j, k, p; + int c[L + 2][L + 2]; + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!board[i][j] && neighbor(i, j)) + { + memcpy(c, board, sizeof(int) * L * L);//更新棋盘 + c[i][j] = red; + for (k = 0;k < 8;k++)//i表示八个方向 + for (p = 1;p <= 5;p++)//j表示沿这个方向走了几步 + { + int dx = i + p * dir[k][0]; + int dy = j + p * dir[k][1]; + if (c[dx][dy] != red)break; + } + if (p == 5) + { + AI_x = j; + AI_y = i; + return 1; + } + } + } + return 0; +} */ diff --git "a/\345\256\236\351\252\214/BetaGo/go.h" "b/\345\256\236\351\252\214/BetaGo/go.h" index f7f0698d..c1283d38 100644 --- "a/\345\256\236\351\252\214/BetaGo/go.h" +++ "b/\345\256\236\351\252\214/BetaGo/go.h" @@ -12,13 +12,18 @@ #define wall 3 #define col 4 #define row 2 +#define PTIF 2147483647//正无穷,Beta +#define NGIF -2147483648//负无穷,Alpha extern int board[L+2][L+2]; extern int AI_regrex, AI_regrey, man_regrex, man_regrey; extern int AI_x, AI_y; extern int man_x, man_y; +extern int AI_regretx, AI_regrety; +extern int man_regretx, man_regrety; extern int dir[][2]; +extern int rank; void BackGround(unsigned int ForeColor, unsigned int BackGroundColor); void gotoxy(int x, int y); @@ -27,6 +32,8 @@ void chess_menu(); void board_array(); void man_move();//红子棋移动光标 void machine_move(); +void clearlocation(int x, int y); +void location(int x, int y, int color); void man_machine();//人机对战 int judge_winner(int x, int y, int temp);//判断输赢 @@ -35,4 +42,5 @@ void welcome(); char Gametips(); int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2]); int minMax_AB(int deep, int me, int Alpha, int Beta, int tmp_board[][L + 2]); -int evaluate(int me, int copy[][L + 2]); \ No newline at end of file +int evaluate(int me, int copy[][L + 2]); +int priority(); \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214/BetaGo/max-min.c" index 5e64335a..84d3d88f 100644 --- "a/\345\256\236\351\252\214/BetaGo/max-min.c" +++ "b/\345\256\236\351\252\214/BetaGo/max-min.c" @@ -1,4 +1,3 @@ - #include "go.h" typedef struct { @@ -41,29 +40,32 @@ typedef struct break; } } - - //特殊情况优先 - //标记已经搜索且在最大路径上的节点,避免重复搜索 - for (int j = 0;j <= value;j++) + if (value == 5)//成五的情况最最优先,不需要再考虑两头的死活 + ; + else { - int dx = x + j * dir[maxdir][0]; - int dy = y + j * dir[maxdir][1]; - vis[dx][dy] = 1; - } - - //判断连子的死活 - int dx1 = x + value * dir[maxdir][0]; - int dy1 = y + value * dir[maxdir][1]; - int dx2 = x - dir[maxdir][0]; - int dy2 = y - dir[maxdir][1]; - if(dx1<0||dy1<0) - value--; - else - if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) + //标记已经搜索且在最大路径上的节点,避免重复搜索 + for (int j = 0;j <= value;j++) + { + int dx = x + j * dir[maxdir][0]; + int dy = y + j * dir[maxdir][1]; + vis[dx][dy] = 1; + } + + //判断连子的死活 + int dx1 = x + value * dir[maxdir][0]; + int dy1 = y + value * dir[maxdir][1]; + int dx2 = x - dir[maxdir][0]; + int dy2 = y - dir[maxdir][1]; + if (dx1 < 0 || dy1 < 0) value--; - if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) - value--; + else + if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) + value--; + if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) + value--; + } return value; } @@ -105,6 +107,13 @@ typedef struct return empty_cnt; } +int IDDFS() +{ + for (int i = 2;i < rank;i = i + 2) + { + if (!minMax_AB(i, red, NGIF, PTIF, board))break; + } +} int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) //分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF { @@ -121,8 +130,10 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) rival = 2; else rival = 1; - if (depth == 0||judge_winner(tree.X,tree.Y,me)==me) + if (depth == 0) return evaluate(me, tmp_board)-evaluate(rival,tmp_board); + if (judge_winner(tree.X, tree.Y, me) == me) + return 0; if (depth % 2)//判断是min层还是max层,奇数是min层 { for (i = 1;i < L + 1;i++) @@ -155,7 +166,7 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) { memcpy(c, tmp_board, sizeof(int) * L * L); //用一个新的数组表示棋盘,以免破坏原棋盘 - c[i][j] = me; + c[i][j] = me; minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); c[i][j] = 0; if (minmax > tree.Alpha) diff --git "a/\345\256\236\351\252\214/BetaGo/minmaxAB.c" "b/\345\256\236\351\252\214/BetaGo/minmaxAB.c" index c0c7f312..bd3a84d8 100644 --- "a/\345\256\236\351\252\214/BetaGo/minmaxAB.c" +++ "b/\345\256\236\351\252\214/BetaGo/minmaxAB.c" @@ -1,97 +1,9 @@ /* -#include "go.h" -typedef struct -{ - int Alpha; - int Beta; - int X; - int Y; -}Tree; -//怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 - -int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2])//搜索有多少颗连子 -{ - int value = 0; - int maxdir = 0; - int T, F; - - if (me == 1) - { - T = red; - F = white; - } - else - { - F = red; - T = white; - } - - for (int i = 0;i < 8;i++)//i表示八个方向 - for (int j = 1;j <= 5;j++)//j表示沿这个方向走了几步 - { - int dx = x + j * dir[i][0]; - int dy = y + j * dir[i][1]; - if (copy[dx][dy] != T) - { - if (j > value) - { - value = j;//记录最大连子数和最大的方向 - maxdir = i; - } - break; - } - } - - //特殊情况优先 - - //标记已经搜索且在最大路径上的节点,避免重复搜索 - for (int j = 0;j <= value;j++) - { - int dx = x + j * dir[maxdir][0]; - int dy = y + j * dir[maxdir][1]; - vis[dx][dy] = 1; - } - - //判断连子的死活 - int dx1 = x + value * dir[maxdir][0]; - int dy1 = y + value * dir[maxdir][1]; - int dx2 = x - dir[maxdir][0]; - int dy2 = y - dir[maxdir][1]; - if (dx1 < 0 || dy1 < 0) - value--; - else - if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) - value--; - if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) - value--; - return value; -} - -int evaluate(int me, int copy[][L + 2])//全局评估某一方的分数,turn=1评估red,a=2评估white -{ - int k = 0, score = 0; - int value = 0; - int vis[17][17] = { {0},{0} }; - - //遍历找到我方棋子开始search 连子 - for (int i = 1;i < L + 1;i++) - for (int j = 1;j < L + 1;j++) - { - if (copy[i][j] == me && (!vis[i][j]))//是我方且没有被搜索过 - { - value = search(i, j, me, vis, copy); - //计分方式:n连子,10^n,有一边死了n-1 - score = score + pow(10, value); - } - } - return score; -} - -int minMax_AB(int depth, int me, int Alpha, int Beta) +int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) //分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF { int i, j; - int c[L + 2][L + 2]; + int c[L+2][L+2]; int minmax; int rival; Tree tree; @@ -103,17 +15,25 @@ int minMax_AB(int depth, int me, int Alpha, int Beta) rival = 2; else rival = 1; - if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) - return evaluate(me); - if (depth % 2 == 0)//判断是min层还是max层,偶数是min层 + if (depth == 0|| judge_winner(tree.X, tree.Y, me) == me) + return evaluate(me, tmp_board)-evaluate(rival,tmp_board); + if (depth % 2)//判断是min层还是max层,奇数是min层 { for (i = 1;i < L + 1;i++) for (j = 1;j < L + 1;j++) { - if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j]&& neighbor(i, j) && tree.Alpha < tree.Beta) { + memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta); + if (judge_winner(i, j, white) == white && depth == rank-1) + //优先情况:对方已经有活四就必须堵 + { + AI_x = j; + AI_y = i; + return 0; + } + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); c[i][j] = 0; if (minmax < tree.Beta) { @@ -132,11 +52,19 @@ int minMax_AB(int depth, int me, int Alpha, int Beta) for (i = 1;i < L + 1;i++) for (j = 1;j < L + 1;j++) { - if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) { + memcpy(c, tmp_board, sizeof(int) * L * L); //用一个新的数组表示棋盘,以免破坏原棋盘 c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta); + if (judge_winner(i, j, red) == red&&depth==rank) + //优先情况:自己已经有活四就必须接着下 + { + AI_x = j; + AI_y = i; + return 0; + } + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); c[i][j] = 0; if (minmax > tree.Alpha) { @@ -156,18 +84,4 @@ int minMax_AB(int depth, int me, int Alpha, int Beta) } -int neighbor(int x, int y)//判断空位置两步之内是否有邻居 -{ - for (int di = 0;di < 8;di++)//i表示八个方向 - for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 - { - int dx = x + dj * dir[di][0]; - int dy = y + dj * dir[di][1]; - if (dx > 0 && dx < L + 1 && dy>0 && dy < L + 1) - if (board[dx][dy] == red || board[dx][dy] == white) - return 1; - } - return 0; -} - */ diff --git "a/\345\256\236\351\252\214/BetaGo/priority.c" "b/\345\256\236\351\252\214/BetaGo/priority.c" new file mode 100644 index 00000000..e69de29b diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" index 623759ea..5a4b63f8 100644 --- "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" +++ "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" @@ -1,41 +1,16 @@ #include "go.h" -#define PTIF 2147483647//正无穷,Beta -#define NGIF -2147483648//负无穷,Alpha int board[L+2][L+2]; -int AI_regrex, AI_regrey, man_regrex, man_regrey; +int AI_regretx, AI_regrety, man_regretx, man_regrety; -int AI_x, AI_y; -int man_x, man_y;//man_y=i,man_x=j +int AI_x=0, AI_y=0; +int man_x=0, man_y=0;//man_y=i,man_x=j //board[i][j]与position之间的关系gotoxy(4 * (man_x-1), 2 * (man_y-1) + 1) int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//八向的常量数组 int flag = 0;//判断输赢 -int count = 0;//计算棋子数量 - -void chess_menu()//打印棋盘旁的菜单 -{ - int i,j; - for(i=1;i<=29;i++) - { - gotoxy(67,i); - printf("||"); - } - for(i=1;i<=29;i++) - { - gotoxy(89,i); - printf("||"); - } - gotoxy(69,1); - printf("--------------------"); - gotoxy(69,29); - printf("--------------------"); - gotoxy(75,3); - printf("模 式"); - gotoxy(75,20); - printf("提 示"); -} +int rank = 2; void board_array() { @@ -52,11 +27,15 @@ void board_array() void man_move()//白棋移动光标 { - loop1:gotoxy(4 * (man_x - 1), 2 * (man_y - 1) + 1); +loop1:location(man_x, man_y,white); + gotoxy(4 * man_x , 2 * (man_y - 1) + 1); char key='y'; - while(key!='0') + while(key!=' ') { key=_getch(); + if (AI_x != 0 && AI_y != 0)//玩家先手,第一次不用清除 + clearlocation(AI_x, AI_y); + clearlocation(man_x, man_y); switch(key) { case 72: @@ -92,7 +71,8 @@ void board_array() } } } - gotoxy(4 * (man_x-1), 2 * (man_y-1) + 1); + location(man_x, man_y,white); + gotoxy(4 * man_x, 2 * (man_y-1) + 1); } if (board[man_y][man_x]) { @@ -104,23 +84,22 @@ void board_array() else { board[man_y][man_x] = white; - BackGround(7, 0); - man_regrex = man_x; - man_regrey = man_y; + man_regretx = man_x; + man_regrety = man_y; printf("●"); } } - - void machine_move()//打印AI的棋子的函数,机器用红子,玩家用白子 { - minMax_AB(4, red, NGIF, PTIF,board); + IDDFS(); + minMax_AB(rank, red, NGIF, PTIF, board); + clearlocation(man_x, man_y); board[AI_y][AI_x] = red; - gotoxy(4*(AI_x-1), 2*(AI_y-1)+1);//坐标和数组的顺序是反的 - BackGround(4, 0); - AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 - AI_regrey = AI_y; + location(AI_x, AI_y, red); + gotoxy(4*AI_x, 2*(AI_y-1)+1);//坐标和数组的顺序是反的 + AI_regretx = AI_x;//记录电脑上一落子的位置 ,方便悔棋 + AI_regrety = AI_y; printf("●"); } @@ -174,6 +153,10 @@ void board_array() printf("玩家为白子,电脑为红子(输入相应序号选择)"); key=_getch(); system("cls"); + gotoxy(2, 5); + printf("请输入难度等级(输入偶数,例:2,4,6,难度等级越大,程序运行越慢):"); + rank = _getch() - '0'; + system("cls"); control = 1; if(key!='1'&& key!='2') { @@ -191,11 +174,11 @@ void board_array() { AI_x = 7; AI_y = 8; - gotoxy(4 * (AI_x - 1), 2 * (AI_y - 1) + 1);//机器第一次下在中间位置 - BackGround(4, 0); - AI_regrex = AI_x;//记录电脑上一落子的位置 ,方便悔棋 - AI_regrey = AI_y; - board[AI_y][AI_x] = 1; + AI_regretx = AI_x;//记录电脑上一落子的位置 ,方便悔棋 + AI_regrety = AI_y; + board[AI_y][AI_x] = red; + location(AI_x, AI_y,red); + gotoxy(4 * AI_x, 2 * (AI_y - 1) + 1);//机器第一次下在中间位 printf("●"); } while(flag==0) @@ -228,22 +211,18 @@ void board_array() { MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); } - if(count>=225) - { - MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); - } } void Regret()//悔棋函数 { - gotoxy(4 * (man_x - 1), 2 * (man_y - 1) + 1); + gotoxy(4 * man_regretx , 2 * (man_regrety - 1) + 1); BackGround(0,0); printf(" "); - board[man_y][man_x]=0; - gotoxy(4 * (AI_x - 1), 2 * (AI_y - 1) + 1); + board[man_regrety][man_regretx]=0; + gotoxy(4 * AI_regretx , 2 * (AI_regrety - 1) + 1); BackGround(0,0); printf(" "); - board[AI_y][AI_x]=0; + board[AI_regrety][AI_regretx]=0; } From 2db1986434c26eda287539e0ae7eeba75256a76d Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Sun, 13 Jun 2021 21:39:27 +0800 Subject: [PATCH 17/19] =?UTF-8?q?[=E5=90=AF=E5=8F=91=E5=BC=8F=E6=90=9C?= =?UTF-8?q?=E7=B4=A2+=E4=BF=AE=E5=A4=8D=E6=A3=8B=E7=9B=98=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=BC=A0=E9=80=92bug]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/level1.12link (1).c | 154 ---- homework/level1.12link (1).h | 25 - homework/level1.12warehouse.c | 29 - .../p01_runningLetter}/level1.1.cpp | 0 {homework => level1/p02_isPrime}/level1.2.c | 0 .../p03_Diophantus}/level1.3.cpp | 0 .../p04_ narcissus}/level1.4.cpp | 0 {homework => level1/p05_allPrimes}/level1.5.c | 0 .../p06_Goldbach}/level1.6.cpp | 0 ...4\344\272\232\345\257\206\347\240\201.pdf" | Bin .../p07_encrypt_decrypt}/level1.7.cpp | 0 .../p08_hanoi}/level1.8hanoi.c | 0 {homework => level1/p09_maze}/level1.9.c | 0 .../p10_pushBoxes}/level1.10pushbox.c | 0 .../p10_pushBoxes}/pushboxmap/level1.txt | 0 .../p10_pushBoxes}/pushboxmap/level2.txt | 0 .../p10_pushBoxes}/pushboxmap/level3.txt | 0 .../p10_pushBoxes}/pushboxmap/level4.txt | 0 .../p11_linkedList}/level1.11linkedList.c | 0 .../p11_linkedList}/level1.11linkedList.h | 0 .../p12_warehouse}/level1.13link.c | 0 .../p12_warehouse}/level1.13link.h | 0 .../p12_warehouse}/level1.13warehouse.c | 0 .../p12_warehouse}/warehouse.txt | 0 .../BetaGo/BetaGo.vcxproj" | 8 +- .../BetaGo/BetaGo.vcxproj.filters" | 16 +- .../BetaGo/Chess.c" | 42 +- .../BetaGo/Chess.h" | 9 +- "\345\256\236\351\252\214/BetaGo/GUI.c" | 31 +- "\345\256\236\351\252\214/BetaGo/draft.c" | 2 + "\345\256\236\351\252\214/BetaGo/heuristic.c" | 103 +++ "\345\256\236\351\252\214/BetaGo/heuristic.h" | 14 + "\345\256\236\351\252\214/BetaGo/max-min.c" | 158 ++-- "\345\256\236\351\252\214/BetaGo/max-min.h" | 16 + .../\344\272\224\345\255\220\346\243\213.c" | 771 ------------------ .../Chess_GUI/Chess-board.cpp" | 162 ++++ .../Chess_GUI/Chess_GUI.sln" | 31 + .../Chess_GUI/Chess_GUI.vcxproj" | 148 ++++ .../Chess_GUI/Chess_GUI.vcxproj.filters" | 25 + .../Chess_GUI/Chess_GUI.vcxproj.user" | 4 + .../Chess_GUI/HomeScreen.cpp" | 0 "\345\256\236\351\252\214/README.md" | 382 +++++++++ 42 files changed, 1051 insertions(+), 1079 deletions(-) delete mode 100644 homework/level1.12link (1).c delete mode 100644 homework/level1.12link (1).h delete mode 100644 homework/level1.12warehouse.c rename {homework => level1/p01_runningLetter}/level1.1.cpp (100%) rename {homework => level1/p02_isPrime}/level1.2.c (100%) rename {homework => level1/p03_Diophantus}/level1.3.cpp (100%) rename {homework => level1/p04_ narcissus}/level1.4.cpp (100%) rename {homework => level1/p05_allPrimes}/level1.5.c (100%) rename {homework => level1/p06_Goldbach}/level1.6.cpp (100%) rename "homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" => "level1/p07_encrypt_decrypt/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" (100%) rename {homework => level1/p07_encrypt_decrypt}/level1.7.cpp (100%) rename {homework => level1/p08_hanoi}/level1.8hanoi.c (100%) rename {homework => level1/p09_maze}/level1.9.c (100%) rename {homework => level1/p10_pushBoxes}/level1.10pushbox.c (100%) rename {homework => level1/p10_pushBoxes}/pushboxmap/level1.txt (100%) rename {homework => level1/p10_pushBoxes}/pushboxmap/level2.txt (100%) rename {homework => level1/p10_pushBoxes}/pushboxmap/level3.txt (100%) rename {homework => level1/p10_pushBoxes}/pushboxmap/level4.txt (100%) rename {homework => level1/p11_linkedList}/level1.11linkedList.c (100%) rename {homework => level1/p11_linkedList}/level1.11linkedList.h (100%) rename {homework => level1/p12_warehouse}/level1.13link.c (100%) rename {homework => level1/p12_warehouse}/level1.13link.h (100%) rename {homework => level1/p12_warehouse}/level1.13warehouse.c (100%) rename {homework => level1/p12_warehouse}/warehouse.txt (100%) rename "\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" => "\345\256\236\351\252\214/BetaGo/Chess.c" (84%) rename "\345\256\236\351\252\214/BetaGo/go.h" => "\345\256\236\351\252\214/BetaGo/Chess.h" (74%) create mode 100644 "\345\256\236\351\252\214/BetaGo/heuristic.c" create mode 100644 "\345\256\236\351\252\214/BetaGo/heuristic.h" create mode 100644 "\345\256\236\351\252\214/BetaGo/max-min.h" delete mode 100644 "\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" create mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" create mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" create mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" create mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" create mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" rename "\345\256\236\351\252\214/BetaGo/priority.c" => "\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" (100%) create mode 100644 "\345\256\236\351\252\214/README.md" diff --git a/homework/level1.12link (1).c b/homework/level1.12link (1).c deleted file mode 100644 index c2e87a72..00000000 --- a/homework/level1.12link (1).c +++ /dev/null @@ -1,154 +0,0 @@ -#include "link.h" -void HomeScreen() -{ - int n; - int i, j = 1; - gotoxy(43, 18); - color(11); - printf("进销存小程序"); - color(14); //黄色边框 - for (i = 20; i <= 26; i++) //输出上下边框┅ - { - for (j = 27; j <= 74; j++) //输出左右边框┇ - { - gotoxy(j, i); - if (i == 20 || i == 26) - { - printf("-"); - } - else if (j == 27 || j == 74) - { - printf("|"); - } - } - } - color(10); - gotoxy(35, 22); - printf("显示存货请按1"); - gotoxy(55, 22); - printf("出库请按3"); - gotoxy(35, 24); - printf("列表入库请按2"); - gotoxy(55, 24); - printf("退出程序请按4\n"); -} - -void importdata() -{ - char buf[BUFSIZE] = { '\0' }; - char charthead[BUFSIZE] = { '\0' }; - head = NULL; - fopen_s(&fp, "D:/tmp/warehouse.txt", "r"); - if (fp == NULL) - printf("Cannot open file!\n"); - fgets(charthead, BUFSIZE, fp); - do - { - Node* p = (Node*)malloc(sizeof(Node)); - p->next = NULL; - fgets(buf, BUFSIZE, fp); //一次读取一行 - sscanf(buf, "%s\t%d\t%d", &(p->name), &(p->type), &(p->quantity)); - Node* last = head; - if (head) - { - while (last->next) - last = last->next; - last->next = p; - } - else - head = p; - } while (!feof(fp)); - fclose(fp); -} - -void ShowList() -{ - printf("name\ttype\tquantity\n"); - for (Node* q = head;q;q = q->next) - printf("%s\t%d\t%d\n", q->name, q->type, q->quantity); -} - -void Input() -{ - int issame = 1; - Node* p = (Node*)malloc(sizeof(Node)); - p->next = NULL; - printf("请要入库的‘货物名称 货物数量’\n"); - scanf("%s %d", &(p->name), &(p->quantity)); - fflush(stdin); - for (Node* q = head;q->next;q = q->next) - { - if (!strcmp(p->name, q->name)) - { - q->quantity += p->quantity; - issame = 0; - update(); - break; - } - } - if (issame) - { - Node* last = head; - if (head) - { - while (last->next) - last = last->next; - last->next = p; - } - else - head = p; - update(); - } - printf("\n恭喜老板,出库成功!\n"); -} - -void Output() -{ - char outname[100]; - int outcnt, isfound = 1; - color(11); - printf("请输入要出库的‘货物名称 货物数量’:\n"); - scanf("%s %d", &outname, &outcnt); - for (Node* q = head;q->next;q = q->next) - { - if (!strcmp(outname, q->name)) - { - q->quantity -= outcnt; - printf("\n恭喜老板,出库成功!\n"); - if (q->quantity < 0) - printf("存货数量不够\n"); - else - { - update(); - isfound = 0; - } - } - } - if (isfound) - printf("没有该货物的储存记录,无法出库\n"); -} - -void update() -{ - fp = fopen("D:/tmp/warehouse2.txt", "w+"); - fprintf(fp, "*%s\r\n", __DATE__); - for (Node* q = head;q;q = q->next) - fprintf(fp, "\n%s\t%d\t%d", q->name, q->type, q->quantity); - fclose(fp); -} - - -void color(int c) -{ - //SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数 - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); - //更改背景颜色 -} - -void gotoxy(int x, int y) -{ - COORD c; - c.X = x; - c.Y = y; - SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); -} diff --git a/homework/level1.12link (1).h b/homework/level1.12link (1).h deleted file mode 100644 index 23a6b1cd..00000000 --- a/homework/level1.12link (1).h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include -#include -#define BUFSIZE 1000 - -typedef struct node -{ - char name[20]; - int type; - int quantity; - struct node* next; -}Node; - -Node* head; -FILE* fp; - -void HomeScreen(); -void importdata(); -void ShowList(); -void Input(); -void Output(); -void update(); -void color(int c); -void gotoxy(int x, int y); diff --git a/homework/level1.12warehouse.c b/homework/level1.12warehouse.c deleted file mode 100644 index 4126875a..00000000 --- a/homework/level1.12warehouse.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "link.h" -int main() -{ - int n; - while (1) - { - HomeScreen(); - importdata(); - scanf_s("%d", &n); - fflush stdin; - system("cls"); - switch (n) - { - case 1:ShowList();break; - case 2:Input();break; - case 3:Output();break; - case 4:exit(0);break; - } - printf("再次运行程序请按1,退出程序请按0"); - scanf_s("%d", &n); - switch (n) - { - case 1:system("cls");break; - case 2:exit(0); - } - } - return 0; -} - diff --git a/homework/level1.1.cpp b/level1/p01_runningLetter/level1.1.cpp similarity index 100% rename from homework/level1.1.cpp rename to level1/p01_runningLetter/level1.1.cpp diff --git a/homework/level1.2.c b/level1/p02_isPrime/level1.2.c similarity index 100% rename from homework/level1.2.c rename to level1/p02_isPrime/level1.2.c diff --git a/homework/level1.3.cpp b/level1/p03_Diophantus/level1.3.cpp similarity index 100% rename from homework/level1.3.cpp rename to level1/p03_Diophantus/level1.3.cpp diff --git a/homework/level1.4.cpp b/level1/p04_ narcissus/level1.4.cpp similarity index 100% rename from homework/level1.4.cpp rename to level1/p04_ narcissus/level1.4.cpp diff --git a/homework/level1.5.c b/level1/p05_allPrimes/level1.5.c similarity index 100% rename from homework/level1.5.c rename to level1/p05_allPrimes/level1.5.c diff --git a/homework/level1.6.cpp b/level1/p06_Goldbach/level1.6.cpp similarity index 100% rename from homework/level1.6.cpp rename to level1/p06_Goldbach/level1.6.cpp diff --git "a/homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" "b/level1/p07_encrypt_decrypt/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" similarity index 100% rename from "homework/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" rename to "level1/p07_encrypt_decrypt/1.7\347\273\264\345\220\211\345\260\274\344\272\232\345\257\206\347\240\201.pdf" diff --git a/homework/level1.7.cpp b/level1/p07_encrypt_decrypt/level1.7.cpp similarity index 100% rename from homework/level1.7.cpp rename to level1/p07_encrypt_decrypt/level1.7.cpp diff --git a/homework/level1.8hanoi.c b/level1/p08_hanoi/level1.8hanoi.c similarity index 100% rename from homework/level1.8hanoi.c rename to level1/p08_hanoi/level1.8hanoi.c diff --git a/homework/level1.9.c b/level1/p09_maze/level1.9.c similarity index 100% rename from homework/level1.9.c rename to level1/p09_maze/level1.9.c diff --git a/homework/level1.10pushbox.c b/level1/p10_pushBoxes/level1.10pushbox.c similarity index 100% rename from homework/level1.10pushbox.c rename to level1/p10_pushBoxes/level1.10pushbox.c diff --git a/homework/pushboxmap/level1.txt b/level1/p10_pushBoxes/pushboxmap/level1.txt similarity index 100% rename from homework/pushboxmap/level1.txt rename to level1/p10_pushBoxes/pushboxmap/level1.txt diff --git a/homework/pushboxmap/level2.txt b/level1/p10_pushBoxes/pushboxmap/level2.txt similarity index 100% rename from homework/pushboxmap/level2.txt rename to level1/p10_pushBoxes/pushboxmap/level2.txt diff --git a/homework/pushboxmap/level3.txt b/level1/p10_pushBoxes/pushboxmap/level3.txt similarity index 100% rename from homework/pushboxmap/level3.txt rename to level1/p10_pushBoxes/pushboxmap/level3.txt diff --git a/homework/pushboxmap/level4.txt b/level1/p10_pushBoxes/pushboxmap/level4.txt similarity index 100% rename from homework/pushboxmap/level4.txt rename to level1/p10_pushBoxes/pushboxmap/level4.txt diff --git a/homework/level1.11linkedList.c b/level1/p11_linkedList/level1.11linkedList.c similarity index 100% rename from homework/level1.11linkedList.c rename to level1/p11_linkedList/level1.11linkedList.c diff --git a/homework/level1.11linkedList.h b/level1/p11_linkedList/level1.11linkedList.h similarity index 100% rename from homework/level1.11linkedList.h rename to level1/p11_linkedList/level1.11linkedList.h diff --git a/homework/level1.13link.c b/level1/p12_warehouse/level1.13link.c similarity index 100% rename from homework/level1.13link.c rename to level1/p12_warehouse/level1.13link.c diff --git a/homework/level1.13link.h b/level1/p12_warehouse/level1.13link.h similarity index 100% rename from homework/level1.13link.h rename to level1/p12_warehouse/level1.13link.h diff --git a/homework/level1.13warehouse.c b/level1/p12_warehouse/level1.13warehouse.c similarity index 100% rename from homework/level1.13warehouse.c rename to level1/p12_warehouse/level1.13warehouse.c diff --git a/homework/warehouse.txt b/level1/p12_warehouse/warehouse.txt similarity index 100% rename from homework/warehouse.txt rename to level1/p12_warehouse/warehouse.txt diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" index 223f6971..f84d47d2 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" @@ -140,15 +140,17 @@ + + - - - + + + diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" index 9805b9e1..0214e743 100644 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" +++ "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" @@ -18,9 +18,6 @@ 婧愭枃浠 - - 婧愭枃浠 - 婧愭枃浠 @@ -30,12 +27,21 @@ 婧愭枃浠 - + + 婧愭枃浠 + + 婧愭枃浠 - + + 澶存枃浠 + + + 澶存枃浠 + + 澶存枃浠 diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" "b/\345\256\236\351\252\214/BetaGo/Chess.c" similarity index 84% rename from "\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" rename to "\345\256\236\351\252\214/BetaGo/Chess.c" index 5a4b63f8..6deccd3b 100644 --- "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\2131.0.c" +++ "b/\345\256\236\351\252\214/BetaGo/Chess.c" @@ -1,18 +1,19 @@ -#include "go.h" +#include "Chess.h" -int board[L+2][L+2]; +int board[L+2][L+2];//表示棋盘的二维数组 -int AI_regretx, AI_regrety, man_regretx, man_regrety; +int AI_regretx, AI_regrety, man_regretx, man_regrety;//记录人和AI上一轮下棋的位置,便于悔棋 -int AI_x=0, AI_y=0; +int AI_x=0, AI_y=0;//记录AI本轮下棋的位置 int man_x=0, man_y=0;//man_y=i,man_x=j -//board[i][j]与position之间的关系gotoxy(4 * (man_x-1), 2 * (man_y-1) + 1) -int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//八向的常量数组 +//board[i][j]与position之间的关系gotoxy(4 * man_x, 2 * (man_y-1) + 1) +int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//表示八个方向的常量数组 int flag = 0;//判断输赢 int rank = 2; -void board_array() +//初始化表示棋盘的数组 +void board_init() { for (int i = 0;i < L+2;i++) for (int j = 0;j < L+2;j++)//解决边界问题,加一个边界,边界=3 @@ -24,7 +25,7 @@ void board_array() board[i][j] = 3; } } - +//实现人控制的光标移动和下棋 void man_move()//白棋移动光标 { loop1:location(man_x, man_y,white); @@ -89,11 +90,10 @@ loop1:location(man_x, man_y,white); printf("●"); } } - +//实现AI控制的光标移动和下棋 void machine_move()//打印AI的棋子的函数,机器用红子,玩家用白子 { IDDFS(); - minMax_AB(rank, red, NGIF, PTIF, board); clearlocation(man_x, man_y); board[AI_y][AI_x] = red; location(AI_x, AI_y, red); @@ -102,8 +102,8 @@ loop1:location(man_x, man_y,white); AI_regrety = AI_y; printf("●"); } - -int judge_winner(int x, int y, int me)//判断输赢,要向两个方向搜索 +//每下一步棋之后,判断输赢的函数 +int judge_winner(int x, int y, int me, int now_board[L+2][L+2])//判断输赢,要向两个方向搜索 { int n1 = 0, n2 = 0; int flag = 0; @@ -113,7 +113,7 @@ loop1:location(man_x, man_y,white); { int dx = x + j * dir[i][0]; int dy = y + j * dir[i][1]; - if (board[dy][dx] == me)//AI_x,AI_y都是坐标上的x,y,表示数组要反过来 + if (now_board[dy][dx] == me)//AI_x,AI_y都是坐标上的x,y,表示数组要反过来 n1++; else break; @@ -122,7 +122,7 @@ loop1:location(man_x, man_y,white); { int dx = x + j * dir[7 - i][0]; int dy = y + j * dir[7 - i][1]; - if (board[dy][dx] == me) + if (now_board[dy][dx] == me) n2++; else break; @@ -137,7 +137,7 @@ loop1:location(man_x, man_y,white); } return flag; } - +//实现人机对战功能的函数 void man_machine()//人机对战模式 { loop6:system("cls"); @@ -168,7 +168,7 @@ loop1:location(man_x, man_y,white); man_y=7; man_x=8; chess_board(); - board_array(); + board_init(); chess_menu(); if (key == '2') { @@ -189,7 +189,7 @@ loop1:location(man_x, man_y,white); BackGround(6,0); printf(" 玩 家 执 手 "); man_move(); - flag=judge_winner(man_x,man_y,white); + flag=judge_winner(man_x,man_y,white,board); } else { @@ -197,7 +197,7 @@ loop1:location(man_x, man_y,white); BackGround(6,0); printf(" 电 脑 执 手 "); machine_move(); - flag=judge_winner(AI_x,AI_y,red); + flag=judge_winner(AI_x,AI_y,red,board); } control=-control; } @@ -212,7 +212,12 @@ loop1:location(man_x, man_y,white); MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); } } +//实现人与人对战功能的函数 +void man_man() +{ +} +//实现悔棋功能的函数 void Regret()//悔棋函数 { gotoxy(4 * man_regretx , 2 * (man_regrety - 1) + 1); @@ -225,7 +230,6 @@ loop1:location(man_x, man_y,white); board[AI_regrety][AI_regretx]=0; } - int main() { system("title 五子棋"); diff --git "a/\345\256\236\351\252\214/BetaGo/go.h" "b/\345\256\236\351\252\214/BetaGo/Chess.h" similarity index 74% rename from "\345\256\236\351\252\214/BetaGo/go.h" rename to "\345\256\236\351\252\214/BetaGo/Chess.h" index c1283d38..54a23078 100644 --- "a/\345\256\236\351\252\214/BetaGo/go.h" +++ "b/\345\256\236\351\252\214/BetaGo/Chess.h" @@ -12,8 +12,6 @@ #define wall 3 #define col 4 #define row 2 -#define PTIF 2147483647//正无穷,Beta -#define NGIF -2147483648//负无穷,Alpha extern int board[L+2][L+2]; extern int AI_regrex, AI_regrey, man_regrex, man_regrey; @@ -29,7 +27,7 @@ void BackGround(unsigned int ForeColor, unsigned int BackGroundColor); void gotoxy(int x, int y); void chess_menu(); void chess_board();//打印棋盘 -void board_array(); +void board_init(); void man_move();//红子棋移动光标 void machine_move(); void clearlocation(int x, int y); @@ -40,7 +38,4 @@ void location(int x, int y, int color); void Regret();//悔棋函数 void welcome(); char Gametips(); -int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2]); -int minMax_AB(int deep, int me, int Alpha, int Beta, int tmp_board[][L + 2]); -int evaluate(int me, int copy[][L + 2]); -int priority(); \ No newline at end of file + diff --git "a/\345\256\236\351\252\214/BetaGo/GUI.c" "b/\345\256\236\351\252\214/BetaGo/GUI.c" index 9e5adcba..c3975faf 100644 --- "a/\345\256\236\351\252\214/BetaGo/GUI.c" +++ "b/\345\256\236\351\252\214/BetaGo/GUI.c" @@ -1,6 +1,7 @@ -#include "go.h" +#include "Chess.h" -void welcome()//游戏菜单 +//游戏菜单 +void welcome() { int k; char choose; @@ -33,8 +34,8 @@ gotoxy(13, 20); } - -char Gametips()//游戏帮助 +//游戏帮助 +char Gametips() { char choose; int key; @@ -55,8 +56,8 @@ return _getch(); } - -void chess_board()//打印棋盘 +//打印棋盘 +void chess_board() { int i, j; for (i = 1;i <= 29;i++) @@ -79,8 +80,8 @@ printf("——"); } } - -void chess_menu()//打印棋盘旁的菜单 +//打印棋盘旁的菜单 +void chess_menu() { int i, j; for (i = 1;i <= 29;i++) @@ -102,7 +103,7 @@ gotoxy(75, 20); printf("提 示"); } - +//在玩家移动光标和下棋时输出图形对光标所在位置进行定位 void location(int x, int y,int color) // 定位 { if (color == red) @@ -127,8 +128,8 @@ gotoxy(x * 4 + 2, y * 2);puts("┏"); } } - -void clearlocation(int x, int y) //清除定位 +//清除定位 +void clearlocation(int x, int y) { if (x > 1 && y > 1) { @@ -147,14 +148,14 @@ gotoxy(x * 4 + 2, y * 2);puts(" "); } } - -void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 +//背景颜色控制函数 +void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 } - -void gotoxy(int x, int y) //光标函数 +//光标函数 +void gotoxy(int x, int y) { HANDLE handle; COORD coord; //获取坐标轴结构体 diff --git "a/\345\256\236\351\252\214/BetaGo/draft.c" "b/\345\256\236\351\252\214/BetaGo/draft.c" index 552f30dc..08cdb105 100644 --- "a/\345\256\236\351\252\214/BetaGo/draft.c" +++ "b/\345\256\236\351\252\214/BetaGo/draft.c" @@ -226,4 +226,6 @@ int priority() } return 0; } + + */ diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.c" "b/\345\256\236\351\252\214/BetaGo/heuristic.c" new file mode 100644 index 00000000..5bf9303c --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/heuristic.c" @@ -0,0 +1,103 @@ +#include "Chess.h" +#include "heuristic.h" + +//生成可下棋且有邻居的空位的函数 +int generator(int empty[][2],int now_board[L+2][L+2])//产生空子序列 +{ + int empty_cnt = 0; + for (int i = 1;i < L + 1;i += 1) + { + for (int j = 1;j < L + 1;j += 1) + { + if (neighbor(i, j,now_board)&&!now_board[i][j]) + { + empty[empty_cnt][0] = i; + empty[empty_cnt][1] = j; + empty_cnt++; + } + } + } + return empty_cnt; +} +//评估该位置的分数的函数 +int point_evaluate(int x, int y,int me, int now_board[L + 2][L + 2]) +{ + now_board[x][y] = me; + int n1=0, n2=0, t; + int value=0; + for (int i = 0;i < 4;i++)//i表示八个方向 + { + for (int j = 0;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j * dir[i][0]; + int dy = y + j * dir[i][1]; + if (now_board[dy][dx] == me)//AI_x,AI_y都是坐标上的x,y,表示数组要反过来 + n1++; + else + break; + } + for (int j = 0;j <= 5;j++)//j表示沿这个方向走了几步 + { + int dx = x + j * dir[7 - i][0]; + int dy = y + j * dir[7 - i][1]; + if (now_board[dy][dx] == me) + n2++; + else + break; + } + t = n1 + n2; + if (t > value) + { + value = t; + } + } + //判断是不是杀棋 + now_board[x][y] = 0; + return value; +} +//判断该位置两步之内是否有邻居的函数 +int neighbor(int x, int y, int now_board[L+2][L+2])//判断空位置两步之内是否有邻居 +{ + for (int di = 0;di < 8;di++)//i表示八个方向 + for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 + { + int dx = x + dj * dir[di][0]; + int dy = y + dj * dir[di][1]; + if (dx > 0 && dx < L + 1 && dy>0 && dy < L + 1) + if (now_board[dx][dy] == red || now_board[dx][dy] == white) + return 1; + } + return 0; +} +//启发式搜索函数 +void heuristic_search(int point_value[][3], int empty_point[][2], int empty_cnt, int me, int now_board[L + 2][L + 2]) +{ + int cnt = 0; + int others; + if (me == red) + others = white; + else + others = red; + for (int i = 0;i < empty_cnt;i++) + { + int x = empty_point[i][0]; + point_value[i][0] = x; + int y = empty_point[i][1]; + point_value[i][1] = y; + point_value[i][2] = point_evaluate(x, y, me, now_board) + point_evaluate(x, y, others, now_board); + } + + qsort(point_value, empty_cnt, sizeof(int) * 3, comp); + +} +/* +void heuristic_search(struct Point *p, int me, int now_board[L + 2][L + 2]) +*/ +//qsort排序的比较规则函数 +int comp(const void* a, const void* b) +{ + if (((int*)a)[2] < ((int*)b)[2]) + return 1; + else return -1; +} + diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.h" "b/\345\256\236\351\252\214/BetaGo/heuristic.h" new file mode 100644 index 00000000..1d4d7c86 --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/heuristic.h" @@ -0,0 +1,14 @@ +#pragma once +void heuristic_search(int point_value[][3], int empty_point[][2], int empty_cnt, int me); +int neighbor(int x, int y); +int point_evaluate(int x, int y, int me); +int generator(int* empty[][2]); +int comp(const void* a, const void* b); + +typedef struct +{ + int cnt; + int X[100]; + int Y[100]; + int value[100]; +}Point; \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214/BetaGo/max-min.c" index 84d3d88f..6e09b40f 100644 --- "a/\345\256\236\351\252\214/BetaGo/max-min.c" +++ "b/\345\256\236\351\252\214/BetaGo/max-min.c" @@ -1,13 +1,8 @@ -#include "go.h" -typedef struct -{ - int Alpha; - int Beta; - int X; - int Y; -}Tree; +#include "Chess.h" +#include "max-min.h" //怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 +//搜索遍历棋型的函数,评估函数evaluate是在search基础上的打分 int search(int x, int y,int me,int vis[][L+2],int copy[][L+2])//搜索有多少颗连子 { int value = 0; @@ -62,13 +57,17 @@ typedef struct value--; else if (copy[dx1][dy1] == F || copy[dx1][dy1] == wall) + { value--; + if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) + value = 0; + } if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) value--; } return value; } - +//全局分数评估函数 int evaluate(int me,int copy[][L+2])//全局评估某一方的分数,turn=1评估red,a=2评估white { int k=0, score=0; @@ -88,36 +87,20 @@ typedef struct } return score; } - - -int generator(int *empty[][2])//产生空子序列 -{ - - int empty_cnt = 0; - for (int i = 1;i < L + 1;i += 1) - for (int j = 1;j < L + 1;j += 1) - { - if (neighbor(i, j)) - { - empty[empty_cnt][0] = i; - empty[empty_cnt][1] = j; - empty_cnt++; - } - } - return empty_cnt; -} - +//迭代加深搜索 int IDDFS() { - for (int i = 2;i < rank;i = i + 2) + for (int i = 2;i <= rank;i++) { - if (!minMax_AB(i, red, NGIF, PTIF, board))break; + if (!minMax_AB(i, red, NGIF, PTIF, board))break; } + return 0; } + +//极大值极小值搜索(含αβ剪枝) int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) //分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF { - int i, j; int c[L+2][L+2]; int minmax; int rival; @@ -134,12 +117,96 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) return evaluate(me, tmp_board)-evaluate(rival,tmp_board); if (judge_winner(tree.X, tree.Y, me) == me) return 0; + if (depth % 2)//判断是min层还是max层 + { + //min层 + int empty_point[100][2] = { 0 }; + int empty_cnt = generator(empty_point,tmp_board); + int point_value[100][3] = { 0 }; + heuristic_search(point_value, empty_point, empty_cnt,white, tmp_board); + for (int k = 0;k < empty_cnt;k++) + { + int i = point_value[k][0]; + int j = point_value[k][1]; + if (tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + c[i][j] = 0; + if (minmax < tree.Beta) + { + tree.Beta = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Alpha;//α剪枝,抛弃后续节点 + } + } + } + return tree.Beta; + } + else + { + //max层 + int empty_point[100][2] = { 0 }; + int empty_cnt = generator(empty_point, tmp_board); + int point_value[100][3] = { 0 }; + heuristic_search(point_value, empty_point, empty_cnt,red, tmp_board); + for (int k = 0;k < empty_cnt;k++) + { + int i = point_value[k][0]; + int j = point_value[k][1]; + if (tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L); + //用一个新的数组表示棋盘,以免破坏原棋盘 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); + c[i][j] = 0; + if (minmax > tree.Alpha) + { + tree.Alpha = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Beta;//α剪枝,抛弃后续节点 + } + } + } + AI_x = tree.X; + AI_y = tree.Y; + return tree.Alpha; + } + +} + +/* +int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L + 2]) +//分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF +{ + int i, j; + int c[L + 2][L + 2]; + int minmax; + int rival; + Tree tree; + tree.Alpha = Alpha; + tree.Beta = Beta; + tree.X = 0; + tree.Y = 0; + if (me == 1) + rival = 2; + else + rival = 1; + int if_win = judge_winner(tree.X, tree.Y, me, tmp_board); + if (if_win ==me||depth==0) + return evaluate(me, tmp_board) - evaluate(rival, tmp_board); if (depth % 2)//判断是min层还是max层,奇数是min层 { for (i = 1;i < L + 1;i++) for (j = 1;j < L + 1;j++) { - if (!tmp_board[i][j]&& neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j] && neighbor(i, j, tmp_board) && tree.Alpha < tree.Beta) { memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 c[i][j] = me; @@ -154,7 +221,7 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) return tree.Alpha;//α剪枝,抛弃后续节点 } } - } + } return tree.Beta; } else @@ -162,12 +229,12 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) for (i = 1;i < L + 1;i++) for (j = 1;j < L + 1;j++) { - if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j] && neighbor(i, j, tmp_board) && tree.Alpha < tree.Beta) { memcpy(c, tmp_board, sizeof(int) * L * L); //用一个新的数组表示棋盘,以免破坏原棋盘 - c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); c[i][j] = 0; if (minmax > tree.Alpha) { @@ -183,23 +250,12 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) AI_y = tree.Y; return tree.Alpha; } - } +*/ + + + - -int neighbor(int x,int y)//判断空位置两步之内是否有邻居 -{ - for (int di = 0;di < 8;di++)//i表示八个方向 - for (int dj = 1;dj < 3;dj++)//j表示沿这个方向走了几步 - { - int dx = x + dj * dir[di][0]; - int dy = y + dj * dir[di][1]; - if (dx > 0 && dx < L + 1 && dy>0 && dy < L + 1) - if (board[dx][dy] == red || board[dx][dy] == white) - return 1; - } - return 0; -} diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.h" "b/\345\256\236\351\252\214/BetaGo/max-min.h" new file mode 100644 index 00000000..8cad02cf --- /dev/null +++ "b/\345\256\236\351\252\214/BetaGo/max-min.h" @@ -0,0 +1,16 @@ +#pragma once +#define PTIF 2147483647//正无穷,Beta +#define NGIF -2147483648//负无穷,Alpha + +int search(int x, int y, int me, int vis[][L + 2], int copy[][L + 2]); +int minMax_AB(int deep, int me, int Alpha, int Beta, int tmp_board[][L + 2]); +int evaluate(int me, int copy[][L + 2]); +int IDDFS(); + +typedef struct +{ + int Alpha; + int Beta; + int X; + int Y; +}Tree; diff --git "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" "b/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" deleted file mode 100644 index bc2ea03a..00000000 --- "a/\345\256\236\351\252\214/BetaGo/\344\272\224\345\255\220\346\243\213.c" +++ /dev/null @@ -1,771 +0,0 @@ -/*界面文字和系统文字重叠 -悔棋擦不干净 -弹窗上的字是乱码*/ -/* -#include -#include -#include -#include -#include -#define N 65 -#define size 60 -#define L 3 - -int status[N][N]={{0},{0}};//记录棋盘情况,0无,1红棋/玩家,2为白棋/电脑 -int flag=0;//判断输赢 -int direct[2];//方向 -int Value1[N][N]={{0},{0}};//计算权值 -int Value2[N][N]={{0},{0}};//计算权值 -int regrex,regrey,regrex1,regrey1; -int count=0;//计算棋子数量 - -void chess_board();//打印棋盘 -void red_movexy();//红子棋移动光标 -void white_movexy();//白棋移动光标 -void red_chess(int x,int y);//红棋 -void white_chess(int x,int y);//白棋 -void man_man(); -void man_machine();//人机对战 -int judge_chess(int x,int y);//判断这个位置是否下过 -int judge_winner(int x,int y,int temp);//判断输赢 -void machine_attack();//电脑进攻权值 -void machine_defend();//电脑防守权值 -void find_position();//寻找最佳权值 -void Regret();//悔棋函数 - -void BackGround(unsigned int ForeColor, unsigned int BackGroundColor) //颜色 -{ - HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台的句柄 - SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10);//改变当前光标的背景和字体颜色 -} - -void gotoxy(int x, int y) //光标函数 -{ - HANDLE handle; - COORD coord; //获取坐标轴结构体 - coord.X = x; - coord.Y = y; - handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,值为-11 - SetConsoleCursorPosition(handle, coord); //移动光标到x,y处 -} - -void chess_board()//打印棋盘 -{ - int i,j; - BackGround(1, 3); - for (i = 0;i <= size / L;i++) - for(j=0;j<=size;j+=L) - { - gotoxy(j,i); - printf("|"); - } - for(i=0;i<= size / L;i++) - for(j=1;j<=size;j+=L) - { - gotoxy(j,i); - printf("--"); - } -} - -void chess_menu()//打印棋盘旁的菜单 -{ - int i,j; - for(i=1;i<=size/L;i++) - { - gotoxy(67,i); - printf("||"); - } - for(i=1;i<= size / L;i++) - { - gotoxy(67,i); - printf("||"); - } - gotoxy(69,1); - printf("--------------------"); - gotoxy(69, size / L); - printf("--------------------"); - gotoxy(75,3); - printf("模 式"); - gotoxy(75,15); - printf("提 示"); -} - -void red_movexy()//红棋移动光标 -{ - loop2:gotoxy(direct[0],direct[1]); - char key='y'; - int temp; - while(key!=' ') - { - key=_getch(); - switch(key) - { - case 'W': - case 'w': - direct[1]-=1; - if(direct[1]<=1) - direct[1]=1; - break; - case 's': - case 'S': - direct[1]+=1; - if(direct[1]>=size/L) - direct[1]= size / L; - break; - case 'a': - case 'A': - direct[0]-=L; - if(direct[0]<=2) - direct[0]=2; - break; - case 'd': - case 'D': - direct[0]+=L; - if(direct[0]>=size) - direct[0]=size; - break; - case 'q': - case 'Q': - { - int message=MessageBox(NULL,TEXT("是否确定悔棋?"),TEXT("友情提示"),MB_OKCANCEL); - if(IDCANCEL==message) - break; - if(IDOK==message) - { - Regret(); - break; - } - } - } - gotoxy(direct[0],direct[1]); - } - temp=judge_chess(direct[1],direct[0]); - if(temp==1) - { - gotoxy(70,22); - BackGround(4, 0); - printf("这里已经被人下过了"); - goto loop2; - } -} - -void white_movexy()//白棋移动光标 -{ - loop1:gotoxy(direct[0],direct[1]); - char key='y'; - int temp; - while(key!='0') - { - key=_getch(); - switch(key) - { - case 72: - direct[1]-=1; - if(direct[1]<=1) - direct[1]=1; - break; - case 80: - direct[1]+=1; - if(direct[1]>= size / L) - direct[1]= size / L; - break; - case 75: - direct[0]-=L; - if(direct[0]<=2) - direct[0]=2; - break; - case 77: - direct[0]+=L; - if(direct[0]>= size) - direct[0]= size; - break; - case 'B': - case 'b': - { - int message=MessageBox(NULL, TEXT("是否确定悔棋?"), TEXT("友情提示"),MB_OKCANCEL); - if(IDCANCEL==message)break; - if(IDOK==message)Regret();break; - } - } - gotoxy(direct[0],direct[1]); - } - temp=judge_chess(direct[1],direct[0]); - if(temp==1) - { - gotoxy(70,22); - BackGround(4, 0); - printf("这里已经被人下过了"); - goto loop1; - } -} - -void red_chess(int x,int y)//打印红棋 -{ - BackGround(4,3); - regrex=x;//记录上一落子的位置 ,方便悔棋 - regrey=y; - count++; - printf("●"); - status[x][y]=1; -} - -void white_chess(int x,int y)//打印白棋 -{ - BackGround(7,3); - regrex1=x; - regrey1=y; - printf("●"); - count++; - status[x][y]=2; -} - -void machine_chess(int x,int y)//电脑落子 -{ - BackGround(7,3); - status[x][y]=2; - regrex1=x; - regrey1=y; - count++; - gotoxy(y,x); - printf("●"); -} - -int judge_chess(int x,int y)//判断这个地方是否有棋子 -{ - if(status[x][y]==0) - return 0; - else - return 1; -} - -int judge_winner(int x,int y,int temp)//判断输赢 -{ - int i,j,n1,n2; - n1=n2=0; - for(i=x,j=y+4;j<=58;j+=4)//右 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x,j=y;j>=2;j-=4)//左 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x,j=y;i>=1;i-=2)//上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x+2,j=y;i<=30;i+=2)//下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x-2,j=y+4;i>=1&&j<=58;i-=2,j+=4)//右上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x,j=y;i<=30&&j>=2;i+=2,j-=4)//左下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - n1=n2=0; - for(i=x,j=y;i>=0&&j>=0;i-=2,j-=4)//左上 - { - if(status[i][j]==temp) - n1++; - else - break; - } - for(i=x+2,j=y+4;i<=30&&j<=58;i+=2,j+=4)//右下 - { - if(status[i][j]==temp) - n2++; - else - break; - } - if(n1+n2>=5) - return temp; - return 0; -} - -void machine_attack()//电脑进攻权值 -{ - int i1,j1; - int k1,k2,k; - for(int i=1;i<=30;i+=2) - { - for(int j=2;j<=58;j+=4) - { - if(status[i][j]) - Value1[i][j]=0; - if(status[i][j]==0) - { - k1=k2=0; - for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k1++; - else - break; - } - for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k2++; - else - break; - } - k=k1>k2? k1:k2; - k1=k2=0; - for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k1++; - else - break; - } - for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1? k:k1; - k1=k2=0; - for(i1=i-2,j1=j-4;i1>=0&&j1>=0;i1-=2,j1-=4)//往左上数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k1++; - else - break; - } - for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找电脑棋子数 - { - if(status[i1][j1]==2 ) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1?k:k1; - k1=k2=0; - for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k1++; - else - break; - } - for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找电脑棋子数 - { - if(status[i1][j1]==2) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1?k:k1; - switch(k) - { - case 3: - Value1[i][j]=15;break; - case 4: - Value1[i][j]=25;break; - default: - Value1[i][j]=3+2*k;break; - } - } - } - } -} - -void machine_defend()//防守权值 -{ - int i1, j1; - int k1,k2,k; - for(int i=1;i<=30;i+=2) - { - for(int j=2;j<=58;j+=4) - { - if(status[i][j]) - Value2[i][j]=0; - if(status[i][j]==0) - { - k1=k2=0; - for(i1=i,j1=j-4;j1>=2;j1-=4)//往左数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k1++; - else - break; - } - for(i1=i,j1=j+4;j1<=58;j1+=4)//往右数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k2++; - else - break; - } - k=k1>k2? k1:k2; - k1=k2=0; - for(i1=i-2,j1=j;i1>=1;i1-=2)//往上数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k1++; - else - break; - } - for(i1=i+2,j1=j;i1<=30;i1+=2)//往下数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1?k:k1; - k1=k2=0; - for(i1=i-2,j1=j-4;i1>=1&&j1>=2;i1-=2,j1-=4)//往左上数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k1++; - else - break; - } - for(i1=i+2,j1=j+4;i1<=30&&j1<=58;i1+=2,j1+=4)//往右下数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1?k:k1; - k1=k2=0; - for(i1=i+2,j1=j-4;i1<=30&&j1>=2;i1+=2,j1-=4)//往左下数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k1++; - else - break; - } - for(i1=i-2,j1=j+4;i1>=1&&j1<=58;i1-=2,j1+=4)//往右上数寻找玩家棋子数 - { - if(status[i1][j1]==1) - k2++; - else - break; - } - k1=k1>k2? k1:k2; - k=k>k1?k:k1; - switch(k) - { - case 3: - Value2[i][j]=10;break; - case 4: - Value2[i][j]=20;break; - default: - Value2[i][j]=2+k*2; - } - } - } - } -} - -void find_position()//找到最有价值的位置 -{ - int k1=0, k2=0; - int i, j, max=0; - for( i=1;i<=30;i+=2) - for( j=2;j<=58;j+=4) - { - if(max<=Value1[i][j]) - { - max=Value1[i][j]; - k1=i; - k2=j; - } - } - for( i=1;i<=30;i+=2) - for( j=2;j<=58;j+=4) - { - if(max<=Value2[i][j]) - { - max=Value2[i][j]; - k1=i; - k2=j; - } - } - direct[1]=k1; //将找到的位置传给光标 - direct[0]=k2; -} - -void man_man()//人人对战模式 -{ - loop5:system("cls"); - char key; - int control; - gotoxy(2, 3); - printf("1.红 子 先 手"); - - gotoxy(2, 5); - printf("2.白 子 先 手"); - - gotoxy(2, 7); - printf("(输入相应序号选择)"); - key=_getch(); - system("cls"); - if(key=='1') - control=1; - else if(key=='2') - control=-1; - else - goto loop5; - gotoxy(70,5); - printf(" 人 人 对 战 "); - direct[1]=15; - direct[0]=30; - chess_menu(); - chess_board(); - while(flag==0) - { - if(control==1) - { - gotoxy(70,22); - BackGround(6,0); - printf(" 红 子 执 手 "); - red_movexy(); - red_chess(direct[1],direct[0]); - flag=judge_winner(direct[1],direct[0],1); - } - else - { - gotoxy(70,22); - BackGround(6,0); - printf(" 白 子 执 手 "); - white_movexy(); - white_chess(direct[1],direct[0]); - flag=judge_winner(direct[1],direct[0],2); - } - control=-control; - } - if(flag==1) - { - BackGround(7,0); - MessageBox(NULL,TEXT("游戏结束,红子胜利"),TEXT("五子棋游戏"),MB_OK); - } - if(flag==2) - { - MessageBox(NULL,TEXT("游戏结束,白子胜利"),TEXT("五子棋游戏"),MB_OK); - } - if(count>=225) - { - MessageBox(NULL,TEXT("游戏结束,平局"),TEXT("五子棋游戏"),MB_OK); - } -} - -void man_machine()//人机对战模式 -{ - loop6:system("cls"); - char key; - int control; - gotoxy(2, 3); - printf("1.玩 家 先 手(玩家为红子)"); - - gotoxy(2, 5); - printf("2.电 脑 先 手(电脑为白子)"); - - gotoxy(2, 7); - printf("(输入相应序号选择)"); - key=_getch(); - system("cls"); - if(key=='1') - control=1; - else if(key=='2') - { - control=1; - machine_chess(13,26); - } - else - goto loop6; - gotoxy(70,5); - printf(" 人 机 对 战 "); - direct[1]=15; - direct[0]=30; - chess_menu(); - chess_board(); - while(flag==0) - { - if(control==1) - { - gotoxy(70,size/L-5); - BackGround(6,0); - printf(" 玩 家 执 手 "); - red_movexy(); - red_chess(direct[1],direct[0]); - flag=judge_winner(direct[1],direct[0],1); - } - else - { - gotoxy(70,size/L-5); - BackGround(6,0); - printf(" 电 脑 执 手 "); - machine_defend(); - machine_attack(); - find_position(); - machine_chess(direct[1],direct[0]); - flag=judge_winner(direct[1],direct[0],2); - } - control=-control; - } - gotoxy(8,18); - if(flag==1) - { - BackGround(7,0); - MessageBox(NULL,TEXT("太厉害了,您战胜了电脑!"),TEXT("五子棋游戏"),MB_OK); - } - if(flag==2) - { - MessageBox(NULL,TEXT("游戏结束,您输给了电脑"),TEXT("五子棋游戏"),MB_OK); - } - if(count>=225) - { - MessageBox(NULL,TEXT("平局"),TEXT("五子棋游戏"),MB_OK); - } -} - -void Regret()//悔棋函数 -{ - gotoxy(regrey,regrex); - BackGround(0,0); - printf(" "); - status[regrex][regrey]=0; - gotoxy(regrey1,regrex1); - BackGround(0,0); - printf(" "); - status[regrex1][regrey1]=0; - count-=2; -} - -void welcome()//游戏菜单 -{ - int k; - char choose; - system("cls"); - for(k=2;k<=16;k+=2)//游戏菜单 - { - gotoxy(5,k); - printf("|-----------------|"); - } - gotoxy(5, 3); - printf("| 五 子 棋 游 戏 |"); - - gotoxy(5, 5); - printf("| 菜 单 |"); - - gotoxy(5, 7); - printf("| 1.人 人 对 战 |"); - - gotoxy(5, 9); - printf("| 2.人 机 对 战 |"); - - gotoxy(5, 11); - printf("| 3.游 戏 帮 助 |"); - - gotoxy(5, 13); - printf("| 4.更 新 日 志 |"); - - gotoxy(5, 15); - printf("| 5.退 出 游 戏 |"); - - gotoxy(5, 18); - printf("温馨提示:输入菜单对应序号进行操作"); - - gotoxy(5, 20); - printf("祝您游戏愉快!"); - - gotoxy(20, 20); -} - -char Gametips()//游戏帮助 -{ - char choose; - int key; - - system("cls"); - - gotoxy(2, 3); - printf("游戏操作:"); - - gotoxy(4, 5); - printf("① 红色棋子WASD移动光标选择下棋位置,按空格键确认,按Q悔棋"); - - gotoxy(4, 7); - printf("② 白色棋子↑↓←→移动光标选择下棋位置,按0确认,按B悔棋"); - - gotoxy(2, 19); - printf("(按E键返回,按其它任意键退出)"); - - return _getch(); -} - - -int main() -{ - system("title 五子棋"); - system("mode con cols=92 lines=33"); - system("color F0"); - char choose,temp; - loop:welcome(); - choose=_getch(); - switch(choose) - { - case '1': - man_man(); - break; - case '2': - man_machine(); - break; - case '3': - temp=Gametips(); - if(temp=='E'||temp=='e') - goto loop; - break; - case '5': - { - int message = MessageBox(NULL, "是否退出?", "友情提示", MB_OKCANCEL); - if (IDCANCEL == message) - goto loop; - if (IDOK == message)break; - } - - } -} - -*/ diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" "b/\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" new file mode 100644 index 00000000..25822718 --- /dev/null +++ "b/\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" @@ -0,0 +1,162 @@ +#include +#include +#include //不要忘记引入预编译头文件 +#define L 15 +typedef struct chess //设置了一个棋type 的结构类型 +{ + int x; + int y; +}CHESS; +//全局变量 +CHESS bla; +int judge[19 * 30][19 * 30]; +int count = 0;//计数器:判断下哪种棋子 +int flag = 0;//判断游戏是否结束 +void chessboard()//画棋盘背景 +{ + int step = 30; + // 初始化绘图窗口 + initgraph(800, 600); + // 设置背景色为蓝色 + setbkcolor(YELLOW); + // 用背景色清空屏幕 + cleardevice(); + + setlinestyle(PS_SOLID, 2); // 画实线,宽度为2个像素 + setcolor(RGB(0, 0, 0)); // 设置为黑色 + outtextxy(600, 100, _T("W,A,S,D实现位置移动")); + outtextxy(600, 120, _T("G键下棋子")); + + int i, j; + for (i = 1; i <= L; i++) // 画横线和竖线 + { + line(i * step, 1 * step, i * step, L * step); + line(1 * step, i * step, L * step, i * step); + + } + for (i = 0; i <= L; i++) + for (j = 0; j <= L; j++) + judge[i][j] = 0;//初始化坐标判断 + bla.x = 10 * 30; + bla.y = 10 * 30;//初始化棋子坐标 +} +int inputchess(CHESS temp, int color, int t) +{ + bla = temp; + setcolor(color); + setfillcolor(color); + if (bla.x <= L * 30 && bla.y <= L * 30) + fillcircle(bla.x, bla.y, 12); + judge[bla.x][bla.y] = t;//作标记 + int i, j, f; + for (i = 0; i < L; i++) //判断是否有一方胜利 + {/*横向*/ + j = f = 0; + while (f < 5 && j < L) + { + if (judge[i * 30][j * 30] == t) f++; + else f = 0; + j++; + } + if (f == 5) return t; + } + for (j = 0; j < L; j++) + {/*竖向*/ + i = f = 0; + while (f < 5 && i < L) + { + if (judge[i * 30][j * 30] == t) f++; + else f = 0; + i++; + } + if (f == 5) return t; + } + for (i = 0; i < 12; i++) + {/*下斜*/ + j = f = 0; + while (f < 5 && j < 15) + { + if (judge[(i + f) * 30][(j + f) * 30] == t) f++; + else { f = 0; j++; } + } + if (f == 5) return t; + } + for (i = 4; i < 19; i++) + {/*上斜*/ + j = f = 0; + while (f < 5 && j < 12) + { + if (judge[(i - f) * 30][(j + f) * 30] == t) f++; + else { f = 0; j++; } + } + if (f == 5) return t; + } + return 0; +} + +void cursor()//光标函数 +{ + setcolor(RED); + setfillcolor(WHITE); + setwritemode(R2_XORPEN);//二进制模式绘图,便于光标的清除 + CHESS cur = bla; + char c = ' '; + fillcircle(cur.x, cur.y, 4); + while (c != 'g') + { + c = _getch(); + switch (c) + { + case 'a':fillcircle(cur.x, cur.y, 4); cur.x -= 30; fillcircle(cur.x, cur.y, 4); break; + case 'd':fillcircle(cur.x, cur.y, 4); cur.x += 30; fillcircle(cur.x, cur.y, 4); break; + case 'w':fillcircle(cur.x, cur.y, 4); cur.y -= 30; fillcircle(cur.x, cur.y, 4); break; + case 's':fillcircle(cur.x, cur.y, 4); cur.y += 30; fillcircle(cur.x, cur.y, 4); break; + } + } + if (judge[cur.x][cur.y] != 0) + { + count--; + fillcircle(cur.x, cur.y, 4); + } + else + { + int i, j, f; + if (count % 2 == 0) + { + fillcircle(cur.x, cur.y, 4); + flag = inputchess(cur, YELLOW, 2); + if (flag == 2) + { + setcolor(BLACK); + outtextxy(640, 300, _T("黑棋赢!")); + printf("\n\n\n黑棋赢啦!\n\n\n\n\n\n"); + } + } + else + { + fillcircle(cur.x, cur.y, 4); + flag = inputchess(cur, GREEN, 1); + if (flag == 1) + { + outtextxy(640, 300, _T("红棋赢!")); + printf("\n\n\n红棋赢啦!\n\n\n\n"); + + } + } + } + count++; +} + +int main() +{ + chessboard(); + while (true) + { + cursor(); + if (flag == 1 || flag == 2) + break; + } + _getch(); + closegraph(); + return 0; +} diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" new file mode 100644 index 00000000..b2d20bd3 --- /dev/null +++ "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" @@ -0,0 +1,31 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31321.278 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chess_GUI", "Chess_GUI.vcxproj", "{6F592C46-8C4E-45CC-BBD7-45A519F7877E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x64.ActiveCfg = Debug|x64 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x64.Build.0 = Debug|x64 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x86.ActiveCfg = Debug|Win32 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x86.Build.0 = Debug|Win32 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x64.ActiveCfg = Release|x64 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x64.Build.0 = Release|x64 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x86.ActiveCfg = Release|Win32 + {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {496FFC51-7EC7-4035-A003-205DFF047780} + EndGlobalSection +EndGlobal diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" new file mode 100644 index 00000000..eeff5be7 --- /dev/null +++ "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" @@ -0,0 +1,148 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {6f592c46-8c4e-45cc-bbd7-45a519f7877e} + ChessGUI + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" new file mode 100644 index 00000000..a988c855 --- /dev/null +++ "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" @@ -0,0 +1,25 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" new file mode 100644 index 00000000..88a55094 --- /dev/null +++ "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" @@ -0,0 +1,4 @@ +锘 + + + \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/priority.c" "b/\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/priority.c" rename to "\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" diff --git "a/\345\256\236\351\252\214/README.md" "b/\345\256\236\351\252\214/README.md" new file mode 100644 index 00000000..8fea8de8 --- /dev/null +++ "b/\345\256\236\351\252\214/README.md" @@ -0,0 +1,382 @@ +# 浜斿瓙妫婣I + +## 鐣岄潰 + + `json` + +涓轰簡濂借璁$畻娉曪紝鐢ㄦ暟缁勫瓨鍌ㄦ鐩橈紝浠庡瓨鍌ㄦ暟缁勫埌鎵撳嵃鐨勬鐩樹箣闂磋閫氳繃杞崲鍑芥暟 + +鐢绘鐩橈紝15*15 鍏惰涓嬪湪浜ょ晫鐐逛笂 + +column锛60/4=15锛屽垎鐣岀嚎鍗犱竴涓瓧绗︼紝姣忎釜妫嬫牸鏄3涓瓧绗﹀搴 + +row锛30/2=15锛屽垎鐣岀嚎鍦ㄦ渶涓婄 + +鏁扮粍锛0-16锛0,16杈圭晫锛屾鐩樻槸1-15锛 + +锛1,1锛--锛1,0锛 + +gotoxy鍧愭爣鍜屾暟缁勭储寮曚箣闂磋璋冩崲锛岃--y锛屽垪--x + +瀹氫綅鍔熻兘 + +## 绠楁硶 + +瑙勫垯锛氫簲瀛愭15*15 + +骞宠 鍏堟墜浼樺娍锛屽弻3绂佹墜锛岃蛋浜旀鎹㈡ + +### 鏆村姏閬嶅巻鐪嬭繛瀛 + +鍏ㄩ儴閬嶅巻涓閬嶏紝姣忎釜绌轰綅瀛愮湅妯珫鎾囨嵑锛屼笂涓嬶紝宸﹀彸锛屾枩鐫鍒嗗埆姣旇緝閫夋渶澶у糼锛宬鐨勬渶澶у艰涓簐alue锛屽垎鍒畻鐢佃剳鐨剉alue浣滀负杩涙敾鍊硷紝鐜╁鐨剉alue浣滀负闃插畧鎸 + +锛侊紒鍙冭檻浜嗚繛瀛愶紝瀹屽叏娌¤冭檻甯冨眬闂 + +鍒ゆ柇杈撹耽锛屽彧鐢ㄧ湅鏂颁笅鐨勮繖棰楁瀛愮殑妯珫鎾囨嵑鏈夋棤鎴愪簲娲诲洓 + + + +### max-min鍒嗘暟璇勪及 + +浼唬鐮 + +閫掑綊浠g爜鐨勯瓍鍔涳紝绠鐭殑浠g爜娴撶缉浜嗗緢寮虹殑閫昏緫 + +娉ㄦ剰杩欐槸涓涓掑綊锛岀涓娆¤緭鍏ユ悳绱㈡繁搴︽槸4锛岀劧鍚庡啀閬囧埌minimax锛宒epth-1锛屽線涓嬮捇涓灞傦紝鏈鍚庨捇鍒版渶娣变竴灞傦紝杩斿洖褰撳墠璇勫垎锛岀劧鍚庨掑綊鍥炴函锛屽紑濮嬪仛min-max鍐崇瓥銆 + +#### 鍗氬紙鏍 + +鍏堜笉绠″喅绛栵紝鎵惧埌鎵鏈夊彲鑳界殑鎯呭喌锛岀敓鎴愬喅绛栨爲锛屼笉鑳藉湪鏈搴曞眰灏遍変竴涓兼渶澶х殑锛屽洜涓哄弻鏂瑰喅绛栫殑鍘熷洜涓嶅彲鑳借揪鍒 + +鍐嶈冭檻涓や釜浜虹殑绛栫暐锛屼粠鍙跺瓙缁撶偣寮濮嬩粠涓嬪線涓婂仛min-max鍐崇瓥锛屽緱鍒板湪鑰冭檻鍐崇瓥鐨勬儏鍐典笅鐨勬渶浼樿蛋娉 + +#### AB鍓灊 + +伪鍜屛叉槸鏈夌敤鑺傜偣鐨勪笂涓嬬晫锛屾湁鐢ㄧ殑鑺傜偣涓瀹氬湪杩欎釜涓婁笅鐣屼箣闂达紝鏇存柊鑺傜偣锛岃妭鐐筆鏄痬in锛孭鐨勭埗鑺傜偣Q鏄痬ax锛孭鐨勪笅鐣屛=Q鐨勪笅鐣屛诧紱瀛愯妭鐐筊鏄痬ax锛孭鐨勪笂鐣=R鐨勪笂鐣 + +鍒ゆ柇 + +纭畾鏈夌敤 + +鏇存柊鐖惰妭鐐 + +#### 鏁寸洏妫嬭瘎浼 + +琛ㄧず鏁寸洏妫嬪眬 + +15*15鐨勪簩缁存暟缁 + +鎬庝箞鎵惧嚭杩炲瓙 + +閬嶅巻锛熶粠姣忎釜鐐瑰嚭鍙戝墠鍚庡乏鍙筹紝寰堝鏉 + +鐩存帴瀛樺偍锛屾í绔栨拠鎹洪兘瀛樺偍鎴愪竴缁存暟缁 + +鍒嗘暟鐨勮〃绀哄拰璁$畻 + +1.缁欎竴浜涙儏鍐垫墦鍒 + +锛熶笉鏄繛鐫鐨 + +- 鎴愪簲锛100000 +- 娲诲洓, 10000 +- 娲讳笁 1000 +- 娲讳簩 100 +- 娲讳竴 10 + +濡傛灉涓渚ц灏佹浣嗘槸鍙︿竴渚ф病鏈夛紝鍒欒瘎鍒嗛檷涓涓。娆★紝涔熷氨鏄鍥涘拰娲讳笁鏄浉鍚岀殑鍒 + +- 姝诲洓, 1000 +- 姝讳笁 100 +- 姝讳簩 10 + +2.缁煎悎鑰冭檻鐢佃剳鍜岀帺瀹 + +鎸夌収杩欎釜瑙勫垯鎶婃鐩樹笂鐢佃剳鐨勬墍鏈夋瀛愭墦鍒嗭紝涔嬪拰鍗充负鐢佃剳鐨勫崟鏂归潰寰楀垎 `scoreComputer`锛岀劧鍚庡鐜╁鐨勬瀛愬悓鏍锋墦鍒 寰楀埌 `scoreHuman`銆 + +`scoreComputer - scoreHuman` 鍗充负褰撳墠灞鍔跨殑鎬诲垎鏁 + +鐢ㄤ竴鑸殑閬嶅巻鏂规硶 + +妯珫鏂滃悇閬嶅巻涓娆★紝鍥涙閬嶅巻浼氭妸涓棰楁瀛愮畻鍥涙 + +閬嶅巻涓娆★紝鎵惧埌妫嬪瓙鍚庢í绔栨枩鐫妫鏌ワ紝鍚屼竴棰楁瀛愪細琚鍒嗗緢澶氭 + +##### 杩炲瓙鎼滅储 + +鍐欏叓涓柟鍚戝彉鎴愮敤寰幆閬嶅巻鍏釜鏂瑰悜绠鍖栦唬鐮 + +瀹冩部鐫涓鏉¤矾涓鐩磋蛋涓嬪幓锛岀洿鍒拌蛋涓嶅姩浜嗙劧鍚庤繑鍥炰笂涓涓矓璺彛閫夋嫨鍙︿竴鏉¤矾缁х画鍓嶈繘锛屼竴鐩村姝わ紝鐩村埌璧板畬鎵鏈夎兘澶熷埌杈剧殑鍦版柟锛 + +娌跨潃涓鏉¤矾寰勫叆鏍 + +璇ヨ妭鐐规病鏈夎繛鍏跺畠鍒嗘敮-->鍑烘爤锛岃繛浜嗗叾浠栬妭鐐-->鍏朵粬鑺傜偣鍏ユ爤 + +1.閬嶅巻妫嬪眬鎵惧埌榛戝瓙锛岃繘鍏fs + +2.浠庤繖棰楀瓙鍚戝叓涓柟鍚戞悳绱紝鎵惧埌杩炲瓙鏈澶氱殑鏂瑰悜璁板綍寰楀垎锛屾悳绱㈣繃鐨勫氨鏍囪涓婏紝涓嶅啀浣滀负鎼滅储鐨勮捣鐐 + +3.閬嶅巻瀹屽叓涓柟鍚戜箣鍚庯紝鍒ゆ柇姝绘椿锛岃褰曡繖棰楁瀛愬凡缁忚閬嶅巻杩囦簡锛寁is鍜宐oard涓鑷(vis鍦ㄥ嚱鏁颁腑鍒濆鍖栵紝姣忔璇勪及閮借鍏堝垵濮嬪寲涓0) + +鎬绘槸寮澶寸殑绗竴棰楁渶鍏堣閬嶅巻鍒板悧? + +BFS + +闃熷垪缁撴瀯 + +generator + +鏄惁鏈夐偦灞咃紝鏈夐偦灞呭氨杩涘叆璇勪及鍑芥暟锛岃屼笉鏄繘鍏ヨ瘎浼颁箣鍚庡啀鍒ゆ柇閭诲眳 + +#### IDDFS + +AI濂藉儚鑸嶈繎鍙栬繙锛屽湪鑰嶆垜锛 + +explain锛欰I鍙瘮杈冩渶缁堢粨鏋滐紝骞舵病鏈夎冭檻鍒拌矾寰勯暱鐭傞殢鏈洪夋嫨鑳借耽鐨勮蛋娉曪紝缁曚簡杩滆矾 + +鎵浠ヨ繖閲屾垜浠畾涔変竴涓渶浼樿В鐨勬蹇碉細鍒嗘暟鏈楂樼殑璧版硶涓矾寰勬渶鐭殑閭d竴涓蛋娉曘傞偅涔堢幇鍦ㄩ棶棰樺氨鏄垜浠浣曟壘鍒版渶浼樿В銆 + +iddfs鏄竴绉嶄豢bfs锛屾椂闂翠笉姣攂fs鎱㈠緢澶氾紝浣嗘槸鑺傜渷绌洪棿 + +dfs鐨勬悳绱㈡柟寮忓拰閫掑綊绋嬪簭缁撳悎璧锋潵鐞嗚В + +璁剧疆浼樺厛鎯呭喌杩斿洖IDDFS娌¤捣浣滅敤锛屽洜涓轰笉鏄涓涓悳绱㈠埌鏉妫嬬殑锛屼篃娌℃湁杩斿洖0 + +#### 鍚彂寮忔悳绱 + +鐢熸垚鍙悳绱㈢殑绌轰綅+鎺掑簭 + +鎼滅储閭诲眳浣嶇疆 + +蹇帓 qsort + +## 瀛︿範鑳藉姏 + +## bug list + +- [x] 鏄剧ず杩欓噷宸茬粡琚笅杩囦簡锛 + + 绉诲姩鍏夋爣鐨勫嚱鏁板嚭闂锛実otoxy瀵瑰簲浣嶇疆涓巌锛宩鐨勫叧绯诲嚭閿 + +- [x] AI涓鐩翠笅鍦ㄤ竴涓湴鏂 + +- [x] 涓ゅご閮藉牭姝讳簡杩樺線涓棿涓嬶紵 + + 鏀硅繘evaluate鍑芥暟锛屽鏋滀袱渚ч兘琚皝姝伙紝闄ら潪鏄凡鏈変簲棰楁瀛愶紝鍚﹀垯杩炴娌℃湁鎰忎箟寰楀垎涓0 + +- [x] 妫嬬洏浼犲弬澶辫触锛屾兂淇濇姢鍘熸湁鐨勬鐩橈紝鍦ㄥ仛minmax鏃舵柊寤烘鐩樻嫹璐 + +- [x] is_neighbor蹇呴』瑕佷紶鍙傦紝杩涘埌鍐崇瓥鏍戦噷闈箣鍚庝笉鑳界敤board鏉ュ垽鏂紱judge_winner涔熻浼犲弬 + +- [x] 宸﹁竟杈圭晫鏈塨ug锛屽垽鏂竟鐣屽嚭閿欙紝clearlocation鐨勬椂鍊欒娓呴櫎浜 + + 濡傛灉鍧愭爣鍑虹幇璐熷硷紝鍏夋爣灏变細鍦ㄥ師鏉ョ殑浣嶇疆锛屼笉绉诲姩 + + 缁檆learlocation鍔犱笂鑼冨洿 + +- [x] 宸茬粡鏈夋椿鍥涗笉缁х画涓嬩簡锛屽鏂规湁娲诲洓浜嗕笉鍫 + + 1锛塭valuate涓湁杩炴垚浜斿氨涓嶇敤鍐嶇湅澶村熬鏄惁鍫垫浜嗭紝鎶婃垚浜旂殑鍒嗗煎姞鍒版渶鏈澶 + + 2锛塵inmax鍑芥暟涓姞涓婃垚浜斿氨鐩存帴閫鍑-->杩唬鍔犳繁 + + + + +## To-do list + +- [x] 瀹炵幇鍒ゆ柇杈撹耽 + + 鐢ㄥ垎鏁板垽鏂紵鍒╃敤璇勪及涓殑缁撴灉鍓煭鏃堕棿 + + 浠庢柊涓嬬殑杩欓妫嬪瓙寮濮嬮亶鍘嗘悳绱 + +- [x] 瑕佹庝箞閬嶅巻妫嬬洏锛屾椿涓琚噸澶嶇畻浜嗭紵 + + DFS锛屽叓涓柟鍚戜笂杩炲瓙鏈澶氱殑璁板垎锛岃屼笖杩欎簺瀛愪笉鍐嶉噸澶嶅仛璧风偣鎼滅储 + +- [x] 閬嶅巻鐨勮竟鐣岋紵 + + 鐢3琛ㄧずwall + +- [x] 鍒ゆ柇鏈夋棤閭诲眳锛岃竟鐣屾庝箞绠 + +- [x] 濂囨暟灞傛槸min锛宔valuate瑕佺浉鍑 + +- [ ] 鍫电殑鏃跺欓殧浜嗕竴棰楁瀛 鍒ゆ柇姝绘椿value涓嶇敤+1 + +- [x] 璁剧疆涓浜涗紭鍏堟儏鍐 + +- [x] 鎮旀鍔熻兘 + +- [ ] 瀹屽杽浜烘満瀵规垬鍔熻兘鍜岀晫闈 + +- [ ] 鍚彂寮忔悳绱 + + 鐢熸垚绌轰綅缃兘涓嶈兘浠呯敓鎴愪竴娆 + + + + +## 椤圭洰鎰熸偀 + +澶氭枃浠 + +澶存枃浠朵腑澹版槑鍏ㄥ眬鍙橀噺锛坋xtern锛夛紝澹版槑鍑芥暟锛屼笉瑕佸湪澶存枃浠朵腑瀹氫箟锛屼細鍦╨ink鏃堕噸瀹氫箟鎶ラ敊 + +鍒嗚В闂锛宼o-do list + +绋嬪簭鐨勯珮绾ф + +瀹屽鎬э細鐗规畩鎯呭喌鐨勫鐞嗭紝杈圭晫 + +澶ч」鐩厧鐢ㄥ叏灞鍙橀噺 + +椤圭洰鐨勬ā鍧楀寲鎷嗚В + +涔嬪墠璇勪及鍑芥暟鐨勫熀纭 + +鐡堕 + +![image-20210611164858685](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210611164858685.png) + +![image-20210611162646865](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210611162646865.png) + +![image-20210523192853958](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523192853958.png) + +![image-20210523121456857](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523121456857.png) + +![image-20210523094842624](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523094842624.png) + +![image-20210523102221522](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523102221522.png) + +宸叉湁娲诲洓鍗存病鏈夌户缁笅锛宔valuate鍑芥暟鐨勪及鍒嗘柟寮忔湁闂 + +![image-20210523121706279](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523121706279.png) + +鍦╩in_max閲屽姞涓婁紭鍏堟儏鍐碉紝鍙兘琚壀鏋濆壀鎺変簡 + +![image-20210523101848152](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523101848152.png) + +![image-20210606193743892](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210606193743892.png) + +![image-20210608132439531](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210608132439531.png)涓棿鐣欑┖鐢佃剳閫夋嫨浜嗗欢闀胯嚜宸辩殑娲讳笁 + +```c +function alphabeta_minmax(node, depth, 伪, 尾, Player) + if depth = 0 or node is a terminal node//閫掑綊缁堟鏉′欢锛屾悳绱㈠埌鏈娣变竴灞傚氨鍋滄鎼滅储锛岃繑鍥炶瘎浼 + return the heuristic value of node + if Player = MaxPlayer //鍒ゆ柇鏄帺瀹惰繕鏄疉I鍋氬喅绛栵紝AI鍐崇瓥鍒欎负max灞傦紝鐜╁鍐崇瓥鍒欎负min灞 + //鏋佸ぇ鑺傜偣 + for each child of node//鏋佸皬鑺傜偣 + 伪 := max(伪, alphabeta(child, depth-1, 伪, 尾, not(Player) ))//鏋佸ぇ鑺傜偣 + //瀛╁瓙鑺傜偣鐨勎憋紝尾缁ф壙鑷埗鑺傜偣 + if 尾 鈮 伪 + // 璇ユ瀬澶ц妭鐐圭殑鍊>=伪>=尾锛岃鏋佸ぇ鑺傜偣鍚庨潰鐨勬悳绱㈠埌鐨勫艰偗瀹氫細澶т簬尾锛屽洜姝や笉浼氳鍏朵笂灞傜殑鏋佸皬鑺傜偣鎵閫夌敤浜嗐傚浜庢牴鑺傜偣锛屛蹭负姝f棤绌 + break (* Beta cut-off *) + return 伪 + else // 鏋佸皬鑺傜偣 + for each child of node // 鏋佸ぇ鑺傜偣 + 尾 := min(尾, alphabeta(child, depth-1, 伪, 尾, not(Player) )) // 鏋佸皬鑺傜偣 + if 尾 鈮 伪 // 璇ユ瀬澶ц妭鐐圭殑鍊<=尾<=伪锛岃鏋佸皬鑺傜偣鍚庨潰鐨勬悳绱㈠埌鐨勫艰偗瀹氫細灏忎簬伪锛屽洜姝や笉浼氳鍏朵笂灞傜殑鏋佸ぇ鑺傜偣鎵閫夌敤浜嗐傚浜庢牴鑺傜偣锛屛变负璐熸棤绌 + break (* Alpha cut-off *) + return 尾 +(* Initial call *) +alphabeta(origin, depth, -infinity, +infinity, MaxPlayer) +``` + +```c +int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L + 2]) +//鍒嗘暟浼犻,t涓1琛ㄧず绾㈡锛屼负2琛ㄧず鐧芥,璋冪敤鏃禔lpha锛孊eta璧嬩负NGIF,PTIF +{ + int i, j; + int c[L + 2][L + 2]; + int minmax; + int rival; + Tree tree; + tree.Alpha = Alpha; + tree.Beta = Beta; + tree.X = 0; + tree.Y = 0; + if (me == 1) + rival = 2; + else + rival = 1; + if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) + return evaluate(me, tmp_board) - evaluate(rival, tmp_board); + if (depth % 2 == 0)//鍒ゆ柇鏄痬in灞傝繕鏄痬ax灞,鍋舵暟鏄痬in灞 + if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) + return evaluate(me, tmp_board) - evaluate(rival, tmp_board); + if (depth % 2)//鍒ゆ柇鏄痬in灞傝繕鏄痬ax灞,濂囨暟鏄痬in灞 + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L);//鏇存柊妫嬬洏 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + if (judge_winner(i, j, white) == white && depth == rank - 1) + //浼樺厛鎯呭喌锛氬鏂瑰凡缁忔湁娲诲洓灏卞繀椤诲牭 + + { + AI_x = j; + AI_y = i; + return 0; + } + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + c[i][j] = 0; + if (minmax < tree.Beta) + { + tree.Beta = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Alpha;//伪鍓灊锛屾姏寮冨悗缁妭鐐 + } + } + } + return tree.Beta; + } + else + { + for (i = 1;i < L + 1;i++) + for (j = 1;j < L + 1;j++) + { + if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) + { + memcpy(c, tmp_board, sizeof(int) * L * L); + //鐢ㄤ竴涓柊鐨勬暟缁勮〃绀烘鐩橈紝浠ュ厤鐮村潖鍘熸鐩 + c[i][j] = me; + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + if (judge_winner(i, j, red) == red && depth == rank) + //浼樺厛鎯呭喌锛氳嚜宸卞凡缁忔湁娲诲洓灏卞繀椤绘帴鐫涓 + { + AI_x = j; + AI_y = i; + return 0; + } + minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); + c[i][j] = 0; + if (minmax > tree.Alpha) + { + tree.Alpha = minmax; + tree.X = j; + tree.Y = i; + if (tree.Alpha >= tree.Beta) + return tree.Beta;//伪鍓灊锛屾姏寮冨悗缁妭鐐 + } + } + } + AI_x = tree.X; + AI_y = tree.Y; + return tree.Alpha; + } +} +``` + +![image-20210613213456813](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210613213456813.png) + From 1add4f54fb6dec5b85904198d80de61c0d694eca Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Thu, 17 Jun 2021 21:29:55 +0800 Subject: [PATCH 18/19] =?UTF-8?q?[=E7=AE=80=E5=8C=96=E7=9A=84=E7=AE=97?= =?UTF-8?q?=E6=9D=80+GUI]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\345\256\236\351\252\214/BetaGo/Chess.c" | 63 ++++++++- "\345\256\236\351\252\214/BetaGo/Chess.h" | 3 +- "\345\256\236\351\252\214/BetaGo/GUI.c" | 34 +++-- "\345\256\236\351\252\214/BetaGo/heuristic.c" | 79 ++++++++--- "\345\256\236\351\252\214/BetaGo/heuristic.h" | 25 ++-- "\345\256\236\351\252\214/BetaGo/max-min.c" | 126 +++++------------- "\345\256\236\351\252\214/README.md" | 126 ++++-------------- 7 files changed, 214 insertions(+), 242 deletions(-) diff --git "a/\345\256\236\351\252\214/BetaGo/Chess.c" "b/\345\256\236\351\252\214/BetaGo/Chess.c" index 6deccd3b..1853fb25 100644 --- "a/\345\256\236\351\252\214/BetaGo/Chess.c" +++ "b/\345\256\236\351\252\214/BetaGo/Chess.c" @@ -1,4 +1,5 @@ #include "Chess.h" +#include "max-min.h" int board[L+2][L+2];//表示棋盘的二维数组 @@ -6,6 +7,7 @@ int AI_x=0, AI_y=0;//记录AI本轮下棋的位置 int man_x=0, man_y=0;//man_y=i,man_x=j +int man2_x=0, man2_y=0; //board[i][j]与position之间的关系gotoxy(4 * man_x, 2 * (man_y-1) + 1) int dir[][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };//表示八个方向的常量数组 @@ -26,10 +28,10 @@ void board_init() } } //实现人控制的光标移动和下棋 -void man_move()//白棋移动光标 +void man_move()//人类玩家移动光标,为了在人人对战时实现可以由两位玩家操控,这里用指针传递位置坐标实现多态 { loop1:location(man_x, man_y,white); - gotoxy(4 * man_x , 2 * (man_y - 1) + 1); + gotoxy(4 * (man_x) , 2 * (man_y - 1) + 1); char key='y'; while(key!=' ') { @@ -73,7 +75,7 @@ loop1:location(man_x, man_y,white); } } location(man_x, man_y,white); - gotoxy(4 * man_x, 2 * (man_y-1) + 1); + gotoxy(4 * (man_x), 2 * (man_y-1) + 1); } if (board[man_y][man_x]) { @@ -93,7 +95,8 @@ loop1:location(man_x, man_y,white); //实现AI控制的光标移动和下棋 void machine_move()//打印AI的棋子的函数,机器用红子,玩家用白子 { - IDDFS(); + //IDDFS(); + minMax_AB(rank, red, NGIF, PTIF, board); clearlocation(man_x, man_y); board[AI_y][AI_x] = red; location(AI_x, AI_y, red); @@ -140,6 +143,7 @@ loop1:location(man_x, man_y,white); //实现人机对战功能的函数 void man_machine()//人机对战模式 { + system("color F2"); loop6:system("cls"); char key; int control; @@ -162,7 +166,8 @@ loop1:location(man_x, man_y,white); { printf("请重新输入"); goto loop6; - } + } + system("color 0F"); gotoxy(70,5); printf(" 人 机 对 战 "); man_y=7; @@ -215,7 +220,47 @@ loop1:location(man_x, man_y,white); //实现人与人对战功能的函数 void man_man() { - + char key; + int control=1; + system("cls"); + gotoxy(70, 5); + printf(" 人 人 对 战 "); + man_y = 7; + man_x = 8; + man2_y = 7; + man2_x = 8; + chess_board(); + board_init(); + chess_menu(); + while (flag == 0) + { + if (control == 1) + { + gotoxy(70, 22); + BackGround(6, 0); + printf(" 玩 家1 执 手 "); + man_move(); + flag = judge_winner(man_x, man_y, white, board); + } + else + { + gotoxy(70, 22); + BackGround(6, 0); + printf(" 玩 家2 执 手 "); + man_move(); + flag = judge_winner(man2_x, man2_y, red, board); + } + control = -control; + } + if (flag == 1) + { + BackGround(7, 0); + MessageBox(NULL, TEXT("游戏结束,红子胜利"), "五子棋游戏", MB_OK); + } + if (flag == 2) + { + MessageBox(NULL, TEXT("游戏结束,白子胜利"), "五子棋游戏", MB_OK); + } } //实现悔棋功能的函数 void Regret()//悔棋函数 @@ -234,6 +279,7 @@ int main() { system("title 五子棋"); system("mode con cols=92 lines=33"); + system("color F2"); char choose, temp; loop:welcome(); choose = _getch(); @@ -243,11 +289,14 @@ loop:welcome(); man_machine(); break; case '2': + man_man(); + break; + case '3': temp = Gametips(); if (temp == 'E' || temp == 'e') goto loop; break; - case '3': + case '4': { int message = MessageBox(NULL, TEXT("是否退出?"),TEXT( "友情提示"), MB_OKCANCEL); if (IDCANCEL == message) diff --git "a/\345\256\236\351\252\214/BetaGo/Chess.h" "b/\345\256\236\351\252\214/BetaGo/Chess.h" index 54a23078..3fe103b1 100644 --- "a/\345\256\236\351\252\214/BetaGo/Chess.h" +++ "b/\345\256\236\351\252\214/BetaGo/Chess.h" @@ -18,6 +18,7 @@ extern int AI_regrex, AI_regrey, man_regrex, man_regrey; extern int AI_x, AI_y; extern int man_x, man_y; +extern int man2_x, man2_y; extern int AI_regretx, AI_regrety; extern int man_regretx, man_regrety; extern int dir[][2]; @@ -28,7 +29,7 @@ void gotoxy(int x, int y); void chess_menu(); void chess_board();//打印棋盘 void board_init(); -void man_move();//红子棋移动光标 +void man_move();//人类玩家棋移动光标 void machine_move(); void clearlocation(int x, int y); void location(int x, int y, int color); diff --git "a/\345\256\236\351\252\214/BetaGo/GUI.c" "b/\345\256\236\351\252\214/BetaGo/GUI.c" index c3975faf..38ecbe45 100644 --- "a/\345\256\236\351\252\214/BetaGo/GUI.c" +++ "b/\345\256\236\351\252\214/BetaGo/GUI.c" @@ -6,33 +6,43 @@ void welcome() int k; char choose; system("cls"); - for (k = 2;k <= 12;k += 2)//游戏菜单 + BackGround(9, 15); + gotoxy(32, 2); + printf("$$$$$$$$$$$$$$$$$$$"); + gotoxy(32, 17); + printf("$$$$$$$$$$$$$$$$$$$"); + for (k = 4;k <= 16;k += 2)//游戏菜单 { - gotoxy(5, k); + gotoxy(32, k); printf("|-----------------|"); } - gotoxy(5, 3); + BackGround(2, 15); + gotoxy(32, 5); printf("| 五 子 棋 游 戏 |"); - gotoxy(5, 5); + gotoxy(32, 7); printf("| 菜 单 |"); - gotoxy(5, 7); + gotoxy(32, 9); printf("| 1.人 机 对 战 |"); - gotoxy(5, 9); - printf("| 2.游 戏 规 则 |"); + gotoxy(32, 11); + printf("| 2.人 人 对 战 |"); - gotoxy(5, 11); - printf("| 3.退 出 游 戏 |"); + gotoxy(32, 13); + printf("| 3.游 戏 规 则 |"); - gotoxy(5, 15); + gotoxy(32, 15); + printf("| 4.退 出 游 戏 |"); + + gotoxy(20, 19); + BackGround(6, 15); printf("温馨提示:输入菜单对应序号进行操作"); - gotoxy(5, 20); + gotoxy(20, 21); printf("祝您游戏愉快!"); - gotoxy(13, 20); + gotoxy(20, 22); } //游戏帮助 char Gametips() diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.c" "b/\345\256\236\351\252\214/BetaGo/heuristic.c" index 5bf9303c..ce19162d 100644 --- "a/\345\256\236\351\252\214/BetaGo/heuristic.c" +++ "b/\345\256\236\351\252\214/BetaGo/heuristic.c" @@ -2,7 +2,7 @@ #include "heuristic.h" //生成可下棋且有邻居的空位的函数 -int generator(int empty[][2],int now_board[L+2][L+2])//产生空子序列 +int generator(Point empty_point[200],int now_board[L+2][L+2])//产生空子序列 { int empty_cnt = 0; for (int i = 1;i < L + 1;i += 1) @@ -11,8 +11,9 @@ { if (neighbor(i, j,now_board)&&!now_board[i][j]) { - empty[empty_cnt][0] = i; - empty[empty_cnt][1] = j; + empty_point[empty_cnt].X = i; + empty_point[empty_cnt].Y = j; + empty_point[empty_cnt].is_killer = 0; empty_cnt++; } } @@ -34,7 +35,11 @@ int point_evaluate(int x, int y,int me, int now_board[L + 2][L + 2]) if (now_board[dy][dx] == me)//AI_x,AI_y都是坐标上的x,y,表示数组要反过来 n1++; else + { + if (!now_board[dy + dir[i][1]][dx + dir[i][0]]) + n1--; break; + } } for (int j = 0;j <= 5;j++)//j表示沿这个方向走了几步 { @@ -43,7 +48,11 @@ int point_evaluate(int x, int y,int me, int now_board[L + 2][L + 2]) if (now_board[dy][dx] == me) n2++; else + { + if (!now_board[dy+ dir[7 - i][1]][dx+ dir[7 - i][0]]) + n2--; break; + } } t = n1 + n2; if (t > value) @@ -51,7 +60,6 @@ int point_evaluate(int x, int y,int me, int now_board[L + 2][L + 2]) value = t; } } - //判断是不是杀棋 now_board[x][y] = 0; return value; } @@ -70,9 +78,10 @@ int point_evaluate(int x, int y,int me, int now_board[L + 2][L + 2]) return 0; } //启发式搜索函数 -void heuristic_search(int point_value[][3], int empty_point[][2], int empty_cnt, int me, int now_board[L + 2][L + 2]) +int heuristic_search(Point empty_point[200], int empty_cnt, int me, int now_board[L + 2][L + 2]) { int cnt = 0; + int kill_cnt=0; int others; if (me == red) others = white; @@ -80,24 +89,56 @@ void heuristic_search(int point_value[][3], int empty_point[][2], int empty_cnt, others = red; for (int i = 0;i < empty_cnt;i++) { - int x = empty_point[i][0]; - point_value[i][0] = x; - int y = empty_point[i][1]; - point_value[i][1] = y; - point_value[i][2] = point_evaluate(x, y, me, now_board) + point_evaluate(x, y, others, now_board); - } + int x = empty_point[i].X; + int y = empty_point[i].Y; + int me_value = point_evaluate(x, y, me, now_board); + int others_value = point_evaluate(x, y, others, now_board); + empty_point[i].value = me_value + others_value; - qsort(point_value, empty_cnt, sizeof(int) * 3, comp); + //判断是不是杀棋 + //is_killer(&empty_point[i], me_value, others_value); + //if (empty_point[i].is_killer) + //kill_cnt++; + } + + // if(!kill_cnt) + //qsort(empty_point, empty_cnt, sizeof(empty_point[0]), comp1); + //else + qsort(empty_point, kill_cnt, sizeof(empty_point[0]), comp2); + return kill_cnt; +} +//判断是否是杀棋并评定等级 +void is_killer(Point* p, int me_value, int others_value) +{ + if (me_value > 4) + p->is_killer = 4; + else + { + if (others_value > 4) + p->is_killer = 3; + else + { + if (me_value > 3) + p->is_killer = 2; + else + { + if (others_value > 3) + p->is_killer = 1; + } + } + } } -/* -void heuristic_search(struct Point *p, int me, int now_board[L + 2][L + 2]) -*/ + //qsort排序的比较规则函数 -int comp(const void* a, const void* b) +//没有杀棋就用评估分数比较 +int comp1(const void* a, const void* b) +{ + return (*(Point*)a).value < (*(Point*)b).value ? 1 : -1; +} +//有杀棋就用杀棋的级别比较 +int comp2(const void* a, const void* b) { - if (((int*)a)[2] < ((int*)b)[2]) - return 1; - else return -1; + return (*(Point*)a).is_killer < (*(Point*)b).is_killer ? 1 : -1; } diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.h" "b/\345\256\236\351\252\214/BetaGo/heuristic.h" index 1d4d7c86..10e47984 100644 --- "a/\345\256\236\351\252\214/BetaGo/heuristic.h" +++ "b/\345\256\236\351\252\214/BetaGo/heuristic.h" @@ -1,14 +1,17 @@ #pragma once -void heuristic_search(int point_value[][3], int empty_point[][2], int empty_cnt, int me); -int neighbor(int x, int y); -int point_evaluate(int x, int y, int me); -int generator(int* empty[][2]); -int comp(const void* a, const void* b); - typedef struct { - int cnt; - int X[100]; - int Y[100]; - int value[100]; -}Point; \ No newline at end of file + int X; + int Y; + int value; + int is_killer; +}Point; + +int heuristic_search(Point empty_point[200], int empty_cnt, int me, int now_board[L + 2][L + 2]); +int generator(Point empty_point[200], int now_board[L + 2][L + 2]); +int point_evaluate(int x, int y, int me, int now_board[L + 2][L + 2]); +int neighbor(int x, int y, int now_board[L + 2][L + 2]); +void is_killer(Point* p, int me_value, int others_value); +int comp1(const void* a, const void* b); +int comp2(const void* a, const void* b); + diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214/BetaGo/max-min.c" index 6e09b40f..cce03315 100644 --- "a/\345\256\236\351\252\214/BetaGo/max-min.c" +++ "b/\345\256\236\351\252\214/BetaGo/max-min.c" @@ -1,5 +1,6 @@ #include "Chess.h" #include "max-min.h" +#include "heuristic.h" //怎么表示撇捺?不好批量建立一维数组,斜着的再建立二维数组 //搜索遍历棋型的函数,评估函数evaluate是在search基础上的打分 @@ -29,7 +30,7 @@ { if (j > value) { - value = j;//记录最大连子数和最大的方向 + value = j;//记录最大连子数和最大的方向,记录方向是为了之后好寻找 maxdir = i; } break; @@ -60,9 +61,9 @@ { value--; if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) - value = 0; + value = 0;//两头都被堵,分数为0 } - if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall) + if (copy[dx2][dy2] == F || copy[dx2][dy2] == wall)//有一头被堵分数-1 value--; } return value; @@ -105,6 +106,7 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) int minmax; int rival; Tree tree; + Point point[200]; tree.Alpha = Alpha; tree.Beta = Beta; tree.X = 0; @@ -113,21 +115,35 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) rival = 2; else rival = 1; - if (depth == 0) + if (judge_winner(tree.X, tree.Y, me) == me|| depth == 0) return evaluate(me, tmp_board)-evaluate(rival,tmp_board); - if (judge_winner(tree.X, tree.Y, me) == me) - return 0; if (depth % 2)//判断是min层还是max层 { //min层 - int empty_point[100][2] = { 0 }; - int empty_cnt = generator(empty_point,tmp_board); - int point_value[100][3] = { 0 }; - heuristic_search(point_value, empty_point, empty_cnt,white, tmp_board); + int empty_cnt = generator(point,tmp_board); + int kill_cnt; + kill_cnt =heuristic_search(point, empty_cnt,white, tmp_board); + //搜索深度超过四层就开启算杀,只保留估分最高的前五个节点 + if (depth > 4) + { + if (kill_cnt) + empty_cnt = kill_cnt; + else + empty_cnt = 5; + } for (int k = 0;k < empty_cnt;k++) { - int i = point_value[k][0]; - int j = point_value[k][1]; + //如果遇到杀棋,后面的枝全部剪掉 + /*经过测试,这样剪枝效果并不理想,可能是因为由于双方决策的原因,有些杀棋无法达成 + if (kill_cnt) + { + int i = point[k].X; + int j = point[k].Y; + empty_cnt = kill_cnt; + } + */ + int i = point[k].X; + int j = point[k].Y; if (tree.Alpha < tree.Beta) { memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 @@ -149,14 +165,17 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) else { //max层 - int empty_point[100][2] = { 0 }; - int empty_cnt = generator(empty_point, tmp_board); - int point_value[100][3] = { 0 }; - heuristic_search(point_value, empty_point, empty_cnt,red, tmp_board); + int empty_cnt = generator(point, tmp_board); + heuristic_search(point, empty_cnt, red, tmp_board); + if (depth > 4) + { + if (empty_cnt > 5) + empty_cnt = 5; + } for (int k = 0;k < empty_cnt;k++) { - int i = point_value[k][0]; - int j = point_value[k][1]; + int i = point[k].X; + int j = point[k].Y; if (tree.Alpha < tree.Beta) { memcpy(c, tmp_board, sizeof(int) * L * L); @@ -181,77 +200,6 @@ int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) } -/* -int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L + 2]) -//分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF -{ - int i, j; - int c[L + 2][L + 2]; - int minmax; - int rival; - Tree tree; - tree.Alpha = Alpha; - tree.Beta = Beta; - tree.X = 0; - tree.Y = 0; - if (me == 1) - rival = 2; - else - rival = 1; - int if_win = judge_winner(tree.X, tree.Y, me, tmp_board); - if (if_win ==me||depth==0) - return evaluate(me, tmp_board) - evaluate(rival, tmp_board); - if (depth % 2)//判断是min层还是max层,奇数是min层 - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!tmp_board[i][j] && neighbor(i, j, tmp_board) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 - c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - c[i][j] = 0; - if (minmax < tree.Beta) - { - tree.Beta = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Alpha;//α剪枝,抛弃后续节点 - } - } - } - return tree.Beta; - } - else - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!tmp_board[i][j] && neighbor(i, j, tmp_board) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L); - //用一个新的数组表示棋盘,以免破坏原棋盘 - c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - c[i][j] = 0; - if (minmax > tree.Alpha) - { - tree.Alpha = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Beta;//α剪枝,抛弃后续节点 - } - } - } - AI_x = tree.X; - AI_y = tree.Y; - return tree.Alpha; - } -} -*/ diff --git "a/\345\256\236\351\252\214/README.md" "b/\345\256\236\351\252\214/README.md" index 8fea8de8..768a1256 100644 --- "a/\345\256\236\351\252\214/README.md" +++ "b/\345\256\236\351\252\214/README.md" @@ -150,6 +150,8 @@ dfs鐨勬悳绱㈡柟寮忓拰閫掑綊绋嬪簭缁撳悎璧锋潵鐞嗚В 蹇帓 qsort +缁撴瀯浣撴暟缁 + ## 瀛︿範鑳藉姏 ## bug list @@ -203,20 +205,26 @@ dfs鐨勬悳绱㈡柟寮忓拰閫掑綊绋嬪簭缁撳悎璧锋潵鐞嗚В - [x] 濂囨暟灞傛槸min锛宔valuate瑕佺浉鍑 -- [ ] 鍫电殑鏃跺欓殧浜嗕竴棰楁瀛 鍒ゆ柇姝绘椿value涓嶇敤+1 - - [x] 璁剧疆涓浜涗紭鍏堟儏鍐 - [x] 鎮旀鍔熻兘 +- [x] 璁剧疆缁撴瀯浣撲紶閫掔┖浣 + - [ ] 瀹屽杽浜烘満瀵规垬鍔熻兘鍜岀晫闈 - [ ] 鍚彂寮忔悳绱 - 鐢熸垚绌轰綅缃兘涓嶈兘浠呯敓鎴愪竴娆 + 鐢熸垚绌轰綅缃兘涓嶈兘浠呯敓鎴愪竴娆★紝鐩存帴鍦ㄥぇ鍑芥暟閲岄潰瀹氫箟锛屼箣鍚庡眰灞備紶涓嬪幓锛熶絾鏄瘡娆$殑妫嬬洏閮藉湪鏀瑰彉锛屽垎鏁扮殑浼板奸兘鍦ㄦ敼鍙 +鏀硅繘锛氭渶缁堟斁寮冨惎鍙戝紡鎼滅储涓悳绱㈡潃妫 + +鏀惧純杩唬鍔犳繁 + +绠楁潃鍦ㄥ惎鎼滅殑鍩虹涓婃潵鍋 + ## 椤圭洰鎰熸偀 @@ -256,8 +264,6 @@ dfs鐨勬悳绱㈡柟寮忓拰閫掑綊绋嬪簭缁撳悎璧锋潵鐞嗚В 鍦╩in_max閲屽姞涓婁紭鍏堟儏鍐碉紝鍙兘琚壀鏋濆壀鎺変簡 -![image-20210523101848152](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210523101848152.png) - ![image-20210606193743892](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210606193743892.png) ![image-20210608132439531](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210608132439531.png)涓棿鐣欑┖鐢佃剳閫夋嫨浜嗗欢闀胯嚜宸辩殑娲讳笁 @@ -268,15 +274,23 @@ function alphabeta_minmax(node, depth, 伪, 尾, Player) return the heuristic value of node if Player = MaxPlayer //鍒ゆ柇鏄帺瀹惰繕鏄疉I鍋氬喅绛栵紝AI鍐崇瓥鍒欎负max灞傦紝鐜╁鍐崇瓥鍒欎负min灞 //鏋佸ぇ鑺傜偣 - for each child of node//鏋佸皬鑺傜偣 + heuristic_search()//宓屽叆鍚彂寮忔悳绱唬鐮侊紝缁欑┖浣嶆帓搴忥紝鏈夊埄浜庡綋鍓嶇帺瀹剁殑鑺傜偣鎺掑墠闈 + if(depth>limit)//鎼滅储娣卞害澶т簬闄愬畾鍊硷紝鍚姩绠楁潃 + is_killer() + empty_cnt=killer_cnt//寰呴亶鍘嗙殑缁撶偣鏁版敼涓烘潃妫嬬殑鏁扮洰 + for each child of node//閬嶅巻鎺掑簭濂界殑鏋佸皬鑺傜偣 伪 := max(伪, alphabeta(child, depth-1, 伪, 尾, not(Player) ))//鏋佸ぇ鑺傜偣 //瀛╁瓙鑺傜偣鐨勎憋紝尾缁ф壙鑷埗鑺傜偣 if 尾 鈮 伪 // 璇ユ瀬澶ц妭鐐圭殑鍊>=伪>=尾锛岃鏋佸ぇ鑺傜偣鍚庨潰鐨勬悳绱㈠埌鐨勫艰偗瀹氫細澶т簬尾锛屽洜姝や笉浼氳鍏朵笂灞傜殑鏋佸皬鑺傜偣鎵閫夌敤浜嗐傚浜庢牴鑺傜偣锛屛蹭负姝f棤绌 break (* Beta cut-off *) return 伪 - else // 鏋佸皬鑺傜偣 - for each child of node // 鏋佸ぇ鑺傜偣 + else // 鏋佸皬鑺傜偣 + heuristic_search() + if(depth>limit) + is_killer() + empty_cnt=killer_cnt + for each child of node // 閬嶅巻鎺掑簭濂界殑鏋佸ぇ鑺傜偣 尾 := min(尾, alphabeta(child, depth-1, 伪, 尾, not(Player) )) // 鏋佸皬鑺傜偣 if 尾 鈮 伪 // 璇ユ瀬澶ц妭鐐圭殑鍊<=尾<=伪锛岃鏋佸皬鑺傜偣鍚庨潰鐨勬悳绱㈠埌鐨勫艰偗瀹氫細灏忎簬伪锛屽洜姝や笉浼氳鍏朵笂灞傜殑鏋佸ぇ鑺傜偣鎵閫夌敤浜嗐傚浜庢牴鑺傜偣锛屛变负璐熸棤绌 break (* Alpha cut-off *) @@ -285,98 +299,4 @@ function alphabeta_minmax(node, depth, 伪, 尾, Player) alphabeta(origin, depth, -infinity, +infinity, MaxPlayer) ``` -```c -int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L + 2]) -//鍒嗘暟浼犻,t涓1琛ㄧず绾㈡锛屼负2琛ㄧず鐧芥,璋冪敤鏃禔lpha锛孊eta璧嬩负NGIF,PTIF -{ - int i, j; - int c[L + 2][L + 2]; - int minmax; - int rival; - Tree tree; - tree.Alpha = Alpha; - tree.Beta = Beta; - tree.X = 0; - tree.Y = 0; - if (me == 1) - rival = 2; - else - rival = 1; - if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) - return evaluate(me, tmp_board) - evaluate(rival, tmp_board); - if (depth % 2 == 0)//鍒ゆ柇鏄痬in灞傝繕鏄痬ax灞,鍋舵暟鏄痬in灞 - if (depth == 0 || judge_winner(tree.X, tree.Y, me) == me) - return evaluate(me, tmp_board) - evaluate(rival, tmp_board); - if (depth % 2)//鍒ゆ柇鏄痬in灞傝繕鏄痬ax灞,濂囨暟鏄痬in灞 - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) - if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L);//鏇存柊妫嬬洏 - c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - if (judge_winner(i, j, white) == white && depth == rank - 1) - //浼樺厛鎯呭喌锛氬鏂瑰凡缁忔湁娲诲洓灏卞繀椤诲牭 - - { - AI_x = j; - AI_y = i; - return 0; - } - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - c[i][j] = 0; - if (minmax < tree.Beta) - { - tree.Beta = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Alpha;//伪鍓灊锛屾姏寮冨悗缁妭鐐 - } - } - } - return tree.Beta; - } - else - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) - if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L); - //鐢ㄤ竴涓柊鐨勬暟缁勮〃绀烘鐩橈紝浠ュ厤鐮村潖鍘熸鐩 - c[i][j] = me; - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - if (judge_winner(i, j, red) == red && depth == rank) - //浼樺厛鎯呭喌锛氳嚜宸卞凡缁忔湁娲诲洓灏卞繀椤绘帴鐫涓 - { - AI_x = j; - AI_y = i; - return 0; - } - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - c[i][j] = 0; - if (minmax > tree.Alpha) - { - tree.Alpha = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Beta;//伪鍓灊锛屾姏寮冨悗缁妭鐐 - } - } - } - AI_x = tree.X; - AI_y = tree.Y; - return tree.Alpha; - } -} -``` - -![image-20210613213456813](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210613213456813.png) - +![image-20210614093116933](D:\搴旂敤杞欢\Typora2\Typora\typora-user-images\image-20210614093116933.png) From 29a71bf0f45652b621f611ec73b878b39b1560c9 Mon Sep 17 00:00:00 2001 From: ursulalujun <2441299056@qq.com> Date: Thu, 17 Jun 2021 21:53:16 +0800 Subject: [PATCH 19/19] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=95=B4=E7=90=86]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\345\256\236\351\252\214/BetaGo/BetaGo.sln" | 31 --- .../BetaGo/BetaGo.vcxproj" | 158 ------------ .../BetaGo/BetaGo.vcxproj.filters" | 48 ---- .../BetaGo/BetaGo.vcxproj.user" | 4 - "\345\256\236\351\252\214/BetaGo/draft.c" | 231 ------------------ "\345\256\236\351\252\214/BetaGo/minmaxAB.c" | 87 ------- .../Chess_GUI/Chess_GUI.sln" | 31 --- .../Chess_GUI/Chess_GUI.vcxproj" | 148 ----------- .../Chess_GUI/Chess_GUI.vcxproj.filters" | 25 -- .../Chess_GUI/Chess_GUI.vcxproj.user" | 4 - .../Chess_GUI/Chess-board.cpp" | 0 .../Chess_GUI/HomeScreen.cpp" | 0 .../README.md" | 0 .../Chess.cpp" | 0 .../Chess.h" | 0 .../GUI.cpp" | 0 .../Heuristic&killer/heuristic.cpp" | 12 +- .../Heuristic&killer/heuristic.h" | 0 .../min-maxAB/max-min.cpp" | 0 .../min-maxAB/max-min.h" | 0 20 files changed, 6 insertions(+), 773 deletions(-) delete mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.sln" delete mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" delete mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" delete mode 100644 "\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" delete mode 100644 "\345\256\236\351\252\214/BetaGo/draft.c" delete mode 100644 "\345\256\236\351\252\214/BetaGo/minmaxAB.c" delete mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" delete mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" delete mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" delete mode 100644 "\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" rename "\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/Chess-board.cpp" (100%) rename "\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/HomeScreen.cpp" (100%) rename "\345\256\236\351\252\214/README.md" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/README.md" (100%) rename "\345\256\236\351\252\214/BetaGo/Chess.c" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.cpp" (100%) rename "\345\256\236\351\252\214/BetaGo/Chess.h" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.h" (100%) rename "\345\256\236\351\252\214/BetaGo/GUI.c" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/GUI.cpp" (100%) rename "\345\256\236\351\252\214/BetaGo/heuristic.c" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.cpp" (93%) rename "\345\256\236\351\252\214/BetaGo/heuristic.h" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.h" (100%) rename "\345\256\236\351\252\214/BetaGo/max-min.c" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.cpp" (100%) rename "\345\256\236\351\252\214/BetaGo/max-min.h" => "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.h" (100%) diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.sln" "b/\345\256\236\351\252\214/BetaGo/BetaGo.sln" deleted file mode 100644 index 54ba4057..00000000 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.sln" +++ /dev/null @@ -1,31 +0,0 @@ -锘 -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31112.23 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BetaGo", "BetaGo.vcxproj", "{3932EE5E-DA7A-46C4-9A62-742C7FE25302}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x64.ActiveCfg = Debug|x64 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x64.Build.0 = Debug|x64 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x86.ActiveCfg = Debug|Win32 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Debug|x86.Build.0 = Debug|Win32 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x64.ActiveCfg = Release|x64 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x64.Build.0 = Release|x64 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x86.ActiveCfg = Release|Win32 - {3932EE5E-DA7A-46C4-9A62-742C7FE25302}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9FC45EAA-8058-4628-977E-C3026065F929} - EndGlobalSection -EndGlobal diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" deleted file mode 100644 index f84d47d2..00000000 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj" +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {3932ee5e-da7a-46c4-9a62-742c7fe25302} - BetaGo - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - false - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - D:\Documents\c璇█\C璇█璇剧▼\BetaGo;%(AdditionalIncludeDirectories) - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" deleted file mode 100644 index 0214e743..00000000 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.filters" +++ /dev/null @@ -1,48 +0,0 @@ -锘 - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 婧愭枃浠 - - - 婧愭枃浠 - - - 婧愭枃浠 - - - 婧愭枃浠 - - - 婧愭枃浠 - - - 婧愭枃浠 - - - - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" "b/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" deleted file mode 100644 index 88a55094..00000000 --- "a/\345\256\236\351\252\214/BetaGo/BetaGo.vcxproj.user" +++ /dev/null @@ -1,4 +0,0 @@ -锘 - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/BetaGo/draft.c" "b/\345\256\236\351\252\214/BetaGo/draft.c" deleted file mode 100644 index 08cdb105..00000000 --- "a/\345\256\236\351\252\214/BetaGo/draft.c" +++ /dev/null @@ -1,231 +0,0 @@ -/* -int PD[21][15] = { {0},{0} };//principle diagonal -int BD[21][15] = { {0},{0} };//back diagonal -void flat() -{ - for (int i = 0;i < 11;i++) - for (int j = 0;j < L-i;j++) - { - PD[i][j] = board[i + j][j]; - PD[10 + i][j] = board[j][i + j]; - } - for (int i = 0;i < 11;i++) - for (int j = 0;j < L - i;j++) - { - BD[i][j] = board[i + j][L - j]; - BD[10 + i][j] = board[j][L - i - j]; - } -} - -void testflat() -{ - for(int i=0;i<21;i++) - for(int j=0;j<21;j++) - printf("%d\t", PD[i][j]); - for (int i = 0;i < 21;i++) - for (int j = 0;j < 21;j++) - printf("%d\t", BD[i][j]); -} -*/ //c语言平面化可能并不方便 -/* - for(int j=0;j<15;j++) - for (int i = 0;i < 21;i++) - { - if (PD[i][j] == 1) - { - k = 0; - int t = i; - while (PD[t][j] == 1) - t++;k++; - if (PD[i-1][j] == 2 || PD[t+1][j] == 2)//判断不是边界 - k--; - if (PD[i-1][j] == 2 && PD[t+1][j] == 2) - k = -1;//区分死棋和死一 - if (k >= 0) - human_score = human_score + pow(10, k); - - } - - } -#define ONE 10//live one -#define TWO 100 -#define THREE 1000 -#define FOUR 100000 -#define FIVE 10000000 -#define BLOCKED_ONE 1 -#define BLOCKED_TWO 10 -#define BLOCKED_THREE 100 -#define BLOCKED_FOUR 10000 -#define TWO_THREE -#define BLOCK_FOUR -#define FOUR_THREE - */ - - /* - k = 1; - int t = j;//用t暂时存储j,方便之后检查前面的情况,然后j++,避免重复检查 - j++; - while (board[i][j] == T) - { - j++; - k++; - } - if (board[i][j] == F || board[i][t - 1] == F || board[i][j] == wall || board[i][t - 1] == wall) - k--; - if ((board[i][j] == F && board[i][t - 1] == F) || (board[i][j] == wall && board[i][t - 1] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - j = t; - } - } - - for (int i = 1;i < L + 1;i++)//竖向检查 - for (int j = 1;j < L + 1;j++) - { - if (board[i][j] == T) - { - k = 1; - int t = i; - i++; - while (board[i][j] == T)//i=16,这里经过一次i++后,i已经在连棋的后面一格了 - { - i++; - k++; - } - if (board[t - 1][j] == F || board[i][j] == F || board[t - 1][j] == wall || board[i][j] == wall) - k--; - if ((board[t - 1][j] == F && board[i][j] == F )|| (board[t - 1][j] == wall && board[i + 1][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t; - } - } - - for (int i = 1;i < L + 1;i += 1)//检查主对角线 - for (int j = 1;j < L + 1;j += 1) - { - if (board[i][j] == T) - { - k = 1; - int t1 = i, t2 = j; - i++; - j++; - while (board[i][j] == T) - { - i++; - j++; - k++; - } - if (board[t1 - 1][t2 - 1] == F || board[i][j] == F || board[t1 - 1][t2 - 1] == wall || board[i][j] == wall) - //判断不是边界 - k--; - if ((board[t1 - 1][t2 - 1] == F && board[i][j] == F )|| (board[t1 - 1][t2 - 1] == wall && board[i][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t1; - j = t2; - } - } - - for (int i = 1;i < L + 1;i += 1)//检查反对角线 - for (int j = 1;j < L + 1;j += 1) - { - if (board[i][j] == T) - { - k = 1; - int t1 = i, t2 = j; - i += 1; - j -= 1; - while (board[i][j] == T) - { - i += 1; - j -= 1; - k++; - } - if (board[t1 - 1][t2 + 1] == F || board[i][j] == F || board[i][j] == wall || board[i][j] == wall) - k--;//遇到边界也相当于是死棋 - if ((board[t1 - 1][t2 + 1] == F && board[i][j] == F )|| (board[i][j] == wall && board[i][j] == wall)) - k = -1;//区分死棋和死一 - if (k >= 0) - score = score + pow(10, k); - i = t1; - j = t2; - } - } - - int DFS(int me, int others, int depth)//dfs遍历四层决策树 -{ - int my_score = -100; - int t = -1000; - int temp; - int cnt; - int empty_p[100][2] = { {0},{0} }; - int a[4] = { 0 }; - int i = 0; - int best_position = 0; - if (depth==0)//超过预定层数,结束递归,返回分数 - { - t = evaluate(red, white) - evaluate(white, red); - if (t > my_score) - { - my_score = t; - best_position = a[0]; - } - return best_position; - } - else - { - cnt = generator(empty_p); - for (int k = 0;k < cnt;k++) - { - int tree_x = empty_p[k][0]; - int tree_y = empty_p[k][1]; - board[tree_x][tree_y] = me; - a[i] = k; - i++; - temp = me;//交换敌方和己方 - me = others; - others = temp; - DFS(me, others, depth--); - board[tree_x][tree_y] = me;//(回到上一步)清除标记 - - } - - } -} - -#include "go.h" -int priority() -{ - int i, j, k, p; - int c[L + 2][L + 2]; - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!board[i][j] && neighbor(i, j)) - { - memcpy(c, board, sizeof(int) * L * L);//更新棋盘 - c[i][j] = red; - for (k = 0;k < 8;k++)//i表示八个方向 - for (p = 1;p <= 5;p++)//j表示沿这个方向走了几步 - { - int dx = i + p * dir[k][0]; - int dy = j + p * dir[k][1]; - if (c[dx][dy] != red)break; - } - if (p == 5) - { - AI_x = j; - AI_y = i; - return 1; - } - } - } - return 0; -} - - - */ diff --git "a/\345\256\236\351\252\214/BetaGo/minmaxAB.c" "b/\345\256\236\351\252\214/BetaGo/minmaxAB.c" deleted file mode 100644 index bd3a84d8..00000000 --- "a/\345\256\236\351\252\214/BetaGo/minmaxAB.c" +++ /dev/null @@ -1,87 +0,0 @@ -/* -int minMax_AB(int depth, int me, int Alpha, int Beta, int tmp_board[][L+2]) -//分数传递,t为1表示红棋,为2表示白棋,调用时Alpha,Beta赋为NGIF,PTIF -{ - int i, j; - int c[L+2][L+2]; - int minmax; - int rival; - Tree tree; - tree.Alpha = Alpha; - tree.Beta = Beta; - tree.X = 0; - tree.Y = 0; - if (me == 1) - rival = 2; - else - rival = 1; - if (depth == 0|| judge_winner(tree.X, tree.Y, me) == me) - return evaluate(me, tmp_board)-evaluate(rival,tmp_board); - if (depth % 2)//判断是min层还是max层,奇数是min层 - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!tmp_board[i][j]&& neighbor(i, j) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L);//更新棋盘 - c[i][j] = me; - if (judge_winner(i, j, white) == white && depth == rank-1) - //优先情况:对方已经有活四就必须堵 - { - AI_x = j; - AI_y = i; - return 0; - } - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta, c); - c[i][j] = 0; - if (minmax < tree.Beta) - { - tree.Beta = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Alpha;//α剪枝,抛弃后续节点 - } - } - } - return tree.Beta; - } - else - { - for (i = 1;i < L + 1;i++) - for (j = 1;j < L + 1;j++) - { - if (!tmp_board[i][j] && neighbor(i, j) && tree.Alpha < tree.Beta) - { - memcpy(c, tmp_board, sizeof(int) * L * L); - //用一个新的数组表示棋盘,以免破坏原棋盘 - c[i][j] = me; - if (judge_winner(i, j, red) == red&&depth==rank) - //优先情况:自己已经有活四就必须接着下 - { - AI_x = j; - AI_y = i; - return 0; - } - minmax = minMax_AB(depth - 1, rival, tree.Alpha, tree.Beta,c); - c[i][j] = 0; - if (minmax > tree.Alpha) - { - tree.Alpha = minmax; - tree.X = j; - tree.Y = i; - if (tree.Alpha >= tree.Beta) - return tree.Beta;//α剪枝,抛弃后续节点 - } - } - } - AI_x = tree.X; - AI_y = tree.Y; - return tree.Alpha; - } - -} - - -*/ diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" deleted file mode 100644 index b2d20bd3..00000000 --- "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.sln" +++ /dev/null @@ -1,31 +0,0 @@ -锘 -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31321.278 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chess_GUI", "Chess_GUI.vcxproj", "{6F592C46-8C4E-45CC-BBD7-45A519F7877E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x64.ActiveCfg = Debug|x64 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x64.Build.0 = Debug|x64 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x86.ActiveCfg = Debug|Win32 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Debug|x86.Build.0 = Debug|Win32 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x64.ActiveCfg = Release|x64 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x64.Build.0 = Release|x64 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x86.ActiveCfg = Release|Win32 - {6F592C46-8C4E-45CC-BBD7-45A519F7877E}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {496FFC51-7EC7-4035-A003-205DFF047780} - EndGlobalSection -EndGlobal diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" deleted file mode 100644 index eeff5be7..00000000 --- "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj" +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {6f592c46-8c4e-45cc-bbd7-45a519f7877e} - ChessGUI - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" deleted file mode 100644 index a988c855..00000000 --- "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.filters" +++ /dev/null @@ -1,25 +0,0 @@ -锘 - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 婧愭枃浠 - - - 婧愭枃浠 - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" "b/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" deleted file mode 100644 index 88a55094..00000000 --- "a/\345\256\236\351\252\214/Chess_GUI/Chess_GUI.vcxproj.user" +++ /dev/null @@ -1,4 +0,0 @@ -锘 - - - \ No newline at end of file diff --git "a/\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/Chess-board.cpp" similarity index 100% rename from "\345\256\236\351\252\214/Chess_GUI/Chess-board.cpp" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/Chess-board.cpp" diff --git "a/\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/HomeScreen.cpp" similarity index 100% rename from "\345\256\236\351\252\214/Chess_GUI/HomeScreen.cpp" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/Chess_GUI/HomeScreen.cpp" diff --git "a/\345\256\236\351\252\214/README.md" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/README.md" similarity index 100% rename from "\345\256\236\351\252\214/README.md" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/README.md" diff --git "a/\345\256\236\351\252\214/BetaGo/Chess.c" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.cpp" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/Chess.c" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.cpp" diff --git "a/\345\256\236\351\252\214/BetaGo/Chess.h" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.h" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/Chess.h" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/Chess.h" diff --git "a/\345\256\236\351\252\214/BetaGo/GUI.c" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/GUI.cpp" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/GUI.c" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\344\270\213\346\243\213\345\212\237\350\203\275/GUI.cpp" diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.c" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.cpp" similarity index 93% rename from "\345\256\236\351\252\214/BetaGo/heuristic.c" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.cpp" index ce19162d..d376421a 100644 --- "a/\345\256\236\351\252\214/BetaGo/heuristic.c" +++ "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.cpp" @@ -96,14 +96,14 @@ int heuristic_search(Point empty_point[200], int empty_cnt, int me, int now_boar empty_point[i].value = me_value + others_value; //判断是不是杀棋 - //is_killer(&empty_point[i], me_value, others_value); - //if (empty_point[i].is_killer) - //kill_cnt++; + is_killer(&empty_point[i], me_value, others_value); + if (empty_point[i].is_killer) + kill_cnt++; } - // if(!kill_cnt) - //qsort(empty_point, empty_cnt, sizeof(empty_point[0]), comp1); - //else + if(!kill_cnt) + qsort(empty_point, empty_cnt, sizeof(empty_point[0]), comp1); + else qsort(empty_point, kill_cnt, sizeof(empty_point[0]), comp2); return kill_cnt; } diff --git "a/\345\256\236\351\252\214/BetaGo/heuristic.h" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.h" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/heuristic.h" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/Heuristic&killer/heuristic.h" diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.c" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.cpp" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/max-min.c" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.cpp" diff --git "a/\345\256\236\351\252\214/BetaGo/max-min.h" "b/\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.h" similarity index 100% rename from "\345\256\236\351\252\214/BetaGo/max-min.h" rename to "\345\256\236\351\252\214\357\274\210\344\272\224\345\255\220\346\243\213\357\274\211/\347\256\227\346\263\225/min-maxAB/max-min.h"