How to implement frequency of attack in game? - frequency

In a RPG game,suppose there are role A and B.
A will conduct x attacks per second
B will conduct y attacks per second
If we suppose A initiates the attack and the final attacks may be :
A A B A B ...
How to calculate the sequence of attacks?

Here's one way to do it in Python 3.0 using a generator and fractions:
def get_attack_sequence(a, b):
from fractions import Fraction
count_a = count_b = 0
rate_a = Fraction(1, a)
rate_b = Fraction(1, b)
while 1:
new_count_a = count_a + rate_a
new_count_b = count_b + rate_b
if new_count_a < new_count_b:
yield "A"
count_a = new_count_a
elif new_count_a > new_count_b:
yield "B"
count_b = new_count_b
else:
yield "A|B"
count_a = new_count_a
count_b = new_count_b
attack_sequence = get_attack_sequence(3, 2)
print(' '.join(next(attack_sequence) for _ in range(10)))
Output:
A B A A|B A B A A|B A B
An attack frequency of 0 needs to be checked for. I haven't done this in the above code for simplicity, but it's easy to fix and probably best handled outside this function (a battle where one player can't attack wouldn't be very interesting anyway).
An advantage of this idea is that it could be easily extended to more than 2 simultaneous players.
Another advantage is that it can also handle attack rates of less than one attack per second without any modification (e.g. B attacks only once every two seconds, i.e. attack frequency = 0.5).

Count who has more attacks. Call him MORE. Divide MORE/LESS and take floor, the result is = N. Then for every N attacks of MORE add one of LESS and pad with attacks of MORE when finished. That's each second.
Example:
MORE = 5
LESS = 2
MORE/LESS floor = 2
Then:
MORE MORE LESS MORE MORE LESS MORE
Another example:
MORE = 3
LESS = 2
MORE/LESS floor = 1
Then:
MORE LESS MORE LESS MORE

Related

Evaluating time complexity for the binomial coefficient

I'm new to Theoretical Computer Science, and I would like to calculate the time complexity of the following algorithm that evaluates the binomial coefficient defined as
nf = 1;
for i = 2 to n do nf = nf * i;
kf = 1;
for i = 2 to k do kf = kf * i;
nkf = 1;
for i = 2 to n-k do nkf = nkf * i;
c = nf / (kf * nkf);
My textbook suggests to use Stirling's approximation
However, I can get the same result by considering that for i = 2 to n do nf = nf * i; have complexity O(n-2)=O(n), that is predominant.
Stirling's approximation seems a little bit overkill. Is my approach wrong?
In your first approach you calculate n!, k! and (n-k)! separately and then calculate the binomial coefficient. Therefore since all of those terms can be calculated with at most operations you have O(n) time complexity.
However, you are wrong about the time complexity of calculating the Stirling's formula. You only need log(n) in base 2 operations to calculate it. This is because when trying to calculate p'th power of some real number, instead of multiplicating it p times, you can instead keep squaring the number to calculate it quickly. For example:
If you want to calculate 2^17, instead of doing 17 operations like this:
return 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
you can do this:
a = 2*2
b = a*a
c = b*b
d = c*c
return d * 2
which is only 5 operations.
Note: However keep in mind that the Stirling's formula is not equal to the factorial. It is only an approximation but a good one.
Edit: Also you can consider a^n as e^(log(a)*n) and then calculate it by the quickly converging series expansion
1 + (log(a)n) + ((log(a)n)^2)/2! + ((log(a)n)^3)/3! + ...
Since the series converges very quickly you can get really close approximations in no time.

Algorithms for factorizing a 30 decimal digit number

