//Solves the linear system Ax = b and returns x, where A and b are known and A //is square. A and b are complex. double complex * c_solve(double complex **A, double complex *b, int N) { int i, j, k, p; double complex m, sum = 0., temp, *x, **B; B = c_allocmatrix(N, N); x = (double complex *) malloc (N * sizeof(double complex)); for(i = 0; i < N; i++) { x[i] = b[i]; for(j = 0; j < N; j++) { B[i][j] = A[i][j]; } } for(j = 0; j<N-1; j++) { p = c_pivot_row(B, N, N, j, j); c_rowswap(B, p, j); temp = x[p]; x[p] = x[j]; x[j] = temp; for(i = j+1; i<N; i++) { if (B[j][j] == 0.) throwErr("Singular Matrix", "c_solve"); if (B[i][j] != 0.) { m = B[i][j] / B[j][j]; m *= -1.; //B[i] += m * B[j] for (k = 0; k < N; k++) B[i][k] += m * B[j][k]; x[i] += m * x[j]; } } } x[N-1] /= B[N-1][N-1]; for(i=N-2;i>=0; i--) { for(j=i+1; j<N; j++) sum += B[i][j] * x[j]; x[i] = (x[i] - sum) / B[i][i]; sum = 0.; } for (i = 0; i < N; i++) free(B[i]); free(B); return x; }
// Computes the condition number of complex N x N matrix A. // The condition number is defined as the ratio of the largest to the smallest // singular values. Uses LAPACK. // Note: may need to append _ to name of LAPACK functions. double ccondit_num (double complex **A, int N) { double complex *a, *cwork = NULL; double kappa, rcond, anorm; double *rwork = NULL; char NORM = '1'; int info; // Convert A for LAPACK functions a = cmat_to_fortran (A, N, N); // Allocate work, rwork for zgecon (work is not used in anorm with NORM='1') cwork = c_allocvector (2 * N); if (cwork == NULL) throwMemErr ("cwork", "ccondit_num"); rwork = allocvector (2 * N); if (rwork == NULL) throwMemErr ("rwork", "ccondit_num"); // Compute 1-norm of A anorm = zlange_ (&NORM, &N, &N, a, &N, rwork); // Compute reciprocal of condition number zgecon_ (&NORM, &N, a, &N, &anorm, &rcond, cwork, rwork, &info); kappa = 1. / rcond; if (info != 0) throwErr ("Illegal argument to zgecon", "ccondit_num"); free (a); free (cwork); free (rwork); return kappa; }
//------------------------------------------------------------------------------ // Prints a chart of strategies to a .tex file. //------------------------------------------------------------------------------ void printChart (Strategy **chart, const char *filename, int showWinPct, int MAKE_SIMPLE_CHART) { FILE *file = NULL; int i, j; file = fopen(filename, "w"); if (file == NULL) throwErr("File could not be opened.", "printChart"); fprintf(file, "\\documentclass{article}\n\n"); fprintf(file, "\\usepackage{amsmath, amssymb}\n"); fprintf(file, "\\pagenumbering{gobble}\n\n"); fprintf(file, "\\addtolength{\\oddsidemargin}{-.5in}\n"); fprintf(file, "\\addtolength{\\evensidemargin}{-.5in}\n"); fprintf(file, "\\addtolength{\\textwidth}{1in}\n"); fprintf(file, "\\addtolength{\\topmargin}{-1.5in}\n"); fprintf(file, "\\addtolength{\\textheight}{2.3in}\n\n"); fprintf(file, "\\begin{document}\n\n\\begin{center}\n\\begin{large}\n"); fprintf(file, "Blackjack Strategy\n\\end{large}\n\\end{center}\n\n"); fprintf(file, "\\begin{small}\n"); fprintf(file, "\\begin{center}\n\\emph{Dealer's up card}\n\\end{center}\n\n"); fprintf(file, "\\begin{tabular}{"); for (j = 0; j <= NUM_CARDS; j++) fprintf(file, "c|"); fprintf(file, "}\n"); for (j = 2; j <= NUM_CARDS; j++) fprintf(file, "& %d ", j); fprintf(file, "& A \\\\\n"); //Note: Ace is printed on the *right* side //Print the hands in the following order: 5 - 21, soft 13 - bust, AA, 22, //then 3,3 - 10,10. for (i = FIVE; i <= TWENTYONE; i++) printHand(i, chart, showWinPct, file); for (i = SOFT_THIRTEEN; i <= BUST; i++) printHand(i, chart, showWinPct, file); if (!(MAKE_SIMPLE_CHART)) { printHand(SOFT_TWELVE, chart, showWinPct, file); printHand(FOUR, chart, showWinPct, file); for (i = THREES; i <= TENS; i++) printHand(i, chart, showWinPct, file); } fprintf(file, "\\hline\n\\end{tabular}\n\n"); fprintf(file, "\\end{small}\n\n"); fprintf(file, "\\vspace{.1in}\n"); fprintf(file, "\\noindent KEY:\\\\\nH: Hit\\quad S: Stand\\quad DD: "); fprintf(file, "Double down\\quad SPL: Split\\\\\n"); fprintf(file, "X/Y: X\\%% chance of winning, Y\\%% chance of losing. " "(May not add up to 100 due to pushes. For splits, this is the"); fprintf(file, " probability of winning each of the two split hands.)\n\n"); fprintf(file, "\\end{document}\n"); fclose(file); }
void CEgIStream::ResetBuf() { throwErr( cNoErr ); mIsTied = false; mNextPtr = getCStr(); mBufPos = 0; mPos = 0; }
boost::iostreams::stream_offset VFileDevice::seek( boost::iostreams::stream_offset off, std::ios_base::seekdir way) { sf::Int64 from; if (way == std::ios_base::beg) from = 0; else if (way == std::ios_base::cur) from = m_f.tell(); else if (way == std::ios_base::end) from = m_f.getSize(); else throw std::invalid_argument("invalid seekdir"); throwErr(); sf::Int64 const result = m_f.seek(from + off); throwErr(); return result; }
void CEgIStream::fillBuf() { long bytes = mReadBufSize; Dim( bytes ); mNextPtr = getCStr(); mBufPos = mPos; if ( long(length()) < bytes ) // Verify that we dimmed ok bytes = length(); fillBlock( mPos, getCStr(), bytes ); if ( bytes <= 0 ) throwErr( cEOSErr ); mStrLen = bytes; // Our str len could have only gotten shorter }
//------------------------------------------------------------------------------ // Prints a Latex chart of the results of running simulations of each possible // hand. //------------------------------------------------------------------------------ void printSimsChart (HandSim **simsChart, Strategy **chart, const char *filename, int nsims) { FILE *file = NULL; int i, j; file = fopen(filename, "w"); if (file == NULL) throwErr("File could not be opened.", "printChart"); fprintf(file, "\\documentclass{article}\n\n"); fprintf(file, "\\usepackage{amsmath, amssymb, color}\n"); fprintf(file, "\\pagenumbering{gobble}\n\n"); fprintf(file, "\\addtolength{\\oddsidemargin}{-.5in}\n"); fprintf(file, "\\addtolength{\\evensidemargin}{-.5in}\n"); fprintf(file, "\\addtolength{\\textwidth}{1in}\n"); fprintf(file, "\\addtolength{\\topmargin}{-1.5in}\n"); fprintf(file, "\\addtolength{\\textheight}{2.3in}\n\n"); fprintf(file, "\\begin{document}\n\n\\begin{center}\n\\begin{large}\n"); fprintf(file, "Blackjack Strategy\n\\end{large}\n\\end{center}\n\n"); fprintf(file, "\\begin{small}\n"); fprintf(file, "\\begin{center}\n\\emph{Dealer's up card}\n\\end{center}\n\n"); fprintf(file, "\\begin{tabular}{"); for (j = 0; j <= NUM_CARDS; j++) fprintf(file, "c|"); fprintf(file, "}\n"); for (j = 2; j <= NUM_CARDS; j++) fprintf(file, "& %d ", j); fprintf(file, "& A \\\\\n"); //Note: Ace is printed on the *right* side //Print the hands in the following order: 5 - 21, soft 13 - bust, AA, 22, //then 3,3 - 10,10. for (i = FIVE; i <= TWENTYONE; i++) printHandSims(i, simsChart, chart, file, nsims); for (i = SOFT_THIRTEEN; i <= BUST; i++) printHandSims(i, simsChart, chart, file, nsims); printHandSims(SOFT_TWELVE, simsChart, chart, file, nsims); printHandSims(FOUR, simsChart, chart, file, nsims); for (i = THREES; i <= TENS; i++) printHandSims(i, simsChart, chart, file, nsims); fprintf(file, "\\hline\n\\end{tabular}\n\n"); fprintf(file, "\\end{small}\n\n"); fprintf(file, "\\end{document}\n"); fclose(file); }
//------------------------------------------------------------------------------ // Returns the symbol (H, S, DD, SP) corresponding to the given action. //------------------------------------------------------------------------------ char * actionSymbol (int action) { if (action == STAND) return "S"; else if (action == HIT) return "H"; else if (action == SPLIT) return "SPL"; else if (action == DOUBLE_DOWN) return "DD"; else { throwErr("Unknown action", "actionSymbol"); return ""; } }
Boolean XWinLibrary::Load( const VFilePath &inPath) { VFilePath executablePath; if (_BuildExecutablePath( inPath, executablePath)) { fInstance = ::LoadLibraryExW( executablePath.GetPath().GetCPointer(), NULL, 0); } if (fInstance == NULL) { XBOX::VString path( executablePath.GetPath()); DebugMsg("VComponentManager erreur load %V\n", &path); StThrowFileError throwErr( inPath, VE_LIBRARY_CANNOT_LOAD, ::GetLastError()); fInstance = NULL; } return fInstance != NULL; }
unsigned char CEgIStream::PeekByte() { register unsigned char c; if ( mIsTied ) { if ( mPos != 0 ) c = *((unsigned char*) mNextPtr); } else if ( mPos < long(mBufPos + mStrLen) && mPos >= mBufPos ) c = *((unsigned char*) mNextPtr); else if ( noErr() ) { fillBuf(); if ( noErr() ) c = PeekByte(); else throwErr( cNoErr ); } return c; }
void CEgIStream::Tie( const char* inSrce, long inNumBytes ) { throwErr( cNoErr ); mIsTied = true; mPos = - inNumBytes; // When mPos reaches zero, we're at tied end of stream mNextPtr = inSrce; // Set up our data ptr // If -1 was passed in thru inNumBytes, must calc the length of the C str. if ( inNumBytes < 0 ) { mPos = 0; while ( *inSrce ) { mPos--; inSrce++; } } if ( ! mNextPtr ) mPos = 0; }
long CEgIStream::GetBlock( void* destPtr, unsigned long inBytes ) { long bytesRead = inBytes; if ( mIsTied ) { if ( - mPos >= long(inBytes) ) UtilStr::Move( destPtr, mNextPtr, bytesRead ); else { bytesRead = 0; throwErr( cTiedEOS ); } } else if ( mPos >= mBufPos && mPos + bytesRead <= long(mBufPos + mStrLen) ) UtilStr::Move( destPtr, mNextPtr, bytesRead ); else fillBlock( mPos, destPtr, bytesRead ); mPos += bytesRead; mNextPtr += bytesRead; return bytesRead; }
unsigned char CEgIStream::GetByte() { register unsigned char c; if ( mIsTied ) { if ( mPos != 0 ) { c = *((unsigned char*) mNextPtr); mNextPtr++; mPos++; } else throwErr( cTiedEOS ); } else if ( mPos < long(mBufPos + mStrLen) && mPos >= mBufPos ) { c = *((unsigned char*) mNextPtr); mNextPtr++; mPos++; } else if ( noErr() ) { fillBuf(); c = GetByte(); } return c; }
//Runs Monte Carlo simulations to test the strategy void run_sims () { //File name to print chart to const char *filename = "Simulations chart.tex"; //Number of simulations to run for each combination of hand and up card (to //start with; user may add more simulations during the running of the //program) const int N_SIMS = 1000; Strategy **chart = NULL; HandSim **simsChart; int i, j; int N; //number of simulations to run int n; //number that have been completed int m; //number of additional sims to run int info; //First, compute the strategy chart in the same way as bj_strat.c. //chart is a NUM_HANDS by NUM_CARDS+1 matrix, with entry i,j being hands[i] //and the card with face value j. chart = (Strategy **) malloc(NUM_HANDS * sizeof(Strategy *)); for (i = 0; i < NUM_HANDS; i++) chart[i] = (Strategy *) malloc((NUM_CARDS+1) * sizeof(Strategy)); if (chart == NULL) throwMemErr("chart", "main"); //Make vector of possible hands makeHands(); //Make matrix of dealer's probabilities of ending up with a given total given //each given up card dealersProbabilities = makeDealersProbabilities(); //Compute optimal strategy for each combination of player's hand and //dealer's up card calculateStrategyChart (chart, FALSE); simsChart = initializeSimsChart(); n = 0; N = N_SIMS; while (n < N) { for (i = 0; i < NUM_HANDS; i++) //i = player's hand { if (!(hands[i].isObvious)) { for (j = 1; j <= NUM_CARDS; j++) //j = up card { runSims (simsChart, chart, i, j, N - n); } } printf("Finished running simulations for hand %d of %d.\n", i + 1, NUM_HANDS); } n = N; //Print chart to Latex printSimsChart (simsChart, chart, filename, n); printf("Completed %d simulations for each hand. Maximum error: %.0f%%." "\nHow many more simulations would you like to run? (Enter N=0 to " "finish.)\nN = ", n, fmax(getMaxWinErr(chart, simsChart, n), getMaxLossErr(chart, simsChart, n))); info = scanf("%d", &m); if (info != 1) throwErr("Error with scanf", "run_sims"); printf("\n"); N += m; } freematrix(dealersProbabilities, NUM_CARDS+1); for (i = 0; i < NUM_HANDS; i++) free(chart[i]); free(chart); for (i = 0; i < NUM_HANDS; i++) free(simsChart[i]); free(simsChart); }
std::streamsize VFileDevice::write(char const* s, std::streamsize n) { sf::Int64 const result = m_f.write(s, n); throwErr(); return result; }
std::streamsize VFileDevice::read(char* s, std::streamsize n) { sf::Int64 const result = m_f.read(s, n); throwErr(); return result; }
VFileDevice::VFileDevice(VFile& f): m_f(f) { throwErr(); }