[solved]checking for duplicate variable values in a list and adjusting them via user input

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

[solved]checking for duplicate variable values in a list and adjusting them via user input

#1 Post by Scribbles »

What is the best way in renpy to create an event if two or more variables equal each other in a list? so...

Code: Select all

## throughout the game these variable values are adjusted
default a = 0
default b = 0
default c = 0
default d = 0

## a variable to reflect the outcome of the two highest variables (see below)
default option = 0

#the default list
default my_list = [a, b, c, d]


init python:
    def list_test():
        ##all my global variables
        temp_list = []
        
        #to order the highest variables first
        my_list.sort(reverse=True)
        
        ## I would like to test for duplicates here, and if found offer a menu option as a tie breaker
        ## How would I do that???? 
        
        ## to make a new list of the highest two variables
        temp_list.append(my_list[0])
        temp_list.append(my_list[1])
        
        if a in temp_list and b in temp_list:
            option = 1
        if a in temp_list and c in temp_list:
            option = 2
        if a in temp_list and d in temp_list:
            option = 3
        if b in temp_list and c in temp_list:
            option = 4
        if b in temp_list and d in temp_list:
            option = 5
        if c in temp_list and d in temp_list:
            option = 6
        

I am sort of familiar with for/while loops, but I haven't gotten the hang of them yet. I feel like the answer is probably there but I can't figure it out > < any help would be appreciated!
Image - Image -Image

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#2 Post by Scribbles »

M brother helped me design an algorithm to test for it, I'll post my solution for it later in case anyone else needs to know such a weird specific thing > < lol (yay for smart little brothers!)
Image - Image -Image

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#3 Post by Scribbles »

My solution is very... involved... but I'll share in case anyone else ever needs it.

basically takes a list with 4 values, and finds the two highest values, and if there is a tie between the highest or 2nd highest value, offer a tie breaker with user input (allowing the user to break the tie), and then offers 6 outcomes

it works unless all the values stay at 0, it may be too redundant or something but it's what I managed to do lol (i tried to remove my custom variables so it could be easier to read, so if there is a weird one somewhere it's probably one i forgot.... > <)

Code: Select all


default a = 0
default b = 0
default c = 0
default d = 0

my_list = []

label start:
    ## all your code for stuff

    label t_i_test:
        ## Determines if a tie breaker is needed - should be a loop until the tie breaker is no longer needed.
        $ tie_breaker_determine()
        
        if tie_breaker_needed:
            call screen tie_breaker
            jump t_i_test
        else:
            hide screen tie_breaker
    ## test for the outcome
    $ outcome_test()
    

Code: Select all


## the screen code for the tie breaker:

screen tie_breaker():
    
    tag menu
    
    ## This pulls up and allows the player to select to add to the values in order to break the tie
    
    vbox:
        xalign 0.5 
        yalign 0.5

        text "Tie Breaker" 
        if a_max:
            textbutton "A" action [SetVariable("a", a + 1), Return()] 
        if b_max:
            textbutton "B" action [SetVariable("b", b + 1), Return()] 
        if c_max:
            textbutton "C" action [SetVariable("c", c + 1), Return()] 
        if d_max:
            textbutton "D" action [SetVariable("d", d + 1), Return()] 

NOW for all of the functions..... there are a lot....

Code: Select all

            
init python:
    def change_temp_list(str):
        global temp_list
        global my_list
        int = len(temp_list)

        ## This either empties or fills the list depending on the parameter provided, I did this so I didn't have to make a million temp_list variables and worry    
        ## about them over lapping
        
        if str == "empty":
            if int == 0:
                pass
            else:
                while int > 0:
                    for i in temp_list:
                        temp_list.remove(i)
                        int -= 1
                    
        if str == "fill":
            my_list_calc()
            for i in my_list:
                temp_list.append(i)
                
init python:
    def my_list_calc():
        global my_list
        global a
        global b
        global c
        global d

        ## this adds the values, and removes the leftover so the list stays at 4 items (otherwise it just continues to add values)
        
        my_list.insert(0, a)
        my_list.insert(1, b)
        my_list.insert(2, c)
        my_list.insert(3, d)
        my_list= my_list[:4]
            
