Rule.cs
上传用户:yiyuerguo
上传日期:2014-09-27
资源大小:3781k
文件大小:9k
源码类别:

C#编程

开发平台:

Others

  1. using System;
  2. namespace FiveStones
  3. {
  4. /// <summary>
  5. /// Rule 的摘要说明。
  6. /// 游戏规则类
  7. /// </summary>
  8. public class Rule
  9. {
  10. /// <summary>
  11. /// 判断下棋位置是否有子
  12. /// </summary>
  13. /// <param name="m"></param>
  14. /// <param name="n"></param>
  15. /// <param name="arrchessboard"></param>
  16. /// <returns></returns>
  17. public static bool IsExist(int m, int n, int[,] arrchessboard)
  18. {
  19. if (arrchessboard[m,n] < 2)
  20. {
  21. return true;
  22. }
  23. else
  24. {
  25. return false;
  26. }
  27. }
  28. /// <summary>
  29. /// 返回结果(1:双三禁手失败/2:双四禁手失败/3:长连禁手失败/4:胜利/5:平局/6:继续)
  30. /// </summary>
  31. /// <param name="m"></param>
  32. /// <param name="n"></param>
  33. /// <param name="arrchessboard"></param>
  34. /// <returns></returns>
  35. public static int Result(int m, int n, int[,] arrchessboard)
  36. {
  37. //m,n点四个方向的连子数,依次正东正西,正南正北方,西北东南,西南东北
  38. int[] arrf = new int[4];
  39. arrf[0] = Xnum(m,n,arrchessboard);
  40. arrf[1] = Ynum(m,n,arrchessboard);
  41. arrf[2] = YXnum(m,n,arrchessboard);
  42. arrf[3] = XYnum(m,n,arrchessboard);
  43. //测试
  44. //return Ynum(m,n,arrchessboard);
  45. //检查是否失败
  46. if (IsFail(arrf, arrchessboard[m,n]) > 0)
  47. {
  48. return IsFail(arrf, arrchessboard[m,n]);
  49. }
  50. else
  51. {
  52. //检查是否胜利
  53. if (IsWin(arrf))
  54. {
  55. return 4;
  56. }
  57. else
  58. {
  59. //检查是否平局
  60. if (IsTie(arrchessboard))
  61. {
  62. return 5;
  63. }
  64. else
  65. {
  66. return 6;
  67. }
  68. }
  69. }
  70. }
  71. #region  检查是否失败,是否胜利,是否平局
  72. /// <summary>
  73. /// 是否失败(0:没有失败/1:双三禁手/2:双四禁手/3:长连禁手)
  74. /// </summary>
  75. /// <param name="arr"></param>
  76. /// <param name="stoneflag">是黑棋还是白棋</param>
  77. /// <returns>没有失败:0/双三禁手:1/双四禁手:2/长连禁手:3</returns>
  78. public static int IsFail(int[] arr, int stoneflag)
  79. {
  80. if (stoneflag == 1)
  81. {
  82. //如果是白棋不验证因为白棋无禁手
  83. return 0;
  84. }
  85. else
  86. {
  87. //验证双三禁手(该处的双三因该是活的双三)
  88. int num = 0; //活的3子相连的个数
  89. for (int i=0;i<4;i++)
  90. {
  91. if (arr[i] == 3)
  92. {
  93. num++;
  94. }
  95. }
  96. if (num > 1)
  97. {
  98. return 1;
  99. }
  100. //验证双四禁手(该处的双四因该是活的双四)
  101. num = 0; //活的4子相连的个数
  102. for (int i=0;i<4;i++)
  103. {
  104. if (arr[i] == 4)
  105. {
  106. num++;
  107. }
  108. }
  109. if (num > 1)
  110. {
  111. return 2;
  112. }
  113. //验证长连禁手
  114. for (int i=0;i<4;i++)
  115. {
  116. if (Math.Abs(arr[i]) > 5)
  117. {
  118. return 3;
  119. }
  120. }
  121. return 0;
  122. }
  123. }
  124. /// <summary>
  125. /// 是否胜利
  126. /// </summary>
  127. /// <param name="arr"></param>
  128. /// <returns>胜利:true</returns>
  129. private static bool IsWin(int[] arr)
  130. {
  131. for (int i=0;i<4;i++)
  132. {
  133. if (Math.Abs(arr[i]) == 5)
  134. {
  135. return true;
  136. }
  137. }
  138. return false;
  139. }
  140. /// <summary>
  141. /// 是否平局
  142. /// </summary>
  143. /// <param name="arrchessboard"></param>
  144. /// <returns>平局:true</returns>
  145. private static bool IsTie(int[,] arrchessboard)
  146. {
  147. //当所有位置都有子时为平局
  148. for (int i=0;i<15;i++)
  149. {
  150. for (int j=0;j<15;j++)
  151. {
  152. if (arrchessboard[i,j] == 2)
  153. return false;
  154. }
  155. }
  156. return true;
  157. }
  158. #endregion
  159. #region 从四个方向检测,连子个数
  160. /// <summary>
  161. /// 正东正西检测与m,n点棋子相同的棋子个数
  162. /// </summary>
  163. /// <param name="m"></param>
  164. /// <param name="n"></param>
  165. /// <param name="arrchessboard"></param>
  166. /// <returns>如果返回负值则表示改方向在无子可下</returns>
  167. public static int Xnum(int m, int n, int[,] arrchessboard)
  168. {
  169. //检查是否无子可下(当flag=2时表示无子可下)
  170. int flag = 0;
  171. //连子个数
  172. int num = 1;
  173. //正东方向检查(x+)
  174. int i = m+1;
  175. //不超出棋格
  176. while(i < 15)
  177. {
  178. //前方的棋子与m,n点不同时跳出循环
  179. if (arrchessboard[i,n] == arrchessboard[m,n])
  180. {
  181. num++;
  182. i++;
  183. }
  184. else
  185. {
  186. break;
  187. }
  188. }
  189. //正东方向超出棋格
  190. if (i==15)
  191. {
  192. flag++;
  193. }
  194. else
  195. {
  196. //正东方向有别的子不可在下
  197. if(arrchessboard[i,n] != 2)
  198. {
  199. flag++;
  200. }
  201. }
  202. //正西方向检查(x-)
  203.             i = m-1;
  204. while(i >= 0)
  205. {
  206. //前方的棋子与m,n点不同时跳出循环
  207. if (arrchessboard[i,n] == arrchessboard[m,n])
  208. {
  209. num++;
  210. i--;
  211. }
  212. else
  213. {
  214. break;
  215. }
  216. }
  217. //正西方向超出棋格
  218. if (i == -1)
  219. {
  220. flag++;
  221. }
  222. else
  223. {
  224. //正西方向有别的子不可在下
  225. if(arrchessboard[i,n] != 2)
  226. {
  227. flag++;
  228. }
  229. }
  230. if (flag == 2)
  231. {
  232. return -num;
  233. }
  234. else
  235. {
  236. if (flag == 1 && num == 3 )
  237. {
  238. //连子数为3时有一边不能下就不是活三
  239. return -num;
  240. }
  241. else
  242. {
  243. return num;
  244. }
  245. }
  246. }
  247. /// <summary>
  248. /// 正南正北方向检测
  249. /// </summary>
  250. /// <param name="m"></param>
  251. /// <param name="n"></param>
  252. /// <param name="arrchessboard"></param>
  253. /// <returns>如果返回负值则表示改方向在无子可下</returns>
  254. public static int Ynum(int m, int n, int[,] arrchessboard)
  255. {
  256. //检查是否无子可下(当flag=2时表示无子可下)
  257. int flag = 0;
  258. //连子个数
  259. int num = 1;
  260. //正南方向检查(y+)
  261. int i = n+1;
  262. while(i<15)
  263. {
  264. //前方的棋子与m,n点不同时跳出循环
  265. if (arrchessboard[m,i] == arrchessboard[m,n])
  266. {
  267. num++;
  268. i++;
  269. }
  270. else
  271. {
  272. break;
  273. }
  274. }
  275. //正南方向超出棋格
  276. if (i==15)
  277. {
  278. flag++;
  279. }
  280. else
  281. {
  282. //正南方向有别的子不可在下
  283. if(arrchessboard[m,i] != 2)
  284. {
  285. flag++;
  286. }
  287. }
  288. //正北方向检查(y-)
  289. i = n-1;
  290. while(i >= 0)
  291. {
  292. //前方的棋子与m,n点不同时跳出循环
  293. if (arrchessboard[m,i] == arrchessboard[m,n])
  294. {
  295. num++;
  296. i--;
  297. }
  298. else
  299. {
  300. break;
  301. }
  302. }
  303. //正北方向超出棋格
  304. if (i == -1)
  305. {
  306. flag++;
  307. }
  308. else
  309. {
  310. //正北方向有别的子不可在下
  311. if(arrchessboard[m,i] != 2)
  312. {
  313. flag++;
  314. }
  315. }
  316. if (flag == 2)
  317. {
  318. return -num;
  319. }
  320. else
  321. {
  322. if (flag == 1 && num == 3 )
  323. {
  324. //连子数为3时有一边不能下就不是活三
  325. return -num;
  326. }
  327. else
  328. {
  329. return num;
  330. }
  331. }
  332. }
  333. /// <summary>
  334. /// 西北东南方向检查
  335. /// </summary>
  336. /// <param name="m"></param>
  337. /// <param name="n"></param>
  338. /// <param name="arrchessboard"></param>
  339. /// <returns>如果返回负值则表示改方向在无子可下</returns>
  340. public static int YXnum(int m, int n, int[,] arrchessboard)
  341. {
  342. //检查是否无子可下(当flag=2时表示无子可下)
  343. int flag = 0;
  344. //连子个数
  345. int num = 1;
  346. //东南方向(x+,y+)
  347. int i = m+1;
  348. int j = n+1;
  349. //不超出棋格
  350. while(i < 15 && j < 15)
  351. {
  352. //前方的棋子与m,n点不同时跳出循环
  353. if (arrchessboard[i,j] == arrchessboard[m,n])
  354. {
  355. num++;
  356. i++;
  357. j++;
  358. }
  359. else
  360. {
  361. break;
  362. }
  363. }
  364. //东南方向超出棋格
  365. if (i==15 || j==15)
  366. {
  367. flag++;
  368. }
  369. else
  370. {
  371. //东南方向有别的子不可在下
  372. if(arrchessboard[i,j] != 2)
  373. {
  374. flag++;
  375. }
  376. }
  377. //西北方向(x-,y-)
  378. i = m-1;
  379. j = n-1;
  380. //不超出棋格
  381. while(i >= 0 && j >= 0)
  382. {
  383. //前方的棋子与m,n点不同时跳出循环
  384. if (arrchessboard[i,j] == arrchessboard[m,n])
  385. {
  386. num++;
  387. i--;
  388. j--;
  389. }
  390. else
  391. {
  392. break;
  393. }
  394. }
  395. //西北方向超出棋格
  396. if (i == -1 || j == -1)
  397. {
  398. flag++;
  399. }
  400. else
  401. {
  402. //西北方向有别的子不可在下
  403. if(arrchessboard[i,j] != 2)
  404. {
  405. flag++;
  406. }
  407. }
  408. if (flag == 2)
  409. {
  410. return -num;
  411. }
  412. else
  413. {
  414. if (flag == 1 && num == 3 )
  415. {
  416. //连子数为3时有一边不能下就不是活三
  417. return -num;
  418. }
  419. else
  420. {
  421. return num;
  422. }
  423. }
  424. }
  425. /// <summary>
  426. /// 西南东北方向检查
  427. /// </summary>
  428. /// <param name="m"></param>
  429. /// <param name="n"></param>
  430. /// <param name="arrchessboard"></param>
  431. /// <returns>如果返回负值则表示改方向在无子可下</returns>
  432. public static int XYnum(int m, int n, int[,] arrchessboard)
  433. {
  434. //检查是否无子可下(当flag=2时表示无子可下)
  435. int flag = 0;
  436. //连子个数
  437. int num = 1;
  438. //西南方向(x-,y+)
  439. int i = m-1;
  440. int j = n+1;
  441. //不超出棋格
  442. while(i >= 0 && j < 15)
  443. {
  444. //前方的棋子与m,n点不同时跳出循环
  445. if (arrchessboard[i,j] == arrchessboard[m,n])
  446. {
  447. num++;
  448. i--;
  449. j++;
  450. }
  451. else
  452. {
  453. break;
  454. }
  455. }
  456. //西南方向超出棋格
  457. if (i == -1 || j == 15)
  458. {
  459. flag++;
  460. }
  461. else
  462. {
  463. //西南方向有别的子不可在下
  464. if(arrchessboard[i,j] != 2)
  465. {
  466. flag++;
  467. }
  468. }
  469. //东北方向(x+,y-)
  470. i = m+1;
  471. j = n-1;
  472. //不超出棋格
  473. while(i < 15 && j >= 0)
  474. {
  475. //前方的棋子与m,n点不同时跳出循环
  476. if (arrchessboard[i,j] == arrchessboard[m,n])
  477. {
  478. num++;
  479. i++;
  480. j--;
  481. }
  482. else
  483. {
  484. break;
  485. }
  486. }
  487. //东北方向超出棋格
  488. if (i == 15 || j == -1)
  489. {
  490. flag++;
  491. }
  492. else
  493. {
  494. //东北方向有别的子不可在下
  495. if(arrchessboard[i,j] != 2)
  496. {
  497. flag++;
  498. }
  499. }
  500. if (flag == 2)
  501. {
  502. return -num;
  503. }
  504. else
  505. {
  506. if (flag == 1 && num == 3 )
  507. {
  508. //连子数为3时有一边不能下就不是活三
  509. return -num;
  510. }
  511. else
  512. {
  513. return num;
  514. }
  515. }
  516. }
  517. #endregion
  518. }
  519. }