找回密码
 欢迎注册
楼主: 056254628

[讨论] 一种棋类游戏

[复制链接]
发表于 2009-10-13 22:15:32 | 显示全部楼层
穷举也是一种策略.
不过这里发现还可以优化.
考虑到不同的状态,它们所有棋子所在格子和邻居覆盖的集合可能相同.采用这个集合作为hash表的关键字更加好,应该可以大量降低表格的大小,从而大量节省内存空间
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-15 10:22:30 | 显示全部楼层
有结果了么
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-15 12:02:08 | 显示全部楼层
8*8先手败
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-10-15 20:34:32 | 显示全部楼层
可以 以n为奇数(n*n的棋盘)来验证程序的正确性。
只有对于所有的n(n为奇数)结果都是先手胜,程序才有可能是正确的。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-15 22:13:26 | 显示全部楼层
  1. // chp.cpp : Defines the entry point for the console application.
  2. //

  3. #include "stdafx.h"
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #define N 8
  8. #define BITS (N*N)
  9. typedef unsigned long long SET;
  10. SET nghb[BITS];
  11. #define EMPTY_SET    0LL
  12. #define INDEX(x,y)   ((x)*N+(y))
  13. #define GET_X(ind)   ((ind)/N)
  14. #define GET_Y(ind)   ((ind)%N)
  15. #define ADD_INDEX(s, ind)  ((s)|=1LL<<(ind))
  16. #define TEST_INDEX(s, ind)  (((s)&(1LL<<(ind)))!=0)
  17. #define CORNMASK     (3|(3<<N))
  18. #define TEST_BIT(x, b)   (((x)&(1LL<<(b)))!=0)
  19. #define SET_BIT(x, b)    ((x)|=(1LL<<(b)))

  20. #define GET_CORN(x)  (((x)&3)| (((x)>>N)&3)<<2)
  21. #define DISP_CORN(x) (((x)&3)| ((((x)>>2)&3)<<N))
  22. #define ECVALUE(x)   (((x)&~CORNMASK)|DISP_CORN(cr[GET_CORN(x)]))

  23. #define STABLE 50000033
  24. #define WALK   1000
  25. int hc;
  26. int ec;
  27. int nec;
  28. int lec;
  29. long long htable[STABLE];
  30. long long htable2[STABLE];
  31. char cr[16]={1,-1,-1,-1,-1,-1,-1,-1,4,-1,5,-1,3,-1,11,7};
  32. char rc[16]={-1,0,-1,12,8,10,-1,15,-1,-1,-1,14,-1,-1,-1,-1};

  33. FILE *fout;
  34. void dump(long long v)
  35. {
  36.         int i,j;
  37.         for(i=0;i<N;i++){
  38.                 for(j=0;j<N;j++){
  39.                         if(TEST_BIT(v,i*N+j)){
  40.                                 fprintf(fout,"1 ");
  41.                         }else{
  42.                                 fprintf(fout,"0 ");
  43.                         }
  44.                 }
  45.                 fprintf(fout,"\n");
  46.         }
  47.         fprintf(fout,"\n");
  48. }

  49. void copy_ec(long long *p)
  50. {
  51.         int i,t;
  52.         for(i=0,t=0;i<STABLE;i++){
  53.                 if(htable[i]!=-1LL){
  54.                         if(cr[GET_CORN(htable[i])]!=-1){
  55.                                 p[t++]=htable[i];
  56.                         }
  57.                 }
  58.         }
  59. }

  60. void dump_ec(long long htable[])
  61. {
  62.         int i;
  63.         fout = fopen("dump.txt","w");
  64.         for(i=0;i<STABLE;i++){
  65.                 if(htable[i]!=-1LL){
  66.                         if(cr[GET_CORN(htable[i])]!=-1){
  67.                                 dump(htable[i]);
  68.                         }
  69.                 }
  70.         }
  71.         fclose(fout);
  72. }

  73. void init()
  74. {
  75.     memset(htable,-1,sizeof(htable));
  76.         memset(htable2,-1,sizeof(htable2));
  77. }

  78. int hash(SET s)
  79. {
  80.     return (int)(s%STABLE);
  81. }

  82. int add_hash(long long htable[],long long key, bool eq)
  83. {
  84.     int v=hash(key);
  85.     long long ev;
  86.     ev=ECVALUE(key);
  87.     if(hc>=STABLE){
  88.         fprintf(stderr,"out of hash table range\n");
  89.         exit(-1);
  90.     }
  91.     do{
  92.         if(htable[v]==-1LL){
  93.             if(eq){
  94.                 htable[v]=ev;nec++;
  95.             }else{
  96.                 htable[v]=key;
  97.                                 ec++;
  98.             }
  99.             hc++;
  100.             return v;
  101.         }else if(htable[v]!=key&&htable[v]!=ev){
  102.             v=(v+WALK)%STABLE;
  103.         }else{
  104.             if(eq){
  105.                 assert(htable[v]==ev);
  106.             }else{
  107.                 assert(htable[v]==key);
  108.             }
  109.             return v;
  110.         }
  111.     }while(1);
  112. }

  113. int query_hash_entry(long long htable[],long long key)///return index to hash table
  114. {
  115.     long long ev=ECVALUE(key);
  116.     int v=hash(key);
  117.     do{
  118.         if(htable[v]==-1LL)return v;
  119.         if(htable[v]==key||htable[v]==ev)
  120.             return v;
  121.         v=(v+WALK)%STABLE;
  122.     }while(1);
  123. }

  124. void init_neighbour()
  125. {
  126.     int i,j;
  127.     for(i=0;i<N;i++){
  128.         for(j=0;j<N;j++){
  129.             SET s=EMPTY_SET;
  130.             ADD_INDEX(s,INDEX(i,j));
  131.             if(i>0&&j>0){
  132.                 ADD_INDEX(s,INDEX(i-1,j-1));
  133.             }
  134.             if(i>0){
  135.                 ADD_INDEX(s,INDEX(i-1,j));
  136.             }
  137.             if(j>0){
  138.                 ADD_INDEX(s,INDEX(i,j-1));
  139.             }
  140.             if(i>0&&j<N-1){
  141.                 ADD_INDEX(s,INDEX(i-1,j+1));
  142.             }
  143.             if(j<N-1){
  144.                 ADD_INDEX(s,INDEX(i,j+1));
  145.             }
  146.             if(i<N-1&&j>0){
  147.                 ADD_INDEX(s,INDEX(i+1,j-1));
  148.             }
  149.             if(i<N-1){
  150.                 ADD_INDEX(s,INDEX(i+1,j));
  151.             }
  152.             if(i<N-1&&j<N-1){
  153.                 ADD_INDEX(s,INDEX(i+1,j+1));
  154.             }
  155.             nghb[INDEX(i,j)]=s;
  156.         }
  157.     }
  158. }

  159. void visit(long long neighb)
  160. {
  161.         int i;
  162.         int e=query_hash_entry(htable,neighb);
  163.         if(htable[e]==neighb){
  164.                 int ee=query_hash_entry(htable2,neighb);
  165.                 if(htable2[ee]==-1){
  166.                         htable2[ee]=neighb;
  167.                         lec++;
  168.                         for(i=0;i<BITS;i++){
  169.                                 if(TEST_BIT(neighb,i)==0){
  170.                                         long long newneighb=neighb;
  171.                                         newneighb|=nghb[i];
  172.                                         visit(newneighb);
  173.                                 }
  174.                         }
  175.                 }
  176.         }else{
  177.                 for(i=0;i<BITS;i++){
  178.                         if(TEST_BIT(neighb,i)==0){
  179.                                 long long newneighb=neighb;
  180.                                 newneighb|=nghb[i];
  181.                                 int e2=query_hash_entry(htable,newneighb);
  182.                                 if(htable[e2]==newneighb){
  183.                                         visit(newneighb);
  184.                                         break;
  185.                                 }
  186.                         }
  187.                 }
  188.         }
  189. }

  190. int query(long long neighb)
  191. {
  192.     int e=query_hash_entry(htable,neighb);
  193.     if(htable[e]!=-1)
  194.         return e;
  195.     int i;
  196.     for(i=0;i<BITS;i++){
  197.         if(TEST_BIT(neighb,i)==0){
  198.             long long newneighb=neighb;
  199.             newneighb|=nghb[i];
  200.             int r=query(newneighb);
  201.             if(htable[r]==newneighb)
  202.                 break;
  203.         }
  204.     }
  205.     if(i<BITS){///find any status is newneighb
  206.         return add_hash(htable,neighb,true);
  207.     }else{
  208.         return add_hash(htable,neighb,false);
  209.     }
  210. }

  211. int cmpll(const void *p,const void *q)
  212. {
  213.         const long long *lp=(const long long *)p;
  214.         const long long *lq=(const long long *)q;
  215.         if(*lp==*lq)return 0;
  216.         if(*lp<*lq)return -1;
  217.         return 1;
  218. }

  219. int _tmain(int argc, _TCHAR* argv[])
  220. {
  221.         int i,j;
  222.     init();
  223.     init_neighbour();
  224.     int s=query(0LL);
  225.     if(htable[s]==0LL){
  226.         printf("First fail\n");
  227.     }else{
  228.         printf("First successful\n");
  229.     }
  230.         printf("Total table size %d\n",hc);
  231.         printf("Total eq stat found %d\n",ec);
  232.         printf("Total neq stat found %d\n",nec);
  233.         visit(0LL);
  234.         printf("Total lec stat found %d\n",lec);
  235. //        dump_ec(htable2);
  236. #if 0
  237.         for(i=0;i<BITS;i++){
  238.                 long long r=nghb[i];
  239.                 printf("%d set={ ",i);
  240.                 for(j=0;j<BITS;j++){
  241.                         if(!TEST_BIT(r,j)){
  242.                                 long long newneighb=r;
  243.                                 newneighb|=nghb[j];
  244.                                 int u=query_hash_entry(htable,newneighb);
  245.                                 if(htable[u]==newneighb){
  246.                                         printf("%d ",j);
  247.                                 }
  248.                         }
  249.                 }
  250.                 printf("}\n");
  251.         }
  252. #endif
  253.         return 0;
  254. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 08:21:38 | 显示全部楼层
15# mathe
用什么编译器编译
C:\vc6>cl ch.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

ch.cpp
ch.cpp(4) : fatal error C1083: Cannot open include file: 'stdafx.h': No such file or directory

C:\vc6>cl ch.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

ch.cpp
ch.cpp(10) : error C2632: 'long' followed by 'long' is illegal
ch.cpp(32) : error C2632: 'long' followed by 'long' is illegal
ch.cpp(33) : error C2632: 'long' followed by 'long' is illegal
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 08:48:08 | 显示全部楼层
VC7,8,9,gcc
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 08:54:05 | 显示全部楼层
要多大内存啊?我1G内存的电脑都跑不动。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 09:16:51 | 显示全部楼层
那么把main函数中对visit的调用删除(那部分没有用,是我自己调试用的)然后将全局变量htable2也删除,visit函数删除
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 09:17:21 | 显示全部楼层
如果在vc6下,将所有long long 改为__int64.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-17 16:56 , Processed in 0.068796 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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