123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- #include <iostream>
- #include <stdlib.h>
- #include <bits/stdc++.h>
- #include <thread>
- using namespace std;
- class Game {
- unsigned long white = 0, black = 0;
- public:
- void print() {
- for(int i=0; i<4; i++) {
- for(int j=0; j<4; j++) {
- for(int k=0; k<4; k++) {
- bool w = white >> (k + i*4 + j*16) & 1;
- bool b = black >> (k + i*4 + j*16) & 1;
- cout << (b&&w ? 'E' : (w ? 'W' : (b ? 'B' : '.')));
- }
- cout << ' ';
- }
- cout << endl;
- }
- cout << endl;
- }
- int freeLocations() {
- return ((white | black) >> 16*3) ^ 0xFFFF;
- }
- bool place(unsigned long & map) {
- int locations = freeLocations();
- if(locations == 0)
- return false;
- int choice;
- do {
- choice = rand() % 16;
- } while ((locations & (1 << choice)) == 0);
- for(int i=0; i<4; i++) {
- if(((black|white) & 1UL << (i*16 + choice)) == 0) {
- map |= 1UL << (i*16 + choice);
- break;
- }
- }
- return true;
- }
- int check(unsigned long set) {
- for(int i=0; i<4; i++) {
- for(int j=0; j<4; j++) {
- // horizontal x
- if((set >> (i*4 + j*16) & 15) == 15) return 1;
- // vertical y
- if((set >> (i + j*4) & 0x1000100010001UL) == 0x1000100010001UL) return 2;
- // horizontal z
- if((set >> (i + j*16) & 0x1111) == 0x1111) return 3;
- }
- // diagonal xz
- if((set >> i*16 & 0x8421) == 0x8421) return 10;
- if((set >> i*16 & 0x1248) == 0x1248) return 11;
- // diagonal xy
- if((set >> i*4 & 0x8000400020001UL) == 0x8000400020001UL) return 20;
- if((set >> i*4 & 0x1000200040008UL) == 0x1000200040008UL) return 21;
- // diagonal yz
- if((set >> i & 0x1000010000100001UL) == 0x1000010000100001UL) return 30;
- if((set >> i & 0x1001001001000UL) == 0x1001001001000UL) return 31;
- }
- // diagonal xyz
- if((set & 0x8000040000200001UL) == 0x8000040000200001UL) return 40;
- if((set & 0x1000020000400008UL) == 0x1000020000400008UL) return 41;
- if((set & 0x8004002001000UL) == 0x8004002001000UL) return 50;
- if((set & 0x1002004008000UL) == 0x1002004008000UL) return 51;
- return 0;
- }
- int play(int startPosition) {
- white = 1 << startPosition;
- black = 0;
- while(freeLocations()) {
- place(black);
- //print();
- int result = check(black);
- if(result) {
- return -result;
- }
- place(white);
- //print();
- result = check(white);
- if(result) {
- return result;
- }
- }
- }
- };
- void do_work(int startPosition) {
- int whiteCount=0, blackCount=0, draw=0, x=0, y=0, z=0, xy=0, xz=0, yz=0, xyz=0;
- for(int i=1; i<=1000000; i++) {
- Game game;
- int result = game.play(startPosition);
- if(result > 0)
- whiteCount++;
- if(result < 0)
- blackCount++;
- if(result == 0)
- draw++;
- else if(abs(result) == 1)
- x++;
- else if(abs(result) == 2)
- y++;
- else if(abs(result) == 3)
- z++;
- else if(abs(result) < 20)
- xz++;
- else if(abs(result) < 30)
- xy++;
- else if(abs(result) < 40)
- yz++;
- else
- xyz++;
-
- }
- printf(
- "Start position: %d White: %d Black: %d Draw: %d x: %d y: %d z: %d xz: %d xy: %d yz: %d xyz: %d\n",
- startPosition, whiteCount, blackCount, draw, x, y, z, xz, xy, yz, xyz);
- }
- int main() {
- list<thread> threads;
- for(int i=0; i<16; i++) {
- threads.push_front(thread(do_work, i));
- }
- for(auto &t : threads) {
- t.join();
- }
- }
|