init python:
    def find_highest_values():
        global my_list
        global max_value
        global max_value_2
        global temp_list

        ## This finds the two highest values in the list
        
        ## empty the temp list
        change_temp_list("empty")
        
        ##make sure to calculate the list items
        my_list_calc()
        
        ## put the my_list info into the temp list
        change_temp_list("fill")
            
        ## find the first maximum value
        max_value = max(temp_list)
        
        ## Remove list elements that are = to max_value
        temp_list = [x for x in temp_list if x != max_value]
                
        ## Get's the 2nd maximum value
        if len(temp_list) > 1:
            max_value_2 = max(temp_list)
        if len(temp_list) == 0:
            max_value_2 = 0
        if len(temp_list) == 1:
            max_value_2 = temp_list[0]
            
init python:
    def tie_breaker_determine():
        global my_list
        global tie_breaker_needed
        global max_value
        global max_value_2
        global num_of_max_values
        global num_of_max_values_2
        global temp_list

        ## This determines if the tie breaker is needed
        
        ##Clear out temp_list
        change_temp_list("empty")
        
        ##make sure to calculate the my_list values
        my_list_calc()
        
        ## put the my_list info into the temp list
        change_temp_list("fill")
        
        ## Find Max_1 and Max_2
        find_highest_values()
        
        ## refill the list
        change_temp_list("empty")
        change_temp_list("fill")
        
        ## Start at 0 so this can be adjusted
        num_of_max_values = 0
        num_of_max_values_2 = 0
        
        ## count the number of max values in the list
        for i in temp_list:
            if i == max_value:
                num_of_max_values += 1
        
        ## count the number of 2nd max values in the list
        if max_value_2 == 0:
            num_of_max_values_2 = 0
        else:
            for i in temp_list:
                if i == max_value_2:
                    num_of_max_values_2 += 1
                
    ## Test Passed:
        
        ## NO DUPLICATES!!
        if num_of_max_values <= 1 and num_of_max_values_2 <= 1:
            tie_breaker_needed = False
            
    ## Test Failed:
        if num_of_max_values >= 2 or num_of_max_values_2 >= 2: 
            tie_breaker_needed = True
            ## This function is for adding the right values to the tie breaker screen
            tie_breaker_screen_test(1)
        if num_of_max_values_2 >=2:
            tie_breaker_needed = True
            ## This function is for adding the right values to the tie breaker screen
            tie_breaker_screen_test(2)
                
init python:
    def tie_breaker_screen_test(num):
        global a
        global b
        global c
        global d
        global a_max
        global b_max
        global c_max
        global d_max
        global max_value
        global max_value_2
        
        if num == 1:
            if a == max_value:
                a_max = True
            if b == max_value:
                b_max = True
            if c == max_value:
                c_max = True
            if d == max_value:
                d_max = True
            
        if num == 2:
            if a == max_value_2:
                a_max = True
            if b == max_value_2:
                b_max = True
            if c == max_value_2:
                c_max = True
            if d == max_value_2:
                d_max = True
                
init python:
    def outcome_test():
        global a
        global b
        global c
        global d
        global temp_list
        global outcome
        global max_value
        global max_value_2

        ##Outcome test
        
        change_temp_list("empty")
        
        temp_list.append(max_value)
        temp_list.append(max_value_2)
        
        if a in temp_list and b in temp_list:
            outcome = "1"
        elif a in temp_list and c in temp_list:
            outcome = "2"
        elif a in temp_list and d in temp_list:
            outcome = "3"
        elif b in temp_list and c in temp_list:
            outcome = "4"
        elif b in temp_list and d in temp_list:
            outcome = "5"
        elif c in temp_list and d in temp_list:
            outcome = "6"
        else:
            outcome = "FUNCTION RUN ERROR"

Image - Image -Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#4 Post by trooper6 »

I think there is a way easier way to do this. Let me ponder this a bit and get back to you.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#5 Post by Scribbles »

trooper6 wrote: Thu Aug 10, 2017 4:23 pm I think there is a way easier way to do this. Let me ponder this a bit and get back to you.
quite possibly! lol I tested several possible values to make sure this would work, had a lot of issues with getting and evaluating the 2nd highest value when duplicates were involved, I also made the "outcome test" bit into a callable block so it makes for less code for me to write if I need it again. I'm only sort of getting the hang of lists, for loops, while loops, and iterations. Tried to make it into a dictionary, but it was too hard to fiddle with the values the way I needed to (that I knew of)
Image - Image -Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#6 Post by trooper6 »

Quick question...I assume you only care about tie breaking the highest, right?
You wouldn't care about tie breaking if the numbers were 9, 5, 5, 4, is that correct?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#7 Post by trooper6 »

