Advertisement
YaQNjx

A2048 single file version

Nov 16th, 2019
720
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.55 KB | None | 0 0
  1. EXPORT lib2048_ADD(now, pool)
  2. BEGIN
  3. LOCAL th, elem, pos, m;
  4.  
  5. FOR th FROM 1 TO SIZE(pool) DO
  6. pool(th)►elem;
  7. elem(CEILING(RANDOM(SIZE(elem))))►m;
  8. WHILE 1 DO
  9. {CEILING(RANDOM(4)),CEILING(RANDOM(4))}►pos;
  10. IF now(pos(1),pos(2))==0 THEN
  11. BREAK;
  12. END;
  13. END;
  14. m►now(pos(1),pos(2));
  15. END;
  16. RETURN now;
  17. END;
  18.  
  19.  
  20. EXPORT lib2048_MOVE(now, move)
  21. BEGIN
  22. LOCAL pos_now, pos_prev, next, num_now, num_prev, row,col, score;
  23. LOCAL pos_head, offset_row, offset_col, num_max;
  24.  
  25. MAKEMAT(0,4,4)►next;0►score;0►num_max;
  26. move(1)►pos_head;move(2)►offset_row;move(3)►offset_col;
  27.  
  28. //{{4,1},{-1,0},{0,1}}
  29. FOR col FROM 0 TO 3 DO
  30. 0►num_prev;
  31. pos_head+col*offset_col-offset_row►pos_prev;
  32. FOR row FROM 0 TO 3 DO
  33. pos_head+col*offset_col+row*offset_row►pos_now;
  34. now(pos_now(1),pos_now(2))►num_now;
  35. IF num_now≠0 THEN
  36. IF num_now==num_prev THEN
  37. num_prev*2►num_prev;
  38. num_prev►next(pos_prev(1),pos_prev(2));
  39. MAX(num_prev,num_max)►num_max;
  40. score+num_prev►score;
  41. 0►num_prev;
  42. ELSE
  43. pos_prev+offset_row►pos_prev;
  44. num_now►next(pos_prev(1),pos_prev(2));
  45. num_now►num_prev;
  46. END;
  47. END;
  48. END;
  49. END;
  50. RETURN {next,score,num_max};
  51. END;
  52.  
  53.  
  54. EXPORT lib2048_IFEND(now)
  55. BEGIN
  56. LOCAL row,col,out;
  57. 2►out;
  58.  
  59. FOR row FROM 1 TO 4 DO
  60. FOR col FROM 1 TO 3 DO
  61. IF now(row,col)==now(row,col+1) THEN
  62. 1►out;
  63. END;
  64. END;
  65. END;
  66.  
  67. FOR row FROM 1 TO 3 DO
  68. FOR col FROM 1 TO 4 DO
  69. IF now(row,col)==now(row+1,col) THEN
  70. 1►out;
  71. END;
  72. END;
  73. END;
  74.  
  75. FOR row FROM 1 TO 4 DO
  76. FOR col FROM 1 TO 4 DO
  77. IF now(row,col)==0 THEN
  78. 0►out;
  79. END;
  80. END;
  81. END;
  82.  
  83. RETURN out;
  84. END;
  85.  
  86.  
  87. //由于发现以"上左下左上左下左..."的操作就能吊打本AI,故此AI被弃用
  88. // (ㄒoㄒ)/~~ 凭什么人家连瞎子都打不过
  89. EXPORT lib2048_AUTO(now, pool, try, deep)
  90. BEGIN
  91. LOCAL score, p, ppool, out, sum, tha, lsum, thb;
  92. LOCAL thc,p2,t;
  93.  
  94. {{{1,1},{1,0},{0,1}},{{1,1},{0,1},{1,0}},{{4,1},{-1,0},{0,1}},{{4,4},{0,-1},{-1,0}}}►ppool;
  95. {0,0,0,0}►lsum;
  96.  
  97. FOR tha FROM 1 TO 3 DO
  98. ppool(tha)►p;
  99. 0►sum;
  100. FOR thb FROM 1 TO try DO
  101. 0►score;
  102. p►p2;
  103. FOR thc FROM 1 TO deep DO
  104. lib2048_MOVE(now,{p2(1),p2(2),p2(3)})►out;
  105. out(1) ► now;
  106. out(2) + score ► score;
  107. lib2048_IFEND(now)►t;
  108. IF t==2 THEN
  109. BREAK;
  110. END;
  111. IF t==0 THEN
  112. lib2048_ADD(now, {pool})►now;
  113. END;
  114. ppool(CEILING(RANDOM(3)))►p2;
  115. END;
  116. sum+score►sum;
  117. END;
  118. sum►lsum(tha);
  119. END;
  120. RETURN ppool(POS(lsum,MAX(lsum)));
  121. END;
  122.  
  123.  
  124. EXPORT lib2048_STAT(now)
  125. BEGIN
  126. LOCAL row, col, score, max;
  127.  
  128. 0►score;0►max;
  129.  
  130. FOR row FROM 1 TO 4 DO
  131. FOR col FROM 1 TO 4 DO
  132. IF now(row, col) ≥ 4 THEN
  133. now(row, col)►max;
  134. score + 2 ^ ((LOG(now(row, col)) / LOG(2)) - 1)►score;
  135. END;
  136. IF now(row, col) > max THEN
  137. now(row, col)►max;
  138. END;
  139. END;
  140. END;
  141.  
  142. RETURN {score, max};
  143. END;
  144.  
  145.  
  146. EXPORT lib2048_UNLUCKY(now)
  147. BEGIN
  148. LOCAL row, col, stat, big, count, poss, pos;
  149. {0, 0, 0}►big;
  150. {0, 0, 0}►count;
  151. {{},{},{}}►poss;
  152.  
  153. lib2048_STAT(now)►stat;
  154. stat(2)►big(1);
  155.  
  156. IF big(1) ≤ 256 THEN
  157. RETURN {0, now};
  158. END;
  159.  
  160. big(1) / 2 ► big(2);
  161. big(2) / 2 ► big(3);
  162.  
  163. FOR row FROM 1 TO 4 DO
  164. FOR col FROM 1 TO 4 DO
  165. IF now(row, col) == big(1) THEN
  166. CONCAT(poss(1),{{row, col}}) ► poss(1);
  167. count(1) + 1 ► count(1);
  168. END;
  169. IF now(row, col) == big(2) THEN
  170. CONCAT(poss(2),{{row, col}}) ► poss(2);
  171. count(2) + 1 ► count(2);
  172. END;
  173. IF now(row, col) == big(3) THEN
  174. CONCAT(poss(3),{{row, col}}) ► poss(3);
  175. count(3) + 1 ► count(3);
  176. END;
  177. END;
  178. END;
  179.  
  180. IF count(1) ≥ 2 THEN
  181. poss(1) ► pos;
  182. pos(1) ► pos;
  183. big(1) * 2 ► now(pos(1),pos(2));
  184.  
  185. poss(1) ► pos;
  186. pos(2) ► pos;
  187. 0 ► now(pos(1),pos(2));
  188. RETURN {1, now, big(1) * 2};
  189. END;
  190.  
  191. IF count(1) ≥ 1 AND count(2) ≥ 2 THEN
  192. poss(1) ► pos;
  193. pos(1) ► pos;
  194. big(1) * 2 ► now(pos(1),pos(2));
  195.  
  196. poss(2) ► pos;
  197. pos(1) ► pos;
  198. 0 ► now(pos(1),pos(2));
  199.  
  200. poss(2) ► pos;
  201. pos(2) ► pos;
  202. 0 ► now(pos(1),pos(2));
  203. RETURN {1, now, big(1) * 2};
  204. END;
  205.  
  206. IF count(1) ≥ 1 AND count(2) ≥ 1 AND count(3) ≥ 2 THEN
  207. poss(1) ► pos;
  208. pos(1) ► pos;
  209. big(1) * 2 ► now(pos(1),pos(2));
  210.  
  211. poss(2) ► pos;
  212. pos(1) ► pos;
  213. 0 ► now(pos(1),pos(2));
  214.  
  215. poss(3) ► pos;
  216. pos(1) ► pos;
  217. 0 ► now(pos(1),pos(2));
  218.  
  219. poss(3) ► pos;
  220. pos(2) ► pos;
  221. 0 ► now(pos(1),pos(2));
  222. RETURN {1, now, big(1) * 2};
  223. END;
  224.  
  225. RETURN {0, now};
  226. END;
  227.  
  228.  
  229. EXPORT lib2048_INVERT(flash, delay, times)
  230. BEGIN
  231. LOCAL th;
  232.  
  233. IF flash == 0 THEN
  234. RETURN flash;
  235. END;
  236.  
  237. FOR th FROM 1 TO times DO
  238. WAIT(delay);
  239. INVERT;
  240. END;
  241. END;
  242.  
  243.  
  244. END;
  245.  
  246. EXPORT lib2048_REDRAW(completely,now,show_text,score,num_max)
  247. BEGIN
  248. LOCAL row, col, num_now, long, color, th;
  249.  
  250. IF completely THEN
  251. RECT_P();
  252.  
  253. FOR th FROM 0 TO 124 STEP 31 DO
  254. LINE_P(th,0,th,124,0);
  255. LINE_P(0,th,124,th,0);
  256. END;
  257. END;
  258.  
  259. IF show_text THEN
  260. TEXTOUT_P("当前得分:" + string(score),143,15,2,0,255,3);
  261. TEXTOUT_P("最大数字:" + string(num_max),143,39,2,0,255,3);
  262. END;
  263.  
  264. FOR row FROM 1 TO 4 DO
  265. FOR col FROM 1 TO 4 DO
  266. now(row,col)►num_now;
  267. IF num_now==0 THEN
  268. RECT_P(31*col-29,31*row-29,31*col-2,31*row-2,3);
  269. ELSE
  270. 0►color;
  271. FLOOR(LOG(num_now))+1►long;
  272. RECT_P(31*col-29,31*row-29,31*col-2,31*row-2,color);
  273. TEXTOUT_P(num_now,31*col-15-3*long,31*row-22,1,3);
  274. END;
  275. END;
  276. END;
  277.  
  278. END;
  279.  
  280. EXPORT A2048()
  281. BEGIN
  282. LOCAL score, num_max, now, next, key, output, th;
  283. LOCAL show_text, add_when_nothing_changed, load, unlucky_protect, move_pool, flash, ifend_output, pool;
  284.  
  285.  
  286. //参数区
  287. //0为否,1为是
  288.  
  289. //随机池
  290. //默认为{2,2,2,2,2,2,2,2,2,4}
  291. {2,2,2,2,2,2,2,2,2,4}►pool;
  292.  
  293. //是否显示当前得分和最大数字
  294. 1►show_text;
  295.  
  296. //当按下一个方向键,数字没有任何变化时,是否添加新的数字
  297. //原版2048游戏中为否
  298. 1►add_when_nothing_changed;
  299.  
  300. //启动时加载的关卡
  301. //[0],代表从头开始,随机生成两个方块
  302. //应为一个4×4的矩阵,如有错误,程序可能会崩溃!
  303. //如[[0,0,0,0],[0,0,0,0],[0,0,0,0],[4,4,2,2]]►load;
  304. [0]►load;
  305.  
  306. //开启非酋保护,在一些很不幸运的情况下提供一些帮助
  307. //(每局游戏只有一次保护)
  308. //(包括加载的关卡)
  309. //详情请查看lib2048_UNLUCKY(now)
  310. 1►unlucky_protect;
  311.  
  312. //开启闪烁效果
  313. 1►flash;
  314.  
  315. //参数区结束
  316.  
  317.  
  318. //初始化变量
  319. 0►score;MAKEMAT(0,4,4)►next;0►num_max;
  320. {0,0,0,0,0,0,0,0,{{1,1},{1,0},{0,1}},{{4,4},{0,-1},{-1,0}},0,0,0,{{1,1},{0,1},{1,0}},{{4,1},{-1,0},{0,1}}}►move_pool;
  321.  
  322. //加载输入的关卡
  323. load►now;
  324. IF now == [0] THEN
  325. MAKEMAT(0,4,4)►now;
  326. lib2048_ADD(now, {pool,pool})►now;
  327. ELSE
  328. lib2048_STAT(now)►output;
  329. output[1]►score;
  330. output[2]►num_max;
  331. END;
  332.  
  333. //绘制界面
  334. lib2048_REDRAW(1,now,show_text,score,num_max);
  335.  
  336. //主循环
  337. WHILE 1 DO
  338. //获取按键,进行移动,处理结果,进行重绘
  339. GETKEY►key;
  340.  
  341. IF POS({9,10,14,15},key)==0 THEN
  342. CONTINUE;
  343. END;
  344. lib2048_MOVE(now,move_pool(key))►output;
  345.  
  346. output(1) ► next;
  347. output(2) + score ► score;
  348. MAX(num_max,output(3)) ► num_max;
  349.  
  350. lib2048_REDRAW(0,next,show_text,score,num_max);
  351.  
  352. lib2048_IFEND(next)►ifend_output;
  353.  
  354. //如果有空位,添加新的方块
  355. IF ifend_output == 0 THEN
  356. IF next≠now OR add_when_nothing_changed THEN
  357. WAIT(0.2);
  358. lib2048_ADD(next, {pool})►next;
  359. lib2048_REDRAW(0,next,show_text,score,num_max);
  360. END;
  361. END;
  362.  
  363. //判定是否死亡
  364. IF ifend_output == 2 THEN
  365. lib2048_UNLUCKY(next)►output;
  366. IF unlucky_protect == 0 OR output(1) == 0 THEN
  367. TEXTOUT_P("你死了!",143,63,2,0,255,3);
  368. INVERT;
  369. WAIT(3);
  370. FREEZE;
  371. BREAK;
  372. END;
  373.  
  374. 0►unlucky_protect;
  375. lib2048_INVERT(flash,0.5,2);
  376. WAIT(0.5);
  377.  
  378. //清空键盘缓冲区
  379. FOR th FROM 1 TO 20 DO
  380. GETKEY;
  381. END;
  382. MSGBOX("酋长大人,你触发了非酋保护!");
  383.  
  384. lib2048_REDRAW(1,next,show_text,score,num_max);
  385. lib2048_INVERT(flash,0.5,5);
  386. WAIT(0.5);
  387.  
  388. output(2) ► next;
  389. output(3) + score ► score;
  390. output(3) ► num_max;
  391.  
  392. lib2048_REDRAW(1,next,show_text,score,num_max);
  393. WAIT(0.1);
  394. lib2048_INVERT(flash,0.1,6);
  395. END;
  396.  
  397. next►now;
  398.  
  399. END;
  400. END;
  401.  
  402. //space.bilibili.com/14228634
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement