So i'm trying to make a program that uses the League of Legends API in C#.
I found a NuGet package that makes using the API a lot easier.
Everything works fine so far except the code execution stops after the
first for loop i use.
Here's the code: (of course i took out the api key)
string[] summnames;
long[] champids;
long[] teamids;
long[] champs;
CreepScoreAPI.ParticipantLive[] enemy;
CreepScoreAPI.ParticipantLive[] ally;
CreepScoreAPI.ParticipantLive centsumm;
CreepScoreAPI.ParticipantLive[] champsss;
CreepScoreAPI.ChampionStatic[] champions;
CreepScoreAPI.Summoner[] sumners;
CreepScoreAPI.League[] leaguesz;
Dictionary<string, List<CreepScoreAPI.League>>[] leagues;
int[] champidsint;
string[] champnames;
int s;
int se;
public async Task<string> game(string summname)
{
string data;
CreepScoreAPI.CreepScore cs = new CreepScoreAPI.CreepScore("api key");
var summoner = await cs.RetrieveSummoner(CreepScoreAPI.CreepScore.Region.EUNE, summname);
long summid = summoner.id;
var thegame = await summoner.RetrieveCurrentGameInfo();
CreepScoreAPI.ParticipantLive[] participants = thegame.participants.ToArray();
for (int i = 0; i <= 9; i++) { summnames[i] = participants[i].summonerName;}
for (int i = 0; i <= 9; i++) { champids[i] = participants[i].championId;}
for (int i = 0; i <= 9; i++) { teamids[i] = participants[i].teamIdLong;}
for (int i = 0; i <= 9; i++) { champids[i] = participants[i].championId;}
for (int i = 0; i <= 9; i++) { champidsint[i] = Convert.ToInt32(champids[i]);}
for (int i = 0; i <= 9; i++) { champions[i] = await cs.RetrieveChampionData( CreepScoreAPI.CreepScore.Region.EUNE, champidsint[i], CreepScoreAPI.Constants.StaticDataConstants.ChampData.All, "en_US", "7.1.1",false ); }
for (int i = 0; i <= 9; i++) { champnames[i] = champions[i].name; }
for (int i = 0; i <= 9; i++) { sumners[i] = await cs.RetrieveSummoner(CreepScoreAPI.CreepScore.Region.EUNE, summnames[i]); }
for (int i = 0; i <= 9; i++) { leagues[i] = await sumners[i].RetrieveLeague(); }
/* teamsorter */
foreach (CreepScoreAPI.ParticipantLive p in participants)
{
if (p.summonerId == summid)
{
centsumm = p;
}
if (p.teamIdLong == centsumm.teamIdLong)
{
ally[s] = p;
s++;
}
if (p.teamIdLong != centsumm.teamIdLong)
{
enemy[se] = p;
se++;
}
}
data = " I'LL FORMAT A STRING THAT OUTPUTS ALL THE DATA I NEED HERE";
return data;
}
When I call the game function and input the name of the summoner i gets to the first for loop and doesn't even populate the summnames[] array and stops execution with no error code.
What I'm trying to do with all the loops is populate the variables I made before the function so I can use them later for other purposes.
I think you should assign all the arrays and set their length to at least 10.
This could solve the problem.
Related
I want to remove a specific object from an array, put it in a smaller array without getting out of range. This is what I've tried but it won't work.
Skateboard[] newSkateboard = new Skateboard[_skateboards.Length - 1];
for (int i = 0; i < _skateboards.Length; i++)
{
if (skateboard.Code != _skateboards[i].Code)
{
newSkateboard[i] = _skateboards[i];
}
}
Sure.
var j = 0;
for (int i = 0; i < _skateboards.Length; i++)
{
if (skateboard.Code != _skateboards[i].Code)
{
newSkateboard[j] = _skateboards[i];
j = j + 1;
}
}
I need to streamwrite into a file.txt a 10 random numbers combinations (NOT REPEATED) like lottery program. I got everything except Non-repeated random numbers. it has to be seen (file.txt) like a 2D array with 10 combinations thx.
class Matriz
{
private int[,] array;
private int nfilas, ncols;
public void Ingresar()
{
Random aleatori = new Random();
nfilas = 10;
ncols = 6;
Console.WriteLine("\n");
array = new int[nfilas, ncols];
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
array[filas, columnas] = aleatori.Next(0, 50);
}
}
public void Imprimir()
{
StreamWriter fitxer = new StreamWriter(#"C:\andres\lotto649.txt");
int contador = 0;
for (int f = 0; f < nfilas; f++)
{
for (int c = 0; c < ncols; c++)
fitxer.Write(array[f, c] + " ");
fitxer.WriteLine();
contador++;
}
fitxer.WriteLine($"\n\n\tHay {contador} combinaciones de la Loteria 6/49");
fitxer.Close();
}
static void Main(string[] args)
{
Matriz array_menu = new Matriz();
array_menu.Ingresar();
array_menu.Imprimir();
}
}
Something like this should work.
Before inserting the new number in the given position, check the row thus far if the same number is already in there and if so, repeat the process until you get a number that isn't yet in there.
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
{
bool cont = true;
while(cont)
{
cont = false;
int newRand = aleatori.Next(0, 50);
for(int i = 0; i < columnas; i++)
if(array[filas, i] == newRand)
cont = true;
if(cont)
continue;
array[filas, columnas] = newRand;
break;
}
}
}
Alternatively, since the number is small you could also work with a list of ints and remove the given value from there.
This has the advantage, that you'll never have to redo your random number as it will always produce a valid result. The above example could (theoretically) run indefinitely long.
for (int filas = 0; filas < nfilas; filas++)
{
List<int> nums = new List<int>(49);
for(int i = 0; i < 49; i++)
nums.Add(i + 1); //num 1...49
for (int columnas = 0; columnas < ncols; columnas++)
{
int index = aleatori.Next(0, nums.Count)
array[filas, columnas] = nums[index];
nums.RemoveAt(index);
}
}
if (cmd == "card_request") {
Debug.Log("FOund cards");
ISFSObject responseParams = (SFSObject)evt.Params["params"];
Debug.Log(responseParams.GetClass("cards").ToString());
SFSArray data = (SFSArray)responseParams.GetSFSArray("cards");
Debug.Log(data.GetUtfString(0));
//for (int i = 0; i < data.GetUtfString(0).IndexOf("value"); i++) {
firstSplit = data.GetUtfString(0).Split(';');
Debug.Log(firstSplit);
//}
for (int i = 0; i < firstSplit[0].IndexOf("value"); i++) {
secondSplit = firstSplit[0].Split(':');
Debug.Log(secondSplit);
}
for (int i = 0; i < secondSplit[0].IndexOf("value"); i++) {
thirdSplit = secondSplit[0].Split(',');
Debug.Log(thirdSplit);
}
}
the data is coming fine at this line Debug.Log(data.GetUtfString(0)); But when I try to split it it gives errors. Somebody can please suggest me the effective way to split UTF string. Null exceptions occurs at secondSplit and thirdSplit
I have gone through my code and tried to make it as efficient as i can think possible. Still i can not get this program to run all the way through without freezing my box. The maximum amount of time that i have let it run without it freezing it was about 2 hours. I can not believe this did not execute in that amount of time.
Is it an issue with my computer or is this brute force method of solving this problem that inefficient.
What are some ways that i can avoid this type of inefficiency when writing methods in the future?
private void Form1_Load(object sender, EventArgs e)
{
ArrayList listOfAbundantNumbers = new ArrayList();
ArrayList listOfSums = new ArrayList();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total+=i;
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
}
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
printLn(total + "");
}
private ArrayList divisorList(long input)
{
ArrayList divisors = new ArrayList();
for (long i = 2; i < Math.Round(Math.Sqrt(input),0,0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private Boolean isAbundandt(long input)
{
long sum = 0;
ArrayList divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = Convert.ToInt64(divisor[i]);
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}
Avoid using ArrayList, prefer generic collection such as List<Int64> because you conversion may be quite expensive.
There is a part in your program which is in O(n^3). It can be reduce to O(n^2) easily. Just replace the following code (O(n) because of List<T>.Contains):
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
by:
listOfSums.Add(num);
where listOfSums is now a HashSet<Int64> (it's used to have a collection without duplicates).
Moreover, you can reduce the time for populating the listOfSums by a factor of 2 by just noticing that if you exchange i and a, the sum is the same, then, only one of the two combinations is added to the listOfSums.
You can replace:
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
by;
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
The final code is:
private static void Main()
{
List<Int64> listOfAbundantNumbers = new List<Int64>();
HashSet<Int64> listOfSums = new HashSet<Int64>();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total += i;
}
for (int i = 0; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
listOfSums.Add(num);
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
Console.WriteLine(total + "");
}
private static List<Int64> divisorList(long input)
{
List<Int64> divisors = new List<Int64>();
for (long i = 2; i < Math.Round(Math.Sqrt(input), 0, 0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private static Boolean isAbundandt(long input)
{
long sum = 0;
List<Int64> divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = divisor[i];
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}
i have this code:
Thread[] threadsArray = new Thread[4];
for (int i = 0; i < 4; i++)
{
threadsArray[i] = new Thread(() => c1.k(i));
}
for (int i = 0; i < 4; i++)
{
threadsArray[i].Start();
}
for (int i = 0; i < 4; i++)
{
threadsArray[i].Join();
}
the function k is this:
void k(int i)
{
while(true)
Console.WriteLine(i);
}
for some reason just the last thread is running and printing 4444444....
why aren't all the threads running?
All of the threads are printing the same variable.
Your lambda expression (() => c1.k(i)) captures the i variable by reference.
Therefore, when the lambda expression runs after i++, it picks up the new value of i.
To fix this, you need to declare a separate variable inside the loop so that each lambda gets its own variable, like this:
for (int i = 0; i < 4; i++)
{
int localNum = i;
threadsArray[i] = new Thread(() => c1.k(localNum));
}
You are closing over the i variable.
Try this instead
for (int i = 0; i < 4; i++)
{
int x = i;
threadsArray[i] = new Thread(() => c1.k(x));
}
Thread[] threadsArray = new Thread[4];
for (int i = 0; i < 4; i++)
{
//better use ParameterizedThreadStart Delegate
threadsArray[i] = new Thread(k);
}
for (int i = 0; i < 4; i++)
{
//passing the value to the function
threadsArray[i].Start(i);
}
for (int i = 0; i < 4; i++)
{
threadsArray[i].Join();
}
//changing the input data type
void k(object i)
{
while (true)
Console.WriteLine((int)i);
}