0

Hello I am building a blackjack game and I am stuck the deal button is not working and I am trying to get that to redirecting to another URL. Also do I need that many variables to update the game as the client is playing ? This is my third day doing flask after and my first web application. Any help or pointing me in the right direction would be appreciated here is the HTML code for the inputs as well as my starting code on flask

    <form action="/deal" method="Post" >
    <input class="hit_button" type="submit" value="Hit" name="Hit"/>
    <input class="stay_button" type="submit" value="Stay" name="Stay"/>
    </form>
    <form action="/" method="Post" >
    <input class="deal_button" type="submit" value="Deal" name="Deal"/>
    </form>

    from flask import Flask, render_template, request, Response, redirect, url_for
    import random
    import main
    import datetime as dt
    
    app = Flask(__name__)
    
    year = dt.datetime.now().year
    count = 0
    
    
    @app.route('/', methods=['POST', "GET"])
    def home():
        global count
        if count == 0:
            count += 1
            return render_template("index.html", year=year)
        elif request.method == "GET":
            if request.form.get("Stay", False):
                return redirect(url_for('/deal'))
    
    
    @app.route('/deal', methods=['POST', "GET"])
    def deal():
        if len(main.player_hand) == 0:
            main.start()
            main.get_current_score(main.player_hand)
            return render_template("index.html", year=year, player=main.player_hand, dealer=main.dealer_hand[1:],
                                   score_d=main.get_dealer_starting_value(main.dealer_hand),
                                   score_p=main.get_current_score(main.player_hand))
        if request.method == "POST":
            if request.form.get("Hit", False):
                if main.get_current_score(main.player_hand) <= 21:
                    main.player_hand_dealt()
                    return render_template("index.html", year=year, player=main.player_hand, dealer=main.dealer_hand[1:],
                                           score_d=main.get_dealer_starting_value(main.dealer_hand),
                                           score_p=main.get_current_score(main.player_hand))
rlima003
  • 11
  • 5
  • Looks like clicking deal issues a `POST /` and your `/` route does the redirect to `/deal` only if the method is a GET. That _should_ be POST? – ccchoy Oct 20 '22 at 17:38
  • @ccchoy I used POST originally and didnt do anything so i tried GET which i figured it was wrong too but said lets see what it does and it did nothing – rlima003 Oct 20 '22 at 18:15
  • If you changed just the form method to "GET", I think the form values get translated into query parameters rather than a form body like [here](https://stackoverflow.com/questions/15352739/how-to-submit-form-with-get-method-and-using-uri-template) such that `request.form.get("Stay", False)` is False. have you tried putting a `breakpoint()` into the top of the home handler and inspecting some of these values? Also ensuring from browser dev tools what the outbound request looks like (i.e. if it's a GET with query params vs a POST with a form body) – ccchoy Oct 20 '22 at 18:22
  • Also should the if be checking for `Deal` instead of `Stay`? – ccchoy Oct 20 '22 at 18:23
  • You can access/check the query parameters from the request object using `request.args.get("Deal")` rather than pulling from `.form` - https://stackoverflow.com/questions/11774265/how-do-you-access-the-query-string-in-flask-routes – ccchoy Oct 20 '22 at 18:26

1 Answers1

0

Clicking the Deal button will submit a POST to / with Deal=Deal in the post body as Content-Type: application/x-www-form-urlencoded

Your if condition inside of the home route only redirects to /deal if the request is a GET and if the request form body has a value for Stay. This should be changed to if request.method == "POST": and request.form.get("Deal")

or

if you want the form to submit a GET, then the form's markup should have method="GET" and in the home route, you should look for the request data in the query parameters via request.args.get("Deal").

ccchoy
  • 704
  • 7
  • 16
  • It worked ! Thank yo so much ! A follow up question (idk if this is allowed here) is there a way to not have so many variables in render_template ? or should the most of the game logic be played outside the @app.route – rlima003 Oct 20 '22 at 18:44
  • I don’t want to get too into subjective software architecture things here as there’s undoubtedly a number of different ways to write this code; however to just the Q around reducing the number of kwargs being passed into the ‘render_template’, you could just encapsulate related items into objects(tuples, classes, dicts, etc) like a scores tuple if ur goal is to reduce the # of kwargs. Beyond that, it kinda depends/is hard to give strong recommendations without more context. In general try to limit the data to only what you need – ccchoy Oct 20 '22 at 23:14
  • thank you I appreciate suggestions – rlima003 Oct 20 '22 at 23:17