void CGA::Cross() { // 种群中染色体个数 int nSize = m_vecChromosomes.size(); // 先把当前种群拷贝出来 ChromosomeGroup groupCopy(m_vecChromosomes.begin(), m_vecChromosomes.end()); // 相邻染色体两两杂交 for ( int i = 0; i < ( m_vecChromosomes.size() / 2 ) * 2; i += 2 ) { #if 0 float fRate = 0.0F; #else float fRate = Randf(); #endif if ( fRate <= m_fpCrossRate ) { // 计算i 和 i + 1中 // 记录该染色体中每个基因(点V)与给定向量(V1V2), 向量V1V 在向量 V1V2上的投影的长度 和 该点V的索引 std::vector<Index2Dist> vecIndeies1; auto genes = m_vecChromosomes[ i ].GetGenes(); for (int index = 0; index < genes.size(); ++ index ) { int nVX = genes[ index ].nX; int nVY = genes[ index ].nY; int nV1X = 10; int nV1Y = 2000; int nV2X = 10; int nV2Y = -2000; // 向量V1V(nVX - nV1X, nVY - nV1Y) // 向量V1V2(nV2X - nV1X, nV1Y - nV2Y) int x1 = nVX - nV1X; int y1 = nVY - nV1Y; int x2 = nV2X - nV1X; int y2 = nV2Y - nV1Y; // 计算V1V与V1V2 float fArcCos = (x1 * x2 + y1 * y2) / ( sqrt(1.0F * x1 * x1 + y1 * y1) * sqrt(1.0F * x2 * x2 + y2 * y2) ); // 投影 = |V1V| * cosX float fLength = sqrt( 1.0F * x1 * x1 + y1 * y1 ) * fArcCos; Index2Dist id; id.nIndex = index; id.fDist = fLength; id.gene = genes[ index ]; vecIndeies1.push_back(id); } // for // 按照fDist排序 std::sort(vecIndeies1.begin(), vecIndeies1.end()); ////////////////////////////////////////////////////////////////////////// // 记录该染色体中每个基因(点V)与给定向量(V1V2), 向量V1V 在向量 V1V2上的投影的长度 和 该点V的索引 std::vector<Index2Dist> vecIndeies2; auto genes2 = m_vecChromosomes[ i + 1 ].GetGenes(); for (int index = 0; index < genes2.size(); ++ index ) { int nVX = genes2[ index ].nX; int nVY = genes2[ index ].nY; int nV1X = 100; int nV1Y = 1000; int nV2X = 100; int nV2Y = -1000; // 向量V1V(nVX - nV1X, nVY - nV1Y) // 向量V1V2(nV2X - nV1X, nV1Y - nV2Y) int x1 = nVX - nV1X; int y1 = nVY - nV1Y; int x2 = nV2X - nV1X; int y2 = nV2Y - nV1Y; // 计算V1V与V1V2 float fArcCos = (x1 * x2 + y1 * y2) / ( sqrt(1.0F * x1 * x1 + y1 * y1) * sqrt(1.0F * x2 * x2 + y2 * y2) ); // 投影 = |V1V| * cosX float fLength = sqrt( 1.0F * x1 * x1 + y1 * y1 ) * fArcCos; Index2Dist id; id.nIndex = index; id.fDist = fLength; id.gene = genes2[ index ]; vecIndeies2.push_back(id); } // for // 按照dist从小到大排序 std::sort(vecIndeies2.begin(), vecIndeies2.end()); // 杂交后的两个新个体(染色体) GeneGroup g1, g2; // 拷贝两个排序后的vec std::vector<Index2Dist> vec1Copy(vecIndeies1.begin(), vecIndeies1.end()); std::vector<Index2Dist> vec2Copy(vecIndeies2.begin(), vecIndeies2.end()); int cnt1 = 0; int cnt2 = vecIndeies2.size() - 1; for ( ; cnt1 < vecIndeies1.size() && cnt2 >= 0 && g1.size() < vecIndeies1.size(); ++ cnt1, -- cnt2 ) { auto it1 = std::find(g1.begin(), g1.end(), vecIndeies1[ cnt1 ].gene ); if ( it1 == g1.end() ) { g1.push_back( vecIndeies1[ cnt1 ].gene ); auto itTemp = std::find(vec1Copy.begin(), vec1Copy.end(), vecIndeies1[ cnt1 ].gene); if ( itTemp != vec1Copy.end() ) { vec1Copy.erase(itTemp); } } auto it2 = std::find(g1.begin(), g1.end(), vecIndeies2[ cnt2 ].gene ); if ( it2 == g1.end() ) { g1.push_back( vecIndeies2[ cnt2 ].gene); auto itTemp = std::find(vec2Copy.begin(), vec2Copy.end(), vecIndeies2[ cnt2 ].gene); if ( itTemp != vec2Copy.end() ) { vec2Copy.erase(itTemp); } } } // for // 将vec1Copy 和 vec2Copy 中剩余的点放入g2 for ( auto iter = vec1Copy.begin(); iter != vec1Copy.end(); ++ iter ) { g2.push_back(iter->gene); } for ( auto iter = vec2Copy.begin(); iter != vec2Copy.end(); ++ iter ) { g2.push_back(iter->gene); } // 用新个体代替两个父个体 // g1代替i位置染色体, g2代替i+1位置染色体 m_vecChromosomes[ i ].SetGenes(g1); m_vecChromosomes[ i + 1 ].SetGenes(g2); } // if } // for }
/** * set the renderer's camera */ void ren_draw_set_camera(vec2_t camera_orig, vec2_t camera_targ) { vec2Copy(camera_orig, rSys->cameraOrg); vec2Copy(camera_targ, rSys->cameraTarg); }
int applyWallAcceleration(int player, int dt) { // find distance to enemy walls left & right enum { eLeft, eRight, eMax }; segment2 segments[eMax]; Data *data = game->player[player].data; int dirLeft = (data->dir + 3) % 4; int dirRight = (data->dir + 1) % 4; float left, right; float x, y; vec2 vPos; int i, j; getPositionFromIndex(&x, &y, player); vPos.v[0] = x; vPos.v[1] = y; for(i = 0; i < eMax; i++) { vec2Copy(&segments[i].vStart, &vPos); } segments[eLeft].vDirection.v[0] = dirsX[dirLeft]; segments[eLeft].vDirection.v[1] = dirsY[dirLeft]; segments[eRight].vDirection.v[0] = dirsX[dirRight]; segments[eRight].vDirection.v[1] = dirsY[dirRight]; left = FLT_MAX; right = FLT_MAX; for(i = 0; i < game->players; i++) { segment2 *wall = game->player[i].data->trails; if(i == player) continue; if(game->player[i].data->trail_height < TRAIL_HEIGHT) continue; for(j = 0; j < game->player[i].data->trailOffset + 1; j++) { float t1, t2; vec2 v; if(segment2_Intersect(&v, &t1, &t2, segments + eLeft, wall) && t1 > 0 && t1 < left && t2 >= 0 && t2 <= 1) left = t1; if(segment2_Intersect(&v, &t1, &t2, segments + eRight, wall) && t1 > 0 && t1 < right && t2 >= 0 && t2 <= 1) right = t1; wall++; } } { float accell_limit = getSettingf("wall_accel_limit"); if(left < accell_limit || right < accell_limit) { float boost = getSettingf("wall_accel_use") * dt / 1000.0f; data->speed += boost; return 1; } else { return 0; } } }