int play(int me, int opponent, int row, int col, bool first_player, move_t **moves) { bool can_capture_right, can_capture_left; move_t *moves_right, *moves_left; int score_right = 0; int score_left = 0; if (me == BLACK) { D printf("BLACK: "); can_capture_left = can_capture(me,opponent,row,col,row+1,col+1,row+2,col+2); can_capture_right = can_capture(me,opponent,row,col,row+1,col-1,row+2,col-2); D printf(" From (%d,%d): Right? %s Left? %s\n",row,col,(can_capture_right ? "Yes" : "No"), (can_capture_left ? "Yes" : "No")); if (can_capture_left) score_left = 1 + test_capture(me,opponent,row,col,row+1,col+1,row+2,col+2,first_player,&moves_left); if (can_capture_right) score_right = 1 + test_capture(me,opponent,row,col,row+1,col-1,row+2,col-2,first_player,&moves_right); moves_left = move_gen(row+2,col+2,moves_left); moves_right = move_gen(row+2,col-2,moves_right); } else { D printf("WHITE: "); can_capture_left = can_capture(me,opponent,row,col,row-1,col-1,row-2,col-2); can_capture_right = can_capture(me,opponent,row,col,row-1,col+1,row-2,col+2); if (can_capture_left) score_left = 1 + test_capture(me,opponent,row,col,row-1,col-1,row-2,col-2,first_player,&moves_left); if (can_capture_right) score_right = 1 + test_capture(me,opponent,row,col,row-1,col+1,row-2,col+2,first_player,&moves_right); moves_left = move_gen(row-2,col-2,moves_left); moves_right = move_gen(row-2,col+2,moves_right); } if ((!can_capture_right) && (!can_capture_left) && first_player) { move_t *temp_moves; *moves = NULL; D printf(" returning 0 (no captures available)\n"); return - find_best_move(opponent,me,false,&temp_moves); } else { if ((can_capture_left && (!can_capture_right)) || (can_capture_left && can_capture_right && (score_left > score_right))) { *moves = moves_left; D printf(" returning %d (score_left)\n",score_left); return score_left; } else { *moves = moves_right; D printf(" returning %d (score_right)\n",score_right); return score_right; } } }
// recursive DFS for calculating score of all subtree nodes long parallel_dfs(char* board, int blackPrisoners, int whitePrisoners, int depth, int color, int turnNumber) { char tempBoard[BOARD_SIZE * BOARD_SIZE]; int tempBlackPrisoners; int tempWhitePrisoners; int legalMoves = 0; // printf("%d - %d", my_rank, depth); // fflush(stdout); get_black_score(board, turnNumber); get_white_score(board, turnNumber); long nodeScore = calculate_influence(board); long subTreeScore = 0; int move; if ( depth <= MAX_PARALLEL_DEPTH ) { for ( int i = 0; i < BOARD_SIZE * BOARD_SIZE && legalMoves < MAX_RANDOM_MOVES; i++ ) { move = rand() % ( BOARD_SIZE * BOARD_SIZE ); if ( is_legal(move, board, turnNumber) == 0 ) { legalMoves++; memcpy( tempBoard, board, BOARD_SIZE * BOARD_SIZE * sizeof(char) ); tempBlackPrisoners = blackPrisoners; tempWhitePrisoners = whitePrisoners; tempBoard[move] = color; test_capture( tempBoard, &tempBlackPrisoners, &tempWhitePrisoners, move, color ); subTreeScore += parallel_dfs(tempBoard, tempBlackPrisoners, tempWhitePrisoners, depth + 1, color, turnNumber + 2); } } // pass move // printf("legalMoves = %d\n", legalMoves); legalMoves++; tempBlackPrisoners = blackPrisoners; tempWhitePrisoners = whitePrisoners; subTreeScore += parallel_dfs( board, tempBlackPrisoners, tempWhitePrisoners, depth + 1, color, turnNumber); return nodeScore + ((subTreeScore * 5 * depth )/ legalMoves); } return nodeScore; }
static void test_audioclient(void) { IAudioClient *ac; IUnknown *unk; HRESULT hr; ULONG ref; WAVEFORMATEX *pwfx, *pwfx2; REFERENCE_TIME t1, t2; HANDLE handle; hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; handle = CreateEventW(NULL, FALSE, FALSE, NULL); hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL); ok(hr == E_POINTER, "QueryInterface(NULL) returned %08x\n", hr); unk = (void*)(LONG_PTR)0x12345678; hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk); ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08x\n", hr); ok(!unk, "QueryInterface(IID_NULL) returned non-null pointer %p\n", unk); hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, (void**)&unk); ok(hr == S_OK, "QueryInterface(IID_IUnknown) returned %08x\n", hr); if (unk) { ref = IUnknown_Release(unk); ok(ref == 1, "Released count is %u\n", ref); } hr = IAudioClient_QueryInterface(ac, &IID_IAudioClient, (void**)&unk); ok(hr == S_OK, "QueryInterface(IID_IAudioClient) returned %08x\n", hr); if (unk) { ref = IUnknown_Release(unk); ok(ref == 1, "Released count is %u\n", ref); } hr = IAudioClient_GetDevicePeriod(ac, NULL, NULL); ok(hr == E_POINTER, "Invalid GetDevicePeriod call returns %08x\n", hr); hr = IAudioClient_GetDevicePeriod(ac, &t1, NULL); ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr); hr = IAudioClient_GetDevicePeriod(ac, NULL, &t2); ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr); hr = IAudioClient_GetDevicePeriod(ac, &t1, &t2); ok(hr == S_OK, "Valid GetDevicePeriod call returns %08x\n", hr); trace("Returned periods: %u.%05u ms %u.%05u ms\n", (UINT)(t1/10000), (UINT)(t1 % 10000), (UINT)(t2/10000), (UINT)(t2 % 10000)); hr = IAudioClient_GetMixFormat(ac, NULL); ok(hr == E_POINTER, "GetMixFormat returns %08x\n", hr); hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "Valid GetMixFormat returns %08x\n", hr); if (hr == S_OK) { trace("pwfx: %p\n", pwfx); trace("Tag: %04x\n", pwfx->wFormatTag); trace("bits: %u\n", pwfx->wBitsPerSample); trace("chan: %u\n", pwfx->nChannels); trace("rate: %u\n", pwfx->nSamplesPerSec); trace("align: %u\n", pwfx->nBlockAlign); trace("extra: %u\n", pwfx->cbSize); ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "wFormatTag is %x\n", pwfx->wFormatTag); if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { WAVEFORMATEXTENSIBLE *pwfxe = (void*)pwfx; trace("Res: %u\n", pwfxe->Samples.wReserved); trace("Mask: %x\n", pwfxe->dwChannelMask); trace("Alg: %s\n", IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)?"PCM": (IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other")); } hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2); ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08x\n", hr); ok(pwfx2 == NULL, "pwfx2 is non-null\n"); CoTaskMemFree(pwfx2); hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL); ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08x\n", hr); hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL); ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08x\n", hr); hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL); ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr); hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2); ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08x\n", hr); ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n"); hr = IAudioClient_IsFormatSupported(ac, 0xffffffff, pwfx, NULL); ok(hr == E_INVALIDARG, "IsFormatSupported(0xffffffff) call returns %08x\n", hr); } test_uninitialized(ac); hr = IAudioClient_Initialize(ac, 3, 0, 5000000, 0, pwfx, NULL); ok(hr == AUDCLNT_E_NOT_INITIALIZED, "Initialize with invalid sharemode returns %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0xffffffff, 5000000, 0, pwfx, NULL); ok(hr == E_INVALIDARG, "Initialize with invalid flags returns %08x\n", hr); /* It seems that if length > 2s or periodicity != 0 the length is ignored and call succeeds * Since we can only initialize successfully once skip those tests */ hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, NULL, NULL); ok(hr == E_POINTER, "Initialize with null format returns %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Valid Initialize returns %08x\n", hr); if (hr != S_OK) { skip("Cannot initialize %08x, remainder of tests is useless\n", hr); CoTaskMemFree(pwfx); return; } hr = IAudioClient_GetStreamLatency(ac, NULL); ok(hr == E_POINTER, "GetStreamLatency(NULL) call returns %08x\n", hr); hr = IAudioClient_GetStreamLatency(ac, &t1); ok(hr == S_OK, "Valid GetStreamLatency call returns %08x\n", hr); trace("Returned latency: %u.%05u ms\n", (UINT)(t1/10000), (UINT)(t1 % 10000)); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == AUDCLNT_E_ALREADY_INITIALIZED, "Calling Initialize twice returns %08x\n", hr); hr = IAudioClient_SetEventHandle(ac, NULL); ok(hr == E_INVALIDARG, "SetEventHandle(NULL) returns %08x\n", hr); hr = IAudioClient_Start(ac); ok(hr == AUDCLNT_E_EVENTHANDLE_NOT_SET, "Start before SetEventHandle returns %08x\n", hr); hr = IAudioClient_SetEventHandle(ac, handle); ok(hr == S_OK, "SetEventHandle returns %08x\n", hr); hr = IAudioClient_Reset(ac); ok(hr == S_OK, "Reset on a resetted stream returns %08x\n", hr); hr = IAudioClient_Stop(ac); ok(hr == S_FALSE, "Stop on a stopped stream returns %08x\n", hr); hr = IAudioClient_Start(ac); ok(hr == S_OK, "Start on a stopped stream returns %08x\n", hr); test_capture(ac, handle, pwfx); IAudioClient_Release(ac); CloseHandle(handle); CoTaskMemFree(pwfx); }
// Called on process 0, calculates all the legal moves in the current turn and divides them up to all the processors // Waits until all processors have finished their calculation and then returns the optimum move. int get_move_mpi(GameBoard* goBoard, int color) { int legalMoves = 0; char tempBoard[BOARD_SIZE * BOARD_SIZE + 4]; long possibleMoves[BOARD_SIZE * BOARD_SIZE + 1]; long bestMove = 0; int bestMoveIndex; int tempBlackPrisoners; int tempWhitePrisoners; MPI_Request requestArray[BOARD_SIZE * BOARD_SIZE + 1]; MPI_Status statusArray[BOARD_SIZE * BOARD_SIZE + 1]; for ( int i = 0; i < BOARD_SIZE * BOARD_SIZE; i++ ) { if ( is_legal(i, goBoard->board, goBoard->turnNumber) == 0 ) { legalMoves++; memcpy( tempBoard, goBoard->board, (BOARD_SIZE * BOARD_SIZE) * sizeof(char) ); tempBlackPrisoners = goBoard->blackPrisoners; tempWhitePrisoners = goBoard->whitePrisoners; tempBoard[i] = color; test_capture( tempBoard, &tempBlackPrisoners, &tempWhitePrisoners, i, color ); tempBoard[BOARD_SIZE * BOARD_SIZE] = (char) tempBlackPrisoners; tempBoard[BOARD_SIZE * BOARD_SIZE + 1] = (char) tempWhitePrisoners; tempBoard[BOARD_SIZE * BOARD_SIZE + 2] = (char) goBoard->turnNumber + 2; tempBoard[BOARD_SIZE * BOARD_SIZE + 3] = (char) color; // last four entries of tempBoard contain blackPrisoners, whitePrisoners, turnNumber, and current color. MPI_Send(tempBoard, BOARD_SIZE * BOARD_SIZE + 4, MPI_CHAR, legalMoves, 19, MPI_COMM_WORLD); // send board to processor with rank equal to legalMoves MPI_Irecv( &possibleMoves[i], 1, MPI_LONG, legalMoves, 19, MPI_COMM_WORLD, &requestArray[legalMoves - 1] ); // start non-blocking receive } else { possibleMoves[i] = 0; } } legalMoves++; memcpy( tempBoard, goBoard->board, (BOARD_SIZE * BOARD_SIZE) * sizeof(char)); tempBoard[BOARD_SIZE * BOARD_SIZE] = (char) goBoard->blackPrisoners; tempBoard[BOARD_SIZE * BOARD_SIZE + 1] = (char) goBoard->whitePrisoners; tempBoard[BOARD_SIZE * BOARD_SIZE + 2] = (char) goBoard->turnNumber + 2; tempBoard[BOARD_SIZE * BOARD_SIZE + 3] = (char) color; MPI_Send(tempBoard, BOARD_SIZE * BOARD_SIZE + 4, MPI_CHAR, legalMoves, 19, MPI_COMM_WORLD); // send board to processor with rank equal to legalMoves MPI_Irecv(&possibleMoves[BOARD_SIZE * BOARD_SIZE], 1, MPI_LONG, legalMoves, 19, MPI_COMM_WORLD, &requestArray[legalMoves - 1]); // start non-blocking receive // wait until all IRecv is complete MPI_Waitall(legalMoves, requestArray, statusArray); if (debug) { for (int i = BOARD_SIZE - 1; i >= 0 ; i--) { printf("\n%d:\n", i); for (int j = 0; j < BOARD_SIZE; j++) { printf("%ld ", possibleMoves[i * BOARD_SIZE + j]); } printf("\n"); fflush(stdout); } printf( "PASS: %ld\n", possibleMoves[BOARD_SIZE * BOARD_SIZE] ); } do { bestMoveIndex = rand() % ( BOARD_SIZE * BOARD_SIZE ); } while (is_legal(bestMoveIndex, goBoard->board, goBoard->turnNumber) != 0); bestMove = possibleMoves[bestMoveIndex]; // check each possible move and select the best outcome if (color == BLACK) { for (int i = 0; i < BOARD_SIZE * BOARD_SIZE + 1; i++) { if ( possibleMoves[i] > bestMove && possibleMoves[i] != 0) { bestMove = possibleMoves[i]; bestMoveIndex = i; } } } else { for (int i = 0; i < BOARD_SIZE * BOARD_SIZE + 1; i++) { if ( possibleMoves[i] < bestMove && possibleMoves[i] != 0) { bestMove = possibleMoves[i]; bestMoveIndex = i; } } } //printf("BEST MOVE: %ld BEST MOVE INDEX: %d\n", bestMove, bestMoveIndex); //fflush (stdout); if (bestMoveIndex == BOARD_SIZE * BOARD_SIZE) { return -1; // passing move } return bestMoveIndex; }