简体   繁体   中英

Check for duplicates in a randomly generated list and replace them

I am making a minesweeper game with randomly generated bombs. Yet at times I have found that there are duplicates in my list of coordinates of bombs. How do I check for duplicates in a list and replace them with other randomised coordinates.

from random import randint

def create_bombpos():
    global BOMBS, NUM_BOMBS, GRID_TILES
    for i in range(0, NUM_BOMBS):
        x = randint(1, GRID_TILES)
        y = randint(1, GRID_TILES)
        BOMBS.append((x, y))
    print(BOMBS)

The user can decide how big the board is by input of GRID_TILES . If they input 5, the board will be 5x5. The ammount of bombs is:

GRID_TILES * GRIDTILES / 5

Searching each time through your whole BOMBS list would cost you O(n) (linear time). Why don't you use a set instead? a Set guarantees that you ll end up with distinct (in terms of hashing) elements.

from random import randint

def create_bombpos():
BOMBS = set()
i = 0
while i<NUM_BOMBS:
   x = randint(1, GRID_TILES)
   y = randint(1, GRID_TILES)
   if (x,y) not in BOMBS
       BOMBS.add((x, y))
       i = i + 1
print(BOMBS)

Let me give u an example of a set:

>>> a = set()
>>> a.add((1,2))
>>> a
{(1, 2)}
>>> a.add((1,2))
>>> a.add((1,3))
>>> a.add((1,2))
>>> a
{(1, 2), (1, 3)}

I can add the same element to a set many times, but only 1 instance will be present.

from random import randint

def create_bombpos():
    global BOMBS, NUM_BOMBS, GRID_TILES
    i = 0
    while i<NUM_BOMBS:
       x = randint(1, GRID_TILES)
       y = randint(1, GRID_TILES)
       if (x,y) not in BOMBS
           BOMBS.append((x, y))
           i = i + 1
    print(BOMBS)

If the newly generated point is already in the list, then i won't get incremented, and we will find another newly generated point, till it is not present in BOMBS .

Hope it helps!!

You could also use random.sample to achieve this:

from random import sample

GRID_TILES = 100
NUM_BOMBS = 5

indexes = sample(range(GRID_TILES * GRID_TILES), NUM_BOMBS)
BOMBS = [(i // GRID_TILES, i % GRID_TILES) for i in indexes]

Use a python set for this, it will automatically check for duplicates and simply ignore every entry that already is in the list. I also think the runtime is much better than using a list and checking for duplicates manually.

Link: https://docs.python.org/2/library/sets.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM