{"id":7243,"date":"2021-01-10T19:37:03","date_gmt":"2021-01-10T14:07:03","guid":{"rendered":"http:\/\/www.pythonpool.com\/?p=7243"},"modified":"2026-07-13T12:30:43","modified_gmt":"2026-07-13T07:00:43","slug":"python-hangman","status":"publish","type":"post","link":"https:\/\/www.pythonpool.com\/python-hangman\/","title":{"rendered":"Build a Python Hangman Game: Input, State, and Validation"},"content":{"rendered":"<p><strong>Quick answer:<\/strong> A reliable Python Hangman game keeps its state explicit: choose a secret word, normalize one-letter guesses, track correct and wrong letters, reveal the matching positions, and stop as soon as the word is complete or attempts are exhausted. Separate the state transitions from input and random selection so the game can be tested deterministically.<\/p>\n<figure class=\"pythonpool-article-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/python-hangman.png\" alt=\"Python Pool infographic showing Hangman game state secret word guesses validation attempts win and replay loop\" width=\"1536\" height=\"1024\" loading=\"lazy\" decoding=\"async\"><figcaption>Keep Hangman state explicit: choose a word, normalize one-letter guesses, track correct and wrong letters, and stop cleanly on win or exhausted attempts.<\/figcaption><\/figure>\n\n\n<p class=\"wp-block-paragraph\">A Hangman game is a practical beginner project because it uses input validation, loops, strings, lists, sets, and conditional logic in one small program. In this tutorial, we will build a command-line Hangman game in Python that chooses a secret word, tracks correct and wrong guesses, and stops when the player wins or runs out of attempts.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The main improvement over a hard-coded demo is that the word is selected from a sequence with <a href=\"https:\/\/docs.python.org\/3\/library\/random.html#random.choice\" target=\"_blank\" rel=\"noreferrer noopener\">random.choice()<\/a>, which the Python documentation defines for picking an item from a non-empty sequence. We will also normalize player input with <a href=\"https:\/\/docs.python.org\/3\/library\/stdtypes.html#str.lower\" target=\"_blank\" rel=\"noreferrer noopener\">str.lower()<\/a> so uppercase and lowercase guesses behave the same way.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #990303;color:#990303\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #990303;color:#990303\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#How_the_Hangman_Logic_Works\" >How the Hangman Logic Works<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Complete_Python_Hangman_Code\" >Complete Python Hangman Code<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Code_Explanation\" >Code Explanation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Example_Output\" >Example Output<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Common_Improvements\" >Common Improvements<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Model_The_Game_State\" >Model The Game State<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Normalize_And_Validate_One_Letter\" >Normalize And Validate One Letter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Inject_Randomness_And_Input\" >Inject Randomness And Input<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Test_Win_Loss_And_Replay\" >Test Win, Loss, And Replay<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Keep_The_Terminal_Loop_Thin\" >Keep The Terminal Loop Thin<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Keep_Display_And_Rules_Separate\" >Keep Display And Rules Separate<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/#Frequently_Asked_Questions\" >Frequently Asked Questions<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"How_the_Hangman_Logic_Works\"><\/span>How the Hangman Logic Works<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The game needs five pieces of state:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>secret_word<\/code>: the word the player is trying to guess.<\/li>\n\n\n\n<li><code>guessed_letters<\/code>: a set of letters the player already tried.<\/li>\n\n\n\n<li><code>wrong_guesses<\/code>: how many incorrect guesses have been made.<\/li>\n\n\n\n<li><code>max_wrong_guesses<\/code>: the losing limit.<\/li>\n\n\n\n<li>A loop that keeps asking for letters until the player wins or loses.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you are new to the looping part, see Python Pool&#8217;s guide to <a href=\"https:\/\/www.pythonpool.com\/for-vs-while-loop-python\/\">for vs while loops in Python<\/a>. For a refresher on user prompts, read <a href=\"https:\/\/www.pythonpool.com\/python-user-input\/\">Python user input<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Complete_Python_Hangman_Code\"><\/span>Complete Python Hangman Code<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Save this as <code>hangman.py<\/code> and run it with Python 3:<\/p>\n\n\n\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre class=\"wp-block-code\"><code>import random\n\nWORDS = (\"python\", \"variable\", \"function\", \"iterator\", \"package\")\n\n\ndef show_progress(secret_word, guessed_letters):\n    return \" \".join(\n        letter if letter in guessed_letters else \"_\"\n        for letter in secret_word\n    )\n\n\ndef play_hangman():\n    secret_word = random.choice(WORDS)\n    guessed_letters = set()\n    wrong_guesses = 0\n    max_wrong_guesses = 6\n\n    print(\"Guess the word:\", show_progress(secret_word, guessed_letters))\n\n    while wrong_guesses &lt; max_wrong_guesses:\n        guess = input(\"Enter one letter: \").strip().lower()\n\n        if len(guess) != 1 or not guess.isalpha():\n            print(\"Please enter exactly one alphabet letter.\")\n            continue\n\n        if guess in guessed_letters:\n            print(\"You already tried that letter.\")\n            continue\n\n        guessed_letters.add(guess)\n\n        if guess in secret_word:\n            print(\"Correct:\", show_progress(secret_word, guessed_letters))\n\n            if all(letter in guessed_letters for letter in secret_word):\n                print(f\"You won! The word was {secret_word}.\")\n                return\n        else:\n            wrong_guesses += 1\n            remaining = max_wrong_guesses - wrong_guesses\n            print(f\"Wrong. {remaining} guesses left.\")\n            print(show_progress(secret_word, guessed_letters))\n\n    print(f\"You lost. The word was {secret_word}.\")\n\n\nif __name__ == \"__main__\":\n    play_hangman()<\/code><\/pre><\/div>\n\n\n\n\n<!-- Python Pool visual layout repair 2026-07-13 -->\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/hangman-state-b194.png\" alt=\"Python Pool infographic showing a secret word, guesses, attempts, and game state\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>A Hangman game needs explicit state for the word, guesses, attempts, and outcome.<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Code_Explanation\"><\/span>Code Explanation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>WORDS<\/code> stores the possible answers. A tuple is fine here because the game does not need to edit the word list while it runs. If you want to select from a changing list, read <a href=\"https:\/\/www.pythonpool.com\/randomly-select-from-list-python\/\">randomly select from a list in Python<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>show_progress()<\/code> builds the masked display. For every letter in the secret word, it shows the letter if the user guessed it and an underscore otherwise. The expression is joined with spaces so the output is easier to read.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>input()<\/code> reads the player&#8217;s next guess. The official <a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#input\" target=\"_blank\" rel=\"noreferrer noopener\">input()<\/a> documentation explains that it reads a line from standard input and returns it as a string. The code then uses <code>strip()<\/code> to remove extra spaces and <code>lower()<\/code> to make guesses case-insensitive. Python Pool also has a separate tutorial on <a href=\"https:\/\/www.pythonpool.com\/python-lowercase\/\">converting strings to lowercase in Python<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A set is used for <code>guessed_letters<\/code> because membership checks such as <code>guess in guessed_letters<\/code> are direct and readable. That lets the game reject repeated guesses before changing the score.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Example_Output\"><\/span>Example Output<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre class=\"wp-block-code\"><code>Guess the word: _ _ _ _ _ _\nEnter one letter: p\nCorrect: p _ _ _ _ _\nEnter one letter: z\nWrong. 5 guesses left.\np _ _ _ _ _\nEnter one letter: y\nCorrect: p y _ _ _ _<\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The exact word and output will vary because <code>random.choice()<\/code> selects a word at runtime.<\/p>\n\n\n\n\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/hangman-guess-b194.png\" alt=\"Python Pool infographic mapping a player guess through validation, reveal, miss, and update\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Process each guess through validation, reveal, miss handling, and state update.<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Common_Improvements\"><\/span>Common Improvements<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add more words to <code>WORDS<\/code> or load them from a text file.<\/li>\n\n\n\n<li>Print an ASCII drawing after each wrong guess.<\/li>\n\n\n\n<li>Track wins and losses across multiple rounds.<\/li>\n\n\n\n<li>Use categories such as easy, medium, and hard words.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">After this project, another small game to practice the same ideas is <a href=\"https:\/\/www.pythonpool.com\/rock-paper-scissors-python\/\">Rock Paper Scissors in Python<\/a>. You can also strengthen the iteration concepts with <a href=\"https:\/\/www.pythonpool.com\/python-iterate-through-list\/\">Python list iteration<\/a>.<\/p>\n\n\n<h2><span class=\"ez-toc-section\" id=\"Model_The_Game_State\"><\/span>Model The Game State<span class=\"ez-toc-section-end\"><\/span><\/h2><p>A small state object makes the rules visible. The secret word and guessed letters are data, while a method derives the displayed pattern. Do not mutate the secret word when revealing a guess.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">from dataclasses import dataclass, field\n\n@dataclass\nclass Game:\n    word: str\n    attempts: int = 6\n    guessed: set[str] = field(default_factory=set)\n\n    def display(self):\n        return \" \".join(letter if letter in self.guessed else \"_\" for letter in self.word)\n\n    def won(self):\n        return all(letter in self.guessed for letter in self.word)\n\nprint(Game(\"python\").display())\n<\/code><\/pre><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Normalize_And_Validate_One_Letter\"><\/span>Normalize And Validate One Letter<span class=\"ez-toc-section-end\"><\/span><\/h2><p>Accept surrounding whitespace and case differences, but require exactly one alphabetic character. Invalid or repeated guesses should produce feedback without consuming an attempt or changing the set of valid guesses.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">def normalize_guess(raw, guessed):\n    guess = raw.strip().lower()\n    if len(guess) != 1 or not guess.isalpha():\n        return None, \"Enter one letter.\"\n    if guess in guessed:\n        return None, \"You already tried that letter.\"\n    return guess, None\n\nprint(normalize_guess(\" P \" , set()))\nprint(normalize_guess(\"pp\", set()))\n<\/code><\/pre><\/div>\n\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/hangman-loop-b194.png\" alt=\"Python Pool infographic comparing input, state update, win check, loss check, and repeat\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>The game loop should check win and loss conditions after each valid guess.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Inject_Randomness_And_Input\"><\/span>Inject Randomness And Input<span class=\"ez-toc-section-end\"><\/span><\/h2><p>random.choice() is fine for a real game, but tests should be able to provide a known word and a fixed sequence of guesses. Keeping selection outside the state machine makes win and loss paths repeatable.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">import random\n\nWORDS = [\"python\", \"matplotlib\", \"notebook\"]\nsecret = random.choice(WORDS)\n\ntest_game = Game(\"python\")\nfor guess in [\"p\", \"y\", \"t\", \"h\", \"o\", \"n\"]:\n    test_game.guessed.add(guess)\nprint(test_game.won())\n<\/code><\/pre><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Test_Win_Loss_And_Replay\"><\/span>Test Win, Loss, And Replay<span class=\"ez-toc-section-end\"><\/span><\/h2><p>Test the state transitions without patching terminal input. Cover a correct guess, an incorrect guess, a duplicate, invalid text, a completed word, exhausted attempts, and a fresh game for replay. These cases catch most beginner-game bugs.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">def apply_guess(game, guess):\n    if guess in game.guessed:\n        return \"duplicate\"\n    game.guessed.add(guess)\n    if guess not in game.word:\n        game.attempts -= 1\n        return \"wrong\"\n    return \"correct\"\n\ncase = Game(\"cat\", attempts=2)\nprint(apply_guess(case, \"x\"), case.attempts)\nprint(apply_guess(case, \"c\"), case.display())\n<\/code><\/pre><\/div>\n\n<figure class=\"pythonpool-article-visual pythonpool-supporting-visual\"><img src=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/hangman-check-b194.png\" alt=\"Python Pool infographic testing duplicate guesses, invalid input, word reveal, randomness, and validation\" width=\"1536\" height=\"1054\" loading=\"lazy\" decoding=\"async\"><figcaption>Check duplicate guesses, invalid input, word secrecy, randomness, and terminal states.<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Keep_The_Terminal_Loop_Thin\"><\/span>Keep The Terminal Loop Thin<span class=\"ez-toc-section-end\"><\/span><\/h2><p>The interactive loop should coordinate prompts and messages, not contain every rule. Call the state functions, print the current display, and stop after each transition when won() or attempts reaches zero. A thin loop is easier to replace with a web or test interface.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">def play(game, guesses):\n    for raw in guesses:\n        guess, error = normalize_guess(raw, game.guessed)\n        if error:\n            print(error)\n            continue\n        result = apply_guess(game, guess)\n        print(result, game.display(), game.attempts)\n        if game.won() or game.attempts == 0:\n            break\n\nplay(Game(\"code\", attempts=3), [\"c\", \"x\", \"o\", \"d\", \"e\"])\n<\/code><\/pre><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Keep_Display_And_Rules_Separate\"><\/span>Keep Display And Rules Separate<span class=\"ez-toc-section-end\"><\/span><\/h2><p>The display function should only translate state into text. Keeping rendering separate means a later interface can show the same state with HTML, a GUI, or a terminal prompt without duplicating win and loss logic. It also makes output assertions simple in tests.<\/p><div class=\"pythonpool-code-scroll\" style=\"max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;\"><pre><code class=\"language-python\">def status(game):\n    if game.won():\n        return \"won\"\n    if game.attempts &lt;= 0:\n        return \"lost\"\n    return \"playing\"\n\nstate = Game(\"data\", attempts=1)\nprint(state.display(), status(state))\n<\/code><\/pre><\/div><p>Python&#8217;s official <a href=\"https:\/\/docs.python.org\/3\/library\/random.html#random.choice\">random.choice()<\/a> reference covers selection from a non-empty sequence, and the <a href=\"https:\/\/docs.python.org\/3\/library\/dataclasses.html\">dataclasses documentation<\/a> explains explicit state containers. Related Python Pool references include <a href=\"https:\/\/www.pythonpool.com\/randomly-select-from-list-python\/\">random selection<\/a>, <a href=\"https:\/\/www.pythonpool.com\/python-getch-library\/\">input handling<\/a>, and <a href=\"https:\/\/www.pythonpool.com\/python-testing-framework\/\">testing frameworks<\/a>.<\/p>\n\n<p>For related game inputs and verification, compare <a href=\"https:\/\/www.pythonpool.com\/randomly-select-from-list-python\/\">random selection<\/a>, <a href=\"https:\/\/www.pythonpool.com\/python-getch-library\/\">input handling<\/a>, and <a href=\"https:\/\/www.pythonpool.com\/python-testing-framework\/\">Python testing frameworks<\/a> when separating game state from the terminal loop.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Frequently_Asked_Questions\"><\/span>Frequently Asked Questions<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3>How do I make Hangman in Python?<\/h3>\n<p>Choose a secret word, track guessed letters and remaining attempts, reveal matching letters, reject invalid or repeated guesses, and stop on a win or loss.<\/p>\n<h3>How do I choose a random Hangman word?<\/h3>\n<p>Use random.choice() on a non-empty sequence of allowed words and keep the word list separate from the game-state logic.<\/p>\n<h3>How do I validate Hangman guesses?<\/h3>\n<p>Normalize the input, require one alphabetic character, reject repeated guesses, and give the player a clear message without changing the state.<\/p>\n<h3>How can I test a Hangman game?<\/h3>\n<p>Inject a deterministic word and input sequence, then test win, loss, repeated guesses, invalid input, and replay behavior without relying on random choice.<\/p>\n<script type=\"application\/ld+json\">{\"@context\":\"https:\/\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"How do I make Hangman in Python?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Choose a secret word, track guessed letters and remaining attempts, reveal matching letters, reject invalid or repeated guesses, and stop on a win or loss.\"}},{\"@type\":\"Question\",\"name\":\"How do I choose a random Hangman word?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Use random.choice() on a non-empty sequence of allowed words and keep the word list separate from the game-state logic.\"}},{\"@type\":\"Question\",\"name\":\"How do I validate Hangman guesses?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Normalize the input, require one alphabetic character, reject repeated guesses, and give the player a clear message without changing the state.\"}},{\"@type\":\"Question\",\"name\":\"How can I test a Hangman game?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Inject a deterministic word and input sequence, then test win, loss, repeated guesses, invalid input, and replay behavior without relying on random choice.\"}}]}<\/script>","protected":false},"excerpt":{"rendered":"<p>Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.<\/p>\n","protected":false},"author":12,"featured_media":7596,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1146,15],"tags":[3214,3212,3211,3210,3213,3215],"class_list":["post-7243","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-project","category-tutorials","tag-hangman-game-python","tag-hangman-in-python","tag-hangman-python","tag-hangman-python-code","tag-python-hangman-game","tag-python-hangman-program","infinite-scroll-item"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.1 (Yoast SEO v28.0) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Build a Python Hangman Game: Input, State, and Validation<\/title>\n<meta name=\"description\" content=\"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pythonpool.com\/python-hangman\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a Python Hangman Game: Input, State, and Validation\" \/>\n<meta property=\"og:description\" content=\"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pythonpool.com\/python-hangman\/\" \/>\n<meta property=\"og:site_name\" content=\"Python Pool\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-10T14:07:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-13T07:00:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/python-hangman.png\" \/>\n<meta name=\"author\" content=\"Prachee Sao\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Python Pool\" \/>\n<meta name=\"twitter:description\" content=\"Practical Python tutorials, error fixes, code examples, and project guides.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/python-hangman.png\" \/>\n<meta name=\"twitter:creator\" content=\"@pythonpool\" \/>\n<meta name=\"twitter:site\" content=\"@pythonpool\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Prachee Sao\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/\"},\"author\":{\"name\":\"Prachee Sao\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/person\\\/b91d749826b21e606d55cda77d51ef47\"},\"headline\":\"Build a Python Hangman Game: Input, State, and Validation\",\"datePublished\":\"2021-01-10T14:07:03+00:00\",\"dateModified\":\"2026-07-13T07:00:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/\"},\"wordCount\":997,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/Theatre-Actor-Portfolio-Website-15.png\",\"keywords\":[\"hangman game python\",\"hangman in python\",\"hangman python\",\"hangman python code\",\"python hangman game\",\"python hangman program\"],\"articleSection\":[\"Project\",\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/\",\"name\":\"Build a Python Hangman Game: Input, State, and Validation\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/Theatre-Actor-Portfolio-Website-15.png\",\"datePublished\":\"2021-01-10T14:07:03+00:00\",\"dateModified\":\"2026-07-13T07:00:43+00:00\",\"description\":\"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/Theatre-Actor-Portfolio-Website-15.png\",\"contentUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/Theatre-Actor-Portfolio-Website-15.png\",\"width\":1350,\"height\":650,\"caption\":\"python hangman\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/python-hangman\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pythonpool.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build a Python Hangman Game: Input, State, and Validation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#website\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/\",\"name\":\"Python Pool\",\"description\":\"Practical Python tutorials, error fixes, code examples, and project guides.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pythonpool.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#organization\",\"name\":\"Python Pool\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/aa.png\",\"contentUrl\":\"https:\\\/\\\/www.pythonpool.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/aa.png\",\"width\":452,\"height\":185,\"caption\":\"Python Pool\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/pythonpool\",\"https:\\\/\\\/www.youtube.com\\\/c\\\/pythonpool\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.pythonpool.com\\\/#\\\/schema\\\/person\\\/b91d749826b21e606d55cda77d51ef47\",\"name\":\"Prachee Sao\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g\",\"caption\":\"Prachee Sao\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build a Python Hangman Game: Input, State, and Validation","description":"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pythonpool.com\/python-hangman\/","og_locale":"en_US","og_type":"article","og_title":"Build a Python Hangman Game: Input, State, and Validation","og_description":"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.","og_url":"https:\/\/www.pythonpool.com\/python-hangman\/","og_site_name":"Python Pool","article_published_time":"2021-01-10T14:07:03+00:00","article_modified_time":"2026-07-13T07:00:43+00:00","og_image":[{"url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/python-hangman.png","type":"","width":"","height":""}],"author":"Prachee Sao","twitter_card":"summary_large_image","twitter_title":"Python Pool","twitter_description":"Practical Python tutorials, error fixes, code examples, and project guides.","twitter_image":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2026\/07\/python-hangman.png","twitter_creator":"@pythonpool","twitter_site":"@pythonpool","twitter_misc":{"Written by":"Prachee Sao","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pythonpool.com\/python-hangman\/#article","isPartOf":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/"},"author":{"name":"Prachee Sao","@id":"https:\/\/www.pythonpool.com\/#\/schema\/person\/b91d749826b21e606d55cda77d51ef47"},"headline":"Build a Python Hangman Game: Input, State, and Validation","datePublished":"2021-01-10T14:07:03+00:00","dateModified":"2026-07-13T07:00:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/"},"wordCount":997,"commentCount":0,"publisher":{"@id":"https:\/\/www.pythonpool.com\/#organization"},"image":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2021\/01\/Theatre-Actor-Portfolio-Website-15.png","keywords":["hangman game python","hangman in python","hangman python","hangman python code","python hangman game","python hangman program"],"articleSection":["Project","Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.pythonpool.com\/python-hangman\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.pythonpool.com\/python-hangman\/","url":"https:\/\/www.pythonpool.com\/python-hangman\/","name":"Build a Python Hangman Game: Input, State, and Validation","isPartOf":{"@id":"https:\/\/www.pythonpool.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/#primaryimage"},"image":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2021\/01\/Theatre-Actor-Portfolio-Website-15.png","datePublished":"2021-01-10T14:07:03+00:00","dateModified":"2026-07-13T07:00:43+00:00","description":"Build a Python Hangman game with random word selection, input validation, guessed-letter state, win conditions, and safe replay logic.","breadcrumb":{"@id":"https:\/\/www.pythonpool.com\/python-hangman\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pythonpool.com\/python-hangman\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pythonpool.com\/python-hangman\/#primaryimage","url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2021\/01\/Theatre-Actor-Portfolio-Website-15.png","contentUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2021\/01\/Theatre-Actor-Portfolio-Website-15.png","width":1350,"height":650,"caption":"python hangman"},{"@type":"BreadcrumbList","@id":"https:\/\/www.pythonpool.com\/python-hangman\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pythonpool.com\/"},{"@type":"ListItem","position":2,"name":"Build a Python Hangman Game: Input, State, and Validation"}]},{"@type":"WebSite","@id":"https:\/\/www.pythonpool.com\/#website","url":"https:\/\/www.pythonpool.com\/","name":"Python Pool","description":"Practical Python tutorials, error fixes, code examples, and project guides.","publisher":{"@id":"https:\/\/www.pythonpool.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pythonpool.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.pythonpool.com\/#organization","name":"Python Pool","url":"https:\/\/www.pythonpool.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pythonpool.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2020\/08\/aa.png","contentUrl":"https:\/\/www.pythonpool.com\/wp-content\/uploads\/2020\/08\/aa.png","width":452,"height":185,"caption":"Python Pool"},"image":{"@id":"https:\/\/www.pythonpool.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/pythonpool","https:\/\/www.youtube.com\/c\/pythonpool"]},{"@type":"Person","@id":"https:\/\/www.pythonpool.com\/#\/schema\/person\/b91d749826b21e606d55cda77d51ef47","name":"Prachee Sao","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d018c3758049ab2511d0772ac1f73c338aaa8c921577f39e0f1e5716fc7efcb4?s=96&d=wavatar&r=g","caption":"Prachee Sao"}}]}},"_links":{"self":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/7243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/comments?post=7243"}],"version-history":[{"count":15,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/7243\/revisions"}],"predecessor-version":[{"id":41525,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/posts\/7243\/revisions\/41525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/media\/7596"}],"wp:attachment":[{"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/media?parent=7243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/categories?post=7243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pythonpool.com\/wp-json\/wp\/v2\/tags?post=7243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}