在 Flask 中创建游戏 / 在不同的 html 页面中打印 while 循环的值

问题描述 投票:0回答:1

对于一个项目,我目前正在尝试使用 Flask 在 python 中创建一个游戏(Hangman 的变体),以使其可以在 html 页面上访问。这个游戏注定是聋哑儿童用来提高他们的法语写作水平的。

这是我第一次真正使用 Flask 或任何 Python Web 框架(我几个月前开始使用 Python)。 我的游戏使用txt文件作为数据库。该文件包含按难度分类的单词(简单、中等、困难)。我能够创建 3 个页面:menu.html、choisir_diff.html 和starter_partie.html。

这是我的 python 文件(main.py)中的函数:


from flask import Flask, render_template, request, redirect, url_for, session
import random
import math


app = Flask(__name__)
app.secret_key = 'your_secret_key'

def liste_mots(path_file):

    dico = {"Facile" : [], "Moyen" : [], "Difficile" : []}

    with open(path_file, "r") as fichier:
        for mot in fichier:
            mot = mot.strip()
            if not mot:
                continue
            if mot in ["Facile", "Moyen", "Difficile"]:
                difficulte = mot
            else:
                dico[difficulte].append(mot)

    #print(dico)
    return dico

@app.route('/')
def menu():
    return render_template("menu.html")

@app.route('/choisir_diff/<difficulte>')
def choisir_diff(difficulte):

    dico = liste_mots("mots.txt")
    mots = dico[difficulte]
    return render_template('choisir_diff.html', difficulte=difficulte, mots=mots)

菜单显示三个难度级别,choisir_diff 级别允许用户在列表中选择一个单词,而starter_partie 级别则用于“启动游戏”。 这个想法是,计算机将通过向用户发送字母来尝试猜测所选单词,用户将回答“是”(如果该字母在所选单词中)或“否”(如果不在所选单词中)。当计算机猜出单词字母的 3/5 时,或者达到 8 次尝试时,它就会开始向用户发送单词。如果这些单词之一被选中,那么计算机就赢了!

计算机发送的字母和单词的选择是在 while 循环中进行的。我特别尝试预测简短的单词,要求计算机首先建议非常常见的字母,并选择何时开始发送单词而不是字母。 我的循环可能并不完美,但当我将其隔离在另一个文件中并在循环的每一轮打印我的值时,它似乎可以工作。这是我的 while 循环(我给变量起了英文名称!):

 
word_dict = liste_mot("mots.txt")
selected_words = word_dict["Difficult"]
letters = list(selected_word)
word_length = len(letters)
letter_limit = math.floor(0.6 * len(letters))
print(letter_limit)
guessed_letters = ["_"] * word_length
common_letters = list("eastirnulodmcpévhgfb")
uncommon_letters = list("qjàxèêzykôûwâîüùëœçï")
alphabet = list("eastirnulodmcpévhgfbqjàxèêzykôûwâîüùëœçï")
current_turn = 0

while (true_guessed_letters := len(guessed_letters) - guessed_letters.count("_")) < letter_limit and current_turn < 9:
    print(f"true_guessed_letters: {true_guessed_letters}")
    print(f"guessed_letters: {guessed_letters}")
    print(f"hangman traits: {current_turn}")
    print("-" * 50)
    if len(letters) > 6:
        if true_guessed_letters < 5 and any(c in common_letters for c in letters):
            computer_choice = random.choice(common_letters)
            current_letter = computer_choice
            session['current_letter'] = current_letter
            if computer_choice in letters:
                indices = [i for i, letter in enumerate(letters) if letter == computer_choice]
                for index in indices:
                    guessed_letters[index] = computer_choice
                common_letters.remove(computer_choice)
                alphabet.remove(computer_choice)
                print(guessed_letters)
            else:
                current_turn += 1
                common_letters.remove(computer_choice)
                alphabet.remove(computer_choice)
        else:
            computer_choice = random.choice(alphabet)
            current_letter = computer_choice
            session['current_letter'] = current_letter
            print(f"alphabet letter choice: {computer_choice}")
            if computer_choice in letters:
                indices = [i for i, letter in enumerate(letters) if letter == computer_choice]
                for index in indices:
                    guessed_letters[index] = computer_choice
                alphabet.remove(computer_choice)
            else:
                current_turn += 1
                alphabet.remove(computer_choice)
    elif len(letters) < 5:
        if true_guessed_letters < 3 and any(c in uncommon_letters for c in letters if c != "_") and uncommon_letters:
            computer_choice = random.choice(uncommon_letters)
            current_letter = computer_choice
            session['current_letter'] = current_letter
            if computer_choice in letters:
                indices = [i for i, letter in enumerate(letters) if letter == computer_choice]
                for index in indices:
                    guessed_letters[index] = computer_choice
                uncommon_letters.remove(computer_choice)
                alphabet.remove(computer_choice)
            else:
                current_turn += 1
                uncommon_letters.remove(computer_choice)
                alphabet.remove(computer_choice)
        else:
            computer_choice = random.choice(alphabet)
            current_letter = computer_choice
            session['current_letter'] = current_letter
            if computer_choice in letters:
                indices = [i for i, letter in enumerate(letters) if letter == computer_choice]
                for index in indices:
                    guessed_letters[index] = computer_choice
                alphabet.remove(computer_choice)
            else:
                current_turn += 1
                alphabet.remove(computer_choice)`

# The computer starts trying to guess words if the number of turns reaches 8 or if 3/5 of the letters have been guessed.
# Possible words to be guessed are those containing all the guessed letters so far (ignoring their positions for simplicity).
# Possible words to be guessed are also those of the same length as the chosen one.
`
possible_words = [word for word in word_dict if all(letter in word if letter != '_' else True for letter in guessed_letters)]
possible_words = [word for word in possible_words if len(word) == len(letters)]
print(possible_words)

