// plays a single game to completion void PlayGame() { BCGame.Reset(); int32 MaxTries = BCGame.GetMaxTries(); // loop asking for guesses while the game // is NOT won and there are still tries remaining while(!BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries) { FText Guess = GetValidGuess(); // submit valid guess to the game, and receive counts FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess); PrintGuess(BullCowCount); } return; }
/** * Implicit time integration solver. (Nonlinear version) * Works with both backward difference * integration (BD) and the trapazoid rule (TR). In either case, the algorithm * is supposed to be unconditionally stable. This function only solves the * problem at the next time step. In order to solve for the desired variables * over the entire time domain, call this function repeatedly. * * The time deriviative is calculated using the following formula: * y'(t1) = a/dt * [y(t1) - y(t0)] + b*y'(t0) * Here, t1 is the time at the current time step and t0 is at the previous one. * The variables a and b are constants that determine which algorithm is used * to approximate the derivative. For a=1, b=0, backward difference is used, * and for a=2, b=-1, trapazoid rule is used. * * @param problem Finite element problem to solve * @param guess Initial guess at the solution for the next time step. If this * is not supplied (NULL), then the solution is predicted based on the * previous time steps. * @returns Pointer to a matrix of the calculated values. This can be safely * disregarded since the matrix is also stored in the finite element * problem structure. */ matrix* NLinSolve1DTransImp(struct fe1d *problem, matrix *guess) { int iter = 0; /* Current iteration number */ int maxiter = 5000; /* Maximum allowed iterations before terminating */ /* Constants that determine the integration algorithm. If a=1 and b=0, then * the backward difference method is being used. For the trapazoid rule, * a=2, and b=-1. */ int a, b; solution *prev; /* Solution at the previous time step */ matrix *J, *F, *R; /* Jacobian matrix and the residuals matrix */ matrix *tmp1, *tmp2; /* Temporary matricies */ matrix *u, *du, *dx; matrix *dguess; /* Time derivative of the guess */ /* Use BD */ a = 1; b = 0; /* Note: This solver doesn't work at all with anything but backward * difference for time integration. The linear one doesn't either, but it * at least contains some code for it. */ /* Get the previous solution */ prev = FetchSolution(problem, problem->t-1); du = prev->dval; u = prev->val; /* Predict the next solution if an initial guess isn't supplied. */ if(!guess) guess = PredictSolnO0(problem); dx = NULL; //exit(0); do { iter++; /* Quit if we've reached the maximum number of iterations */ if(iter == maxiter) break; problem->guess = guess; /* Delete the matricies from the previous iteration */ DestroyMatrix(problem->J); DestroyMatrix(problem->dJ); DestroyMatrix(problem->F); /* Delete the dx matrix from the previous iteration. */ if(dx) DestroyMatrix(dx); /* Initialize the matricies */ AssembleJ1D(problem, guess); AssembledJ1D(problem, guess); AssembleF1D(problem, guess); //problem->guess = NULL; /* Calculate the Jacobian matrix */ tmp1 = mtxmulconst(problem->dJ, a/problem->dt); J = mtxadd(tmp1, problem->J); DestroyMatrix(tmp1); /* Calculate the load vector */ tmp1 = mtxmulconst(problem->dJ, a/problem->dt); tmp2 = mtxmul(tmp1, u); F = mtxadd(problem->F, tmp2); DestroyMatrix(tmp1); DestroyMatrix(tmp2); /* Apply boundary conditions. */ DestroyMatrix(problem->J); DestroyMatrix(problem->F); problem->J = J; problem->F = F; problem->applybcs(problem); /* Calculate the residual vector */ tmp1 = mtxmul(problem->J, guess); mtxneg(tmp1); R = mtxadd(problem->F, tmp1); DestroyMatrix(tmp1); //mtxprnt(problem->J); //puts(""); //mtxprnt(problem->dJ); //puts(""); //mtxprnt(problem->F); /* Solve for dx */ dx = SolveMatrixEquation(J, R); /* Delete the residual matrix and the Jacobian matrix*/ DestroyMatrix(R); /* Add the change in the unknowns to the guess from the previous * iteration */ tmp1 = mtxadd(guess, dx); DestroyMatrix(guess); guess = tmp1; #ifdef VERBOSE_OUTPUT /* Print the current iteration number to the console. */ printf("\rIteration %d", iter); fflush(stdout); // Flush the output buffer. #endif } while(!CheckConverg1D(problem, dx)); /* Delete the final dx matrix */ DestroyMatrix(dx); if(iter==maxiter) { printf("Nonlinear solver failed to converge. " "Maximum number of iterations reached.\n" "Failed to calculate solution at time step %d of %d\n" "Exiting.\n", problem->t, problem->maxsteps); printf("Current step size: %g\n", problem->dt); PrintSolution(problem, problem->t-1); printf("Current guess:\n"); PrintGuess(problem, guess); exit(0); } #ifdef VERBOSE_OUTPUT if(iter == -1) /* If we've determined the matrix to be singular by calculating the * determinant, then output the appropriate error message. */ printf("\rSingular matrix.\n"); else if(iter == maxiter) /* If the solver didn't find a solution in the specified number of * iterations, then say so. */ printf("\rNonlinear solver failed to converge. " "Maximum number of iterations reached.\n"); else /* Print out the number of iterations it took to converge * successfully. */ printf("\rNonlinear solver converged after %d iterations.\n", iter); #endif /* Solve for the time derivative of the result. */ dguess = CalcTimeDerivative(problem, guess); StoreSolution(problem, guess, dguess); /* Delete the time derivative of the pervious solution to save memory. */ //DeleteTimeDeriv(prev); return guess; }