2

私はサイコロゲームをプログラミングしています。このコード セグメントは、正しい入力 (たとえば、5+4*3/2-1) を取得し、後でプログラムがクラッシュしないようにするための入力用です。

GUIにはeasyguiを使用しています。最初は次のようなコードでした。

#possible_inputs = a list of operators (+-*/) and the values from the dices (1-6) as well as "OK, "Del" and "Reroll"
#raw_user_input = empty list
#br_value - the target value
#dice_value_list - the values from the dices
var = 0

    while(var != possible_inputs.index("OK")):
        var = eg.indexbox(raw_user_input, "Targetvalue: " + br_value_str, possible_inputs)
        if(var != possible_inputs.index("OK")):
          raw_user_input.append(possible_inputs[var])  
        if(var == possible_inputs.index("Del")):
            raw_user_input[:] = []
        if(var == possible_inputs.index("Reroll")):
            #reroll dices

    if(len(raw_user_input) == 0):
        eg.msgbox("No input given", "ERROR")
        return gui_input(dice_value_list, br_value)

    for r in range(len(raw_user_input)):
        if(r%2 == 0):
            if(raw_user_input[r] not in dice_value_list):
                eg.msgbox("Incorrect expression", "ERROR")
                return gui_input(dice_value_list, br_value)            
        else:
            if(raw_user_input[r] not in allowed_operators):
                eg.msgbox("Incorrect expression", "ERROR")
                return gui_input(dice_value_list, br_value)     

それは問題なく機能し、入力が間違っていないため、プログラムがクラッシュすることはありませんでした。

ただし、入力を計算する関数を while ループ内に配置して、計算された式をメッセージボックスにリアルタイムでユーザーに提供できるようにする必要があります。そこで、プログラムを次のように変更しました。

    input_value_calc = 0
    while(var != possible_inputs.index("OK")):
        var = eg.indexbox(raw_user_input, "Target value: " + br_value_str + ", current target value " + str(input_value_calc), possible_inputs)
        if(var != possible_inputs.index("OK")):
          raw_user_input.append(possible_inputs[var])  
        if(var == possible_inputs.index("Del")):
            raw_user_input[:] = []
        if(var == possible_inputs.index("Reroll")):
            #reroll dices

        br_check, values_input, input_value_calc = user_input_value_check(raw_user_input,br_value):

def user_input_value_check(raw_user_input,br_value):

    if(len(raw_user_input) == 0):
        eg.msgbox("No input given", "ERROR")
        gui_input(dice_value_list, br_value)

    for r in range(len(raw_user_input)):
        if(r%2 == 0):
            if(raw_user_input[r] not in dice_value_list):
                eg.msgbox("Incorrect expression", "ERROR")
                gui_input(dice_value_list, br_value)            
        else:
            if(raw_user_input[r] not in allowed_operators):
                eg.msgbox("Incorrect expression", "ERROR")
                gui_input(dice_value_list, br_value)
#rest of the program calculates the score, which works fine
#the function returns True/False (if the input evaluates to the correct br_value), values_input (again for other functions in the program), input_value_calc (the evaluated input value)

最初に正しい入力をした場合はすべて問題ありませんが、今の問題は、間違った入力 (2 つの演算子または 2 つの値が隣り合っている、演算子で始まるなど) を与えるたびに、間違っていると表示され、与えさせてくれることです。別の入力。ただし、今回はボタンが正しく機能していません (たとえば、del を押すと、入力に「del」が追加されます)。

誰かが私にこれを手伝ってくれて本当に感謝しています! ありがとう!

4

1 に答える 1

0

@大災害、

おそらく、あなたが試みていることを達成する別の方法があります。たとえば、ユーザーが情報を完全に入力した後にデータ検証を行います。代わりに、ユーザーに正しいことを強制しないでください。そのため、ユーザーが最初に ' * ' を押すことを許可してはなりません。彼らは最初にサイコロを押す必要があります。次に、強制的に演算子 (' * ' など) のみを選択し、ダイの選択と操作の選択 (時計のティック...トック...ティック...トックのように) を交互に行う必要があります。

また、ユーザーがサイコロを一度選択すると、それを再度選択することはできません (私は思います)。そのため、選択後にリストから削除してください。

次のコードを検討してください。完璧ではありませんが、あなたがやろうとしていたことに似せてみました。あなたが持っているよりも新しいバージョンのeasyguiでこれをテストしたので、うまくいくとは約束できません:

import easygui as eg

def get_user_input(target_value, dice_rolls):

    operator_choices = ['+', '-', '*', '/']
    operator_choices.extend(['OK', 'Del', 'Reroll'])
    dice_choices = [str(r) for r in dice_rolls]
    dice_choices.extend(['Del', 'Reroll'])

    raw_user_input = list()
    mode = 'tick'
    while True:
        if mode == 'tick':
            choices = dice_choices
        else:
            choices = operator_choices
        var = eg.indexbox(''.join(raw_user_input), "Target value: {}".format(target_value), choices)
        if var is None:
            raise ValueError("Dialog closed with invalid entry")
        choice = choices[var]
        if choice == 'OK':
            return ''.join(raw_user_input)
        if choice == 'Del':
            raw_user_input = list()
            dice_choices = [str(r) for r in dice_rolls]
            dice_choices.extend(['Del', 'Reroll'])
            mode = 'tick'
            continue
        if choice == 'Reroll':
            return None
        raw_user_input.append(choice)
        if mode == 'tick': # Remove the dice from the list of dice
            del dice_choices[dice_choices.index(choices[var])]
        if mode == 'tick':
            mode = 'tock'
        else:
            mode = 'tick'


br_value = 12 # Sample value
dice_value_list = [4, 2, 1, 1, 5] # Sample rolls

try:
    user_input = get_user_input(br_value, dice_value_list)
except:
    print("Your data entry was cancelled by the user")
    exit()

if user_input is None:
    print("Rerolling the dice")
    #.... do that now!

print("User entered: {}".format(user_input))
####
# Now, put code here to process your user_input
# ....
#
####

プログラミングを続けてください!難しいこともありますが、やりがいもあります!

于 2014-12-17T08:43:34.083 に答える