I am making a python project with the 2D physics engine pymunk, but I am not familiar with pymunk or the base C library that it interatcs with, Chipmunk2D. I have quite a few different objects that I want to collide with others, but not collide with certain ones. There is a wall, an anchor point in the wall, a segment attached to the anchor point with a circle on the end, and a car. I want the car to ONLY collide with the wall and the segment, but the wall needs to also collide with the circle on the end of the segment. Other than that I want no collisions. I have tried using groups with the pymunk.ShapeFilter object, but the specific collisions are too complex for only using groups. I searched for a while and found out about categories and masks, but after looking at it I didn't understand. The explanation didn't make much sense to me and it was using bitwise operators which I don't really understand that well. I have been looking for a while but could not find any good tutorial or explanation so I want to know if someone could explain to me how it works or cite some useful resources.
It can look a bit tricky at first, but is actually quite straight forward, at least as long as you dont have too complicated needs.
With ShapeFilter you set the category that the shape belongs to, and what categories it can collide with (the mask property).
Both categories and the mask are stored as 32 bit integers (for performance), but instead just think of it as a list of 0s and 1s (maximum 32 digits long), where 1 means that the position is taken by that category. The list is written in Python in binary notation (0bxxxxx) where the x's is the list of 0s and 1s.
Lets say you have 3 categories of things. Cars, trees and clouds. Cars can collide with other cars and trees, trees can collide with cars, trees and clouds. And clouds can only collide with trees.
First I define the categories. In this example I only have three categories, so I only use 3 digits, but if I had more I could make it longer (up to 32 digits):
car = 0b100
tree = 0b010
cloud = 0b001
I want car to collide with itself. I also want it to collide with the tree. That means that the car mask should put 1s at the same positions as the of 1s of the car category and the tree category car_mask = 0b110. The tree can collide with car, itself and cloud, so all 3 positions should be set: tree_mask = 0b111. Finally, the Cloud can only collide with trees: cloud_mask = 0b010.
Then you need to assign these Shape Filters to the shapes:
car_shape.filter = pymunk.ShapeFilter(category = car, mask=car_mask)
tree_shape.filter = pymunk.ShapeFilter(category = tree, mask=tree_mask)
cloud_shape.filter = pymunk.ShapeFilter(category = cloud, mask=cloud_mask)
i have this simple game where there is a ball bouncing on the screen and the player can move left and right of the screen and shoot an arrow up to pop the ball, every time the player hits a ball, the ball bursts and splits into two smaller balls until they reach a minimum size and disappear.
I am trying to solve this game with a genetic algorithm based on the python neat library and on this tutorial on flappy bird https://www.youtube.com/watch?v=MMxFDaIOHsE&list=PLzMcBGfZo4-lwGZWXz5Qgta_YNX3_vLS2, so I have a configuration file in which I have to specify how many input nodes must be in the network, I had thought to give as input the player's x coordinate, the distance between the player's x-coordinate and the ball's x-coordinate and the distance between the player's y-coordinate and the ball's y-coordinate.
My problem is that at the beginning of the game I have only one ball but after a few moves I could have more balls in the screen so I should have a greater number of input nodes,the more balls there are on the screen the more input coordinates I have to provide to the network.
So how to set the number of input nodes in a variable way?
config-feedforward.txt file
"""
# network parameters
num_hidden = 0
num_inputs = 3 #this needs to be variable
num_outputs = 3
"""
python file
for index,player in enumerate(game.players):
balls_array_x = []
balls_array_y = []
for ball in game.balls:
balls_array_x.append(ball.x)
balls_array_x.append(ball.y)
output = np.argmax(nets[index].activate(("there may be a number of variable arguments here")))
#other...
final code
for index,player in enumerate(game.players):
balls_array_x = []
balls_array_y = []
for ball in game.balls:
balls_array_x.append(ball.x)
balls_array_y.append(ball.y)
distance_list = []
player_x = player.x
player_y = player.y
i = 0
while i < len(balls_array_x):
dist = math.sqrt((balls_array_x[i] - player_x) ** 2 + (balls_array_y[i] - player_y) ** 2)
distance_list.append(dist)
i+=1
i = 0
if len(distance_list) > 0:
nearest_ball = min(distance_list)
output = np.argmax(nets[index].activate((player.x,player.y,nearest_ball)))
This is a good question and as far as I can tell from a quick Google search hasn't been addressed for simple ML algorithms like NEAT.
Traditionally resizing methods of Deep NN (padding, cropping, RNNs, middle-layers, etc) can obviously not be applied here since NEAT explicitly encodes each single neuron and connection.
I am also not aware of any general method/trick to make the input size mutable for the traditional NEAT algorithm and frankly don't think there is one. Though I can think of a couple of changes to the algorithm that would make this possible, but that's of no help to you I suppose.
In my opinion you therefore have 3 options:
You increase the input size to the maximum number of balls the algorithm should track and set the x-diff/y-diff value of non-existent balls to an otherwise impossible number (e.g. -1). If balls come into existence you actually set the values for those x-diff/y-diff input neurons and set them to -1 again when they are gone. Then you let NEAT figure it out. Also worth thinking about concatenating 2 separate NEAT NNs, with the first NN having 2 inputs, 1 output and the second NN having 1 (player pos) + x (max number of balls) inputs and 2 outputs (left, right). The first NN produces an output for each ball position (and is identical for each ball) and the second NN takes the first NNs output and turns it into an action. Also: The maximum number of balls doesn't have to be the maximum number of displayable balls, but can also be limited to 10 and only considering the 10 closest balls.
You only consider 1 ball for each action side (making your input 1 + 2*2). This could be the consideration of the lowest ball on each side or the closest ball on each side. Such preprocessing can make such simple NN tasks however quite easy to solve. Maybe you can add inertia into your test environment and thereby add a non-linearity that makes it not so straightforward to always teleport/hurry to the lowest ball.
You input the whole observation space into NEAT (or a uniformly downsampled fraction), e.g. the whole game at whatever resolution is lowest but still sensible. I know that this observation space is huge, but NEAT works quite well in handling such spaces.
I know that this is not the variable input size option of NEAT that you might have hoped for, but I don't know about any such general option/trick without changing the underlying NEAT algorithm significantly.
However, I am very happy to be corrected if someone knows a better option!
The dungeon game is described as:
The demons had captured the princess (P) and imprisoned her
in the bottom-right corner of a dungeon. T
he dungeon consists of M x N rooms laid out in a 2D grid.
Our valiant knight (K) was initially positioned in the top-left room
and must fight his way through the dungeon to rescue the princess.
The knight has an initial health point represented by a positive integer.
If at any point his health point drops to 0 or below, he dies immediately.
Some of the rooms are guarded by demons,
so the knight loses health (negative integers) upon entering these rooms;
other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).
In order to reach the princess as quickly as possible,
the knight decides to move only rightward or downward in each step.
Write a function to determine the knight's minimum initial health
so that he is able to rescue the princess.
For example, given the dungeon below, the initial health of
the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.
Notes:
The knight's health has no upper bound.
Any room can contain threats or power-ups, even the first room the knight enters
and the bottom-right room where the princess is imprisoned.
Example:
dungeon = [[-2, -3, 4],
[-6, -15, 0],
[10, 25, -6]]
Answer: 8
The code solution is:
def dungeonGame(dungeon):
dp = [float("inf") for _ in dungeon[0]]
dp[-1] = 1
for i in reversed(range(len(dungeon))):
dp[-1] = max(dp[-1] - dungeon[i][-1], 1)
for j in reversed(range(len(dungeon[i]) - 1)):
min_HP_on_exit = min(dp[j], dp[j + 1])
dp[j] = max(min_HP_on_exit - dungeon[i][j], 1)
return dp[0]
Can somebody explain how the solution above is working? Why is the dp only len 3 with the provided example? Is it because there are only 3 steps required, excluding start and finish rooms? Why is it getting the minimum on the adjacent dp's and then the maximum? Also how come it seems that the last column is not being taken into consideration since dungeon[i][j], where j only goes up to 1 (taking the given example matrix). I know the solution is written well, just trying to understand how its taking all the path into consideration.
This algorithm works its way back from the bottom right, going left and then up, finding the optimal score for each step along the way. I recommend you execute the algorithm with pen and paper, writing down the current values of i, j and dp along the way. That should really clear things up.
(Start): No i and no j yet, dp = [inf inf 1]
You'll need at least 1 HP after reaching the bottom right in order to win.
(After entering the first loop): i=2, dp = [inf inf 7].
You need 7 health to survive the -6 of the bottom right square itself.
(After entering the inner loop): i=2, j=1, dp = [inf 1 7]
If you're in the bottom center square, the bare minimum 1 health is enough to survive that square's +25, and reach the adjacent square that requires at least 7. And so on.
This is the crucial line that chooses between going right (stored in the next element of the intermediate results, dp[j + 1]) or down, dp[j].
min_HP_on_exit = min(dp[j], dp[j + 1])
There are only three elements to the intermediate results because with the movement rules (only move right and down) and a dungeon with a diagonal of 3, there are only at most 3 places where you could be after any number of moves.
Every time the solver moves up a line, the last column is taken care of as a special case here:
dp[-1] = max(dp[-1] - dungeon[i][-1], 1)
Why? Well, it's different from the other columns in that you can't move right, only down.
I'm still quite new to python, and am working through a problem for class. I feel like I'm really close to the solution, but my numbers still aren't coming out how I would expect from probability.
In the problem, we have a bag with two chips inside. We know one of the chips is white, and the other is either black or white. These conditions are true each time we play the game.
In the game, we've drawn one chip out of the bag and it was white. The problem is to write a function that approximates the probability of drawing two white chips out of the bag. The argument of the function is the number of times we play the game.
Here's the code I've written so far:
def prob_two_whites(num):
counter = 0 #counts the number of iterations or games played
first_white = 0 #counts how many times the first pull was white
double_white = 0 #counts how many times the second pull was white, if the first was also white
while counter < num: #runs a game until total number of games is reached
chip_1 = "white" #this is the chip we know is white
chip_2 = np.random.choice(["white","black"]) #chip two has an equal chance of being white or black for each game
result = np.random.choice([chip_1, chip_2], 2, replace = False) #drawing both chips without replacement
if result[0] == "white": #if the first chip pulled is white
first_white += 1 # add one to the first white
if result[1] == "white": #if the second pull was white, given the first was also white
double_white += 1 # add one to double_white
counter +=1 #add one to the counter
return (float(double_white)/float(first_white)) / (float(first_white)/float(counter))
Effectively, the result should be approximately 66.66%
Probabilistically, the chance of the first pull being white is 75%. Once the first white is pulled, there's approximately a 50% chance of the second pull being white.
When I look at the distinct counts of first_white and double_white, the first_white numbers appear to be tallying as they should (about 75% of total count), but my double_white counts are consistently too high. I feel like my code is pretty straight-forward, but somehow it seems I'm counting double-whites more than I should.
Any help anyone could provide would be very appreciated!
Thank you!
I the issue is not with any of the random number generation or the counting, but with your probability computation at the end.
The conditional probability of getting two white results given that the first result was white is double_white / first_white (simply divide the two counts). That's a simplified form of the ratio of their independent probabilities: (double_white / count) / (first_white / count) (note that count can be canceled out)
Normally Bayes' law would say there needs to be an extra term in the numerator when dividing those probabilities or counts. But as it happens, the extra term is the reversed conditional probability (the probability the first chip was white if both of them are white) which is 100% (or 1). Multiplying by 1 doesn't do anything so it can be left out of the calculation.
I've omitted all the float calls above, both for clarity, and because they really shouldn't be necessary. If you're using Python 3, division between two integers will generate a float result by default (you can explicitly request integer division by using the // floor division operator). If you're still stuck using Python 2, you can get the Python 3 behavior if you put from __future__ import division at the top of your file (I strongly recommend it!).
Before I say anything else - the problem may look lengthy but it's actually just 1 problem in the core, that kind of gets repeated. I'm trying to create a "puzzle solver" that has to do with probability. This is a model where the person solving the problem has to do it without computer help, but I want to be able to have a script, where I can just change the variables for different conditions. We use this test for potential employees and we have to come up with the answers. It's pretty tedious, so I was hoping someone could give me a hand trying to do it in Python? I'm still learning Python but because I see how easily everyone can "manipulate" it to give them what they need I was hoping to learn how to do that, so I don't have to do this over and over again by hand.
Here's an example of the test -
Given facts:
There are 5 houses in a row, numbered from left to right as 1, 2, 3, 4, 5.
Each house is painted a different color: Red, Orange, Yellow, Green, or Blue.
Each house is owned by a different person: Ann, Bob, Carl, Dorothy, or Ed.
Each house has a different number of windows: one, two, three, four, five
Each house was built in a different year: 1970, 1980, 1990, 2000, or 2010.
Each person knows a different language: Spanish, French, Latin, German, Italian.
Then we give them the constraints:
Bob lives in the yellow house.
Ann knows Latin.
There are 5 windows on the orange house.
Dorothy lives in a house with 2 windows.
The orange house is immediately to the right of the green house.
The German speaker lives in the house built in 2000.
The red house was built in 1970.
The middle house has 3 windows.
Carl lives in the first house.
The house built in 1980 is next to the house of the Italian speaker.
The house built in 1970 is next to the house where the French speaker lives.
The house built in 1990 has 1 window.
Ed lives in a house built in 2010.
Carl lives next to the blue house.
The potential employee has to figure out:
for each house numbered 1 to 5, who lives there, what color is the house, how many windows it has, when was it built and what language does the occupant speak.
And that is exactly what I want to put into Python!
I gave it a go and here's my reasoning behind it:
def permutations(x):
outlist = []
for a in x:
for b in x:
if b == a:
continue
for c in x:
if c == b or c == a:
continue
for d in x:
if d == a or d == b or d == c:
continue
for e in x:
if e == a or e==b or e==c or e==d:
continue
outlist.append([a,b,c,d,e])
return outlist
The "checks" in the loop are so that the loop continues if an entry would be repeated, so that the inner loops don’t have to execute unless the early loops are valid - saves time!
Given a list x of five elements, this function returns a list of lists, each of which is a permutation of the original five elements where no one element is equal to another.
So, if the list input is x = [1,2,3,4,5], the returned output is a list of possible permutations of this:
Outlist = [[1,2,3,4,5],[1,2,3,5,4],[1,2,4,3,5],[1,2,4,5,3], ...]
which will have 5! = 120 elements.
So, I know how it works in theory but writing it down in Python proved to much for me to "translate".
I assigned the name variables (Ann,Bob,Carl,Dorothy,Ed) one of these permutations (say [1,2,5,4,3]), which means that Ann lives in house 1, Bob lives in house 2, Carol lives in house 5, Dorothy lives in house 4, Ed lives in house 3.
Similarly, I know you can assign to the color variables (Red,Orange,Yellow,Green,Blue) another of these permutations (say [5,4,3,1,2]) which means that house 5 is red, house 4 is orange, house 3 is yellow, house 1 is green and house 2 is blue.
You can assign the same or another permutation to the number of windows (one,two,three,four,five), the year the house was built (Seven,Eight,Nine,Zero,Ten) and the language spoken.
And this is where I get really lost because I'm having a hard time understanding how the same numbers can be reused - don't they get written over in such cases?
First things first though - it's better (more time efficient) if we first check whether the clues are true for this assignment. If not, the person taking the test can go to another assignment!
Coding-wise this is how I imagined it but my limited knowledge of Python didn't really help me write "proper code":
a) check if Bob lives in the yellow house, by Bob == Yellow
(that is, the house number assigned to Bob is the same as the house number assigned to Yellow.
b) check if the house built in 1970 is next to the house where the French speaker lives, do absolute value calculation ->
abs(Seven – French) == 1
Meaning the house numbers assigned to Seven and French differ by only 1.
Further on I know there are additional checks and all of the them must be passed as True for the five permutation assignments to be the solution of the puzzle.
Then I made an assignment of the permutation to the variables using a loop:
for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
It will assign Ann the value a[0], Bob the value a[1], Carol the value a[2], Dorothy the value a[3] and Ed the value a[4], and because we loop through all permutations in outlist, where outlist is the output of the function, a list of permutation lists.
Another problem - making a list of lists... showing to be a bit of a struggle.
I know I have to write five nested loops of assignment to the variables of interest. To verify whether the assignment satisfies the clues I thought about checking a subset of the clues incrementally in each loop once I'd have a partial assignment, so then I wouldn’t enumerate the inner loop unless the subset of clues is satisfied. Again, it gives the program to run faster and be more effective.
Here's an attempt at the first loop, which is (for instance) over names. I know Carl must live in house 1, and the other loops don't get executed if this is not true! On paper, you have to keep repeating the process until Carl == 1!
Attempt at writing code:
for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
if Carl != 1:
continue
for b in outlist:
(Red,Orange,Yellow,Green,Blue) = b
if ...
With this code, the inner four loops only execute when Carl == 1.
I have to continue I know, but the overlap of variables is a problem here too.
AND FINALLY - I was advised to "time the function" by using the time module
time.time().
I know the current time reported back in a Mac (so mine) is in microseconds, and this is written according to that. Not sure HOW to get the right code tho.
import time
start = time.time()
#CODE
end = time.time()
print('Running Time: {} msecs'.format((end - start)*0.001))
Thank you for getting to the end of this! I find it very overwhelming and don't know where to start but I would sure love to have something like this doing all my permutations for me!
Use itertools.permutations() to generate permutations:
from itertools import permutations
for colors in permutations(range(5)):
# colors is permuted combination of 5 integers between 0 and 4, inclusive.
This uses numbers from 0 to 4 as that comes more natural to Python, but the principle is the same; if you want you can use range(1, 6) instead to generate permutations of integers 1 through to 5, inclusive.
Now nest your permutation loops. The outer loop is for the colour choices; each number representing the colour for that house. Test the constraints, eliminate all that don't fit (any combo that has orange not next to green doesn't fit). Where the constraints fit, loop over permutations for the owner, eliminate those that don't fit, loop over window counts for those that do, etc.
Use one function to test constraints, allowing for missing aspects, to keep testing simple.
You'll find that you can eliminate most combos very quickly very early.