Swapping data in arrays - c#

I made Twitch bot for points and i need now !top10 command,i made it to read my points.ini file and if contains channelName that i use to store number of points and usernames in usernamesTop10 and pointsTop10 arrays.
I need now to cycle trough whole document and compare points and then swap points and username if newUser has more points.
These are steps:
1) get first username in file.
2) get points of that user.
3) record both in respective arrays.
4) get next username.
5) get points of that user.
6) compare points vs entire array and insert at point where they
have more points than the last person and fewer points than the next
person Repeat steps 4 to 6 until end of file
Here is code : http://pastebin.com/PztMj9Nw (I couldn't past it here, dunno why)
It's not finished, so please, could you help me with it? I'm not that smart i guess...
Thanks in advance, i appreciate any help!

Perhaps some help from a design standpoint might help.
I'm assuming you are storing your current top 10 in some array?
If so you should access this top 10 array and find the user with the lowest points. Keep track of this value. Lets say we call this variable 'threshold'.
To update your top 10, loop through your file calling GetPoints on every user. If you find a user with points > threshold, kick the lowest user out of the top10 and replace them with this new user. Be sure to update your new threshold value.
Repeat this until you can no longer find any users with more points than your threshold.
Additionally, if you want to keep your top 10 in order you can implement a simple sort algorithm.

Related

How do I randomly split a multiset into sets of predetermined sizes, without duplicates?

I'm looking for help on a problem which I don't know how to deal with. I'm guessing similar questions have already been asked, but I couldn't google it the right way.
What I'm trying to do is a randomizer for the boards in FFXII in C# and there's a part of the problem I don't know how to solve: the randomization.
I'm simplifying a bit here: there are 12 boards containing licenses that you can unlock to equip stuff or use magic. Board spots may be empty and no single license may appear twice on one board, but licenses can occur several times if they are on different boards. Each board also has a different number of licenses. There's a total of 1626 licenses on the boards, with the number of unique licenses being around 350. I have a list of all licenses, along with the number times they occur in the original board setup. (The one you get if you play the game normally.)
I would like help with generating 12 random licence lists of predetermined size, without duplicates, from the multiset of licence occurences in the original game. What I'm specifically worried about is that the algorithm might get stuck in a state where there are more duplicate elements than there are sets with room for those elements. The total size of the 12 lists is equal to the number of elements in the multiset, of course. (I'll place them on the board myself, that is not too difficult.)

Most occurring combinations from pack of cards deck

I have history of records for Deck of cards (52) for combinations, now I want to find what are the most occurring combinations from history records.
I can iterate on each card / number and check for combination from history but this is not the efficient algorithm, so I am looking the most used way of finding combinations from history.
Let say I have history in a table:
AKJ
JKQ
AKK
AJJ
A123
AKJ
AkQ
A234
AKQ
AKQ
AKQ
similar to all cards
Now I want to get most occurred combination for A - in the above AKQ -4 tunes
Similarly for all cards
I have tried with foreach card iterate on history and get combinations into list and get count but this is inefficient
I want to know what is the best pattern matching one, do I need to use sets and how?
From what i understand, you are trying to get the count of the combination which is most frequent for a particular card/number.
And a combination would match a number if the number is present anywhere in the combination.
I think to answer this type of question efficiently for a growing history, you can use a graph to model the history.
The graph would be bipartite (nodes of 2 types). One type of nodes would be each single number (13 of them) and the other type of nodes would be the unique combinations present in the history.
Each combination node would be connected to all the numbers present in the combination. Each combination node would also have a count of its frequency.
In your example, node A would be connected to AKJ(2 times), AKK(1 time), AJJ(1 time), A123(1 time), A234(1 time) and AKQ(4 times).
Whenever a combination occurs, you can check whether it is already present in the graph (using a hash table). If present, increment its count. Else, add a new combination node for it and connect it to the numbers present in it.
Using this graph, you can query the combinations matching any number by iterating through its neighbors and find the neighbor(combination) with the highest frequency. So for A, from the list of its neighbors, the most frequent one is AKQ.
If i suggest your question right, you want to get the count of usages of each card in your history.
What you can do is:
iterate through the possible cards and find all in history
or
iterate through the history and count the maximum for each card.
To win performance here, it is possible to have a look at the actual maximum count and look how many cards are still in the history.
If you just want to know the kind of card you are finished.
If you want to know the count you have to iterate through all of the cards.

Traveling salesman prob on 2d map with walls (obstacles) so pathfinding needed