Okay, I made the code for you, using a dict for your data. I'm also assuming you mean to use this for love points or something like that.

So here is the code you'd want to add, the function and the screen, along with a little tester function and code testing it:

Code: Select all

default points = {"Alex":0, "Basil":0, "Chuck":0, "Dex":0}

init python:
    def tie_check(): #Used to check for ties
        global points
        value_list = points.values() #make a list of all the vaules in your dict (the numbers in our case)
        value_set = set(value_list) #make a set of the list...remember, sets can't have dupes, so if there are dupes, they won't be added
        tied_keys = set() #make an empty set where we will store the highest keys (name) later
        if len(value_list) != len(value_set): #if the lenght of the set and the length of the list are not the same there are dupes
            if (len(value_set) == 1) and (0 in value_set) : #if there is only one number and it's 0, they are all and we don't do anything
                pass
            else: #if we get here it is because there are dupes in the set and they aren't all 0, so we have to figure out who the leaders
                for k1,v1 in points.items(): #loop though the list
                    for k2, v2 in points.items(): #loop through it a second time
                        if (v1 < v2): #compare each value with each value in the list, if it is less than any number we break
                            break
                    else:
                        tied_keys.add(k1) #if a number doesn't cause a break, it is the highest and its name is added to the tied_keys set. 
                if len(tied_keys) > 1: #check to see if there is more than one person in our tied_keys set, if so we call tie_breaker screen
                    renpy.call_screen("tie_breaker", items=tied_keys) #you pass along the list of names of people who are tied for the lead
                    
    def print_points(): #this is here for testing purposes. Keep it to run the code posted below, but you can drop it for your project
        global points
        list_string = ""
        for k,v in points.items(): #all his does is spit out all your points so you can see everything is working
            list_string += "{0}: {1}\n".format(k,v)
        renpy.say(None, list_string)

screen tie_breaker(items): #here is your tie breaker screen
    style_prefix "choice" #it uses the same style as the choice menu...you don't have to do that, but I thought it looked nice
    vbox:
        text "Who do you like best?" xalign 0.5
        for i in items:
            textbutton "[i]" action [SetDict(points, i, points[i]+1), Return()] #this makes the list of buttons 
            #the action is to increase the value in the dict for the person you choose and then close the screen

# The game starts here.
label start:  
    "We begin by seeing all the points at 0"
    $print_points()
    $tie_check()
    "You shouldn't see a menu because there are no ties for the first ranked person. 
     We aren't going to test if all the points are tied at 0."
    
    "Now we add 2 points to Alex and check again"
    $ points["Alex"] += 2 #this is how you add value to a dict, in case you didn't know.
    $print_points()
    $tie_check()
    "You shouldn't see a menu because while there are duplicate 0s, there is no tie among the top ranked person."

    "Now we add 2 points to Chuck and check again"
    $ points["Chuck"] += 2
    $print_points()
    $tie_check()
    "You should have seen a menu asking you to break the tie between Alex and Chuck."

    "now we add 1 point to Basil"
    $ points["Basil"] += 1
    $print_points()
    $tie_check()
    "You shouldn't have seen a menu becaue there are no dupes."
    
    "over"

    return


I recommend putting this code in a new project to test it out and then taking the screen and the tie_breaker function into your game.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#8 Post by Scribbles »

it doesn't work if there are more than 2 dupes, (if there are three or more, it doesn't call the screen, and if the second highest value is a dupe it doesn't call the screen) so 3,3,3,3 will call the screen once to change it to 3,3,3,4 but then stop, and if it's 4,3,3,2, it won't call it again to break the tie between 3 and 3

it's actually 4 personality traits, and the two highest traits assign one of 6 possible careers. (Kindness, Strength, Intelligence, Confidence)(medicine - K&I, sociology - K&C, security - S&I, science - I&C, agriculture - K&S, maintenance - S&C)

