diff --git a/app.py b/app.py index cc155e0..c87f43b 100644 --- a/app.py +++ b/app.py @@ -4,30 +4,49 @@ from string import ascii_lowercase from flask import Flask, render_template, session, request, redirect, url_for, flash import sensitive -from lib import cat_words, ROUNDS +from lib import cat_words, ROUNDS, WORD_LENGTH from play import build_non_letter_hint, build_letter_hint app = Flask(__name__) app.config['SECRET_KEY'] = sensitive.SECRET_KEY + WORDS = list(cat_words()) NUM_GAMES = len(WORDS) - 1 GUESS_SPLITTER = '|' + +RANDOM_GAME_ID = -1 + +KEY_WORD = 'word' +KEY_GAME_ID = 'game_id' +KEY_GUESSES = 'guesses' +KEY_GUESS = 'guess' +KEY_STATE = 'state' + STATE_PLAYING = 'PLAYING' STATE_WIN = 'WIN' STATE_LOSE = 'LOSE' -RANDOM_GAME_ID = -1 + +COLOR_GREY = 'grey' +COLOR_GREEN = 'green' +COLOR_YELLOW = 'yellow' + +ERROR_GAME_ID_RANGE = "game_id must be between 0 and {}".format(NUM_GAMES) +ERROR_NEED_WORD = 'need a word' +ERROR_GUESS_LENGTH = "Make a {} letter guess.".format(WORD_LENGTH) +ERROR_WORD_NOT_IN_LIST = 'Not in word list: {}' +ERROR_NO_GAME = 'No game started.' def init_game(game_id, word): - session['game_id'] = game_id - session['word'] = word - session['guesses'] = '' - session['state'] = STATE_PLAYING + session[KEY_GAME_ID] = game_id + session[KEY_WORD] = word + session[KEY_GUESSES] = '' + session[KEY_STATE] = STATE_PLAYING def resolve_guesses(): - word = session['word'] - guesses = session.get('guesses', '').split(GUESS_SPLITTER) + word = session[KEY_WORD] + guesses = session.get(KEY_GUESSES, '').split(GUESS_SPLITTER) guesses_colored = [] for guess in guesses: non_letters_hints = build_non_letter_hint(guess, word) @@ -35,13 +54,13 @@ def resolve_guesses(): colored_guess = [] for pos, letter in enumerate(guess): if letter in non_letters_hints: - color = 'grey' + color = COLOR_GREY elif letters_hints[pos] == letter.upper(): - color = 'green' + color = COLOR_GREEN elif letters_hints[pos] == letter: - color = 'yellow' + color = COLOR_YELLOW else: - color = 'grey' + color = COLOR_GREY colored_guess.append((letter, color)) guesses_colored.append(colored_guess) return guesses_colored @@ -51,14 +70,20 @@ def build_game_state(): guesses_colored = resolve_guesses() return render_template('game.html', guesses=guesses_colored, - state_playing=session['state'] == STATE_PLAYING, - state=session['state']) + state_playing=session[KEY_STATE] == STATE_PLAYING, + WORD_LENGTH=WORD_LENGTH, + KEY_GUESS=KEY_GUESS, + state=session[KEY_STATE]) + +# ############################################################################# +# ROUTES +# ############################################################################# @app.route('/') def home(): num_games = NUM_GAMES - return render_template('home.html', num_games=num_games) + return render_template('home.html', num_games=num_games, KEY_GAME_ID=KEY_GAME_ID) @app.route('/init/random') @@ -70,14 +95,14 @@ def init_random_game(): @app.route('/init/deterministic', methods=['post']) def init_deterministic_game(): - game_id = request.form.get('game_id') + game_id = request.form.get(KEY_GAME_ID) return redirect(url_for('init_deterministic_game_id', game_id=game_id)) @app.route('/init/deterministic/') def init_deterministic_game_id(game_id): if not 0 <= int(game_id) <= NUM_GAMES: - flash("game_id must be between 0 and {}".format(NUM_GAMES)) + flash(ERROR_GAME_ID_RANGE) return redirect(url_for('home')) word = WORDS[int(game_id)] init_game(game_id, word) @@ -86,43 +111,44 @@ def init_deterministic_game_id(game_id): @app.route('/random') def random_game(): - if 'word' not in session or 'state' not in session: + if KEY_WORD not in session or KEY_STATE not in session: return redirect(url_for('init_random_game')) return build_game_state() @app.route('/deterministic/') def deterministic_game_id(game_id): - if 'word' not in session or 'state' not in session or ('game_id' in session and session['game_id'] != game_id): + if (KEY_WORD not in session or KEY_STATE not in session or + (KEY_GAME_ID in session and session[KEY_GAME_ID] != game_id)): return redirect(url_for('init_deterministic_game_id', game_id=game_id)) return build_game_state() @app.route('/guess', methods=['post']) def make_guess(): - if 'word' not in session or 'guesses' not in session: - flash('need a word') + if KEY_WORD not in session or KEY_GUESSES not in session: + flash(ERROR_NEED_WORD) return redirect(url_for('home')) - guess = request.form.get('guess') - if len(guess) != 5 and not all([x in ascii_lowercase for x in guess]): - flash("Make a 5 letter guess.") - return build_game_state() + guess = request.form.get(KEY_GUESS) guess = guess.lower() - if guess not in WORDS: - flash('Not in word list: {}'.format(guess)) + if len(guess) != WORD_LENGTH and not all([x in ascii_lowercase for x in guess]): + flash(ERROR_GUESS_LENGTH) return build_game_state() - word = session['word'] - round = len(session['guesses'].split(GUESS_SPLITTER)) - if round >= ROUNDS: - session['state'] = STATE_LOSE + if guess not in WORDS: + flash(ERROR_WORD_NOT_IN_LIST.format(guess)) + return build_game_state() + word = session[KEY_WORD] + round_i = len(session[KEY_GUESSES].split(GUESS_SPLITTER)) + if round_i >= ROUNDS: + session[KEY_STATE] = STATE_LOSE if guess == word: - session['state'] = STATE_WIN - session['guesses'] += '{}{}'.format(guess, GUESS_SPLITTER) - if 'game_id' not in session: - flash('no game_id') + session[KEY_STATE] = STATE_WIN + session[KEY_GUESSES] += '{}{}'.format(guess, GUESS_SPLITTER) + if KEY_GAME_ID not in session: + flash(ERROR_NO_GAME) return redirect(url_for('home')) - game_id = session['game_id'] - if game_id == -1: + game_id = session[KEY_GAME_ID] + if game_id == RANDOM_GAME_ID: return redirect(url_for('random_game')) return redirect(url_for('deterministic_game_id', game_id=game_id)) diff --git a/templates/game.html b/templates/game.html index cd2a8cf..d7b4261 100644 --- a/templates/game.html +++ b/templates/game.html @@ -13,7 +13,8 @@ {% if state_playing %}
-
diff --git a/templates/home.html b/templates/home.html index 8c725a4..f438ed5 100644 --- a/templates/home.html +++ b/templates/home.html @@ -3,7 +3,7 @@ Random game
- +
{% endblock %} \ No newline at end of file