Once again with a new dice-problem, and a malfunctioning script in python.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • BurnTard
    New Member
    • May 2007
    • 52

    Once again with a new dice-problem, and a malfunctioning script in python.

    Hello, I have a problem that's hugely annoying. The other day, me and a friend made a program for creating a Dungons and Dragons roleplaying character, and after about a day of work, it was working properly. Only for us to find that it did not fully agree with the rules of the game, and it was slightly flawed, so I decided to write a new one. Only problem? Most of the time, while the program should give an output of six numbers, it only gives me anything between two and five. So does one of the great geek spot the problem? Please tell me, it would be a great help! :)

    So here's the temporary script:

    [CODE=Python]

    import random

    for n in range(1,7):

    d1=random.randi nt(1,6)
    d2=random.randi nt(1,6)
    d3=random.randi nt(1,6)
    d4=random.randi nt(1,6)


    for n in range(1):
    if d1<d2 and d1<d3 and d1<d4:
    print d2+d3+d4
    break


    elif d2<d1 and d2<d3 and d2<d4:
    print d1+d3+d4
    break


    elif d3<d1 and d3<d2 and d3<d4:
    print d1+d2+d4
    break


    elif d4<d1 and d4<d2 and d4<d3:
    print d1+d2+d3
    break


    elif d1==d2:
    if d1<d3:
    if d1<d4:
    print d2+d3+d4


    elif d1==d3:
    if d1<d2:
    if d1<d4:
    print d2+d3+d4


    elif d1==d4:
    if d1<d2:
    if d1<d3:
    print d2+d3+d4


    elif d2==d1:
    if d2<d3:
    if d2<d4:
    print d1+d3+d4


    elif d2==d3:
    if d2<d1:
    if d2<d4:
    print d1+d3+d4


    elif d2==d4:
    if d2<d1:
    if d2<d3:
    print d1+d3+d4


    elif d3==d1:
    if d3<d2:
    if d3<d4:
    print d1+d2+d4


    elif d3==d2:
    if d3<d1:
    if d3<d4:
    print d1+d2+d4


    elif d3==d4:
    if d3<d1:
    if d3<d2:
    print d1+d2+d4


    elif d4==d1:
    if d4<d2:
    if d4<d3:
    print d1+d2+d3

    elif d4==d2:
    if d4<d1:
    if d4<d3:
    print d1+d2+d3


    elif d4==d3:
    if d4<d1:
    if d4<d2:
    print d1+d2+d3


    elif d1==d2 and d1==d3:
    if d1<d4:
    print d2+d3+d4


    elif d1==d2 and d1==d4:
    if d1<d3:
    print d2+d3+d


    elif d1==d3 and d1==d4:
    if d1<d2:
    print d2+d3+d4


    elif d2==d1 and d2==d3:
    if d2<d4:
    print d1+d3+d4


    elif d2==d3 and d2==d4:
    if d2<d1:
    print d1+d3+d4


    elif d2==d1 and d2==d4:
    if d2<d3:
    print d1+d3+d4


    elif d3==d1 and d3==d2:
    if d3<d4:
    print d1+d2+d4


    elif d3==d2 and d3==d4:
    if d3<d1:
    print d1+d2+d4


    elif d3==d1 and d3==d4:
    if d3<d2:
    print d1+d2+d4


    elif d4==d1 and d4==d2:
    if d4<d3:
    print d1+d2+d3


    elif d4==d2 and d4==d3:
    if d4<d1:
    print d1+d2+d3


    elif d4==d1 and d4==d3:
    if d4<d2:
    print d1+d2+d3


    elif d1==d2 and d1==d3 and d1==d4 and d2==d1 and d2==d3 and d2==d4 and d3==d1 and d3==d2 and d3==d4 and d4==d1 and d4==d2 and d4==d3:
    print d1+d2+d3

    [/CODE]
  • Smygis
    New Member
    • Jun 2007
    • 126

    #2
    After removing several lines of code a realized that i culd not make sense of whats happening in youre code.

    And i do not know the rules of that game so i gave up.

    But there is a lot of strange things going on in that pace of code. And there is a lot of dead code in it aswell. No code after line 102 will ever be executet as far as i can see.

    But please, Dont use space to indent. Use tab. Or atleast 3+ spaces, Then i culd atleast have used find/replace.

    Comment

    • bartonc
      Recognized Expert Expert
      • Sep 2006
      • 6478

      #3
      Originally posted by Smygis
      After removing several lines of code a realized that i culd not make sense of whats happening in youre code.

      And i do not know the rules of that game so i gave up.

      But there is a lot of strange things going on in that pace of code. And there is a lot of dead code in it aswell. No code after line 102 will ever be executet as far as i can see.

      But please, Dont use space to indent. Use tab. Or atleast 3+ spaces, Then i culd atleast have used find/replace.
      Thank you, Smygis, for your input. However, tabs are not necessary. 4 spaces per indent is what most Python editors use.

      Comment

      • bvdet
        Recognized Expert Specialist
        • Oct 2006
        • 2851

        #4
        I cannot tell what your are trying to do with the large number of 'if' statements. If we could find out what your rules are, we might be able to make a suggestion. This will print six numbers:[code=Python]import random
        for n in range(6):

        dList = [random.randint( 1,6) for _ in range(4)]

        s = random.sample([0,1,2,3], 3)
        print dList[s[0]]+dList[s[1]]+dList[s[2]][/code]

        Comment

        • bartonc
          Recognized Expert Expert
          • Sep 2006
          • 6478

          #5
          Originally posted by BurnTard
          Hello, I have a problem that's hugely annoying. The other day, me and a friend made a program for creating a Dungons and Dragons roleplaying character, and after about a day of work, it was working properly. Only for us to find that it did not fully agree with the rules of the game, and it was slightly flawed, so I decided to write a new one. Only problem? Most of the time, while the program should give an output of six numbers, it only gives me anything between two and five. So does one of the great geek spot the problem? Please tell me, it would be a great help! :)
          Our newest contributor, Smygis, is quite correct. The stucture of you code needs help. We need to help you understand the use of loops and find a more structured way of setting up the rules of the game. However, most Python experts may not know the rules of the game. One thing your code really lacks is comments explaining what it should do. I'll have a brief look, but it will help us help you if you could expain each section of code with comments. Thanks.

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            I think I see that this[CODE=python]
            elif d3<d1 and d3<d2 and d3<d4:
            print d1+d2+d4
            break[/CODE]
            is intended to print 3 numbers but is written to print the total of them instead.[CODE=python]
            elif d3<d1 and d3<d2 and d3<d4:
            print d1, d2, d4
            break[/CODE]
            This would print 3 numbers and exit the loop.

            Comment

            • Smygis
              New Member
              • Jun 2007
              • 126

              #7
              Originally posted by bartonc
              Thank you, Smygis, for your input. However, tabs are not necessary. 4 spaces per indent is what most Python editors use.
              I however prefer tab, But i use a tab with of 4 spaces. And some editors dont use the tab char and simply replace the tab with (4) spaces. What i dont like is one space as indent, It gets hard to read the code in my opinion.

              Comment

              • bartonc
                Recognized Expert Expert
                • Sep 2006
                • 6478

                #8
                Originally posted by Smygis
                I however prefer tab, But i use a tab with of 4 spaces. And some editors dont use the tab char and simply replace the tab with (4) spaces. What i dont like is one space as indent, It gets hart to read the code in my opinion.
                I agree 100%.

                Thank you for joining us here at TheScripts.

                Comment

                • bartonc
                  Recognized Expert Expert
                  • Sep 2006
                  • 6478

                  #9
                  Here it is, re-indented. Just one command in Boa Constructor![CODE=python]import random

                  for n in range(1,7):

                  d1=random.randi nt(1,6)
                  d2=random.randi nt(1,6)
                  d3=random.randi nt(1,6)
                  d4=random.randi nt(1,6)


                  for n in range(1):
                  if d1<d2 and d1<d3 and d1<d4:
                  print d2+d3+d4
                  break


                  elif d2<d1 and d2<d3 and d2<d4:
                  print d1+d3+d4
                  break


                  elif d3<d1 and d3<d2 and d3<d4:
                  print d1+d2+d4
                  break


                  elif d4<d1 and d4<d2 and d4<d3:
                  print d1+d2+d3
                  break


                  elif d1==d2:
                  if d1<d3:
                  if d1<d4:
                  print d2+d3+d4


                  elif d1==d3:
                  if d1<d2:
                  if d1<d4:
                  print d2+d3+d4


                  elif d1==d4:
                  if d1<d2:
                  if d1<d3:
                  print d2+d3+d4


                  elif d2==d1:
                  if d2<d3:
                  if d2<d4:
                  print d1+d3+d4


                  elif d2==d3:
                  if d2<d1:
                  if d2<d4:
                  print d1+d3+d4


                  elif d2==d4:
                  if d2<d1:
                  if d2<d3:
                  print d1+d3+d4


                  elif d3==d1:
                  if d3<d2:
                  if d3<d4:
                  print d1+d2+d4


                  elif d3==d2:
                  if d3<d1:
                  if d3<d4:
                  print d1+d2+d4


                  elif d3==d4:
                  if d3<d1:
                  if d3<d2:
                  print d1+d2+d4


                  elif d4==d1:
                  if d4<d2:
                  if d4<d3:
                  print d1+d2+d3

                  elif d4==d2:
                  if d4<d1:
                  if d4<d3:
                  print d1+d2+d3


                  elif d4==d3:
                  if d4<d1:
                  if d4<d2:
                  print d1+d2+d3


                  elif d1==d2 and d1==d3:
                  if d1<d4:
                  print d2+d3+d4


                  elif d1==d2 and d1==d4:
                  if d1<d3:
                  print d2+d3+d


                  elif d1==d3 and d1==d4:
                  if d1<d2:
                  print d2+d3+d4


                  elif d2==d1 and d2==d3:
                  if d2<d4:
                  print d1+d3+d4


                  elif d2==d3 and d2==d4:
                  if d2<d1:
                  print d1+d3+d4


                  elif d2==d1 and d2==d4:
                  if d2<d3:
                  print d1+d3+d4


                  elif d3==d1 and d3==d2:
                  if d3<d4:
                  print d1+d2+d4


                  elif d3==d2 and d3==d4:
                  if d3<d1:
                  print d1+d2+d4


                  elif d3==d1 and d3==d4:
                  if d3<d2:
                  print d1+d2+d4


                  elif d4==d1 and d4==d2:
                  if d4<d3:
                  print d1+d2+d3


                  elif d4==d2 and d4==d3:
                  if d4<d1:
                  print d1+d2+d3


                  elif d4==d1 and d4==d3:
                  if d4<d2:
                  print d1+d2+d3


                  elif d1==d2 and d1==d3 and d1==d4 and d2==d1 and d2==d3 and d2==d4 and d3==d1 and d3==d2 and d3==d4 and d4==d1 and d4==d2 and d4==d3:
                  print d1+d2+d3
                  [/CODE]

                  Comment

                  • bartonc
                    Recognized Expert Expert
                    • Sep 2006
                    • 6478

                    #10
                    Here's something with a bit better stucture:[CODE=python]# import needed modules
                    import random

                    # define classes
                    class Die(object):
                    """A class representing a single six-sided die.
                    A die of this class has an optional name.
                    __init__() calls self.role() so creation produces a roled die."""

                    def __init__(self, name=""):
                    """Assign an optional name and role self."""
                    self.name = name
                    self.role()

                    def __cmp__(self, other):
                    # overload the compare operation for ==, !=, <, >, etc #
                    return cmp(self.value, other.value)

                    def __repr__(self):
                    """Identify self and report value when printed."""
                    return "My name is %s. My value is %d" %(repr(self.nam e), self.value)


                    def role(self):
                    """Assign a random value between 1 and 6 to the value of this instance."""
                    self.value = random.randint( 1,6)

                    def get(self):
                    """Just return the value of this instance."""
                    return self.value

                    ### define utility functions ###
                    def RoleDice(dice):
                    """Given a list of die to role, role them.
                    Since lists are mutable, don't actually return the list."""
                    for die in dice:
                    die.role()

                    def PrintDice(dice) :
                    """Call each die's __repr__() method with print."""
                    for die in dice:
                    print die


                    ### Define rules ###
                    def AllEqual(dice):
                    """True or False: Are all the dice of equal value?"""
                    for i in range(len(dice) - 1):
                    if dice[i] != dice[i + 1]:
                    # if any one is NOT EQUAL to another, the answer is false!
                    return False
                    # if it makes it this far, they are all equal
                    return True


                    ### Create objects to work with ###
                    # a list of dice names
                    diceNames = ['First', 'Second', 'Third', 'Forth']

                    # a list of named dice
                    dice = [Die(name) for name in diceNames]

                    # test compare #
                    dice[0].value = 4
                    dice[1].value = 4
                    print dice[0] == dice[1]

                    # test object creation
                    PrintDice(dice)
                    print

                    # test utility functions and rules
                    for i in range(5): # run 5 tests
                    RoleDice(dice)
                    PrintDice(dice)
                    print "All dice are %s equal" %["not", ""][AllEqual(dice)]
                    print[/CODE]with a class and doc strings thrown in for free!

                    Comment

                    • BurnTard
                      New Member
                      • May 2007
                      • 52

                      #11
                      Originally posted by bartonc
                      I think I see that this[CODE=python]
                      elif d3<d1 and d3<d2 and d3<d4:
                      print d1+d2+d4
                      break[/CODE]
                      is intended to print 3 numbers but is written to print the total of them instead.[CODE=python]
                      elif d3<d1 and d3<d2 and d3<d4:
                      print d1, d2, d4
                      break[/CODE]
                      This would print 3 numbers and exit the loop.

                      No, it is meant to print the sum. I know the code is rather messy. It started out pretty clean, but as my aggression built, my neatness decreased, and whenever it returned the wrong answer, I felt an urge to add more code. With all the "dead code" done, it gives an output of six numbers about half of the time. I'll see what I can do about comments and neatness though.

                      Comment

                      • BurnTard
                        New Member
                        • May 2007
                        • 52

                        #12
                        Originally posted by bartonc
                        Here's something with a bit better stucture:[CODE=python]# import needed modules
                        import random

                        # define classes
                        class Die(object):
                        """A class representing a single six-sided die.
                        A die of this class has an optional name.
                        __init__() calls self.role() so creation produces a roled die."""

                        def __init__(self, name=""):
                        """Assign an optional name and role self."""
                        self.name = name
                        self.role()

                        def __cmp__(self, other):
                        # overload the compare operation for ==, !=, <, >, etc #
                        return cmp(self.value, other.value)

                        def __repr__(self):
                        """Identify self and report value when printed."""
                        return "My name is %s. My value is %d" %(repr(self.nam e), self.value)


                        def role(self):
                        """Assign a random value between 1 and 6 to the value of this instance."""
                        self.value = random.randint( 1,6)

                        def get(self):
                        """Just return the value of this instance."""
                        return self.value

                        ### define utility functions ###
                        def RoleDice(dice):
                        """Given a list of die to role, role them.
                        Since lists are mutable, don't actually return the list."""
                        for die in dice:
                        die.role()

                        def PrintDice(dice) :
                        """Call each die's __repr__() method with print."""
                        for die in dice:
                        print die


                        ### Define rules ###
                        def AllEqual(dice):
                        """True or False: Are all the dice of equal value?"""
                        for i in range(len(dice) - 1):
                        if dice[i] != dice[i + 1]:
                        # if any one is NOT EQUAL to another, the answer is false!
                        return False
                        # if it makes it this far, they are all equal
                        return True


                        ### Create objects to work with ###
                        # a list of dice names
                        diceNames = ['First', 'Second', 'Third', 'Forth']

                        # a list of named dice
                        dice = [Die(name) for name in diceNames]

                        # test compare #
                        dice[0].value = 4
                        dice[1].value = 4
                        print dice[0] == dice[1]

                        # test object creation
                        PrintDice(dice)
                        print

                        # test utility functions and rules
                        for i in range(5): # run 5 tests
                        RoleDice(dice)
                        PrintDice(dice)
                        print "All dice are %s equal" %["not", ""][AllEqual(dice)]
                        print[/CODE]with a class and doc strings thrown in for free!

                        Woah, that is way to complicated for me! I only got into Python some two weeks ago, if that long, and I have no idea what a class is, and definitions are way above me! Please, try to keep it simple!

                        Comment

                        • bartonc
                          Recognized Expert Expert
                          • Sep 2006
                          • 6478

                          #13
                          Originally posted by BurnTard
                          No, it is meant to print the sum. I know the code is rather messy. It started out pretty clean, but as my aggression built, my neatness decreased, and whenever it returned the wrong answer, I felt an urge to add more code. With all the "dead code" done, it gives an output of six numbers about half of the time. I'll see what I can do about comments and neatness though.
                          Here's how a list of objects could help you solve the first part:[CODE=python]

                          def AddLowest(nItem s, dice):
                          tmpList = sorted(dice)
                          valueList = [die.get() for die in tmpList[0:nItems]]
                          return sum(valueList), tmpList[0:nItems]

                          ### Create objects to work with ###
                          # a list of dice names
                          diceNames = ['First', 'Second', 'Third', 'Forth', 'Fifth', 'Sixth', 'Seventh']

                          # a list of named dice
                          dice = [Die(name) for name in diceNames]

                          testResult = AddLowest(3, dice)

                          print "The sum of the lowest 3 dice is %d" %testResult[0]
                          print "The lowest 3 dice are:"
                          for die in testResult[1]:
                          print die
                          print[/CODE]
                          with lots of test code thrown in for free!

                          Comment

                          • BurnTard
                            New Member
                            • May 2007
                            • 52

                            #14
                            Okay, so I'm obviously not allowed to edit the first post... Well, I realize that I failed spectacularly in actually telling you guys what the script should do... Here is what the recipe is supposed to mean, if you were to do it in real life:

                            Roll four six-sided dice
                            ignore the smallest
                            add up the remaining, and note the result

                            do over until you have got six values

                            now this seemed rather simple to me at first, but I allways missed something, and when an event occurs that the script does not anticipate, apparently, it just breaks the loop and starts at the wee beginning. The script as it was when I first thought I was finished looked somewhat like this:

                            [Code=Python]
                            import random


                            d1="" # Most of the time I have to add these at the top of the script as I go, because otherwise the program gives me the outputs like "d1 not defined", because it didn't bother to roll the dice before checking the program for errors or some such nonsense...
                            d2=""
                            d3=""
                            d4=""



                            for n in range(1,7): # So it does it six times of course

                            d1=random.randi nt(1,6) # Rolls a six sided die
                            d2=random.randi nt(1,6) # Rolls a second six-sided die
                            d3=random.randi nt(1,6)
                            d4=random.randi nt(1,6)

                            for n in range(1): # Just to create a loop which can be broken

                            if d1<d2 and d1<d3 and d1<d4: # As in "if d1 is smallest"
                            print d2+d3+d4 # Sums them up and prints them
                            break # If I'm not wrong, this breaks the "for n in range(1)" loop, and goes to the second part of the "for n in range(1,7)" loop.

                            elif d2<d1 and d2<d3 and d2<d4: # As in if the second die is smallest
                            print d1+d3+d4
                            break

                            elif d3<d1 and d3<d2 and d3<d4:
                            print d1+d2+d4
                            break

                            elif d4<d1 and d4<d2 and d4<d3:
                            print d1+d2+d3
                            break

                            elif d1==d2==d3==d4: # This is the short version, as you might have seen from the previous one. I tried this one first, but I don't think it does what I want it to...
                            print d1+d2+d3 # If they're all alike, it matters not which one I ignore
                            # And since this is the end, I should not have to break a loop, when it only repeats once anyways. Oh well....
                            break

                            [/code]

                            So there it is, all properly indented and commented. My eyes fail to recognize the fault, but mayhap one of the hawks among you can?

                            Comment

                            • BurnTard
                              New Member
                              • May 2007
                              • 52

                              #15
                              Originally posted by bartonc
                              Here's how a list of objects could help you solve the first part:[CODE=python]

                              def AddLowest(nItem s, dice):
                              tmpList = sorted(dice)
                              valueList = [die.get() for die in tmpList[0:nItems]]
                              return sum(valueList), tmpList[0:nItems]

                              ### Create objects to work with ###
                              # a list of dice names
                              diceNames = ['First', 'Second', 'Third', 'Forth', 'Fifth', 'Sixth', 'Seventh']

                              # a list of named dice
                              dice = [Die(name) for name in diceNames]

                              testResult = AddLowest(3, dice)

                              print "The sum of the lowest 3 dice is %d" %testResult[0]
                              print "The lowest 3 dice are:"
                              for die in testResult[1]:
                              print die
                              print[/CODE]
                              with lots of test code thrown in for free!

                              Ur... So... I didn't get that. I fell out, like, when you defined AddLowest

                              Comment

                              Working...