Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

608 lines
11 KiB

  1. //
  2. // MineSweeper By Andriy Doroshchuk
  3. //
  4. global cursorOverClosed = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
  5. global cursorOverOpened = CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
  6. global frameColor = CA.F_RED | CA.F_GREEN | CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE;
  7. global closedColor = CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE;
  8. global openedColor = CA.F_BLUE | CA.B_BLUE | CA.TRAILING_BYTE;
  9. global numberColor = CA.F_BLUE | CA.F_GREEN| CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
  10. global markColor = CA.F_BLUE | CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
  11. global mineColor = CA.F_GREEN| CA.F_RED | CA.B_BLUE | CA.TRAILING_BYTE;
  12. global helpColor = CA.F_GREEN| CA.F_RED | CA.F_BLUE |CA.B_BLUE | CA.TRAILING_BYTE;
  13. global winColor = CA.F_GREEN| CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
  14. global looseColor = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
  15. // wait till key will be released
  16. global WaitForKey = function(key)
  17. {
  18. for (;ISPRESSED(key);){}
  19. };
  20. // print debug message
  21. global DebugText = function(text)
  22. {
  23. CATTRIB(frameColor);
  24. XYTEXT(0, 0, text);
  25. };
  26. game = table(
  27. x = 15,
  28. y = 0,
  29. lx = 30,
  30. ly = 15,
  31. mineCurr = 0,
  32. mineMax = 10,
  33. currLevel = 2,
  34. cX = 0,
  35. cY = 0,
  36. field = table(),
  37. // index in the field
  38. Index = function(x, y)
  39. {
  40. return (y*.lx+x);
  41. },
  42. // draw field frame
  43. DrawFrame = function()
  44. {
  45. i;
  46. // set color
  47. CATTRIB(frameColor);
  48. // borders
  49. for (i=.x+1; i<.x+.lx+1; i=i+1)
  50. {
  51. XYTEXT(i, .y, "-");
  52. XYTEXT(i, .y+.ly+1, "-");
  53. }
  54. for (i=.y+1; i<.y+.ly+1; i=i+1)
  55. {
  56. XYTEXT(.x, i, "|");
  57. XYTEXT(.x+.lx+1, i, "|");
  58. }
  59. // corners
  60. XYTEXT(.x, .y, "\1");
  61. XYTEXT(.x+.lx+1, .y, "\1");
  62. XYTEXT(.x, .y+.ly+1, "\1");
  63. XYTEXT(.x+.lx+1, .y+.ly+1, "\1");
  64. // count
  65. XYTEXT(.x+3, .y, "[" + .mineCurr.String() + ":" + .mineMax.String() + "]");
  66. },
  67. // field cell drawing
  68. DrawCell = function(x, y, cursor)
  69. {
  70. index = .Index(x, y);
  71. // debug cell = .field[index].String();
  72. cell = " ";
  73. // closed cell
  74. if (.field[index] < 10)
  75. {
  76. if (cursor)
  77. {
  78. CATTRIB(cursorOverClosed);
  79. cell = "W";
  80. }
  81. else
  82. {
  83. CATTRIB(closedColor);
  84. }
  85. }
  86. // opened cell
  87. else if (.field[index] < 20)
  88. {
  89. if (.field[index] == 10)
  90. {
  91. if (cursor)
  92. {
  93. CATTRIB(cursorOverOpened);
  94. cell = "W";
  95. }
  96. else
  97. {
  98. CATTRIB(openedColor);
  99. }
  100. }
  101. else if (.field[index] < 19)
  102. {
  103. if (cursor)
  104. {
  105. CATTRIB(cursorOverOpened);
  106. }
  107. else
  108. {
  109. CATTRIB(numberColor);
  110. }
  111. val = .field[index] % 10;
  112. cell = val.String();
  113. }
  114. else
  115. {
  116. CATTRIB(mineColor);
  117. cell = "@";
  118. }
  119. }
  120. // intended mine
  121. else
  122. {
  123. if (cursor)
  124. {
  125. CATTRIB(cursorOverOpened);
  126. }
  127. else
  128. {
  129. CATTRIB(markColor);
  130. }
  131. cell = "?";
  132. }
  133. XYTEXT(.x+x+1, .y+y+1, cell);
  134. },
  135. // field cell drawing
  136. DrawCurrCell = function(cursor)
  137. {
  138. .DrawCell(.cX, .cY, cursor);
  139. },
  140. // field drawing
  141. DrawField = function()
  142. {
  143. i; j;
  144. .DrawFrame();
  145. for (i=0; i<.lx; i=i+1)
  146. {
  147. for (j=0; j<.ly; j=j+1)
  148. {
  149. .DrawCell(i, j, 0);
  150. }
  151. }
  152. },
  153. // help string
  154. HelpString = function(msg, line, mode)
  155. {
  156. if (mode == 1)
  157. {
  158. CATTRIB(CA.F_BLUE | CA.F_GREEN | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE);
  159. }
  160. else if (mode == 2)
  161. {
  162. CATTRIB(CA.F_RED | CA.B_BLACK | CA.TRAILING_BYTE);
  163. }
  164. else
  165. {
  166. CATTRIB(CA.F_GREEN | CA.B_BLACK | CA.TRAILING_BYTE);
  167. }
  168. XYTEXT(0, 25-line, " ");
  169. XYTEXT((80-msg.Length())/2, 25-line, msg);
  170. },
  171. // Initialise field
  172. InitField = function(level)
  173. {
  174. i; j;
  175. t1;t2;
  176. count; position; index;
  177. // clear screen
  178. CATTRIB(frameColor);
  179. CLS();
  180. // set current level
  181. .currLevel = level;
  182. // field extents
  183. if (level == 1)
  184. {
  185. .lx = 10;
  186. .ly = 10;
  187. .mineMax = 8;
  188. }
  189. else if (level == 2)
  190. {
  191. .lx = 18;
  192. .ly = 15;
  193. .mineMax = 35;
  194. }
  195. else
  196. {
  197. .lx = 30;
  198. .ly = 15;
  199. .mineMax = 90;
  200. }
  201. .x = (80-.lx)/2;
  202. .mineCurr = 0;
  203. // init field contents
  204. max = .lx*.ly;
  205. for (i=0; i<max; i=i+1)
  206. {
  207. .field[i] = 0;
  208. }
  209. // put mines on the field
  210. for (count=1; count<=.mineMax; count=count+1)
  211. {
  212. position = randint(0, .lx*.ly+1-count);
  213. for (i=0; i<.lx; i=i+1)
  214. {
  215. for (j=0; j<.ly; j=j+1)
  216. {
  217. index = .Index(i, j);
  218. if (.field[index] == 0)
  219. {
  220. if (position == 0)
  221. {
  222. .field[index] = 9;
  223. i = .lx;
  224. j = .ly;
  225. }
  226. else
  227. {
  228. position = position - 1;
  229. }
  230. }
  231. }
  232. }
  233. }
  234. // calculate mines environment
  235. for (i=0; i<.lx; i=i+1)
  236. {
  237. for (j=0; j<.ly; j=j+1)
  238. {
  239. if (.field[.Index(i, j)] == 9)
  240. {
  241. for (t1=i-1; t1<i+2; t1=t1+1)
  242. {
  243. for (t2=j-1; t2<j+2; t2=t2+1)
  244. {
  245. if ((t1!=i || t2!=j)
  246. && (t1>=0) && (t1<.lx)
  247. && (t2>=0) && (t2<.ly))
  248. {
  249. index = .Index(t1, t2);
  250. if (.field[index] < 9)
  251. {
  252. .field[index] = .field[index] + 1;
  253. }
  254. }
  255. }
  256. }
  257. }
  258. }
  259. }
  260. // draw field frame
  261. .DrawFrame();
  262. // set current cell
  263. .cX=.lx/2;
  264. .cY=.ly/2;
  265. .DrawField();
  266. .DrawCell(.cX, .cY, 1);
  267. .HelpString("", 4, 0);
  268. .HelpString("F2 - beginner. F3 - intermediate. F4 - expert", 2, 0);
  269. .HelpString("Enter - open. Space - mark as a mine. Backspace - open around.", 1, 0);
  270. },
  271. // restart current game
  272. RestartField = function()
  273. {
  274. .InitField(.currLevel);
  275. },
  276. // restart game after finishing
  277. Restart = function(win)
  278. {
  279. .HelpString("", 2, 0);
  280. .HelpString("", 1, 0);
  281. if (win)
  282. {
  283. .HelpString("Congratulations, you won! Press F1 to continue.", 4, 1);
  284. for (; !ISPRESSED(112);){}
  285. }
  286. else
  287. {
  288. .HelpString("Sorry, you are dead! Press F1 to continue.", 4, 2);
  289. .DrawField();
  290. }
  291. for (; !ISPRESSED(112);){}
  292. .RestartField();
  293. },
  294. // field opening when open an empty cell
  295. CheckCell = function(x, y)
  296. {
  297. i; j;
  298. index = .Index(x, y);
  299. if (.field[index] == 0)
  300. {
  301. .field[index] = 10;
  302. // check surrounding
  303. for (i=x-1; i<x+2; i=i+1)
  304. {
  305. for (j=y-1; j<y+2; j=j+1)
  306. {
  307. if ((i!=x || j!=y)
  308. && (i>=0) && (i<.lx)
  309. && (j>=0) && (j<.ly))
  310. {
  311. .CheckCell(i, j);
  312. }
  313. }
  314. }
  315. }
  316. else
  317. {
  318. if (.field[index] < 9)
  319. {
  320. .field[index] = .field[index] + 10;
  321. }
  322. }
  323. .DrawCell(x, y, 0);
  324. },
  325. // check win condition
  326. CheckWin = function()
  327. {
  328. i; j; index;
  329. count = 0;
  330. for (i=0; i<.lx; i=i+1)
  331. {
  332. for (j=0; j<.ly; j=j+1)
  333. {
  334. index = .Index(i, j);
  335. if (.field[index] < 10)
  336. {
  337. count = 0;
  338. i = .lx;
  339. j = .ly;
  340. }
  341. else if (.field[index] >= 20)
  342. {
  343. count = count + 1;
  344. }
  345. }
  346. }
  347. if (count == .mineMax)
  348. {
  349. .DrawCell(.cX, .cY, 0);
  350. .Restart(1);
  351. }
  352. else
  353. {
  354. .DrawCell(.cX, .cY, 1);
  355. }
  356. },
  357. // open field cell
  358. OpenCell = function(x, y, check)
  359. {
  360. i; j;
  361. index = .Index(x, y);
  362. if (!check)
  363. {
  364. if (.field[index] >= 20)
  365. {
  366. return;
  367. }
  368. }
  369. // check the field
  370. if (check && (.field[index] % 10) == 9)
  371. {
  372. for (i=0; i<.lx; i=i+1)
  373. {
  374. for (j=0; j<.ly; j=j+1)
  375. {
  376. index = .Index(i, j);
  377. .field[index] = (.field[index] % 10) + 10;
  378. }
  379. }
  380. .Restart(0);
  381. }
  382. else
  383. {
  384. .CheckCell(x, y);
  385. .CheckWin();
  386. }
  387. },
  388. // open cells around open mine
  389. HelperCell = function()
  390. {
  391. i; j;
  392. index = .Index(.cX, .cY);
  393. // perform the action only if the cell is already open
  394. if (.field[index]>=10 && .field[index]<20)
  395. {
  396. // calculate mines around this cell
  397. mines = 0;
  398. for (i=.cX-1; i<.cX+2; i=i+1)
  399. {
  400. for (j=.cY-1; j<.cY+2; j=j+1)
  401. {
  402. if ((i!=.cX || j!=.cY)
  403. && (i>=0) && (i<.lx)
  404. && (j>=0) && (j<.ly))
  405. {
  406. index = .Index(i, j);
  407. if (.field[index] >= 20)
  408. {
  409. mines = mines + 1;
  410. }
  411. }
  412. }
  413. }
  414. // check that we can open
  415. index = .Index(.cX, .cY);
  416. if (mines == (.field[index] % 10))
  417. {
  418. for (i=.cX-1; i<.cX+2; i=i+1)
  419. {
  420. for (j=.cY-1; j<.cY+2; j=j+1)
  421. {
  422. if ((i!=.cX || j!=.cY)
  423. && (i>=0) && (i<.lx)
  424. && (j>=0) && (j<.ly))
  425. {
  426. .OpenCell(i, j, 0);
  427. }
  428. }
  429. }
  430. }
  431. }
  432. },
  433. // move cursor
  434. Move = function(dir)
  435. {
  436. .DrawCurrCell(0);
  437. if (dir == 1)
  438. {
  439. if (.cY > 0)
  440. {
  441. .cY = .cY - 1;
  442. }
  443. }
  444. else if (dir == 3)
  445. {
  446. if (.cY<.ly-1)
  447. {
  448. .cY = .cY + 1;
  449. }
  450. }
  451. else if (dir == 0)
  452. {
  453. if (.cX > 0)
  454. {
  455. .cX = .cX - 1;
  456. }
  457. }
  458. else if (dir == 2)
  459. {
  460. if (.cX<.lx-1)
  461. {
  462. .cX = .cX + 1;
  463. }
  464. }
  465. WaitForKey(37+dir);
  466. .DrawCurrCell(1);
  467. },
  468. // open current cell
  469. Open = function()
  470. {
  471. WaitForKey(13);
  472. .OpenCell(.cX, .cY, 1);
  473. },
  474. // mark current cell
  475. Mark = function()
  476. {
  477. WaitForKey(32);
  478. index = .Index(.cX, .cY);
  479. if (.field[index] < 10)
  480. {
  481. .field[index] = (.field[index] % 10) + 20;
  482. .mineCurr = .mineCurr + 1;
  483. .DrawFrame();
  484. .CheckWin();
  485. }
  486. else if (.field[index] >= 20)
  487. {
  488. .field[index] = .field[index] % 10;
  489. .mineCurr = .mineCurr -1;
  490. .DrawFrame();
  491. .DrawCurrCell(1);
  492. }
  493. },
  494. // init the game
  495. Run = function()
  496. {
  497. CURSOR(0, 0);
  498. .RestartField();
  499. for (;!ISPRESSED(27);)
  500. {
  501. if (ISPRESSED(37))
  502. {
  503. .Move(0);
  504. }
  505. else if (ISPRESSED(38))
  506. {
  507. .Move(1);
  508. }
  509. else if (ISPRESSED(39))
  510. {
  511. .Move(2);
  512. }
  513. else if (ISPRESSED(40))
  514. {
  515. .Move(3);
  516. }
  517. else if (ISPRESSED(32))
  518. {
  519. .Mark();
  520. }
  521. else if (ISPRESSED(13))
  522. {
  523. .Open();
  524. }
  525. else if (ISPRESSED(8))
  526. {
  527. .HelperCell();
  528. WaitForKey(8);
  529. }
  530. else if (ISPRESSED(113))
  531. {
  532. WaitForKey(113);
  533. .InitField(1);
  534. }
  535. else if (ISPRESSED(114))
  536. {
  537. WaitForKey(114);
  538. .InitField(2);
  539. }
  540. else if (ISPRESSED(115))
  541. {
  542. WaitForKey(115);
  543. .InitField(3);
  544. }
  545. else
  546. {
  547. DebugText(" ");
  548. }
  549. }
  550. }
  551. );
  552. game.Run();