void ToStruct(JOYSTICK_FEATURE& feature) const { feature.name = new char[m_name.length() + 1]; feature.type = m_type; switch (m_type) { case JOYSTICK_FEATURE_TYPE_SCALAR: Primitive().ToStruct(feature.scalar.primitive); break; case JOYSTICK_FEATURE_TYPE_ANALOG_STICK: Up().ToStruct(feature.analog_stick.up); Down().ToStruct(feature.analog_stick.down); Right().ToStruct(feature.analog_stick.right); Left().ToStruct(feature.analog_stick.left); break; case JOYSTICK_FEATURE_TYPE_ACCELEROMETER: PositiveX().ToStruct(feature.accelerometer.positive_x); PositiveY().ToStruct(feature.accelerometer.positive_y); PositiveZ().ToStruct(feature.accelerometer.positive_z); break; case JOYSTICK_FEATURE_TYPE_MOTOR: Primitive().ToStruct(feature.motor.primitive); break; default: break; } std::strcpy(feature.name, m_name.c_str()); }
void posix_words() { Primitive( "getwd", &_getwd ); Colon( "pwd" ); c("getwd"); c("type"); c("cr"); End(); Primitive( "(getenv)", &_getenv ); Primitive( "(setenv)", &_setenv ); Colon( "getenv" ); c("parse-word"); c("(getenv)"); End(); Colon( "setenv" ); c("parse-word"); c("parse-word"); c("(setenv)"); End(); Colon( "printenv" ); c("parse-word"); c("2dup"); c("type"); Literal((Cell)'='); c("emit"); c("(getenv)"); If(); c("type"); Then(); c("cr"); End(); Primitive( "(system)", &_system ); Primitive( "(exec)", &_exec ); /* mmap() protection */ Constant( "PROT_EXEC", (Cell)PROT_EXEC ); Constant( "PROT_READ", (Cell)PROT_READ ); Constant( "PROT_WRITE", (Cell)PROT_WRITE ); Constant( "PROT_NONE", (Cell)PROT_NONE ); /* mmap() Flags */ Constant( "MAP_FIXED", (Cell)MAP_FIXED ); Constant( "MAP_SHARED", (Cell)MAP_SHARED ); Constant( "MAP_PRIVATE", (Cell)MAP_PRIVATE ); Primitive( "mmap", &do_mmap ); Primitive( "getpid", &_getpid ); Primitive( "getppid", &_getppid ); /* Signals for kill */ Constant( "SIGHUP", (Cell)SIGHUP ); Constant( "SIGINT", (Cell)SIGINT ); Constant( "SIGQUIT", (Cell)SIGQUIT ); Constant( "SIGILL", (Cell)SIGILL ); Constant( "SIGTRAP", (Cell)SIGTRAP ); Constant( "SIGABRT", (Cell)SIGABRT ); Constant( "SIGIOT", (Cell)SIGIOT ); Constant( "SIGBUS", (Cell)SIGBUS ); Constant( "SIGFPE", (Cell)SIGFPE ); Constant( "SIGKILL", (Cell)SIGKILL ); Constant( "SIGUSR1", (Cell)SIGUSR1 ); Constant( "SIGSEGV", (Cell)SIGSEGV ); Constant( "SIGUSR2", (Cell)SIGUSR2 ); Constant( "SIGPIPE", (Cell)SIGPIPE ); Constant( "SIGALRM", (Cell)SIGALRM ); Constant( "SIGTERM", (Cell)SIGTERM ); // Constant( "SIGSTKFLT", (Cell)SIGSTKFLT ); // Constant( "SIGCLD", (Cell)SIGCLD ); Constant( "SIGCHLD", (Cell)SIGCHLD ); Constant( "SIGCONT", (Cell)SIGCONT ); Constant( "SIGSTOP", (Cell)SIGSTOP ); Constant( "SIGTSTP", (Cell)SIGTSTP ); Primitive( "kill", &_kill ); }
/* Handle * and / operators */ Condition* Term(const char** str) { Condition* t; Condition* t1; Condition* mid; t = (Condition*)FCEU_dmalloc(sizeof(Condition)); if (!t) return NULL; memset(t, 0, sizeof(Condition)); if (!Primitive(str, t)) { freeTree(t); return 0; } while (next == '*' || next == '/') { int op = next == '*' ? OP_MULT : OP_DIV; scan(str); if (!(t1 = (Condition*)FCEU_dmalloc(sizeof(Condition)))) return NULL; memset(t1, 0, sizeof(Condition)); if (!Primitive(str, t1)) { freeTree(t); freeTree(t1); return 0; } if (!(mid = (Condition*)FCEU_dmalloc(sizeof(Condition)))) return NULL; memset(mid, 0, sizeof(Condition)); mid->lhs = t; mid->rhs = t1; mid->op = op; t = mid; } return t; }
void PopulateEdgelist(EDGELIST *tree) { int level; POSITION parent, child; MOVELIST *childMoves; MOVE theMove; OPEN_POS_DATA pdata, cdata; int resizeCount = 0; int resizeLevelCount = 0; if(!kLoopy || !gUseOpen) level = 0; for(parent=0; parent < gNumberOfPositions; parent++) { if(GetValueOfPosition(parent) == undecided && Remoteness(parent) != REMOTENESS_MAX) { continue; } if(Primitive(parent) != undecided) { continue; } else { childMoves = GenerateMoves(parent); } while(1) { theMove = childMoves->move; child = DoMove(parent, theMove); if(kLoopy && gUseOpen) { pdata = GetOpenData(parent); cdata = GetOpenData(child); level = GetLevelNumber(pdata); } /* If the level is more than the number in tree, resize to handle more levels */ if(level > (GameTree.NumberOfLevels - 1)) { resizeCount++; ResizeTree(&GameTree, level); } (((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Parent = parent; (((GameTree.edges)[level])[(GameTree.nextEdgeInLevel)[level]]).Child = child; (GameTree.nextEdgeInLevel)[level] += 1; /* Resize an individual level if no room left */ if(((GameTree.edgesPerLevel)[level] - 2) <= (GameTree.nextEdgeInLevel)[level]) { resizeLevelCount++; (GameTree.edges)[level] = SafeRealloc((GameTree.edges)[level], (GameTree.edgesPerLevel)[level] * 2 * sizeof(EDGE)); (GameTree.edgesPerLevel)[level] = (GameTree.edgesPerLevel)[level] * 2; } if((childMoves = childMoves->next) == NULL) { break; } } } //printf("Levels resized: %d, tree resized: %d\n", resizeLevelCount, resizeCount); }
T1(Primitive) Vector4T<Primitive> PlaneFit( const Vector3T<Primitive>& pt0, const Vector3T<Primitive>& pt1, const Vector3T<Primitive>& pt2) { /* Note -- this the most straightforward fashion to calculate a plane, but unfortunately it's inaccurate (particularly if the points are close together). There are better methods, but they require more complex math (see, for example, the Triangle library) */ auto normal = Normalize( Cross( pt0 - pt1, pt2 - pt1 ) ); Primitive w = (-Dot( pt0, normal ) - Dot( pt1, normal ) - Dot( pt2, normal )) * Primitive(1./3.); return Expand( normal, w ); }
Primitive operator()(size_t i) const { const double width = grid_[i+1] - grid_[i]; const double density = masses_[i]/width; const double velocity = momenta_[i]/masses_[i]; const double thermal_energy = energies_[i]/masses_[i] - 0.5*pow(velocity,2); const double pressure = eos_.de2p(density, thermal_energy); return Primitive(density, pressure, velocity); }
MOVELIST *GenerateMoves(POSITION position) { // Here, use head = CreateMovelistNode(move,head) ; // then return head when done MOVELIST *CreateMovelistNode(), *head = NULL; int i, j; if(Primitive(position) == undecided) { position /= 2; for(i = 0; i < rows; i++) { int piecesinrow = position % 8; position = position >> 3; for(j = 1; j <= piecesinrow; j++) head = CreateMovelistNode( (MOVE)((i+1)*10 + j), head); } }
T1(Primitive) bool PlaneFit_Checked( Vector4T<Primitive>* result, const Vector3T<Primitive>& pt0, const Vector3T<Primitive>& pt1, const Vector3T<Primitive>& pt2) { assert(result); /* Note -- this the most straightforward fashion to calculate a plane, but unfortunately it's inaccurate (particularly if the points are close together). There are better methods, but they require more complex math (see, for example, the Triangle library) */ Vector3T<Primitive> normal; if (!Normalize_Checked(&normal, Cross(pt0 - pt1, pt2 - pt1))) return false; auto w = (-Dot( pt0, normal ) - Dot( pt1, normal ) - Dot( pt2, normal )) * Primitive(1./3.); *result = Expand( normal, w ); return true; }
double Prmv(char chaine[], char variable, double valeur, void *donnees) { if (!donnees) return ERR_PARAM; OptionsAlgo *optn = (OptionsAlgo*) donnees; double param[5] = {0}; char *tab[5] = {NULL}; tab[0] = malloc(MAX_CHAINE); tab[0][0] = '\0'; tab[1] = malloc(MAX_CHAINE); tab[1][0] = '\0'; RecupererParametres(chaine, param, 5, variable, valeur, tab, MAX_CHAINE); if (param[2] >= CODE_ERREUR || param[3] >= CODE_ERREUR || param[4] >= CODE_ERREUR || !tab[0][0] || !tab[1][0] || tab[1][1]) { free(tab[0]); free(tab[1]); return ERR_PARAM; } double a = Primitive(tab[0], tab[1][0], param[2], param[3], param[4], *optn); free(tab[0]); free(tab[1]); return a; }
Primitive Primitive::operator*(double s) { return Primitive(this->density*s,this->pressure*s,this->velocity*s,this->entropy*s); }
VALUE DetermineZeroValue(POSITION position) { POSITION i,lowSeen,highSeen; POSITION numUndecided, oldNumUndecided, numNew; MOVELIST *moveptr, *headMove; POSITION child; VALUE childValue; POSITION numTot, numWin, numTie; int tieRemoteness, winRemoteness; //if (gTwoBits) // InitializeVisitedArray(); StoreValueOfPosition(position,Primitive(position)); MarkAsVisited(position); oldNumUndecided = 0; numUndecided = 1; numNew = 1; lowSeen = position; highSeen = lowSeen+1; while((numUndecided != oldNumUndecided) || (numNew != 0)) { oldNumUndecided = numUndecided; numUndecided = 0; numNew = 0; for(i = lowSeen; i <= highSeen; i++) { if(Visited(i)) { if(GetValueOfPosition(i) == undecided) { moveptr = headMove = GenerateMoves(i); numTot = numWin = numTie = 0; tieRemoteness = winRemoteness = REMOTENESS_MAX; while(moveptr != NULL) { child = DoMove(i,moveptr->move); numTot++; if(Visited(child)) childValue = GetValueOfPosition(child); else{ childValue = Primitive(child); numNew++; MarkAsVisited(child); StoreValueOfPosition(child,childValue); if(childValue != undecided) { SetRemoteness(child,0); } if(child < lowSeen) lowSeen = child; if(child > highSeen) highSeen = child + 1; } if(childValue == lose) { StoreValueOfPosition(i,win); if(Remoteness(i) > Remoteness(child)+1) SetRemoteness(i,Remoteness(child)+1); } if(childValue == win) { numWin++; if(Remoteness(child) < winRemoteness) { winRemoteness = Remoteness(child); } } if(childValue == tie) { numTie++; if(Remoteness(child) < tieRemoteness) { tieRemoteness = Remoteness(child); } } moveptr = moveptr->next; } FreeMoveList(headMove); if((numTot != 0) && (numTot == numWin + numTie)) { if(numTie == 0) { SetRemoteness(i, winRemoteness+1); StoreValueOfPosition(i,lose); }else{ SetRemoteness(i, tieRemoteness+1); StoreValueOfPosition(i,tie); } } if(GetValueOfPosition(i) == undecided) numUndecided++; } } } printf("\nnumUndecided: " POSITION_FORMAT ", diff: " POSITION_FORMAT ", numNew: " POSITION_FORMAT ", lowSeen: " POSITION_FORMAT ", highSeen: " POSITION_FORMAT, numUndecided,numUndecided - oldNumUndecided,numNew,lowSeen,highSeen); } for(i = 0; i < gNumberOfPositions; i++) { if(Visited(i) && (GetValueOfPosition(i) == undecided)) { SetRemoteness(i,REMOTENESS_MAX); StoreValueOfPosition(i, tie); } UnMarkAsVisited(i); } return GetValueOfPosition(position); }
MOVELIST *GenerateMoves(POSITION position) { int i, j, t, sumTop, sumBottom; int startBin = mancalaL + 1; int endBin = mancalaR; int *arrayHashedBoard; MOVELIST *CreateMovelistNode(), *head = NULL; arrayHashedBoard = array_hash(position); t = arrayHashedBoard[turn]; if(t == 0) { startBin = mancalaR + 1; endBin = boardSize; } /* sum up the top and bottom rows of bins */ for(i = mancalaL + 1, j = mancalaR + 1, sumTop = 0, sumBottom = 0; i < mancalaR && j < boardSize; sumTop += arrayHashedBoard[i], sumBottom += arrayHashedBoard[j], i += 1, j += 1) ; if(Primitive(position) == undecided) { /* on my turn starting, i'm empty -> i get to move from my opponent's bins OR the option is set in which you can choose from any bin on the board */ if(OPT_WINEMPTY == 2 || OPT_MOVEOPP == 1) { if(t == 0 && ((sumBottom == 0 && OPT_WINEMPTY == 2) || OPT_MOVEOPP == 1)) { for(i = mancalaL + 1; i < mancalaR; i += 1) { if(arrayHashedBoard[i] > 0) { head = CreateMovelistNode(i, head); } } } else if(t == 1 && ((sumTop == 0 && OPT_WINEMPTY == 2) || OPT_MOVEOPP == 1)) { for(i = mancalaR + 1; i < boardSize; i += 1) { if(arrayHashedBoard[i] > 0) { head = CreateMovelistNode(i, head); } } } } /* on my turn starting, i'm empty -> i pass */ if(OPT_WINEMPTY == 4 && ((t == 0 && sumBottom == 0) || (t == 1 && sumTop == 0)) ) { head = CreateMovelistNode(0, head); } /* the default moves available */ else { for(i = startBin; i < endBin; i += 1) { if(arrayHashedBoard[i] > 0) { head = CreateMovelistNode(i, head); } } } SafeFree(arrayHashedBoard); if (head == NULL) { head = CreateMovelistNode(0, head); } return head; } else { SafeFree(arrayHashedBoard); return NULL; } }
void Model_Sonic::createPrimitives(ParserContext &ctx, Geometry &geometry, Polygon &polygon) { /* Go through all polygon commands in this polygon and evaluate them, creating * an intermediate Primitive for each vertex segment between BeginVertices * and EndVertices commands. */ // We already counted the number of primitives while reading the command list geometry.primitives.reserve(polygon.primitiveCount); // Running vertex buffer PrimitiveVertex vertex; bool hasVertex = false; Primitive *primitive = 0; StackMixMap::const_iterator stackMix = ctx.stackMix.end(); // Default values StackBoneMap::const_iterator stackBone = ctx.stackBones.find(polygon.defaultStack); ModelNode_Sonic *defaultNode = (stackBone != ctx.stackBones.end()) ? stackBone->second->modelNode : 0; if (defaultNode) vertex.nodes.push_back(PrimitiveNode(defaultNode, 1.0f)); Common::Vector3 primScale(ctx.defaultScale, ctx.defaultScale, ctx.defaultScale); // Texture dimensions, to convert the texture coordinates to OpenGL notation const double tWidth = !geometry.texture.empty() ? geometry.texture.getTexture().getWidth() : 1.0f; const double tHeight = !geometry.texture.empty() ? geometry.texture.getTexture().getHeight() : 1.0f; for (PolygonCommands::const_iterator c = polygon.commands.begin(); c != polygon.commands.end(); ++c) { switch(c->command) { case kPolygonNOP: break; case kPolygonBeginVertices: geometry.primitives.push_back(Primitive((PrimitiveType) c->parameters[0])); primitive = &geometry.primitives.back(); // We calculated the maximum length of a primitive earlier primitive->vertices.reserve(polygon.primitiveSize); break; case kPolygonEndVertices: // We don't strictly need to observe the EndVertices command. // In fact, according to some people, the Nintendo DS itself doesn't either. break; case kPolygonColor: // BGR555 vertex.color[0] = ( c->parameters[0] & 0x1F) / 31.0f; vertex.color[1] = ((c->parameters[0] >> 5) & 0x1F) / 31.0f; vertex.color[2] = ((c->parameters[0] >> 10) & 0x1F) / 31.0f; break; case kPolygonTexCoord: // One unit ^= one texel! vertex.texCoord[0] = readNintendoFixedPoint( c->parameters[0] & 0xFFFF, true, 11, 4) / tWidth; vertex.texCoord[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 11, 4) / tHeight; break; case kPolygonNormal: vertex.normal[0] = readNintendoFixedPoint( c->parameters[0] & 0x03FF, true, 0, 9); vertex.normal[1] = readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 0, 9); vertex.normal[2] = readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 0, 9); break; case kPolygonVertex16: vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0] & 0xFFFF, true, 3, 12); vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12); vertex.vertex[2] = readNintendoFixedPoint( c->parameters[1] & 0xFFFF, true, 3, 12); hasVertex = true; break; case kPolygonVertex10: vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0] & 0x03FF, true, 3, 6); vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 3, 6); vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 3, 6); hasVertex = true; break; case kPolygonVertexXY: vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0] & 0xFFFF, true, 3, 12); vertex.vertex[1] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12); hasVertex = true; break; case kPolygonVertexXZ: vertex.vertex[0] = readNintendoFixedPoint( c->parameters[0] & 0xFFFF, true, 3, 12); vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12); hasVertex = true; break; case kPolygonVertexYZ: vertex.vertex[1] = readNintendoFixedPoint( c->parameters[0] & 0xFFFF, true, 3, 12); vertex.vertex[2] = readNintendoFixedPoint((c->parameters[0] >> 16) & 0xFFFF, true, 3, 12); hasVertex = true; break; case kPolygonVertexDiff: vertex.vertex[0] += readNintendoFixedPoint( c->parameters[0] & 0x03FF, true, 0, 9) / 8; vertex.vertex[1] += readNintendoFixedPoint((c->parameters[0] >> 10) & 0x03FF, true, 0, 9) / 8; vertex.vertex[2] += readNintendoFixedPoint((c->parameters[0] >> 20) & 0x03FF, true, 0, 9) / 8; hasVertex = true; break; case kPolygonMatrixRestore: if ((stackMix = ctx.stackMix.find(c->parameters[0])) != ctx.stackMix.end()) { // Was this stack position filled with kBoneLoadStack? vertex.nodes.clear(); vertex.nodes.reserve(stackMix->second.size()); for (StackMixes::const_iterator m = stackMix->second.begin(); m != stackMix->second.end(); ++m) vertex.nodes.push_back(PrimitiveNode(*m)); } else if ((stackBone = ctx.stackBones.find(c->parameters[0])) != ctx.stackBones.end()) { // Is this a regular bone position? vertex.nodes.clear(); vertex.nodes.push_back(PrimitiveNode(stackBone->second->modelNode, 1.0f)); } // Reset the scale primScale[0] = 1.0f; primScale[1] = 1.0f; primScale[2] = 1.0f; break; case kPolygonMatrixScale: // The NDS probably directly scales the current matrix? primScale[0] *= readNintendoFixedPoint(c->parameters[0], true, 19, 12); primScale[1] *= readNintendoFixedPoint(c->parameters[1], true, 19, 12); primScale[2] *= readNintendoFixedPoint(c->parameters[2], true, 19, 12); break; // Commands we hopefully won't need case kPolygonMatrixMode: case kPolygonMatrixPush: case kPolygonMatrixPop: case kPolygonMatrixStore: case kPolygonMatrixIdentity: case kPolygonMatrixLoad4x4: case kPolygonMatrixLoad4x3: case kPolygonMatrixMult4x4: case kPolygonMatrixMult4x3: case kPolygonMatrixMult3x3: case kPolygonMatrixTranslate: case kPolygonPolygonAttrib: case kPolygonTexImageParam: case kPolygonPaletteBase: case kPolygonDiffuseAmbient: case kPolygonSpecularEmit: case kPolygonLightVector: case kPolygonLightColor: case kPolygonShininess: case kPolygonSwapBuffers: case kPolygonViewport: case kPolygonBoxTest: case kPolygonPosTest: case kPolygonVecTest: throw Common::Exception("Unsupported polygon command: 0x%02X", (uint) c->command); default: throw Common::Exception("Invalid polygon command: 0x%02X", (uint) c->command); } if (hasVertex && primitive) { /* TODO: We're disabling primitives with mixed stack positions here. * To support this, we need a way to properly average several * matrices in evaluatePrimitive(). */ if (vertex.nodes.size() > 1) primitive->invalid = true; primitive->vertices.push_back(vertex); primitive->vertices.back().vertex.multiply(primScale); hasVertex = false; } } }
unsigned int TriangleAdjacencyGraph::calcOptPrim ( unsigned extIteration, bool doStrip, bool doFan, unsigned minFanTriangles ) { int iteration = extIteration; bool sample = iteration > 1 ? true : false; bool checkRevOrder = sample; TriangleList degreeBag[4]; TriangleList *fList = 0; int cost = 0, sampleCost = 0; int stripCost = 0, revCost = 0, fanCost = 0, triCost = 0; int bestCost = 0, worstCost = 0, lowDegree; unsigned int i, n; WalkCase walkCase = START; Triangle *triangle, *next; HalfEdge *twin = 0, *gateEdge = 0, *halfEdge = 0; bool doMainLoop = true; unsigned int seed = 1, bestSeed = 1; int mostDegree = 3; unsigned triangleLeft = _trianglePool.countElem(); srand(1); if (doFan) { n = _temporaryVector.size(); fanCost = 0; // find fans for (i = 0; i < n; i++) if ( (_temporaryVector[i].size() >= minFanTriangles) && (gateEdge = _temporaryVector[i][0].second) && (gateEdge->triangle->valid()) ) { for ( halfEdge = gateEdge->next->next->twin; (halfEdge && halfEdge->triangle->valid() && (halfEdge != gateEdge)); halfEdge = halfEdge->next->next->twin ) ; if (halfEdge == gateEdge) { // fan is closed; mark every triangle triangle = 0; fList = new TriangleList; for ( halfEdge = gateEdge; !triangle || (halfEdge != gateEdge); halfEdge = halfEdge->next->next->twin ) { triangle = halfEdge->triangle; _validTriangleBag.release(*triangle); triangle->drop(); triangle->state = FAN_PART; fList->add(*triangle); } _fanBag.push_back(Primitive(i,fList)); fanCost += (_temporaryVector[i].size() + 2); triangleLeft -= _temporaryVector[i].size(); } } } if (doStrip && iteration) { // push every triangle into the according degree bag degreeBag[mostDegree].paste(_validTriangleBag); for (triangle = degreeBag[mostDegree].first; triangle; triangle = next) { next = triangle->next; if (triangle->valid()) { if (triangle->state != mostDegree) { degreeBag[mostDegree].release(*triangle); _validTriangleBag.release(*triangle); degreeBag[triangle->state].add( *triangle); } } else { cerr << "INVALID TRIANGLE IN VALID TRIANGLE BAG\n" << endl; } } for (iteration--; iteration >= 0; iteration--) { seed = iteration ? rand() : bestSeed; srand (seed); fList = 0; cost = 0; doMainLoop = true; walkCase = START; // run the main loop while (doMainLoop) { switch (walkCase) { case START: stripCost = 0; triangle = 0; for (lowDegree = 1; lowDegree < 4; lowDegree++) if ((degreeBag[lowDegree].empty() == false)) { if (sample) { // pick a random triangle n = degreeBag[lowDegree].countElem() - 1; i = int(float(n) * rand()/float(RAND_MAX)); triangle = degreeBag[lowDegree].first; while (i--) triangle = triangle->next; } else { // pick the first triangle triangle = degreeBag[lowDegree].first; } break; } if (triangle) { // create the new list fList = new TriangleList; // find the best neighbour gateEdge = 0; for (i = 0; i < 3; i++) if ( (twin = triangle->halfEdgeVec[i].twin) && (twin->triangle->state > 0) ) { if ( twin->next->next->twin && (twin->next->next->twin->triangle->state > 0) ) { gateEdge = &triangle->halfEdgeVec[i]; break; } else { if ( twin->next->twin && (twin->next->twin->triangle->state > 0) ) gateEdge = &triangle->halfEdgeVec[i]; else { if ((twin->triangle->state > 0)) gateEdge = &triangle->halfEdgeVec[i]; } } } // release and store the first triangle dropOutTriangle (*triangle,degreeBag); fList->add(*triangle); stripCost += 3; // set the next step if (gateEdge) { walkCase = LEFT; stripCost++; } else walkCase = FINISH; } else doMainLoop = false; break; case LEFT: gateEdge = gateEdge->twin; triangle = gateEdge->triangle; // find the next gate if (triangle->state == DEGREE_0) { gateEdge = 0; walkCase = FINISH; } else if ( (twin = gateEdge->next->next->twin) && (twin->triangle->state > 0) ){ gateEdge = gateEdge->next->next; stripCost++; walkCase = RIGHT; } else { gateEdge = gateEdge->next; stripCost += 2; walkCase = LEFT; } // store the current triangle dropOutTriangle (*triangle,degreeBag); fList->add(*triangle); break; case RIGHT: gateEdge = gateEdge->twin; triangle = gateEdge->triangle; // find the next gate if (triangle->state == DEGREE_0) { gateEdge = 0; walkCase = FINISH; } else if ( (twin = gateEdge->next->twin) && (twin->triangle->state > 0) ) { gateEdge = gateEdge->next; stripCost++; walkCase = LEFT; } else { gateEdge = gateEdge->next->next; stripCost += 2; walkCase = RIGHT; } // store the current triangle dropOutTriangle (*triangle,degreeBag); fList->add(*triangle); break; case FINISH: // try to reverse the strip if ( checkRevOrder && (revCost = calcStripCost(*fList,true)) && (revCost < stripCost) ) { _stripBag.push_back(Primitive(1,fList)); cost += revCost; } else { _stripBag.push_back(Primitive(0,fList)); cost += stripCost; } walkCase = START; fList = 0; break; } } if (sample) { sampleCost = cost + (degreeBag[0].countElem() * 3) + fanCost; if (!bestCost || (sampleCost < bestCost)) { bestCost = sampleCost; bestSeed = seed; } if (sampleCost > worstCost) worstCost = sampleCost; cout << " cost/best/worst: " << sampleCost << '/' << bestCost << '/' << worstCost << endl; } if (iteration) { // reinit the four degree bags degreeBag[mostDegree].paste(degreeBag[0]); n = _stripBag.size(); for (i = 0; i < n; i++) { degreeBag[mostDegree].paste(*_stripBag[i].second); delete _stripBag[i].second; } _stripBag.clear(); for ( triangle = degreeBag[mostDegree].first; triangle; triangle = next) { next = triangle->next; triangle->resetDegreeState(STRIP_PART); if (triangle->valid()) { if (triangle->state != mostDegree) { degreeBag[mostDegree].release(*triangle); degreeBag[triangle->state].add(*triangle); } } else { cerr << "INVALID TRIANGLE IN REINIT\n" << endl; cerr << triangle->state << endl; } } } } } else { // push every valid triangle in degree 0; we don't strip anything degreeBag[0].paste(_validTriangleBag); } if (sample) { cerr << "range: " << bestCost << '/' << worstCost << ' ' << float(100 * (worstCost-bestCost))/float(bestCost) << '%' << endl; } // collect isolated triangles degreeBag[0].paste(_invalidTriangleBag); triCost = degreeBag[0].countElem() * 3; if (triCost) { fList = new TriangleList; fList->paste(degreeBag[0]); _triBag.push_back(Primitive(0,fList)); } return (cost + fanCost + triCost); }
Primitive Primitive::operator/(double s) { return Primitive(this->density/s, this->pressure/s, this->velocity/s,this->entropy/s); }
Primitive eval(Ast *astNode) { // Switch cases == glorified GOTO == lame // I waste stack space like its my job Primitive v, left, right; std::string funcName; std::map<std::string, Ast*>::const_iterator itr; std::map<std::string, Primitive> newstackframe; std::map<std::string, Primitive>::const_iterator stackitr; // Function call and param stuff std::list<Parameter> functionparams; std::list<Parameter> callparams; std::list<Parameter>::const_iterator paramitr; std::vector<Primitive> *vec; std::vector<Primitive> vec2; std::vector<Parameter> members; switch( astNode->getNodetype() ) { case 'F': // Function only has a left branch v = eval(astNode->getLeft()); break; case 'S': // Only need to eval the right hand side since thats your return statement // The left hand side is either a no op, or the line before that does not matter eval(astNode->getLeft()); v = eval(astNode->getRight()); break; case 'A': // Handle the right hand side of an array declaration // Set the values to real values vec = new std::vector<Primitive>(); members = *astNode->getMembers(); for(int i=0;i<members.size();i++) { if(members[i].name == "") { vec->push_back(members[i].value); } else { stackitr = executionstack.top().find(members[i].name); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: undefined variables in array declaration" << std::endl; exit (EXIT_FAILURE); } vec->push_back(executionstack.top()[members[i].name]); } } v = Primitive(vec); v.type = ARRAY; break; case 'a': // Handle rhs of a array index value retrieval stackitr = executionstack.top().find(astNode->getName()); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: list named " << astNode->getName() << " not defined" << std::endl; exit (EXIT_FAILURE); } vec2 = *(executionstack.top()[astNode->getName()].array); v = vec2[(int)eval(astNode->getLeft()).value]; break; case 'l': // Handle len() stackitr = executionstack.top().find(astNode->getName()); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: list named " << astNode->getName() << " not defined" << std::endl; exit (EXIT_FAILURE); } if(executionstack.top()[astNode->getName()].type != ARRAY) { std::cout << " Semantics error: " << astNode->getName() << " is not a list, cant call len()" << std::endl; exit (EXIT_FAILURE); } vec2 = *(executionstack.top()[astNode->getName()].array); v = Primitive((int)vec2.size()); break; case 'm': // Handle list.append(expr) and list.pop(expr) stackitr = executionstack.top().find(astNode->getName()); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: list named " << astNode->getName() << " not defined" << std::endl; exit (EXIT_FAILURE); } if(executionstack.top()[astNode->getName()].type != ARRAY) { std::cout << " Semantics error: " << astNode->getName() << " is not a list, cant call append()" << std::endl; exit (EXIT_FAILURE); } if(astNode->getMethod() == "append") { executionstack.top()[astNode->getName()].array->push_back(eval(astNode->getLeft())); } else if(astNode->getMethod() == "pop") { executionstack.top()[astNode->getName()].array->pop_back(); } else { std::cout << " Semantics error: " << astNode->getMethod() << " method not supported" << std::endl; exit (EXIT_FAILURE); } break; case 'C': // Get function node and evaluate it funcName = astNode->getName(); itr = functions.find(funcName); if(itr == functions.end()) { std::cout << " Semantics error: no function \"" << funcName << "\" found!" << std::endl; exit (EXIT_FAILURE); } // If they try to call main, stop them if(funcName == "main") { std::cout << " Semantics error: Not allowed to call \"main()\", duh." << std::endl; exit (EXIT_FAILURE); } // Match given parameters to function signature in number only (no typing for piethon) functionparams = *itr->second->getParams(); callparams = *astNode->getParams(); if(functionparams.size() != callparams.size()) { std::cout << " Semantics error: given parameters do not match function signature of \"" << funcName << "\"!" << std::endl; exit (EXIT_FAILURE); } // New stack with given params included to match signature for (paramitr = functionparams.begin(); paramitr != functionparams.end(); ++paramitr) { // If identifier get the value of it if(callparams.front().name != "") { stackitr = executionstack.top().find(callparams.front().name); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: no variable named \"" << callparams.front().name << "\" found!" << std::endl; exit (EXIT_FAILURE); } newstackframe[(*paramitr).name] = executionstack.top()[callparams.front().name]; } else { // Otherwise just set to value newstackframe[(*paramitr).name] = callparams.front().value; } callparams.pop_front(); } // Push new stack frame executionstack.push(newstackframe); // Call function v = eval(itr->second); // Pop, back to old stack frame executionstack.pop(); break; case '?': // If if((int)eval(astNode->getLeft()).value == 1) { v = eval(astNode->getRight()); } break; case ':': // If-else if((int)eval(astNode->getLeft()).value == 1) { v = eval(astNode->getMiddle()); } else { v = eval(astNode->getRight()); } break; case 'w': // while while((int)eval(astNode->getLeft()).value == 1) { v = eval(astNode->getRight()); } break; case 'I': // Look up value in table stackitr = executionstack.top().find(astNode->getName()); if(stackitr == executionstack.top().end()) { std::cout << " Semantics error: no variable \"" << astNode->getName() << "\" found!" << std::endl; return 0; } v = executionstack.top()[astNode->getName()]; break; case '=': // Set value of identifier in table if(astNode->getLeft()->getNodetype() == 'a') { vec2 = *(executionstack.top()[astNode->getLeft()->getName()].array); vec2[(int)eval(astNode->getLeft()->getLeft()).value] = eval(astNode->getRight()); executionstack.top()[astNode->getLeft()->getName()].array->assign(vec2.begin(), vec2.end()); } else { executionstack.top()[astNode->getLeft()->getName()] = eval(astNode->getRight()); } break; case '>': if(eval(astNode->getLeft()).value > eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case '.': if(eval(astNode->getLeft()).value >= eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case '<': if(eval(astNode->getLeft()).value < eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case ',': if(eval(astNode->getLeft()).value <= eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case '~': if(eval(astNode->getLeft()).value == eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case '!': if(eval(astNode->getLeft()).value != eval(astNode->getRight()).value) { v = Primitive(1.0); v.type = BOOLEAN; } else { v = Primitive(0.0); v.type = BOOLEAN; } break; case 'n': // Do nothing! break; case 'P': // Handle printing short string messages if(astNode->getName() != "") { std::cout << astNode->getName(); } else { // Print stuff v = eval(astNode->getLeft()); if(v.type == INTEGER) { printf("%d\n", (int)v.value); } if(v.type == FLOATING) { printf("%lf\n", v.value); } // Arrays of arrays not really allowed to print if(v.type == ARRAY) { std::vector<Primitive> vec = *v.array; printf("["); for(int i=0;i<vec.size();i++) { if(vec[i].type == INTEGER) { printf("%d,", (int)vec[i].value); } if(vec[i].type == FLOATING) { printf("%lf,", vec[i].value); } } printf("]\n"); } } break; case 'R': v = eval(astNode->getLeft()); break; case 'K': v = astNode->getNumber(); break; case '+': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(left.value + right.value); v.type = getType(left, right); break; case '-': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(left.value - right.value); v.type = getType(left, right); break; case '*': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(left.value * right.value); v.type = getType(left, right); break; case '/': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(left.value / right.value); v.type = getType(left, right); break; break; case '%': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(fmod(left.value, right.value)); v.type = getType(left, right); break; case '^': left = eval(astNode->getLeft()); right = eval(astNode->getRight()); v = Primitive(pow(left.value, right.value)); v.type = getType(left, right); break; case 'M': v = Primitive(-1 * eval(astNode->getLeft()).value ); break; default: std::cout << "internal error: bad node " << astNode->getNodetype() << std::endl; } return v; }
Primitive Primitive::operator+(Primitive const & other)const { return Primitive(this->density + other.density, this->pressure + other.pressure, this->velocity + other.velocity, this->entropy+other.entropy); }