{"id":223,"date":"2015-01-16T21:06:00","date_gmt":"2015-01-16T21:06:00","guid":{"rendered":"https:\/\/santiagomarquezsolis.com\/index.php\/2026\/04\/20\/game-programming-in-python-part-2\/"},"modified":"2026-04-20T16:12:38","modified_gmt":"2026-04-20T16:12:38","slug":"game-programming-in-python-part-2","status":"publish","type":"post","link":"https:\/\/santiagomarquezsolis.com\/index.php\/en\/2015\/01\/16\/game-programming-in-python-part-2\/","title":{"rendered":"Game Programming in Python. Part 2."},"content":{"rendered":"<p>Welcome back to our Python game programming series! In Part 1, we covered the basics of pygame and created a simple interactive window. In this second part, we&#8217;ll build a complete <strong>Tic-Tac-Toe<\/strong> game with a graphical interface, turn management, and win detection.<\/p>\n<h2>What We&#8217;ll Build<\/h2>\n<p>Our Tic-Tac-Toe game will include:<\/p>\n<ul>\n<li>A graphical 3&#215;3 game board drawn with pygame<\/li>\n<li>Two-player turn management (X and O)<\/li>\n<li>Click detection to place marks<\/li>\n<li>Win detection (rows, columns, diagonals)<\/li>\n<li>Draw detection<\/li>\n<li>Game reset functionality<\/li>\n<\/ul>\n<h2>Setting Up<\/h2>\n<p>Make sure you have pygame installed: <code>pip install pygame<\/code><\/p>\n<h2>The Game Structure<\/h2>\n<pre><code>import pygame\r\nimport sys\r\n\r\n# Constants\r\nWINDOW_SIZE = 600\r\nBOARD_SIZE = 3\r\nCELL_SIZE = WINDOW_SIZE \/\/ BOARD_SIZE\r\nLINE_WIDTH = 5\r\nCIRCLE_RADIUS = CELL_SIZE \/\/ 3\r\nCIRCLE_WIDTH = 15\r\nCROSS_WIDTH = 25\r\nSPACE = CELL_SIZE \/\/ 4\r\n\r\n# Colors\r\nBG_COLOR = (28, 170, 156)\r\nLINE_COLOR = (23, 145, 135)\r\nCIRCLE_COLOR = (239, 231, 200)\r\nCROSS_COLOR = (66, 66, 66)\r\n\r\npygame.init()\r\nscreen = pygame.display.set_mode((WINDOW_SIZE, WINDOW_SIZE))\r\npygame.display.set_caption(\"Tic Tac Toe\")\r\nscreen.fill(BG_COLOR)<\/code><\/pre>\n<h2>Board Logic<\/h2>\n<pre><code>board = [[None] * BOARD_SIZE for _ in range(BOARD_SIZE)]\r\n\r\ndef draw_lines():\r\n    # Horizontal lines\r\n    for i in range(1, BOARD_SIZE):\r\n        pygame.draw.line(screen, LINE_COLOR, (0, i * CELL_SIZE), (WINDOW_SIZE, i * CELL_SIZE), LINE_WIDTH)\r\n    # Vertical lines\r\n    for i in range(1, BOARD_SIZE):\r\n        pygame.draw.line(screen, LINE_COLOR, (i * CELL_SIZE, 0), (i * CELL_SIZE, WINDOW_SIZE), LINE_WIDTH)\r\n\r\ndef draw_marks():\r\n    for row in range(BOARD_SIZE):\r\n        for col in range(BOARD_SIZE):\r\n            if board[row][col] == 'O':\r\n                center = (col * CELL_SIZE + CELL_SIZE \/\/ 2, row * CELL_SIZE + CELL_SIZE \/\/ 2)\r\n                pygame.draw.circle(screen, CIRCLE_COLOR, center, CIRCLE_RADIUS, CIRCLE_WIDTH)\r\n            elif board[row][col] == 'X':\r\n                start1 = (col * CELL_SIZE + SPACE, row * CELL_SIZE + SPACE)\r\n                end1 = (col * CELL_SIZE + CELL_SIZE - SPACE, row * CELL_SIZE + CELL_SIZE - SPACE)\r\n                start2 = (col * CELL_SIZE + CELL_SIZE - SPACE, row * CELL_SIZE + SPACE)\r\n                end2 = (col * CELL_SIZE + SPACE, row * CELL_SIZE + CELL_SIZE - SPACE)\r\n                pygame.draw.line(screen, CROSS_COLOR, start1, end1, CROSS_WIDTH)\r\n                pygame.draw.line(screen, CROSS_COLOR, start2, end2, CROSS_WIDTH)<\/code><\/pre>\n<h2>Win Detection<\/h2>\n<pre><code>def check_winner(player):\r\n    # Check rows\r\n    for row in range(BOARD_SIZE):\r\n        if all(board[row][col] == player for col in range(BOARD_SIZE)):\r\n            return True\r\n    # Check columns\r\n    for col in range(BOARD_SIZE):\r\n        if all(board[row][col] == player for row in range(BOARD_SIZE)):\r\n            return True\r\n    # Check diagonals\r\n    if all(board[i][i] == player for i in range(BOARD_SIZE)):\r\n        return True\r\n    if all(board[i][BOARD_SIZE-1-i] == player for i in range(BOARD_SIZE)):\r\n        return True\r\n    return False\r\n\r\ndef is_board_full():\r\n    return all(board[row][col] is not None \r\n               for row in range(BOARD_SIZE) \r\n               for col in range(BOARD_SIZE))<\/code><\/pre>\n<h2>Main Game Loop<\/h2>\n<pre><code>def main():\r\n    current_player = 'X'\r\n    game_over = False\r\n    \r\n    draw_lines()\r\n    \r\n    while True:\r\n        for event in pygame.event.get():\r\n            if event.type == pygame.QUIT:\r\n                pygame.quit()\r\n                sys.exit()\r\n            \r\n            if event.type == pygame.MOUSEBUTTONDOWN and not game_over:\r\n                mouseX, mouseY = event.pos\r\n                clicked_row = mouseY \/\/ CELL_SIZE\r\n                clicked_col = mouseX \/\/ CELL_SIZE\r\n                \r\n                if board[clicked_row][clicked_col] is None:\r\n                    board[clicked_row][clicked_col] = current_player\r\n                    \r\n                    if check_winner(current_player):\r\n                        print(f\"Player {current_player} wins!\")\r\n                        game_over = True\r\n                    elif is_board_full():\r\n                        print(\"It's a draw!\")\r\n                        game_over = True\r\n                    else:\r\n                        current_player = 'O' if current_player == 'X' else 'X'\r\n            \r\n            if event.type == pygame.KEYDOWN:\r\n                if event.key == pygame.K_r:  # Reset game\r\n                    for row in range(BOARD_SIZE):\r\n                        for col in range(BOARD_SIZE):\r\n                            board[row][col] = None\r\n                    game_over = False\r\n                    current_player = 'X'\r\n                    screen.fill(BG_COLOR)\r\n                    draw_lines()\r\n        \r\n        screen.fill(BG_COLOR)\r\n        draw_lines()\r\n        draw_marks()\r\n        pygame.display.update()\r\n\r\nmain()<\/code><\/pre>\n<h2>What You&#8217;ve Learned<\/h2>\n<p>By building this game, you&#8217;ve practiced:<\/p>\n<ul>\n<li>Drawing shapes and lines with pygame<\/li>\n<li>Handling mouse click events<\/li>\n<li>Mapping screen coordinates to game grid positions<\/li>\n<li>Implementing game logic (win detection, turn management)<\/li>\n<li>Game state management<\/li>\n<\/ul>\n<h2>Extensions to Try<\/h2>\n<p>Once you have the basic game working, try these improvements:<\/p>\n<ul>\n<li>Add a score counter for multiple rounds<\/li>\n<li>Implement a simple AI opponent<\/li>\n<li>Add sound effects<\/li>\n<li>Display the winner with a highlighted winning line<\/li>\n<\/ul>\n<p>Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome back to our Python game programming series! In Part 1, we covered the basics of pygame and created a simple interactive window. In this second part, we&#8217;ll build a complete Tic-Tac-Toe game with a graphical interface, turn management, and win detection. What We&#8217;ll Build Our Tic-Tac-Toe game will include: A graphical 3&#215;3 game board [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[162,282,284],"tags":[286,288,266,290],"class_list":["post-223","post","type-post","status-publish","format-standard","hentry","category-blog-en","category-games-en","category-python-en","tag-juegos-en","tag-pygame-en","tag-python-en","tag-tictactoe-en"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/comments?post=223"}],"version-history":[{"count":1,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/223\/revisions"}],"predecessor-version":[{"id":249,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/223\/revisions\/249"}],"wp:attachment":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/media?parent=223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/categories?post=223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/tags?post=223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}