1

Every time I code something that has direction in it, I always have to make 4 different instances of the code, one for each direction, which makes code hard to maintain and develop. My example below is one example, and I would like to know if I could reduce it to 1 instance. Each instance is very similar, with just very minute differences, how do I combine them all into one?

#This is a simcity sort of remake where everything is split into tiles(48x48)

#I am storing the grid in a 2d numpy array, called grid
#This triggers on mouse release
#startX amd #startY are where you clicked the mouse down
coords = pygame.mouse.get_pos()
finishX = int(coords[0]/TILESIZE)
finishY = int(coords[1]/TILESIZE)
try:
    if abs(startX - finishX) < abs(startY - finishY): #If it is verticle rather then horizontal
        if startY > finishY: #If it's going up

            for i in range(abs(startY - finishY+1)): #Loop through entire length
                if grid[startX, startY-i] == 'g': #If the tile is grass/free (For plots)
                    if tileType == 'r' or tileType == 'c' or tileType == 'i': #If it's a plot
                        if grid[startX-1, startY-i] == 't' or grid[startX, startY-i-1] == 't' or grid[startX+1, startY-i] == 't' or grid[startX, startY-i+1] == 't': #If it has a neighbouring road                                                grid[startX, startY-i] = tileType
                    elif tileType == 't': #If it's a road
                        if cash >= roadCost: #If you can afford a road
                            cash -= roadCost #Decrease cash by said road cost
                            grid[startX, startY-i] = tileType #Set that tile to the new one
                        else:
                            text = "Not enough money to build more road!" # This sets it for the next function
                            displayText(window, text) #Will display text at the bottom of the screen
                else:
                    if tileType == 'g': #If it's the demolish tool, setting the tile to grass
                        if grid[startX, startY-i] == 't':
                            cash += roadCost/2 #Increase Cash by the cost of a road/2
                        grid[startX, startY-i] = 'g' #Set the ground to grass

        else: #If it's going down
            for i in range(abs(startY - finishY)+1):
                if grid[startX, startY+i] == 'g':
                    if tileType == 'r' or tileType == 'c' or tileType == 'i':
                        if grid[startX-1, startY+i] == 't' or grid[startX, startY+i-1] == 't' or grid[startX+1, startY+i] == 't' or grid[startX, startY+i+1] == 't':
                             grid[startX, startY+i] = tileType
                    elif tileType == 't':
                        if cash >= roadCost:
                            cash -= roadCost
                            grid[startX, startY+i] = tileType
                            roadMap[startX, startY+i] = 1
                        else:
                            text = "Not enough money to build more road!"
                            displayText(window, text)
                else:
                    if tileType == 'g':
                        if grid[startX, startY-i] == 't':
                            cash += roadCost/2
                            roadMap[startX-i, startY] = 0
                            roadMap[startX, startY+i] = 0
                        grid[startX, startY+i] = 'g'

    else: #If it's horizontal
        if startX > finishX: #If it's going left
            for i in range(abs(startX - finishX)+1):
                if grid[startX-i, startY] == 'g':
                    if tileType == 'r' or tileType == 'c' or tileType == 'i':
                        if grid[startX-i-1, startY] == 't' or grid[startX-i, startY-1] == 't' or grid[startX-i+1, startY] == 't' or grid[startX-i, startY+1] == 't':
                            grid[startX-i, startY] = tileType
                    elif tileType == 't':
                        if cash > roadCost:
                            cash -= roadCost
                            grid[startX-i, startY] = tileType
                            roadMap[startX-i, startY] = 1
                        else:
                            text = "Not enough money to build more road!"
                            displayText(window, text)
                else:
                    if tileType == 'g':
                        if grid[startX-i, startY] == 't':
                            cash += roadCost/2
                        grid[startX-i, startY] = 'g'

        else: #If it's going right
            for i in range(abs(startX - finishX)+1):
                if grid[startX+i, startY] == 'g':
                    if tileType == 'r' or tileType == 'c' or tileType == 'i':
                        if grid[startX+i-1, startY] == 't' or grid[startX+i, startY-1] == 't' or grid[startX+i+1, startY] == 't' or grid[startX+i, startY+1] == 't':
                            grid[startX+i, startY] = tileType
                    elif tileType == 't':
                        if cash >= roadCost:
                            cash -= roadCost
                            grid[startX+i, startY] = tileType
                            roadMap[startX+i, startY] = 1
                        else:
                            text = "Not enough money to build more road!"
                            displayText(window, text)
                else:
                    if tileType == 'g':
                        if grid[startX, startY-i] == 't':
                            cash += roadCost/2
                            roadMap[startX+i, startY] = 0
                        grid[startX+i, startY] = 'g'



except:
    pass
startX = None
startY = None
finishX = None
finishY = None
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Skezza
  • 21
  • 8
  • 5
    You should start by refactoring your code into functions containing repeatedly used code elements that you then compose into the top-level structure. It will then be easier to see how you might parameterise those functions in order to achieve different (potentially based on direction) results. – dpwr Aug 03 '18 at 15:47
  • could you explain that a little simpler, I get the rough jist but still aren't 100% sure – Skezza Aug 03 '18 at 15:48
  • Welcome to SE. You can always try asking this question over at https://codereview.stackexchange.com/ – Gabriel Fair Aug 03 '18 at 15:52
  • I tend to discourage moves of numpy questions to CR, but this appears to be more about code refactoring than improved use of numpy. CR posters have more patience with code style issues. But beware that CR is pickier about the code being complete and runnable. – hpaulj Aug 03 '18 at 17:05
  • I suggest you start by separating your code into a function that deals with a "move" (i.e. that identifies the next tile that is "landed on" or whatever, I've never played sim city so I don't know), and another function which deals with the consequences of "landing on" that tile. – dpwr Aug 03 '18 at 19:06

0 Answers0