Just some thoughts while analyzing your file. It might appear a little bit chaotic and it is. It follows the steps I did (at least the major steps).
Brush builds your grid?
In that case I suggest to change the name of the function to “buildGrid”, “makeMap” or something like that as this is what it is doing. As this is a major function (at least a function a reader will be interested in) I suggest to place it at the top of the code rather than at the end.
I would go a step deeper and rename the module from “drawGrid” to lets say “grid” as it represents grid(s) not just drawing it.
So you can get “grid.build”.
When you move the classes and internals to a separate module, lets say board.py you can move the bge callable function from mOver.py to grid.py. When you rename it from go() to something more expressive e.g. selectTile() [I guess it selects the tile under the cursor), it would look a bit more helpful.
Just now I do not know what part of your code handles your blast. There is too less information to quickly identify it.
Lets start at mOver.py. I guessed it selects a tile. You placed your blast when selecting. So there must be a relationship.
core['board'].targetHex = ...
I know from drawGrid that core[‘board’] is you current grid
so I assume targetHex is the selected tile.
So lets see what happens with that…
- it is assumed to be a list
- it is checked in “main” [whatever main means ;)]
–> it is used to get A
- it is checked again in “main”
–> it is used to set the position of target
–> there it is —> cube_areaDraw()
lets follow cube_areaDraw().
The name is fine. It is a bit hidden under the lots of over code.
I assume h means tile … no it is Cube which contains coordinates.
A bit confusing … you override h with a complete different datatype.
First it is a Tile (why is a tile called h?).
Then it is a Cube (why is a cube called h?).
I guess r= radius (as it is used as argument I suggest to use the real name rather than a abbreviation).
You do a nested loop => two dimensional processing. This looks like the are blast/area code we are looking for.
You always create a full set of Cubes.
At the border I would expect a smaller set as the “out-of-bounds” Cubes should not be in results.
So I think you are missing some limit checks either in the loops range (more efficient) or when creating/appending the results.
Finally you managed to display the result “wrapped” otherwise you would see the “out-of-bounds” Cubes being out of the grid.
I think showing the incorrect Cubes might be incorrect too.
Lets see where the results end in real objects. … back to the caller of cube_areaDraw() [which does not draw anything, but creates the Cubes of an area] -> “main”
Here is a loop that adds the objects. I guess this is the “real” areaDraw() -> may be encapsulate in “drawCubes”?
I do not see an obvious wrapping.
… cube_to_hex() we convert the cube back … .ah there is a Hex type … what is the difference to Tile?
Means my above statement is not good. “h” for hex is fine (but “h” for Cube is still not).
You place the “brush” ( I guess it acts as cursor) at the location taken of the map and add a new object. I assume “out-of-bound” coordinate would fail the map access.
Here it is, your try: except statement catches that at least it is supposed to do this. Yes, it is a valid bounds check (but I think it might be a little late).
- an except statement should always have an explicit expected error type. Otherwise you hide any unexpected errors and you get no idea why your code behaves like an idiot if it fails ;).
- keep the try block with less statements as possible. Otherwise you might catch errors from irrelevant code. In your situation you can simply skip the current iteration:
for cube in self.areaHexes: hex = cube_to_hex(cube) try: self.brush.worldPosition = self.map[hex.q][hex.r+hex.q//2].pip.worldPosition except KeyError: continue pip = logic.getCurrentScene().addObject('LINE', self.brush) self.areaHexPips.append(pip)
I just recognize you constantly rebuild the area. This is not really efficient and is really disturbing on debugging (via print statements).
Ok now I see. Your “self.map” is not a map/dict.
It is a list. Python lists deal with “out-of-bounds” values by wrapping the indices. -> This is your problem.
Either you say this is fine (it is a valid behavior),
or you do a different limit check than try…except.
Be aware this cures the symptom not the cause (see above)