My professor has given me an RSA factoring problem has assignment. The given modulus is 30 decimal digits long. I have been searching a lot about factoring algorithms. But it has been quite a headache to choose one for my given requirements. Which all algorithms give better performance for 30 decimal digit numbers?
Note: So far I have read about Brute force approach and Quadratic Sieve. The latter is complex and the former time consuming.
There's another method called Pollard's Rho algorithm, which is not as fast as the GNFS but is capable of factoring 30-digit numbers in minutes rather than hours.
The algorithm is very simple. It stops when it finds any factor, so you'll need to call it recursively to obtain a complete factorisation. Here's a basic implementation in Python:
def rho(n):
def gcd(a, b):
while b > 0:
a, b = b, a%b
return a
g = lambda z: (z**2 + 1) % n
x, y, d = 2, 2, 1
while d == 1:
x = g(x)
y = g(g(y))
d = gcd(abs(x-y), n)
if d == n:
print("Can't factor this, sorry.")
print("Try a different polynomial for g(), maybe?")
else:
print("%d = %d * %d" % (n, d, n // d))
rho(441693463910910230162813378557) # = 763728550191017 * 578338290221621
Or you could just use an existing software library. I can't see much point in reinventing this particular wheel.

Is *0.25 faster than / 4 in VB.NET

I know similar questions have been answered before but none of the answers I could find were specific to .NET.
Does the VB.NET compiler optimize expressions like:
x = y / 4
by compiling:
x = y * 0.25
And before anyone says don't worry the difference is small, i already know that but this will be executed a lot and choosing one over the other could make a useful difference in total execution time and will be much easier to do than a more major refactoring exercise.
Perhaps I should have mentioned for the benefit of those who live in an environment of total freedom: I am not at liberty to change to a different language. If I were I would probably have written this code in Fortran.
As suggested here is a simple comparison:
Dim y = 1234.567
Dim x As Double
Dim c = 10000000000.0
Dim ds As Date
Dim df As Date
ds = Now
For i = 1 To c
x = y / 4
Next
df = Now
Console.WriteLine("divide " & (df - ds).ToString)
ds = Now
For i = 1 To c
x = y * 0.25
Next
df = Now
Console.WriteLine("multiply " & (df - ds).ToString)
The output is:
divide 00:00:52.7452740
multiply 00:00:47.2607256
So divide does appear to be slower by about 10%. But this difference is so small that I suspected it to be accidental. Another two runs give:
divide 00:00:45.1280000
multiply 00:00:45.9540000
divide 00:00:45.9895985
multiply 00:00:46.8426838
Suggesting that in fact the optimization is made or that the arithmetic operations are a vanishingly small part of the total time.
In either case it means that I don't need to care which is used.
In fact ildasm shows that the IL uses div in the first loop and mul in the second. So it doesn't make the subsitution after all. Unless the JIT compiler does.

Even Distribution

Say I have turn based game with 20 attack turns and the players attack speed determines how often they get to attack, how would you calculate and or graph a table of "who attacks when" when one person has an attack speed of 5 and another a speed of 8? (These are test values, the values I will be using will vary. 20 attack turns will be the cap, however, each player will be able to invest in their own attack speed with their skill points up to a value of 10)
I've been programming in C for about a 2 years and I'm currently playing with Obj-C making my first indy game, any advise or knowledge would be of great help.
If I understand the problem correctly:
The first to attack will be min(a,b), where a and b are your initial "attack speeds", 5 and 8. Then subtract the min value of both, and if the result is 0 or less add the attacker's original value again. So after the first attack, a=5 again, but now b=8-5=3. Then it's b's turn:
a = 5 - 8 = -3
b = 3 - 8 = -5
Both less than zero, so add 5 and 8 again:
a = 2
b = 3
a attacks:
a = -3 -> a = 2
b = -2 -> b = 6
and thus a gets to score another hit. And so on, until you get a tie -- you're bound to run into that one way or another. You could return a "tie" result, or let the last attacker or last defender "win" that one. Put some thought in this, because what if both players have the same "attack" value?
This math problem tells me who’s turn is when -
For example:
There’s 11 attacks
you attack 8 times and your enemy attacks 3
Determine an attack sequence thats evenly distributed and consistently repeatable.
In this case:
1. player 1 attacks
2. player 1 attacks
3. player 2 attacks
4. player 1 attacks
5. player 1 attacks
6. player 1 attacks
7. player 2 attacks
8. player 1 attacks
9. player 1 attacks
10. player 1 attacks
11. player 2 attacks
(repeat these 11 steps as long as needed)
I first thought the solution would be best done with division until I ran into 20 walls, so
I choose subtraction bc it can be reproduced and works better programmatically, instead of creating an attack sequence by division and storing it as an array and indexing the array each time you need to determine a persons turn.
so my code to do this was:
if (playerTwoWent == 0)
{
difference = difference - player_twos_speed;
}
else if (playerTwoWent == 1)
{
difference = player_ones_speed + difference;
playerTwoWent = 0;
}
if (difference >= 0)
{
printf("player 1s turn: %d\n", difference);
}
else if (difference < 0)
{
if (playerTwoWent == 0)
{
printf("player 2s turn: %d\n", difference);
playerTwoWent = 1;
}
}

How to choose a range for a loop based upon the answers of a previous loop?

I'm sorry the title is so confusingly worded, but it's hard to condense this problem down to a few words.
I'm trying to find the minimum value of a specific equation. At first I'm looping through the equation, which for our purposes here can be something like y = .245x^3-.67x^2+5x+12. I want to design a loop where the "steps" through the loop get smaller and smaller.
For example, the first time it loops through, it uses a step of 1. I will get about 30 values. What I need help on is how do I Use the three smallest values I receive from this first loop?
Here's an example of the values I might get from the first loop: (I should note this isn't supposed to be actual code at all. It's just a brief description of what's happening)
loop from x = 1 to 8 with step 1
results:
x = 1 -> y = 30
x = 2 -> y = 28
x = 3 -> y = 25
x = 4 -> y = 21
x = 5 -> y = 18
x = 6 -> y = 22
x = 7 -> y = 27
x = 8 -> y = 33
I want something that can detect the lowest three values and create a loop. From theses results, the values of x that get the smallest three results for y are x = 4, 5, and 6.
So my "guess" at this point would be x = 5. To get a better "guess" I'd like a loop that now does:
loop from x = 4 to x = 6 with step .5
I could keep this pattern going until I get an absurdly accurate guess for the minimum value of x.
Does anybody know of a way I can do this? I know the values I'm going to get are going to be able to be modeled by a parabola opening up, so this format will definitely work. I was thinking that the values could be put into a column. It wouldn't be hard to make something that returns the smallest value for y in that column, and the corresponding x-value.
If I'm being too vague, just let me know, and I can answer any questions you might have.
nice question. Here's at least a start for what I think you should do for this:
Sub findMin()
Dim lowest As Integer
Dim middle As Integer
Dim highest As Integer
lowest = 999
middle = 999
hightest = 999
Dim i As Integer
i = 1
Do While i < 9
If (retVal(i) < retVal(lowest)) Then
highest = middle
middle = lowest
lowest = i
Else
If (retVal(i) < retVal(middle)) Then
highest = middle
middle = i
Else
If (retVal(i) < retVal(highest)) Then
highest = i
End If
End If
End If
i = i + 1
Loop
End Sub
Function retVal(num As Integer) As Double
retVal = 0.245 * Math.Sqr(num) * num - 0.67 * Math.Sqr(num) + 5 * num + 12
End Function
What I've done here is set three Integers as your three Min values: lowest, middle, and highest. You loop through the values you're plugging into the formula (here, the retVal function) and comparing the return value of retVal (hence the name) to the values of retVal(lowest), retVal(middle), and retVal(highest), replacing them as necessary. I'm just beginning with VBA so what I've done likely isn't very elegant, but it does at least identify the Integers that result in the lowest values of the function. You may have to play around with the values of lowest, middle, and highest a bit to make it work. I know this isn't EXACTLY what you're looking for, but it's something along the lines of what I think you should do.
There is no trivial way to approach this unless the problem domain is narrowed.
The example polynomial given in fact has no minimum, which is readily determined by observing y'>0 (hence, y is always increasing WRT x).
Given the wide interpretation of
[an] equation, which for our purposes here can be something like y =
.245x^3-.67x^2+5x+12
many conditions need to be checked, even assuming the domain is limited to polynomials.
The polynomial order is significant, and the order determines what conditions are necessary to check for how many solutions are possible, or whether any solution is possible at all.
Without taking this complexity into account, an iterative approach could yield an incorrect solution due to underflow error, or an unfortunate choice of iteration steps or bounds.
I'm not trying to be hard here, I think your idea is neat. In practice it is more complicated than you think.