I will look over your code and see if I can adapt it to detect the second highest value and if there is a tie (unless there is already a way in there and I'm just not seeing it or getting it to work right > < )

ETA:

as for the tie breaker, at a point I want the player to take a "test" which really just calculates their personality traits that have been established while they played previously, and then if there are ties a screen would appear saying "Extra Credit!" and offer options (like which picture do you like better?) which would adjust the values. and then after the "test" was over they would be told their assigned career (but it would be based on how they had played the game so far -- so no actual test/questions unless there was a tie)
Image - Image -Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#9 Post by trooper6 »

I wrote it to not care about more than two dupes because I thought you were doing a boyfriend affection point thing. I asked to clarify, but didn't hear back, so just went forward with the tie breaker for the top dupe only. It should be pretty trivial to adjust it. Let me give a quick look. I'll try to do it right now, but if I run out of time before having to get to work, I'll do it in the evening.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#10 Post by Scribbles »

trooper6 wrote: Fri Aug 11, 2017 11:07 am I wrote it to not care about more than two dupes because I thought you were doing a boyfriend affection point thing. I asked to clarify, but didn't hear back, so just went forward with the tie breaker for the top dupe only. It should be pretty trivial to adjust it. Let me give a quick look. I'll try to do it right now, but if I run out of time before having to get to work, I'll do it in the evening.
ah sorry about that, I'm going to look into it now, but you'll probably find a solution before I do, thanks for your help!
Image - Image -Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#11 Post by trooper6 »

Before I post my code, let me ask, do you want tie breakers if all the numbers are 0 or no?
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#12 Post by trooper6 »

I have to head to work now and won't be back for a couple of hours so I'm posting my code now. It doesn't tie break if all the numbers are 0. It also tie breaks from the lowest number to the highest.

Code: Select all

    def tie_check(): #Used to check for ties
        global points
        tied_keys = set() 
        tied_num = "empty"
        are_dupes = True
        while are_dupes:
            value_list = points.values() 
            value_set = set(value_list) 
            if len(value_list) == len(value_set):
                are_dupes = False
            else:
                if (len(value_set) == 1) and (0 in value_set):
                    are_dupes = False
                else:
                    tied_keys.clear()
                    tied_num = "empty"
                    for k1,v1 in points.items():
                        for k2, v2 in points.items(): 
                            if (v1 == v2) and (k1 != k2): 
                                if tied_num == "empty":
                                    tied_num = v1
                                if v1 < tied_num:
                                    tied_num = v1
                                    tied_keys.clear()
                                if v1 == tied_num:
                                    tied_keys.add(k1)                                 
                    renpy.call_screen("tie_breaker", items=tied_keys)
                    tied_keys.clear()
                    tied_num = "empty"
Though I haven't tested it, this should work if you want to tie break even if all the numbers are zeroes:

Code: Select all

    def tie_check(): #Used to check for ties
        global points
        tied_keys = set() 
        tied_num = "empty"
        are_dupes = True
        while are_dupes:
            value_list = points.values() 
            value_set = set(value_list) 
            if len(value_list) == len(value_set):
                are_dupes = False
            else:
                tied_keys.clear()
                tied_num = "empty"
                for k1,v1 in points.items():
                    for k2, v2 in points.items(): 
                        if (v1 == v2) and (k1 != k2): 
                            if tied_num == "empty":
                                tied_num = v1
                            if v1 < tied_num:
                                tied_num = v1
                                tied_keys.clear()
                            if v1 == tied_num:
                                tied_keys.add(k1)                                  
                renpy.call_screen("tie_breaker", items=tied_keys)
                tied_keys.clear()
                tied_num = "empty"
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#13 Post by Scribbles »

trooper6 wrote: Fri Aug 11, 2017 1:04 pm I have to head to work now and won't be back for a couple of hours so I'm posting my code now. It doesn't tie break if all the numbers are 0. It also tie breaks from the lowest number to the highest.

Code: Select all

    def tie_check(): #Used to check for ties
        global points
        tied_keys = set() 
        tied_num = "empty"
        are_dupes = True
        while are_dupes:
            value_list = points.values() 
            value_set = set(value_list) 
            if len(value_list) == len(value_set):
                are_dupes = False
            else:
                if (len(value_set) == 1) and (0 in value_set):
                    are_dupes = False
                else:
                    tied_keys.clear()
                    tied_num = "empty"
                    for k1,v1 in points.items():
                        for k2, v2 in points.items(): 
                            if (v1 == v2) and (k1 != k2): 
                                if tied_num == "empty":
                                    tied_num = v1
                                if v1 < tied_num:
                                    tied_num = v1
                                    tied_keys.clear()
                                if v1 == tied_num:
                                    tied_keys.add(k1)                                 
                    renpy.call_screen("tie_breaker", items=tied_keys)
                    tied_keys.clear()
                    tied_num = "empty"
Though I haven't tested it, this should work if you want to tie break even if all the numbers are zeroes:

Code: Select all

    def tie_check(): #Used to check for ties
        global points
        tied_keys = set() 
        tied_num = "empty"
        are_dupes = True
        while are_dupes:
            value_list = points.values() 
            value_set = set(value_list) 
            if len(value_list) == len(value_set):
                are_dupes = False
            else:
                tied_keys.clear()
                tied_num = "empty"
                for k1,v1 in points.items():
                    for k2, v2 in points.items(): 
                        if (v1 == v2) and (k1 != k2): 
                            if tied_num == "empty":
                                tied_num = v1
                            if v1 < tied_num:
                                tied_num = v1
                                tied_keys.clear()
                            if v1 == tied_num:
                                tied_keys.add(k1)                                  
                renpy.call_screen("tie_breaker", items=tied_keys)
                tied_keys.clear()
                tied_num = "empty"
Ah thank you! I'll test it out. All of the values being zero should never actually happen, so it's not too big of a deal. Thanks so much for your help!
Image - Image -Image

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#14 Post by Scribbles »

ok so it works wonderfully, I adjusted the tie breaker screen to include all of the traits (I thought that would be more user-friendly in case they were going for something specific)

the only thing I'd like to adjust now is having it break the while loop after the two highest are not tied vs none of them being tied. (otherwise the player could see the screen forever depending on how they answer, like if their lowest two scores are tied and they keep picking the traits of their higher two > < ) I'm going to try to comb over the code and figure it out. thanks for your help so far though, your code is way cleaner than what I had going on lol

This is what I've changed it to:

Code: Select all

          
init python:
    def tie_check(): #Used to check for ties
            global personality # the dictionary
            global q_value # question number
            tied_keys = set()  #a set which has no dupes
            tied_num = "empty" # a string
            are_dupes = True # a boolean
            
            ## while dupe values are true
            while are_dupes: 
                ## create a list with the trait values
                value_list = personality.values() 
                ## remove the dupes from the trait values
                value_set = set(value_list) 
                
                ## if the length of both lists are equal than there are no dupes
                if len(value_list) == len(value_set):
                    are_dupes = False
                        
                    
                else:
                    tied_keys.clear() ##clear the dupe key names
                    tied_num = "empty" ##the string
                    
                    ## for key 1 and value 1 in personality dictionary
                    for k1,v1 in personality.items():
                        ## for key 2 in value 2 in personality dictionary
                        for k2, v2 in personality.items(): 
                            ## if value 1 == value 2 and key 1 != key 2:
                            if (v1 == v2) and (k1 != k2): 
                                
                                ## test if the string is "empty"
                                if tied_num == "empty":
                                    ##change the string to value 1
                                    tied_num = v1
                                    
                                ## if value 1 is less than the tied number 
                                if v1 < tied_num:
                                    ## tied number = value 1
                                    tied_num = v1
                                    ## clear the tied keys list?
                                    tied_keys.clear()
                                   
                                ## if value 1 is = to the tied_num string
                                if v1 == tied_num:
                                    ## add the key to the tied_keys set
                                    tied_keys.add(k1)     
                                    
                    ## screen question count variable
                    q_value += 1
                    renpy.call_screen("tie_breaker", items=personality.keys())
                    ## clear the tied_keys list
                    tied_keys.clear()
                    ## reset the tied_num string to empty
                    tied_num = "empty"

init python:
    def career_test():
        global career
        global personality
        
        ## Function Variables
        max_value = 0
        max_value_2 = 0
        career_list = []
        temp_list = []
        
        ## will find if there is a tie and offer a screen if there is until there isn't
        tie_check()
        
        ## find the keys of the 2 highest values
        
        ## fill the list with the personality dictionary values
        temp_list = personality.values()
        ## find the first max value
        max_value = max(temp_list)
        ## remove the max value from the temp list
        temp_list = [x for x in temp_list if x != max_value]
        ## find the 2nd max value
        max_value_2 = max(temp_list)
        
        ## match the key to the value, add the key to a new list
        for k, v in personality.iteritems():
            if v == max_value:
                career_list.append(k)
            if v == max_value_2:
                career_list.append(k)
                
        if "Kindness" in career_list and "Strength" in career_list:
            career = "Agriculture"
        elif "Kindness" in career_list and "Intelligence" in career_list:
            career = "Medicine"
        elif "Kindness" in career_list and "Confidence" in career_list:
            career = "Sociology"
        elif "Strength" in career_list and "Intelligence" in career_list:
            career = "Security"
        elif "Strength" in career_list and "Confidence" in career_list:
            career = "Maintenance"
        elif "Confidence" in career_list and "Intelligence" in career_list:
            career = "Science"
        else:
            career = "FUNCTION RUN ERROR"
     
#here is your tie breaker screen       
screen tie_breaker(items): 
    
    style_prefix "choice" 
    vbox:
        text "Extra Credit Question " + str(q_value) xalign 0.5
        for i in items:
            textbutton "[i]" action [SetDict(personality, i, personality[i]+1), Return()] #this makes the list of buttons 

A lot of this is placeholder stuff for when I have the story fleshed out, I don't want everything to be so straight forward and blunt in the final game > <
Image - Image -Image

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: [solved]checking for duplicate variable values in a list and adjusting them via user input

#15 Post by Scribbles »

@trooper6

I got it working the way I wanted to by combining your code and mine ><;;;;;; it only took me 2 days

Code: Select all

### CAREER TEST FUNCTION 
init python:
    def career_test():
        global personality
        global max_value
        global max_value_2
        global career
        career_list = []
        
        find_highest_values()
        tie_breaker_determine()
        call_for_extra_credit()
        
        ## match the key to the value, add the key to a new list
        for k, v in personality.iteritems():
            if v == max_value:
                career_list.append(k)
            if v == max_value_2:
                career_list.append(k)
                
        if "Kindness" in career_list and "Strength" in career_list:
            career = "Agriculture"
        elif "Kindness" in career_list and "Intelligence" in career_list:
            career = "Medicine"
        elif "Kindness" in career_list and "Confidence" in career_list:
            career = "Sociology"
        elif "Strength" in career_list and "Intelligence" in career_list:
            career = "Security"
        elif "Strength" in career_list and "Confidence" in career_list:
            career = "Maintenance"
        elif "Confidence" in career_list and "Intelligence" in career_list:
            career = "Science"
        else:
            career = "FUNCTION RUN ERROR"
        
### FINDS TWO HIGHEST VALUES  
init python:
    def find_highest_values():
        global personality
        global max_value
        global max_value_2
        temp_list = []

        for k, v in personality.iteritems():
            temp_list.append(v)
            
        max_value = max(temp_list)
        
        temp_list = [x for x in temp_list if x != max_value]
        if len(temp_list) > 1:
            max_value_2 = max(temp_list)
        if len(temp_list) == 0:
            max_value_2 = 0
        if len(temp_list) == 1:
            max_value_2 = temp_list[0]

### CHECKS THE VALUES FOR TIES 
init python:
    def tie_breaker_determine():
        global personality
        global tie_breaker_needed
        global q_value
        global max_value
        global max_value_2
        global num_of_max_values
        global num_of_max_values_2
        #temp_list = []

        #for k, v in personality.iteritems():
            #temp_list.append(v)
        
        ## Find Max_1 and Max_2
        find_highest_values()
        
        temp_list = []
        
        for k, v in personality.iteritems():
            temp_list.append(v)
        
        ## Start at 0 so this can be adjusted
        num_of_max_values = 0
        num_of_max_values_2 = 0
        
        ## count the number of max values in the list
        for i in temp_list:
            if i == max_value:
                num_of_max_values += 1
        
        ## count the number of 2nd max values in the list
        if max_value_2 == 0:
            num_of_max_values_2 = 0
        else:
            for i in temp_list:
                if i == max_value_2:
                    num_of_max_values_2 += 1
                
    ## Test Passed:
        
        ## NO DUPLICATES!!
        if num_of_max_values <= 1 and num_of_max_values_2 <= 1:
            tie_breaker_needed = False
            
    ## Test Failed:
        if num_of_max_values >= 2 or num_of_max_values_2 >= 2: 
            tie_breaker_needed = True
        if num_of_max_values_2 >=2:
            tie_breaker_needed = True

            
### CALL THE TIE BREAKER SCREEN IF NEEDED 
init python:
    def call_for_extra_credit():
        global q_value
        
        while tie_breaker_needed:
            q_value += 1
            renpy.call_screen("tie_breaker", items=personality.keys())
            tie_breaker_determine()
        else:
            pass
            
Image - Image -Image

Post Reply

Who is online

Users browsing this forum: No registered users