找回密码
 欢迎注册
楼主: 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-11-22 11:03 , Processed in 0.027754 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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