Brewcious
Brewcious

Reputation: 25

Odd random.randint behavior

I wrote a program to create the appearance of a snake sliding down the screen. You can pass in a width and length for the path the snake travels down. The snake moves at random staying within the width confines given.

All works fairly well, except when testing my guard rails to keep the snake within the defined width. I noticed at times the snake position (left_side) appears to be able to go to a negative value. Given that I have a guard rail that when left_side == 0 it should only be able to move back right given that when that condition is true my only values I can add to is should be 0 or 1.

How do I fix this?

My code:

import random
import time

def path(path_width, snake_pos):
    path = ""
    for space in range(path_width + 1):
        if space == 0:
            path = path + "|"
        if space == snake_pos:
            path = path + "()"
        if space == width: 
            path = path + "|"
        else:
            path = path + " "
    return path

width = int(input("How wide is your course? "))
length = int(input("How long is your course? "))

left_side = random.randint(1, width -1)

i=1
while i < length:
    if left_side == 0:
        left_side = left_side + random.randint(0, 1)
    if left_side == width:
        left_side = left_side + random.randint(-1, 0)
    else:
        left_side = left_side + random.randint(-1, 1)
    print(path(width, left_side) + " : leftside = " + str(left_side))
    i += 1
    time.sleep(.05)

Upvotes: 1

Views: 127

Answers (1)

Picachieu
Picachieu

Reputation: 3782

The problem with your guard rail lies here:

if left_side == 0:
    left_side = left_side + random.randint(0, 1)
if left_side == width:
    left_side = left_side + random.randint(-1, 0)
else:
    left_side = left_side + random.randint(-1, 1)

The problem is that you're using an if/if/else workflow; if the first if condition is met, it will execute the code within, and then check the second if statement and execute either that code, or the code in the attached else block.

Here's the current workflow of your code: it checks if left_side is 0, and if so adds either 0 or 1 to left_side. It then checks if left_side is equal to width. If it is, then either -1 or 0 will be added to left_side. If it isn't, then the else statement will be executed and either -1, 0, or 1 will be added to left_side.

This means that every iteration of the loop, left_side has a chance of being decreased by one, because either the second if block or the else block below it will execute every iteration, and the random.randint statement in both has the chance to evaluate to -1.

The solution is simply to change the second if statement to an elif statement, like so:

if left_side == 0:
    left_side = left_side + random.randint(0, 1)
elif left_side == width:
    left_side = left_side + random.randint(-1, 0)
else:
    left_side = left_side + random.randint(-1, 1)

Now, if the first condition (left_side == 0) is met, it will not check if left_side == width in the same iteration of the loop, meaning left_side will not be decreased in that iteration.

Upvotes: 6

Related Questions