Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.17 KB | None | 0 0
  1. var directions = [
  2. [0, 1],
  3. [1, 1],
  4. [1, 0],
  5. [1, -1]
  6. ];
  7. /* Mind reader */
  8. function MindReader() {
  9. this.combo = 5;
  10. this.myIdx = 0;
  11. this.enemyIdx = 1;
  12. this.size = 0;
  13. this.gamefield = null;
  14. this.setIdx = function (idx) {
  15. this.myIdx = idx;
  16. this.enemyIdx = Math.abs(idx - 1);
  17. };
  18. this.setCombo = function (combo) {
  19. this.combo = combo;
  20. };
  21. this.play = function (gamefield) {
  22. this.gamefield = gamefield;
  23. this.size = gamefield.length;
  24. var alerting = false; // for debugging
  25. var move;
  26. move = this.win();
  27. if (move !== null) {
  28. if (alerting) {
  29. alert("Win");
  30. }
  31. return move;
  32. }
  33. move = this.fixEnemyWin();
  34. if (move !== null) {
  35. if (alerting) {
  36. alert("Fix enemy win");
  37. }
  38. return move;
  39. }
  40. move = this.winInTwoMoves();
  41. if (move !== null) {
  42. if (alerting) {
  43. alert("Win in two moves");
  44. }
  45. return move;
  46. }
  47. move = this.fixEnemyWinInTwoMoves();
  48. if (move !== null) {
  49. if (alerting) {
  50. alert("Fix enemy win in two moves");
  51. }
  52. return move;
  53. }
  54. move = this.winInThreeMoves();
  55. if (move !== null) {
  56. if (alerting) {
  57. alert("Win in three moves");
  58. }
  59. return move;
  60. }
  61. move = this.fixEnemyWinInThreeMoves();
  62. if (move !== null) {
  63. if (alerting) {
  64. alert("Fix enemy win in three moves");
  65. }
  66. return move;
  67. }
  68. move = this.findBestMove();
  69. if (move !== null) {
  70. if (alerting) {
  71. alert("Best move");
  72. }
  73. return move;
  74. }
  75. var a = Math.floor(this.size / 2);
  76. if (this.gamefield[a][a] === -1) {
  77. return [a, a];
  78. } else {
  79. return this.getRandomPossible();
  80. }
  81. };
  82. this.win = function () {
  83. var defdx, defdy, dx, dy, n, next;
  84. for (var x = 0; x < this.size; x++) {
  85. for (var y = 0; y < this.size; y++) {
  86. if (this.gamefield[x][y] === -1) {
  87. for (var i = 0; i < directions.length; i++) {
  88. defdx = directions[i][0];
  89. defdy = directions[i][1];
  90. dx = defdx;
  91. dy = defdy;
  92. n = 0;
  93. next = true;
  94. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  95. next)) {
  96. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  97. n += 1;
  98. dx += defdx;
  99. dy += defdy;
  100. } else {
  101. next = false;
  102. }
  103. }
  104. dx = -defdx;
  105. dy = -defdy;
  106. next = true;
  107. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  108. next)) {
  109. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  110. n += 1;
  111. dx -= defdx;
  112. dy -= defdy;
  113. } else {
  114. next = false;
  115. }
  116. }
  117. if (n >= this.combo - 1) {
  118. return [x, y];
  119. }
  120. }
  121. }
  122. }
  123. }
  124. return null;
  125. };
  126. this.fixEnemyWin = function () {
  127. var defdx, defdy, dx, dy, n, next;
  128. for (var x = 0; x < this.size; x++) {
  129. for (var y = 0; y < this.size; y++) {
  130. if (this.gamefield[x][y] === -1) {
  131. for (var i = 0; i < directions.length; i++) {
  132. defdx = directions[i][0];
  133. defdy = directions[i][1];
  134. dx = defdx;
  135. dy = defdy;
  136. n = 0;
  137. next = true;
  138. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  139. next)) {
  140. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  141. n += 1;
  142. dx += defdx;
  143. dy += defdy;
  144. } else {
  145. next = false;
  146. }
  147. }
  148. dx = -defdx;
  149. dy = -defdy;
  150. next = true;
  151. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  152. next)) {
  153. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  154. n += 1;
  155. dx -= defdx;
  156. dy -= defdy;
  157. } else {
  158. next = false;
  159. }
  160. }
  161. if (n >= this.combo - 1) {
  162. return [x, y];
  163. }
  164. }
  165. }
  166. }
  167. }
  168. return null;
  169. };
  170. this.winInTwoMoves = function () {
  171. var openA, openB, stepA, stepB, defdx, defdy, dx, dy, n, next;
  172. for (var x = 0; x < this.size; x++) {
  173. for (var y = 0; y < this.size; y++) {
  174. if (this.gamefield[x][y] === -1) {
  175. for (var i = 0; i < directions.length; i++) {
  176. defdx = directions[i][0];
  177. defdy = directions[i][1];
  178. dx = defdx;
  179. dy = defdy;
  180. n = 0;
  181. next = true;
  182. openA = false;
  183. openB = false;
  184. stepA = false;
  185. stepB = false;
  186. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  187. next)) {
  188. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  189. n += 1;
  190. dx += defdx;
  191. dy += defdy;
  192. } else {
  193. next = false;
  194. if (this.gamefield[x + dx][y + dy] === -1) {
  195. openA = true;
  196. dx += defdx;
  197. dy += defdy;
  198. if ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >=
  199. 0)) {
  200. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  201. stepA = true;
  202. }
  203. }
  204. }
  205. }
  206. }
  207. dx = -defdx;
  208. dy = -defdy;
  209. next = true;
  210. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  211. next)) {
  212. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  213. n += 1;
  214. dx -= defdx;
  215. dy -= defdy;
  216. } else {
  217. next = false;
  218. if (this.gamefield[x + dx][y + dy] === -1) {
  219. openB = true;
  220. dx -= defdx;
  221. dy -= defdy;
  222. if ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >=
  223. 0)) {
  224. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  225. stepB = true;
  226. }
  227. }
  228. }
  229. }
  230. }
  231. if ((n >= this.combo - 2 && openA && openB) || (stepA && stepB && n >= (this.combo - 3))) {
  232. return [x, y];
  233. }
  234. }
  235. }
  236. }
  237. }
  238. return null;
  239. };
  240. this.fixEnemyWinInTwoMoves = function () {
  241. var openA, openB, stepA, stepB, defdx, defdy, dx, dy, n, next, h = 0;
  242. var value, bestValue = 0;
  243. var posMoves = new Array();
  244. for (var x = 0; x < this.size; x++) {
  245. for (var y = 0; y < this.size; y++) {
  246. if (this.gamefield[x][y] === -1) {
  247. for (var i = 0; i < directions.length; i++) {
  248. defdx = directions[i][0];
  249. defdy = directions[i][1];
  250. dx = defdx;
  251. dy = defdy;
  252. n = 0;
  253. next = true;
  254. openA = false;
  255. openB = false;
  256. stepA = false;
  257. stepB = false;
  258. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  259. next)) {
  260. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  261. n += 1;
  262. dx += defdx;
  263. dy += defdy;
  264. } else {
  265. next = false;
  266. if (this.gamefield[x + dx][y + dy] === -1) {
  267. openA = true;
  268. dx += defdx;
  269. dy += defdy;
  270. if ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >=
  271. 0)) {
  272. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  273. stepA = true;
  274. }
  275. }
  276. }
  277. }
  278. }
  279. dx = -defdx;
  280. dy = -defdy;
  281. next = true;
  282. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  283. next)) {
  284. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  285. n += 1;
  286. dx -= defdx;
  287. dy -= defdy;
  288. } else {
  289. next = false;
  290. if (this.gamefield[x + dx][y + dy] === -1) {
  291. openB = true;
  292. dx -= defdx;
  293. dy -= defdy;
  294. if ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >=
  295. 0)) {
  296. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  297. stepB = true;
  298. }
  299. }
  300. }
  301. }
  302. }
  303. if ((n >= this.combo - 2 && openA && openB) || (stepA && stepB && n >= (this.combo - 3))) {
  304. value = this.getValue(x, y);
  305. if (value > bestValue){
  306. bestValue = value;
  307. }
  308. posMoves[h++] = [value, [x, y]];
  309. }
  310. }
  311. }
  312. }
  313. }
  314. if (h > 0){
  315. for (var k = 0; k < h; k++){
  316. if (posMoves[k][0] === bestValue){
  317. return posMoves[k][1];
  318. }
  319. }
  320. }
  321. return null;
  322. };
  323. this.winInThreeMoves = function () {
  324. var openA, openB, stepA, stepB, defdx, defdy, dx, dy, n, next, k;
  325. var value, bestValue = 0, h = 0, posMoves = new Array();
  326. for (var x = 0; x < this.size; x++) {
  327. for (var y = 0; y < this.size; y++) {
  328. if (this.gamefield[x][y] === -1) {
  329. k = 0;
  330. for (var i = 0; i < directions.length; i++) {
  331. defdx = directions[i][0];
  332. defdy = directions[i][1];
  333. dx = defdx;
  334. dy = defdy;
  335. n = 0;
  336. next = true;
  337. openA = false;
  338. openB = false;
  339. stepA = false;
  340. stepB = false;
  341. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  342. next)) {
  343. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  344. n += 1;
  345. dx += defdx;
  346. dy += defdy;
  347. } else {
  348. next = false;
  349. if (this.gamefield[x + dx][y + dy] === -1) {
  350. openA = true;
  351. }
  352. }
  353. }
  354. dx = -defdx;
  355. dy = -defdy;
  356. next = true;
  357. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  358. next)) {
  359. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  360. n += 1;
  361. dx -= defdx;
  362. dy -= defdy;
  363. } else {
  364. next = false;
  365. if (this.gamefield[x + dx][y + dy] === -1) {
  366. openB = true;
  367. }
  368. }
  369. }
  370. if (n >= this.combo - 3 && openA && openB) {
  371. k += 1;
  372. }
  373. }
  374. if (k >= 2) {
  375. value = this.getValue(x, y);
  376. if (value > bestValue){
  377. bestValue = value;
  378. }
  379. posMoves[h++] = [value, [x, y]];
  380. }
  381. }
  382. }
  383. }
  384. if (h > 0){
  385. for (var k = 0; k < h; k++){
  386. if (posMoves[k][0] === bestValue){
  387. return posMoves[k][1];
  388. }
  389. }
  390. }
  391. return null;
  392. };
  393. this.fixEnemyWinInThreeMoves = function () {
  394. var openA, openB, stepA, stepB, defdx, defdy, dx, dy, n, next, k;
  395. var value, bestValue = 0, h = 0, posMoves = new Array();
  396. for (var x = 0; x < this.size; x++) {
  397. for (var y = 0; y < this.size; y++) {
  398. if (this.gamefield[x][y] === -1) {
  399. k = 0;
  400. for (var i = 0; i < directions.length; i++) {
  401. defdx = directions[i][0];
  402. defdy = directions[i][1];
  403. dx = defdx;
  404. dy = defdy;
  405. n = 0;
  406. next = true;
  407. openA = false;
  408. openB = false;
  409. stepA = false;
  410. stepB = false;
  411. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  412. next)) {
  413. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  414. n += 1;
  415. dx += defdx;
  416. dy += defdy;
  417. } else {
  418. next = false;
  419. if (this.gamefield[x + dx][y + dy] === -1) {
  420. openA = true;
  421. }
  422. }
  423. }
  424. dx = -defdx;
  425. dy = -defdy;
  426. next = true;
  427. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (
  428. next)) {
  429. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  430. n += 1;
  431. dx -= defdx;
  432. dy -= defdy;
  433. } else {
  434. next = false;
  435. if (this.gamefield[x + dx][y + dy] === -1) {
  436. openB = true;
  437. }
  438. }
  439. }
  440. if (n >= this.combo - 3 && openA && openB) {
  441. k += 1;
  442. }
  443. }
  444. if (k >= 2) {
  445. value = this.getValue(x, y);
  446. if (value > bestValue){
  447. bestValue = value;
  448. }
  449. posMoves[h++] = [value, [x, y]];
  450. }
  451. }
  452. }
  453. }
  454. if (h > 0){
  455. for (var k = 0; k < h; k++){
  456. if (posMoves[k][0] === bestValue){
  457. return posMoves[k][1];
  458. }
  459. }
  460. }
  461. return null;
  462. };
  463. this.findBestMove = function () {
  464. var value, bestValue = 0, i = 0, j = 0;
  465. var allValues = new Array();
  466. var posMoves = new Array();
  467. for (var x = 0; x < this.size; x++) {
  468. for (var y = 0; y < this.size; y++) {
  469. if (this.gamefield[x][y] === -1) {
  470. value = this.getValue(x, y);
  471. allValues[i++] = [value, [x, y]];
  472. if (value > bestValue) {
  473. bestValue = value;
  474. }
  475. }
  476. }
  477. }
  478. if (bestValue > 0) {
  479. for (var z = 0; z < i; z++) {
  480. if (allValues[z][0] === bestValue) {
  481. posMoves[j++] = allValues[z][1];
  482. }
  483. }
  484. return posMoves[Math.floor(Math.random() * j)];
  485. } else {
  486. return null;
  487. }
  488. };
  489. this.getValue = function (x, y) {
  490. var value = 0, dx, dy;
  491. for (var i = 0; i < directions.length; i++) {
  492. dx = directions[i][0];
  493. dy = directions[i][1];
  494. value += this.getValueDirection(x, y, dx, dy);
  495. }
  496. return value;
  497. };
  498. this.getValueDirection = function (x, y, defdx, defdy) {
  499. var value = 0;
  500. var dx = defdx, dy = defdy;
  501. var n = 0;
  502. var next = true;
  503. var skip = true;
  504. var minus = false;
  505. var valuePlus = false;
  506. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (next)) {
  507. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  508. skip = false;
  509. valuePlus = true;
  510. n += 1;
  511. dx += defdx;
  512. dy += defdy;
  513. } else if ((this.gamefield[x + dx][y + dy] === -1) && skip) {
  514. skip = false;
  515. minus = true;
  516. dx += defdx;
  517. dy += defdy;
  518. } else if ((this.gamefield[x + dx][y + dy] === -1) && (skip === false)) {
  519. if (valuePlus) {
  520. n += 0.5;
  521. }
  522. next = false;
  523. } else {
  524. next = false;
  525. }
  526. }
  527. if ((minus) && (valuePlus)) {
  528. value -= 0.25;
  529. }
  530. minus = false;
  531. valuePlus = false;
  532. dx = -defdx;
  533. dy = -defdy;
  534. next = true;
  535. skip = true;
  536. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (next)) {
  537. if (this.gamefield[x + dx][y + dy] === this.myIdx) {
  538. skip = false;
  539. valuePlus = true;
  540. n += 1;
  541. dx -= defdx;
  542. dy -= defdy;
  543. } else if ((this.gamefield[x + dx][y + dy] === -1) && skip) {
  544. skip = false;
  545. minus = true;
  546. dx -= defdx;
  547. dy -= defdy;
  548. } else if ((this.gamefield[x + dx][y + dy] === -1) && (skip === false)) {
  549. if (valuePlus) {
  550. n += 0.5;
  551. }
  552. next = false;
  553. } else {
  554. next = false;
  555. }
  556. }
  557. if ((minus) && (valuePlus)) {
  558. value -= 0.25;
  559. }
  560. minus = false;
  561. valuePlus = false;
  562. if (n > 0) {
  563. if (this.comboPossibleAt(x, y, defdx, defdy, this.myIdx)) {
  564. value = value + Math.pow(2, (n + 0.25));
  565. }
  566. }
  567. dx = defdx;
  568. dy = defdy;
  569. n = 0;
  570. next = true;
  571. skip = true;
  572. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (next)) {
  573. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  574. skip = false;
  575. valuePlus = true;
  576. n += 1;
  577. dx += defdx;
  578. dy += defdy;
  579. } else if ((this.gamefield[x + dx][y + dy] === -1) && skip) {
  580. skip = false;
  581. minus = true;
  582. dx += defdx;
  583. dy += defdy;
  584. } else if ((this.gamefield[x + dx][y + dy] === -1) && (skip === false)) {
  585. if (valuePlus) {
  586. n += 0.5;
  587. }
  588. next = false;
  589. } else {
  590. next = false;
  591. }
  592. }
  593. if ((minus) && (valuePlus)) {
  594. value -= 0.25;
  595. }
  596. minus = false;
  597. valuePlus = false;
  598. dx = -defdx;
  599. dy = -defdy;
  600. next = true;
  601. skip = true;
  602. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0) && (next)) {
  603. if (this.gamefield[x + dx][y + dy] === this.enemyIdx) {
  604. skip = false;
  605. valuePlus = true;
  606. n += 1;
  607. dx -= defdx;
  608. dy -= defdy;
  609. } else if ((this.gamefield[x + dx][y + dy] === -1) && skip) {
  610. skip = false;
  611. minus = true;
  612. dx -= defdx;
  613. dy -= defdy;
  614. } else if ((this.gamefield[x + dx][y + dy] === -1) && (skip === false)) {
  615. if (valuePlus) {
  616. n += 0.5;
  617. }
  618. next = false;
  619. } else {
  620. next = false;
  621. }
  622. }
  623. if ((minus) && (valuePlus)) {
  624. value -= 0.25;
  625. }
  626. if (n > 0) {
  627. if (this.comboPossibleAt(x, y, defdx, defdy, this.myIdx)) {
  628. value = value + Math.pow(2, n);
  629. }
  630. }
  631. return value;
  632. };
  633. this.comboPossibleAt = function (x, y, defdx, defdy, index) {
  634. var n = 1,
  635. dx = defdx,
  636. dy = defdy;
  637. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0)) {
  638. if ((this.gamefield[x + dx][y + dy] === index) || (this.gamefield[x + dx][y + dy] === -1)) {
  639. n += 1;
  640. dx += defdx;
  641. dy += defdy;
  642. } else {
  643. break;
  644. }
  645. }
  646. dx = -defdx;
  647. dy = -defdy;
  648. while ((x + dx < this.size) && (x + dx >= 0) && (y + dy < this.size) && (y + dy >= 0)) {
  649. if ((this.gamefield[x + dx][y + dy] === index) || (this.gamefield[x + dx][y + dy] === -1)) {
  650. n += 1;
  651. dx -= defdx;
  652. dy -= defdy;
  653. } else {
  654. break;
  655. }
  656. }
  657. return n >= this.combo;
  658. };
  659. this.getRandomPossible = function () {
  660. var possMoves = new Array();
  661. var n = 0;
  662. for (var x = 0; x < this.size; x++) {
  663. for (var y = 0; y < this.size; y++) {
  664. if (this.gamefield[x][y] === -1) {
  665. possMoves[n++] = [x, y];
  666. }
  667. }
  668. }
  669. return possMoves[Math.floor(Math.random() * n)];
  670. };
  671. }
  672. /* ------------------ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement