0

This is an attempt a Rubik’s Cube scramble generator. I sometimes get turns of the same face one after the other for example (R,R'). I attempted to fix this using a for and while loop but it didn't work.

import random
def getscramble():
  moves = ["R","F","U","L","B","D"]
  scramble = []
  finascramble = []

  for x in range(25):
     scramble.append(random.choice(moves))


  for x in range(0,len(scramble)-1):
      if scramble[x] == scramble[x+1]:
        scramble[x] = random.choice(moves)

  for x in range(0,len(scramble)-1):
     if scramble[x] == "R" and scramble[x+1] == "L":
          scramble[x+1] = random.choice(moves)
     if scramble[x] == "U" and scramble[x+1]== "D":
          scramble[x+1] == random.choice(moves)
     if scramble[x] == "F" and scramble[x+1] == "B":
          scramble[x+1] == random.choice(moves)

  modifiers = ["","2","'"]

  for x in range(25):
    randy = random.randint(0,2)
    finascramble.append(scramble[x]+modifiers[randy])
  return " ".join(finascramble)

t = True
while t == True:
  again = input()
  if again == "s":
       print()
       print(getscramble())
St1gor
  • 3
  • 3

3 Answers3

0

I offer you this solution:

import random

MOVES = ['R', 'L', 'D', 'U', 'B', 'F']
MODFIERS = ['', '2', "'"]


def getScramble(length=25):
    return ''.join([random.choice(MOVES) for _ in range(length)])


def isValid(scramble):
    for seq in ['LR', 'DU', 'BF'] + [move * 2 for move in MOVES]:
        if seq in scramble or seq[::-1] in scramble:
            return False
    return True


while True:
    scramble = getScramble()
    if isValid(scramble):
        break

scramble = ' '.join([move + random.choice(MODFIERS) for move in scramble])
print(scramble)
0

I've rewritten your scramble function to be a little more efficient and fully working according to your expectations.

import random

moves = ("R", "F", "U", "L", "B", "D")
modifiers = ("", "2", "'")


def getscramble(n=25):

    scramble = random.choices(moves, k=n)

    def is_valid(c, c2):
        together = c + c2
        return (c != c2 and together not in
                ("RL", "UD", "FB", "LR", "DU", "BF"))

    for x in range(1, n):
        before = scramble[x - 1]
        current = scramble[x]
        while not is_valid(before, current):
            current = scramble[x] = random.choice(moves)

    for i, x in enumerate(random.choices(modifiers, k=n)):
        scramble[i] += x

    return " ".join(scramble)
Bharel
  • 23,672
  • 5
  • 40
  • 80
0

You can not append the list if last value appended was the same.

Here is a better while loop that does what you want:

i = len(scramble)
while i < 25:
    current_face = random.choice(moves)
    if i == 0:
        scramble.append(current_face)
    elif scramble[i - 1] == current_face:
        continue
    else:
        scramble.append(current_face)
    i += 1
    print(' '.join(scramble))

This loop ensure list is of fixed length. You can add your modifiers to this list.

But.. If you're not married to the concept of using modifiers, the best thing to do for the sake of randomness and simplicity would be to use above loop with long list with all possible permutations.

import random


def getscramble():
    moves = ["R", "F", "U", "L", "B", "D",
             "R'", "F'", "U'", "L'", "B'", "D'",
             "R2", "F2", "U2", "L2", "B2", "D2"]
    scramble = []

    i = len(scramble)
    while i < 25:
        curent_face = random.choice(moves)
        if i == 0:
            scramble.append(curent_face)
        elif (scramble[i - 1])[0] == curent_face[0]:
            continue
        else:
            scramble.append(curent_face)
        i += 1

     print(' '.join(scramble))


 getscramble()

Output of above code is:

L' R D2 U L' U' F R2 L' U2 D' R' F' B2 F2 L2 R' D' L2 F' U2 F U2 R D