main.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <bits/stdc++.h>
  4. #include <thread>
  5. using namespace std;
  6. class Game {
  7. unsigned long white = 0, black = 0;
  8. public:
  9. void print() {
  10. for(int i=0; i<4; i++) {
  11. for(int j=0; j<4; j++) {
  12. for(int k=0; k<4; k++) {
  13. bool w = white >> (k + i*4 + j*16) & 1;
  14. bool b = black >> (k + i*4 + j*16) & 1;
  15. cout << (b&&w ? 'E' : (w ? 'W' : (b ? 'B' : '.')));
  16. }
  17. cout << ' ';
  18. }
  19. cout << endl;
  20. }
  21. cout << endl;
  22. }
  23. int freeLocations() {
  24. return ((white | black) >> 16*3) ^ 0xFFFF;
  25. }
  26. bool place(unsigned long & map) {
  27. int locations = freeLocations();
  28. if(locations == 0)
  29. return false;
  30. int choice;
  31. do {
  32. choice = rand() % 16;
  33. } while ((locations & (1 << choice)) == 0);
  34. for(int i=0; i<4; i++) {
  35. if(((black|white) & 1UL << (i*16 + choice)) == 0) {
  36. map |= 1UL << (i*16 + choice);
  37. break;
  38. }
  39. }
  40. return true;
  41. }
  42. int check(unsigned long set) {
  43. for(int i=0; i<4; i++) {
  44. for(int j=0; j<4; j++) {
  45. // horizontal x
  46. if((set >> (i*4 + j*16) & 15) == 15) return 1;
  47. // vertical y
  48. if((set >> (i + j*4) & 0x1000100010001UL) == 0x1000100010001UL) return 2;
  49. // horizontal z
  50. if((set >> (i + j*16) & 0x1111) == 0x1111) return 3;
  51. }
  52. // diagonal xz
  53. if((set >> i*16 & 0x8421) == 0x8421) return 10;
  54. if((set >> i*16 & 0x1248) == 0x1248) return 11;
  55. // diagonal xy
  56. if((set >> i*4 & 0x8000400020001UL) == 0x8000400020001UL) return 20;
  57. if((set >> i*4 & 0x1000200040008UL) == 0x1000200040008UL) return 21;
  58. // diagonal yz
  59. if((set >> i & 0x1000010000100001UL) == 0x1000010000100001UL) return 30;
  60. if((set >> i & 0x1001001001000UL) == 0x1001001001000UL) return 31;
  61. }
  62. // diagonal xyz
  63. if((set & 0x8000040000200001UL) == 0x8000040000200001UL) return 40;
  64. if((set & 0x1000020000400008UL) == 0x1000020000400008UL) return 41;
  65. if((set & 0x8004002001000UL) == 0x8004002001000UL) return 50;
  66. if((set & 0x1002004008000UL) == 0x1002004008000UL) return 51;
  67. return 0;
  68. }
  69. int play(int startPosition) {
  70. white = 1 << startPosition;
  71. black = 0;
  72. while(freeLocations()) {
  73. place(black);
  74. //print();
  75. int result = check(black);
  76. if(result) {
  77. return -result;
  78. }
  79. place(white);
  80. //print();
  81. result = check(white);
  82. if(result) {
  83. return result;
  84. }
  85. }
  86. }
  87. };
  88. void do_work(int startPosition) {
  89. int whiteCount=0, blackCount=0, draw=0, x=0, y=0, z=0, xy=0, xz=0, yz=0, xyz=0;
  90. for(int i=1; i<=1000000; i++) {
  91. Game game;
  92. int result = game.play(startPosition);
  93. if(result > 0)
  94. whiteCount++;
  95. if(result < 0)
  96. blackCount++;
  97. if(result == 0)
  98. draw++;
  99. else if(abs(result) == 1)
  100. x++;
  101. else if(abs(result) == 2)
  102. y++;
  103. else if(abs(result) == 3)
  104. z++;
  105. else if(abs(result) < 20)
  106. xz++;
  107. else if(abs(result) < 30)
  108. xy++;
  109. else if(abs(result) < 40)
  110. yz++;
  111. else
  112. xyz++;
  113. }
  114. printf(
  115. "Start position: %d White: %d Black: %d Draw: %d x: %d y: %d z: %d xz: %d xy: %d yz: %d xyz: %d\n",
  116. startPosition, whiteCount, blackCount, draw, x, y, z, xz, xy, yz, xyz);
  117. }
  118. int main() {
  119. list<thread> threads;
  120. for(int i=0; i<16; i++) {
  121. threads.push_front(thread(do_work, i));
  122. }
  123. for(auto &t : threads) {
  124. t.join();
  125. }
  126. }