I need to find optimal path between a number of points on a 2d map.
The 2d map is of a building and will simply have where you can not go (through walls) and all the points on the map. So it's not really a map, rather lines you cannot go through with points to pass through.
I have a number of points, say between 20 and 500
I start with one that I select and then need the route calculated for most optimal path.
I would love hints for where to look for this travelling salesman problem with obstacles. Or even better, done library for doing it.
Bonuses
Things like doors can be weighted as they are less fun to pass through back and forth.
Possibility of prioritizing/Weighting the ability to end close to where you started.
Selecting areas as passable but annoying (weighting down)
.Net/C# code that I can use, I want to use this both on .NET MVC project and Xamarin mobile project so .net code would be great (if code exists)
Update example
In my example here we have an office. Now I have not thought every detail out so this is merely an example.
All the purple dots need to be checked
Yellow area could mean annoying to pass through but doable
Red could mean not active but can be passed if no other option exists.
Blue (walls) are impenetrable and can not be passed.
Green is doors, weighted down possibly as it's annoying to go trough closed doors (usually this would probably make sense anyway as the dots in a room would be easiest to check together.
The user would go to one dot, check it, then the software should tell him which one to do next until he is done.
Bonus could be given for ending close to start place. So for instance in this example, if the red area was normal and contained dots it would have been easy to make it a loop. (So the user comes back close to where he started)
Finally I suppose it would also be smart to differentiate outdoors areas as you would need to get dressed for outdoors, so you only want to go out once.
Also it could be smart to be able to prioritize ending on a point close to stairwell to next floor if they intend to check multiple floors at once.
Of course would have more more complex and larger plans the this exmaple.
Again sorry for just brainstorming out ideas but I have never done this kind of work and is happy for any pointers :-)
Let N be the set of nodes to visit (purple points). For each i and j in N, let c(i,j) be the distance (or travel time) to get from i to j. These can be pre-computed based on actual distances plus walls, doors, other barriers, etc.
Now, you could then add a penalty to c(i,j) if the path from i to j goes through a door, "annoying" area, etc. But a more flexible way might be as follows:
Let k = 1,...,K be the various types of undesirable route attributes (doors, annoying areas, etc.). Let a_k(i,j) be the amount of each of these attributes on the path from i to j. (For example, suppose k=1 represents door, k=2 represents yellow areas, k=3 represents outside. Then from an i in the break area to j in the bathroom might have a_1(i,j) = 1, and from an i to a j both in the yellow areas would have a_2(i,j) = 0.5 or 2.0 or however annoying that area is, etc.)
Then, let p_k be a penalty for each unit of undesirable attribute k -- maybe p_1 = 0.1 if you don't mind going through doors too much but p_2 = 3.0 if you really don't like yellow areas.
Then, let c'(i,j) = c(i,j) + sum{k=1,...,K} p_k * a_k(i,j). In other words, replace the actual distance with the distance plus penalties for all the annoyances. The user can set the p_k values before the optimization in order to express his/her preferences among these. The final penalties p_k * a_k(i,j) should be commensurate with the distance units used for c(i,j), though -- you don't want distances of 100m but penalties of 1,000,000.
Now solve a TSP with distances given by c'(i,j).
The TSP requires you to start and end at the same node, so that preference is really a constraint. If you're going to solve for multiple floors simultaneously, then the stairway times would be in the c(i,j) so there's no need to explicitly encourage routes that end near a stairway -- the solution would tend to do that anyway since stairs are slow. If you're going to solve each floor independently, then just set the start node for each floor equal to the stairway.
I wouldn't do anything about the red (allowable but unused) areas -- that would already be baked into the c(i,j) calculations.
Hope this helps.

Finding a Position on a 2D Map that meets several criteria

