Home > Net >  Cannot get correct recursion in function
Cannot get correct recursion in function

Time:01-28

In my show() function I can't get the correct amount of recursions and boxes showing. It only goes 1 level deep then stops. Any idea on how to fix it? I'll post all my code to give you some background. When it runs it won't continue to show other boxes that don't have bombs around them or numbered boxes. Not sure what is going wrong as I believe the code is correct but I didn't know how to debug the recursion function. I thought since it could be because being called only once in another function it might limit the recursion. But that does not make sense. I want to get this working to see if it would be possible to run a CSP type algorithm against it. Thanks for the help.

import pygame as pg
import random

pg.init()
HEIGHT, WIDTH = 400, 400
gameloop = True
TILESIZE = 25


class Tile:
    def __init__(self, pos):
        self.pos = pos
        self.bomb = False
        self.number = 0
        self.show = False

    def printAttr(self):
        print(self.bomb, self.pos, self.number)


def create_bomb(diction):
    b = []
    for i in range(1,41):
        x = random.randint(0, 15)
        y = random.randint(0, 15)
        while (x,y) in b:
            x = random.randint(0, 15)
            y = random.randint(0, 15)
        b.append((x,y))
    print(len(b))
    for item in b:
        diction[item].bomb = True
        if not diction[item].bomb:
            neighbors = [
                (x   1, y), (x - 1, y), (x, y   1), (x, y - 1), (x   1, y   1),
                (x   1, y - 1), (x - 1, y   1), (x - 1, y - 1)
            ]
            neighbors = [neighbor for neighbor in neighbors if validate_cell(neighbor)]
            for q in neighbors:
                if not diction[q].bomb:
                    diction[q].number  = 1
                else:
                    continue


def validate_cell(neighbor):
    if neighbor[0] < 0 or neighbor[1] < 0:
        return False
    elif neighbor[0] >= 16 or neighbor[1] >= 16:
        return False
    else:
        return True


def create_number(pos, diction):
    if not diction[pos].bomb:
        neighbors = [
            (x   1, y), (x - 1, y), (x, y   1), (x, y - 1), (x   1, y   1),
            (x   1, y - 1), (x - 1, y   1), (x - 1, y - 1)
        ]
        neighbors = [neighbor for neighbor in neighbors if validate_cell(neighbor)]
        count = 0
        for item in neighbors:
            if diction[item].bomb:
                count  = 1
            else:
                continue
        if count >= 0:
            diction[pos].number = count

def create_board_surf(dis, diction): #creating boaurd
    for x in range(16):
        for y in range(16):
            if diction[(x,y)].show == True:
                
                rect = pg.Rect(x * TILESIZE, y * TILESIZE, TILESIZE, TILESIZE)
                pg.draw.rect(dis, pg.Color("grey"), rect, 5)
                if diction[(x,y)].number > 0:
                    rect = pg.Rect(x * TILESIZE 7, y * TILESIZE-3, TILESIZE, TILESIZE)
                    font = pg.font.SysFont("timesnewroman", 25)
                    num = diction[(x,y)].number
                    text = font.render(str(num), False, pg.Color("black"))
                    dis.blit(text, rect)
            else:
                rect = pg.Rect(x * TILESIZE, y * TILESIZE, TILESIZE, TILESIZE)
                pg.draw.rect(dis, pg.Color("grey"), rect, 2)
            # if diction[(x,y)].bomb:
            #     rect = pg.Rect(x * TILESIZE, y * TILESIZE, TILESIZE, TILESIZE)
            #     font = pg.font.SysFont("timesnewroman", 25)
            #     text = font.render("B", False, pg.Color("black"))
            #     dis.blit(text, rect)


def chosen(pos):
    if diction[pos].bomb == True:
        diction[pos].show = True
        gameloop = False
        return gameloop 
    else:
        show(pos)
        gameloop = True
        return gameloop


def show(pos):
    if diction[pos].number == 0 and not diction[pos].show and not diction[pos].bomb:
        diction[pos].show = True
        neighbors = [
                (x   1, y), (x - 1, y), (x, y   1), (x, y - 1), (x   1, y   1),
                (x   1, y - 1), (x - 1, y   1), (x - 1, y - 1)
        ]
        neighbor1= [neighbor for neighbor in neighbors if validate_cell(neighbor)]

        for item in neighbor1:
            show(item)
        return
    if diction[pos].number > 0:
        diction[pos].show = True
        return


diction = {}
for x in range(16):
    for y in range(16):
        diction[(x, y)] = Tile([x, y])
create_bomb(diction)
for x in range(16):
    for y in range(16):
        create_number((x,y), diction)
dis = pg.display.set_mode((HEIGHT, WIDTH))
pg.display.update()
while gameloop:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            gameloop = False
        elif event.type == pg.MOUSEBUTTONDOWN:
            x, y = [int(v // TILESIZE) for v in pos]
            gameloop = chosen((x,y))
        pos = pg.Vector2(pg.mouse.get_pos())
        dis.fill(pg.Color("white"))
        create_board_surf(dis,diction)
        pg.display.flip()

CodePudding user response:

Your show-method doesnt know the (updated) value of the variables x and y, so it sets them to the value they had during the first call to show (note that it is only because they get defined as global variables that these initial values of x and y are visible throughout your call-stack - had your main game-loop been in a separate method you would probably have been warned that they were not initialized). Modify your show method as follows

def show(pos):
    if diction[pos].number == 0 and not diction[pos].show and not diction[pos].bomb:
        diction[pos].show = True
        x=pos[0]
        y=pos[1]
        neighbors = [
                (x   1, y), (x - 1, y), (x, y   1), (x, y - 1), (x   1, y   1),
                (x   1, y - 1), (x - 1, y   1), (x - 1, y - 1)
        ]
        neighbor1= [neighbor for neighbor in neighbors if validate_cell(neighbor)]

        for item in neighbor1:
            show(item)
        return
    if diction[pos].number > 0:
        diction[pos].show = True
        return

and I would expect your program to work.

  • Related