while current_turn < 11:
    if possible_words:
        computer_word_choice = random.choice(possible_words)
        current_word = computer_word_choice
        session['current_word'] = current_word
        print(f"hangman traits: {current_turn}")
        print(f"Computer word attempt: {computer_word_choice}")
        if computer_word_choice != selected_word:
            current_turn += 1
        else:
            break

现在,我的想法是,在我的starter_partie页面上,我有一个按钮“let's go”,它将显示第一个字母(因此是循环第一圈中current_letter的值)。然后,用户可以单击“是”按钮或“否”按钮,他们将被重定向到带有下一个猜测字母的另一个页面(因此是循环第二轮中 current_letter 的值)。重复相同的过程,直到达到 10 current_turn(所以当刽子手绘图完成时,当然我还没有达到该步骤)。

我怎样才能做到这一点?我尝试创建一个新函数 display_letter ,它将获取循环当前回合的值并将其显示在屏幕上。我使用“session”和以下行来做到这一点:session.get('current_letter', ' '), session.get('current_word', ' '), session.get('current_turn', ' ')。但是,当我尝试打印这些值时,它们显示为空(它们采用默认形式“ ”,或者当我取消默认值时它们只是“无”)。

怎样才能达到我想要的结果?如果我确实创建了一个 display_function,它将如何处理它和我的循环之间的交换?它将如何出现在我的 display_function.html 中?

非常感谢您,我对这段文字表示歉意!谢谢!

python flask game-development session-variables web-frameworks
1个回答
0
投票

由于 Web 应用程序和循环的架构,不可能停止 while 循环并在某个时间点提取值。

Web 应用程序的架构由来自浏览器的请求组成,这些请求由服务器应答。但是,您可以使用此过程来保持某种循环的进行。为此,只要循环运行,您就可以将请求发送到同一端点。每个请求对应一个迭代步骤。会话存储可用于跨多个请求维护变量。如果你想打破所谓的循环,你可以将用户重定向到另一个页面。

以下示例说明了所描述的方法。

from flask import (
    Flask, 
    redirect, 
    render_template_string, 
    request, 
    session, 
    url_for
)

app = Flask(__name__)
app.secret_key = 'your secret here'

@app.route('/')
def start():
    session['i'] = 0
    return redirect(url_for('step'))

@app.route('/step', methods=['GET', 'POST'])
def step():
    if 'i' not in session:
        return redirect(url_for('start'))

    i = int(session['i'])

    if request.method == 'POST':

        should_continue = request.form.get('break', False, type=bool)
        if not should_continue or i >= 10:
            return redirect(url_for('end'))
        
        i += 1
        session['i'] = i 

        return redirect(request.url)

    return render_template_string('''
        <p>Current index is {{ i }}.<br/>Should the loop break?</p>
        <form method="post">
            <button type="submit" name="break" value="">Break</button>
            <button type="submit" name="break" value="true">Continue</button>
        </form>
        ''', **locals()
    )

@app.route('/end')
def end():
    if 'i' not in session:
        return redirect(url_for('start'))

    i = session['i']
    return render_template_string('''
        <p>You left the loop at {{ i }}.</p>
        <a href="{{ url_for('start') }}">Try once more.</a>
        ''', **locals())
© www.soinside.com 2019 - 2024. All rights reserved.