as my personal project i develop a game to which users can join at any time.
I have a tiled worldmap that is created from a simple Bitmap which has resources at random positions all over the map except for oceans.
When a player joins i want to create his starting position at a place that has at least 1 tile of each of the 4 resources in range (circle with a still to decide diameter, i think about 3-4 tiles) but no ocean tiles (Tile.Type != "ocean") and not conflicting with a field belonging to another player (Tile.Owner == null).
The map size can vary, currently it's 600x450 and it's implemented as a simple Array: Tile[][] with Tile.Resource being either null or having Tile.Resource.Type as a string of the resource name (as it's configurable by plaintext files to fit any scenery i want to put it in, so no built-in enums possible).
I currently have a loop that simple goes through every possible position, checks every field in range and counts the number of each resource field and discards it if there are none for one of them or if one of them belongs to a player or is an ocean field.
I would prefer if it finds a random position but thats not a requirement, mono-compatibility however is a requirement.
What would be the best way to implement an algorithm for that in C#?
Edit
The Area of players can and will increase/change and resources can be used up and may even appear randomly (=> "Your prospectors found a new goldmine") so pre-calculated positions will propably not work.
Instead of looping through all your positions, why don't you loop through all your resources? Your resources are likely to be more scant. Then pick one of the sets of resources that meet your clustering criterion.
You might consider simulated annealing ... it's not very complex to implement. You have a set of criteria with certain weight, and randomly "shake" the position at a certain "temperature" (the higher the temp, the greater the radius the position may randomly move within, from it's previous position), then when it "cools" you measure the value of the position based on the total weights and subtract negative things, like spawning too close to where they died, or next to other players, etc..., if the value is not within a certain range, you decrease the temperature, but "shake" the positions again, cool down, check weights and overall value, repeat until you get an acceptable solution.
Simulated annealing is used in map making, to label cities and features with maximum clarity, while staying within range and minimizing overlap. Since it's a heuristic approach there is no guarantee that there will be an optimal solution, so you keep "lowering the temp" and eventually just choose the best result.
Let's suppose that once your map is created you don't have to create a new one often.
Just add the following to each Tile and calculate them once after your map was generated:
-int NrOceanTiles
-int NrResourceA
-int ...
Now when you want to get a tile you can do it quite a bit faster:
IEnumerable<Tiles> goodTiles = tiles.Where(tile => tile.NrResourceA >= 1 && tile.NrResourceB >= 2);
Tile goodTile = goodTiles.ElementAt(randomI);
Predefined data would still be the best way forward.
As modifying the map size, and adding/losing resources would not happen as often, just update this data table when they do happen. Perhaps you could do the map/resource changes once per day, and have everything done in a daily database update.
In this way, finding a valid location would be far faster than any algorithm you implement to search all the tiles around it.
If the game isn't going to be designed for a huge number of players, most games implement "start spots" on the map. You'd hand-pick them and record the positions in your map somehow, probably similar to how you're implementing the map resources (i.e., on that spot, there exists an item you can pick up, but on top of the tile map).
Since the resources spawn at random, you could either not spawn resources on the start spots (which could be visible or not), or simply not spawn a player at a start spot on which there is a resource (or look within a 9-cell box to find a close alternate location).
Certainly you would want to hold the set of possible starting locations and update it as resources are created and consumed.
It seems like your best bet is to calculate open locations at map generation. Have your start location calculation function optionally take grid location and size or rectangle corners.
Have a list for Free locations and Occupied locations. Player occupies territory? Move resources in range to the Occupied list. Player gets crushed mercilessly? Move resources in range to the Free list. Resource eliminated? Delete any locations that used it in your Open/Occupied lists. Resource added? Recalculate using your effect radius to determine effected area. When your map area expands, just run the initial calculations on the new section of your grid + effect radius and add the new locations.
Then you just have to set the events up and pick a random Free value when someone joins.

Let user sort records?

I am trying to figure out a way to let the user sort records (etc. a list of friends).
I want to give the user the opportunity to move a record (friend) straight to the top or bottom of the list, or by entering a number (in between).
First I thought of just adding a column called SortOrder (int) to the table with all the users friends and set the number according to which order the records should be shown.
But what I am trying to avoid is that etc. a user have 400 friends, and if he wants to set friend number 400 to be at position 1 in the list, then I will have to update every single record with a new SortOrder.
All data is stored in an MS SQL database.
I hope someone out there have a magic solution for this?
Use floating point numbers for the sort column.
Set the initial items as 0.0, 1.0 etc.
Moving to top, use min -1.0. Moving to bottom, set to max+1.0. Moving between two items, set to (prev+next)/2.0
This is similar to the line numbers approach, but there is more "space" between the numbers. Theoretically, there is still the point where you need to renumber, when two adjancted values grow to close. I have no idea how soon this happens in practice, but I expect it to be very infrequent, so this can be done with any maintenance task.
[edit] FWIW, this problem came back to me a few times, so here's a way that does roughly the same, but with strings.
I wouldn't imagine they'd be doing this often enough to be a real concern but, if you're worried, use the trick we pioneered with our BASIC code from days of yore.
Back when BASIC had line numbers, we'd simply number them 10, 20, 30 and so on, so that if we needed to insert one between 10 and 20, we'd call it 15. Or if 20 should have come before 10, we'd renumber it to 5.
With a 32 bit integer column you could have 200,000 friends with a spacing of 100, more than enough to move things around, especially if you're clever.
You may want to run a sweep job occasionally to renumber the friends to 100, 200, and so on (sort of a disk defragmenter for your social network). Don't try to detect this by the looking at the friend numbers, use another field, setting it to true when a user re-arranges their friends and clearing it when you defragment. This will be more efficient.
It sounds like you're looking for a linked list type structure, where each record would hold the ID of the next record in order.
I don't know about magic, but for moving to the top or bottom, you could just set the SortOrder to MIN/MAX(SortOrder) +/- 1. Who says the top has to be 1 or 0?
Here's how I'd do it: Use your SortOrder column. Presumably, there would be an initial default sort order, say alphabetical, and so everyone would be given a SortOrder value based on their alphabetical order.
Then, when a user moved someone to the top, you could just set SortOrder to max +1. If they moved someone to the bottom, then it would be min -1. If they moved someone to somewhere in the middle, then you would want to calculate which half of the middle they are moving to. If it's the top half, then bump up the SortOrder of everyone above them. If it's the bottom half, then decrease the SortOrder of everyone below.
Not sure there's a more expedient way of doing it...
You could look at it as groups of friends.
Initially, everyone is in Group 0, and the order is by name or something.
- If the user then increases the "Group" of friend (a) to 1, then they move to the top
- If the user then increases the "Group" of friend (b) to 1, then (a) and (b) appear at the top
- If the user then increases the "Group" of friend (b) again, then (b) appears 1st and (a) 2nd
Just a thougt...

Categories

Resources