// Very similar to the above, but takes in a point and searches all derps // We return a pointer to the poor soul or null if none are in range public Derp SearchForDerp(int x, int y, double range) { // return null if there is no collision Derp ret = null; double mindist = range * range; // check against all other enemy derps foreach (Derp o in homeDerps) { myVector toOther = new myVector(o.x - x, o.y - y); if (toOther.mag2() < mindist) { mindist = toOther.mag2(); ret = o; } } foreach (Derp o in awayDerps) { myVector toOther = new myVector(o.x - x, o.y - y); if (toOther.mag2() < mindist) { mindist = toOther.mag2(); ret = o; } } // the unlucky nearest visible enemy return(ret); }
public static int SampleInput(myVector sampleInput, Network N) { float sum; float Error = 0; int foundID = -35; int correctID = 25; int Counter = 0; ClearInputs(N); //float NormalizationCoef = 1 / sampleInput.GetVector().Count; float NormalizationCoef = 1.0f / 50.0f; var WordsList = sampleInput.GetVector(); var InputLayer = N.getNetwork().Where(o => o.type == 0).ToList(); var HiddenLayer = N.getNetwork().Where(o => o.type == 1).ToList(); var OutputLayer = N.getNetwork().Where(o => o.type == 2).ToList(); //while (foundID != correctID && Counter < 20) //{ // sum = 0; // N = ClearInputs(N); // Pierwsza iteracja for (int i = 0; i < sampleInput.GetVector().Count; i++) { InputLayer[i].Input = (float)WordsList[i]; } // Druga iteracja CalculateInput(InputLayer); SigmoidFunction(HiddenLayer, NormalizationCoef); // Trzecia iteracja CalculateInput(HiddenLayer); SigmoidFunction(OutputLayer, NormalizationCoef); // Liczenie wyniku foundID = -OutputLayer.OrderBy(o => o.Input).Reverse().FirstOrDefault().ID - 1; // correctID = -CorrectId(sampleInput, OutputLayer) - 1; // // // Dopasowywanie wag // sum = SumInputs(OutputLayer, sum); // Error = (OutputLayer[correctID].Input - OutputLayer[foundID].Input) / sum; // if (foundID != correctID) // { // AdjustWeights(HiddenLayer, Error); // AdjustWeights(InputLayer, Error); // } // Counter++; //} return(foundID); }
public void InitializeNetwork() { classes = DataClass.CreateDataClasses(bow); classes = TestFunctions.CreateFullSet(classes, bow); myVector x = new myVector(); { x = bow.GetVectorsList()[0]; WithoutHiddenLayerNetwork = NeuralConstruction.CreateDefaultNetwork(x.GetVector().Count, classes); NeuralConstruction.SampleWeight(WithoutHiddenLayerNetwork, bow.GetVectorsList(), classes); NeuralNetwork = NeuralConstruction.CreateNewDefaultNetwork(x.GetVector().Count, classes, 5); } }
private void _Start_Copy_Click(object sender, RoutedEventArgs e) { myVector x = bow.GetVectorsList()[0]; TestClass T = TestFunctions.CreateTest2(classes); List <myVector> vectors = test.GetTestVectors(); List <int> kNNResultsIds = new List <int>(); List <int> NNResultsIds = new List <int>(); List <int> WHNNResultsIds = new List <int>(); // Liczymy foreach (myVector V in vectors) { int id = 0; id = kNN.CalculateKNN(V, classes, 3); kNNResultsIds.Add(id); id = NeuralConstruction.OldSampleInput(V, WithoutHiddenLayerNetwork); WHNNResultsIds.Add(id); id = NeuralConstruction.SampleInput(V, NeuralNetwork); NNResultsIds.Add(id); } // Dodajemy wyniki dla KNN for (int i = 0; i < kNNResultsIds.Count; i++) { TestResult testresult = new TestResult("kNNAlgorithm"); testresult.filltestData(T.GetTrainingClasses(), kNNResultsIds[i], vectors[i]); kNNResults.Add(testresult); } // Dodajemy wyniki dla sieci neuronowej for (int i = 0; i < NNResultsIds.Count; i++) { TestResult testresult = new TestResult("NNAlgorithm"); testresult.filltestData(classes, NNResultsIds[i], vectors[i]); NNResults.Add(testresult); } // Dodajemy wyniki dla sieci neuronowej bez warstwy ukrytej for (int i = 0; i < WHNNResultsIds.Count; i++) { TestResult testresult = new TestResult("WHNNAlgorithm"); testresult.filltestData(classes, WHNNResultsIds[i], vectors[i]); WHNNResults.Add(testresult); } ListView1.ItemsSource = kNNResults; ListView2.ItemsSource = NNResults; ListView3.ItemsSource = WHNNResults; kNNResults = new List <TestResult>(); NNResults = new List <TestResult>(); WHNNResults = new List <TestResult>(); test = new TestClass(); test = TestFunctions.CreateVectorTest(bow); }
private void UczenieSieci_Click(object sender, RoutedEventArgs e) { myVector x = bow.GetVectorsList()[0]; BackPropagation.UczenieSieci(200, test.GetTrainingtVectors(), NeuralNetwork, classes); Console.Beep(); foreach (myVector testvector in test.GetTestVectors()) { int id = NeuralConstruction.SampleInput(testvector, NeuralNetwork); var output = NeuralNetwork.getNetwork().Where(o => o.type == 2).ToList(); } UczenieSieci.IsEnabled = false; }
public static int OldSampleInput(myVector sampleInput, Network N) { var vector = sampleInput.GetVector(); int id = 0; // Zerujemy inputy foreach (var neuron in N.getNetwork()) { neuron.Input = 0; } // Pierwsza iteracja for (int i = 0; i < vector.Count; i++) { // int index = vector[i]; var neuron = N.getNetwork().ElementAt(i); neuron.Input = (float)vector[i]; } // Druga iteracja for (int i = 0; i < vector.Count; i++) { // int index = vector[i]; var neuron = N.getNetwork().ElementAt(i); var ConnectionVector = neuron.GetConnectionsOld(); for (int j = vector.Count, k = 0; k < ConnectionVector.Count; j++, k++) { N.getNetwork().ElementAt(j).Input += neuron.Input * neuron.GetWeights()[k]; } } int connectionCount = N.getNetwork()[0].GetConnectionsOld().Count(); double max = 0; for (int i = vector.Count; i < vector.Count + connectionCount; i++) { var neuron = N.getNetwork().ElementAt(i); if (neuron.Input > max) { max = neuron.Input; id = (-neuron.ID) - 1; } } return(id); }
// Add an attack Animation here // TODO: maybe put the thing that actually applies the damage here, just to consolodate logical code public void AddAttack(Derp from, Derp to) { // This must be located two radius distance from the derp, in the direction of the delivering attacker myVector u = new myVector(from.x - to.x, from.y - to.y); u.toUnit(); // opposite direction for nearest cardinal dir calculation myVector u2 = new myVector(-u.x, -u.y); DerpAttack attack = new DerpAttack(to.x + (u.x * to.stats.radius * 2), to.y + (u.y * to.stats.radius * 2), Geometry.GetNearestCardinalDir(u2)); derpAttacks.Add(attack.key, attack); }
private static int CorrectId(myVector sample, List <Neuron> outputlayer) { int correctID = 0; string correctclassName = sample.GetVectorName(); correctclassName = correctclassName.Remove(correctclassName.Length - 2); foreach (Neuron n in outputlayer) { if (n.Category == correctclassName) { correctID = n.ID; } } return(correctID); }
// Set a derp to move out of the way of another derp. Also returns the slow derp. (even if it actually isn't slower?) // The fastDerp has run into the slow derp, it must tell it to move out of the way. Give the other derp the unit vector to move along public Derp SetToMoveOutOfWay(int slowDerpID, Derp fastDerp) { List <Derp> checkList = (fastDerp.team == TEAM.HOME ? homeDerps : awayDerps); Derp slowDerp = checkList[slowDerpID]; // only actually do this if the slow derp is slower or equal if (slowDerp.stats.spd > fastDerp.stats.spd) { return(slowDerp); } // The Move Vector should be directly away from the fast derp myVector awayVector = new myVector(slowDerp.x - fastDerp.x, slowDerp.y - fastDerp.y); awayVector.toUnit(); // Tell 'em to move slowDerp.moveOutOfWay = true; slowDerp.moveOutOfWayVector = awayVector; return(slowDerp); }
// Search for enemy derps within our radar range // We return a pointer to the poor soul or null if none are in range public Derp SearchForEnemy(Derp d, double range) { // return null if there is no collision Derp ret = null; // For collision we are checking only against our enemies List <Derp> checkingList; if (d.team == TEAM.HOME) { checkingList = awayDerps; } else { checkingList = homeDerps; } double mindist = range * range; // check against all other enemy derps double throwaway1; myLineSegment throwaway2; foreach (Derp o in checkingList) { myVector toOther = new myVector(o.x - d.x, o.y - d.y); if (toOther.mag2() < mindist && !Field.field.CheckFieldCollision(d, toOther, out throwaway1, out throwaway2)) { mindist = toOther.mag2(); ret = o; } } // the unlucky nearest visible enemy return(ret); }
// This is the function that tries to make a step, it can recurse once. public void attemptStep(myVector v, bool recurse) { // Optimistic no collision double t = 1.0; myVector newV = null; // Check for team derp collisions double derpT; myVector derpV = null; int colID = manager.CheckDerpCollision(this, v, out derpT, enemyDetected); // note: this returns -1 if either there is no collision, or if we are colliding with the other team isColliding = (colID != -1); // We have collided with another derp // Tell the other to move out of the way, and have us try to move perpendicular to them if (isColliding && !recurse) { Derp slowDerp = manager.SetToMoveOutOfWay(colID, this); if (slowDerp != null) { // Get the Unit Vector towards the slow Derp myVector u = new myVector(slowDerp.x - x, slowDerp.y - y); u.toUnit(); // Make sure that the slow derp is actually in front of where you want to go if (u.dot(v) > 0.0) { // Get a perpendicular unit vector to follow myVector uPerp = new myVector(-u.y, u.x); // Make sure it is the correct way double dir = uPerp.dot(v); // Wrong way if (dir < -1e-3) { uPerp.x *= -1; uPerp.y *= -1; } // Special Zero case, pick a random direction // this should... almost never happen // I'm concerned this could mess up random synch in multiplayer. Just pick a constant direction. else if (dir < 1e-3) { /* * if (MyRandom.Next(team, 2) % 2 == 0) * { * uPerp.x *= -1; * uPerp.y *= -1; * } */ } // Try moving along the new path double remainingT = (1.0 - derpT); derpV = new myVector(uPerp.x * remainingT * v.mag(), uPerp.y * remainingT * v.mag()); } } } // Check for field collisions double fieldT; myVector fieldV = null; myLineSegment collisionVect; if (Field.field.CheckFieldCollision(this, v, out fieldT, out collisionVect) && !recurse) { // try to move parallel to the wall with the extra t collisionVect.v.toUnit(); // make sure this unit vector is in the right direction double dir = collisionVect.v.dot(v); // Wrong way if (dir < -1e-3) { collisionVect.v.x *= -1; collisionVect.v.y *= -1; } // ignore zero case if (Math.Abs(dir) > 1e-3) { // Try moving along the new path double remainingT = (1.0 - fieldT); fieldV = new myVector(collisionVect.v.x * remainingT * v.mag(), collisionVect.v.y * remainingT * v.mag()); } } // See if we have a collision // If either of the recalculated V values are not null, we hit something along the way if (derpT < 1.0 - 1e-6 || fieldT < 1.0 - 1e-6) { if (fieldT < derpT) { t = fieldT; newV = fieldV; } else { t = derpT; newV = derpV; } } // Only step as far as we can x += v.x * t; y += v.y * t; if (newV != null) { attemptStep(newV, true); } }
public void Update() { // CHECK FOR ATTACKS // use the derp radar to search for visible enemies in range Derp enemy = manager.SearchForEnemy(this, 100.0); enemyDetected = (enemy != null); // see if we can attack this enemy myVector toEnemy = null; if (enemyDetected) { toEnemy = new myVector(enemy.x - x, enemy.y - y); isAttacking = (toEnemy.mag() < stats.radius + enemy.stats.radius + stats.rng); debugDist = toEnemy.mag(); if (isAttacking && (DateTime.Now.Subtract(lastAttack).TotalMilliseconds > (2000 - 15 * stats.aspd))) { lastAttack = DateTime.Now; enemy.takeHit(stats.atk); manager.AddAttack(this, enemy); } } else { isAttacking = false; } // FOLLOW THE TRAIL // Find the vector between the derp and its current node destination double dx = path[pathID].x - x; double dy = path[pathID].y - y; double mag = Math.Sqrt(dx * dx + dy * dy); double t = 1.0; myLineSegment throwaway; int nextPathID = pathID + (team == TEAM.HOME ? 1 : -1); // Check if we can move to the next path node if (mag < (stats.spd * SPEED_CONST)) { pathID = nextPathID; // Recalculate for the next node dx = path[pathID].x - x; dy = path[pathID].y - y; mag = Math.Sqrt(dx * dx + dy * dy); } // Sometimes we can abort the current node for the next-next node else if (nextPathID >= 0 && nextPathID < path.Count) { // if the next node is behind us (meaning we passed it accidentily) then just keep going // we use a manual dot product for this double ndx = path[nextPathID].x - x; double ndy = path[nextPathID].y - y; if (dx * ndx + dy * ndy < 0.0 && !Field.field.CheckFieldCollision(this, new myVector(path[nextPathID].x - x, path[nextPathID].y - y), out t, out throwaway)) { pathID = nextPathID; // Recalculate for the next node dx = path[pathID].x - x; dy = path[pathID].y - y; mag = Math.Sqrt(dx * dx + dy * dy); } // we can give a more liberal option to move forward to the next node // if we are colliding or seeking an enemy derp, and we can see the next node else if (isColliding && mag < GENERIOUS_THRESHHOLD && !Field.field.CheckFieldCollision(this, new myVector(path[nextPathID].x - x, path[nextPathID].y - y), out t, out throwaway)) { pathID = nextPathID; // Recalculate for the next node dx = path[pathID].x - x; dy = path[pathID].y - y; mag = Math.Sqrt(dx * dx + dy * dy); } } // DETERMINE MOVE if (!isAttacking) { // Calculate velocity and try to make the step double velocity = stats.spd * SPEED_CONST; myVector v; if (enemyDetected && toEnemy != null) { toEnemy.toUnit(); v = new myVector(toEnemy.x * velocity, toEnemy.y * velocity); } else if (moveOutOfWay) { // Move out of the way! v = new myVector(moveOutOfWayVector.x * velocity, moveOutOfWayVector.y * velocity); } else { // Move Towards next Node v = new myVector((dx / mag) * velocity, (dy / mag) * velocity); } // DEBUG: error catching double oldx = x; double oldy = y; if (isStuck) { isStuck = false; } // Try to Step attemptStep(v, false); // DEBUG: error catching if (Math.Abs(x - oldx) < 1e-3) { isStuck = true; } // Update our current instantaneous velocity vel.x = x - oldx; vel.y = y - oldy; // WE SHOULD NEVER MOVE THIS FAST. FIND MATH ERRORS. if (Math.Abs(vel.x) > 50 || Math.Abs(vel.y) > 50) { x = oldx; y = oldy; } } // Reset our MoveOUtOfWay variable, it will be set again next round if we need to keep moving out of the way moveOutOfWay = false; // This will be the game end condition eventually if ((team == TEAM.HOME && x > (Field.field.Width - 1) * Field.BLOCK_WIDTH) || (team == TEAM.AWAY && x < Field.BLOCK_WIDTH) || stats.hp <= 0) { Kill(); } }
public int CheckDerpCollision(Derp casting, myVector v, out double t, bool checkBothTeams) { // t is initialized optimistically to the full distance t = 1.0; // the id of the derp is -1 if there is no collision int ret = -1; // For collision we are checking only against our teammates (because we will always attack (and stop moving) before we collide with enemies) <- at least that's the plan List <Derp> checkingList; if (casting.team == TEAM.HOME) { checkingList = homeDerps; } else { checkingList = awayDerps; } // I'm making the optimistic assumption that these lists will be sorted because they are sorted every Draw Step int myID = checkingList.IndexOf(casting); // check derps above me for (int i = myID - 1; i >= 0; --i) { // only check derps near me on the y axis if (casting.y - checkingList[i].y > distThreshholdY) { break; } double check_t = Geometry.DerpCircleCast(casting, checkingList[i], v); if (check_t < t) { t = check_t; ret = i; } } // check derps below me for (int i = myID + 1; i < checkingList.Count; ++i) { // only check derps near me on the y axis if (casting.y - checkingList[i].y > distThreshholdY) { break; } double check_t = Geometry.DerpCircleCast(casting, checkingList[i], v); if (check_t < t) { t = check_t; ret = i; } } // If we need to check the enemy team, then we can't do it quite as fast, but just check against them all if (checkBothTeams) { checkingList = (casting.team == TEAM.HOME ? awayDerps : homeDerps); foreach (Derp o in checkingList) { double check_t = Geometry.DerpCircleCast(casting, o, v); if (check_t < t) { t = check_t; ret = -1; } } } // the id of the colliding derp return(ret); }
// Check for a Derp's Circle-Cast across the field // This will work like a BFS, starting from the initial position // then check all 4 corners around the position to build on the bfs public bool CheckFieldCollision(Derp d, myVector v, out double t, out myLineSegment col) { // initial optimistic setup that there will not be a collision bool ret = false; t = 1.0; col = null; // calculate starting point int startX = (int)(d.x / BLOCK_WIDTH); int startY = (int)(d.y / BLOCK_HEIGHT); // Unit Vector in desired direction myVector vUnit = new myVector(v.x, v.y); vUnit.toUnit(); // set up the bfs Queue<SimpleNode> q = new Queue<SimpleNode>(); bool[,] vis = new bool[height+1, width+1]; q.Enqueue(new SimpleNode(startX, startY, 0)); vis[startY, startX] = true; // Create the 4 line segments so we don't have to do quiiite as much object creation in this loop myLineSegment[] segs = new myLineSegment[4]; for (int i = 0; i < 4; ++i) segs[i] = new myLineSegment(null, null); // BFS int[] dx = { 0, 1, 0, -1 }; int[] dy = { -1, 0, 1, 0 }; int cur_step = 0; while (q.Count > 0) { SimpleNode cur = q.Dequeue(); // end early if we had a hit already in a previous step if (ret && cur_step != cur.step) break; // checking 4 nodes around us myPoint p1 = new myPoint(cur.x * BLOCK_WIDTH, cur.y * BLOCK_HEIGHT); myPoint p2 = new myPoint((cur.x + 1) * BLOCK_WIDTH, cur.y * BLOCK_HEIGHT); myPoint p3 = new myPoint((cur.x + 1) * BLOCK_WIDTH, (cur.y + 1) * BLOCK_HEIGHT); myPoint p4 = new myPoint(cur.x * BLOCK_WIDTH, (cur.y + 1) * BLOCK_HEIGHT); segs[0].Update(p1, p2); segs[1].Update(p2, p3); segs[2].Update(p4, p3); segs[3].Update(p1, p4); for (int i = 0; i < 4; ++i) { int nx = cur.x + dx[i]; int ny = cur.y + dy[i]; if (nx < 0 || nx > width || ny < 0 || ny >= height || vis[ny, nx]) continue; double possible_t; if (Geometry.DerpLineSegmentCast(d, v, segs[i], out possible_t)) { // We have a hit! If the next zone is safe to move in, then continue the bfs if (gameGrid[ny, nx] != '0') { q.Enqueue(new SimpleNode(nx, ny, cur.step + 1)); vis[ny, nx] = true; } // We hit an unnavigable space. Stop the BFS, this is as far as we go else { ret = true; if (Math.Abs(possible_t - t) < 1e-5 && col != null) { // break ties by taking the furthest behind the direction we wish to go // Calculate the center point on the wall, and get the dot product of the vector to that point. // The most negative value is the furthest behind myPoint segMidPoint1 = new myPoint((segs[i].p1.x + segs[i].p2.x) / 2.0, (segs[i].p1.y + segs[i].p2.y) / 2.0); myVector toMidPoint1 = new myVector(segMidPoint1.x - d.x, segMidPoint1.y - d.y); myPoint segMidPoint2 = new myPoint((col.p1.x + col.p2.x) / 2.0, (col.p1.y + col.p2.y) / 2.0); myVector toMidPoint2 = new myVector(segMidPoint2.x - d.x, segMidPoint2.y - d.y); if (vUnit.dot(toMidPoint1) < vUnit.dot(toMidPoint2)) { t = possible_t; col = new myLineSegment(segs[i].p1.x, segs[i].p1.y, segs[i].p2.x, segs[i].p2.y); // careful... memory bugs } } else if (possible_t < t) { t = possible_t; col = new myLineSegment(segs[i].p1.x, segs[i].p1.y, segs[i].p2.x, segs[i].p2.y); // careful... memory bugs } } } } // if we are a special diagonal case, then check the cross hit as well myLineSegment diag = null; char c = gameGrid[cur.y, cur.x]; if (c == '1' || c == '3') diag = new myLineSegment(p2, p4); if (c == '2' || c == '4') diag = new myLineSegment(p1, p3); if (diag != null) { double possible_t; if (Geometry.DerpLineSegmentCast(d, v, diag, out possible_t)) { ret = true; if (Math.Abs(possible_t - t) < 1e-5 && col != null) { // break ties by taking the furthest behind the direction we wish to go // Calculate the center point on the wall, and get the dot product of the vector to that point. // The most negative value is the furthest behind myPoint segMidPoint1 = new myPoint((diag.p1.x + diag.p2.x) / 2.0, (diag.p1.y + diag.p2.y) / 2.0); myVector toMidPoint1 = new myVector(segMidPoint1.x - d.x, segMidPoint1.y - d.y); myPoint segMidPoint2 = new myPoint((col.p1.x + col.p2.x) / 2.0, (col.p1.y + col.p2.y) / 2.0); myVector toMidPoint2 = new myVector(segMidPoint2.x - d.x, segMidPoint2.y - d.y); if (vUnit.dot(toMidPoint1) < vUnit.dot(toMidPoint2)) { t = possible_t; col = new myLineSegment(diag.p1.x, diag.p1.y, diag.p2.x, diag.p2.y); // careful... memory bugs } } else if (possible_t < t) { t = possible_t; col = new myLineSegment(diag.p1.x,diag.p1.y, diag.p2.x, diag.p2.y); // careful... memory bugs } } } cur_step = cur.step; } return ret; }