Simple Tic-Tac-Toe Game Using Python Programming
Data science projects in pondicherry
Create New

Simple Tic-Tac-Toe Game Using Python Programming

Project period

07/22/2020 - 08/31/2020

Views

55

0



Simple Tic-Tac-Toe Game Using Python Programming
Simple Tic-Tac-Toe Game Using Python Programming

This is a python implementation project and it will replace pencil games to real-time computer games, which is popularly known as the Tic Tac Toe game. This game is simply done by the command line using python programming. The gameplay design is so simple that the user won’t find it difficult to use and understand. It is possible to play the game with artificial intelligence, with three levels. We are in a plan to build a two-player tic-tac-toe game, which we can play in the command-line. Initially, we will make an empty game board and then we will take inputs from the players and we will check for the winning condition. If the whole board gets filled and no one wins, we will declare the result as tie and ask users thay they are ready to restart the game. We built this game using Python 3, so make sure you have already installed it. After building this game, we can get a clear idea about important dictionaries in python, and how to access dictionaries, how to iterate over dictionaries, looping like for loop, if else conditions and creating functions in python.

Why: Problem statement

The most favorite game that we had played in our childhood was “tic-tac-toe”. We played this game with our friends using paper and a pencil or pen. So, we people wasted a lot of paper for playing this game. But for a change in this program we are gonna play this game with a computer through python programming. Nowadays people have more stress because of their work and studies. Inorder to reduce their stress, we created this game.

How: Solution description

This game was created by simple python programming. It is possible to play the game with the computer, it has three levels. That is an easy, medium, and difficulty level. we can select the level randomly if we want. With the help of coordinates, we are gonna place x(s). The AI will place o(s) as an opponent. We can also set the levels that we want.

  1. If you will win in one move ( It has two options in a row), it places a third to get three in a row and win.

  2. If the opponent will win in one move, it plays the third itself to block the opponent from winning.

  3. Otherwise, it makes a random move. 

The "**hard**" level difficulty implements the **minimax** algorithm, which is the brute force algorithm that maximizes the value of the own position and minimizes the value of the opponent's position. Basically, it can see all possible outcomes until the end of the game and choose the best of them considering his opponent also would play perfectly. So, it does not rely on the blunders of the opponent, it plays perfectly regardless of the opponent's skill.

The library that we had used :

  1. Import Itertools

  2. Import Random

  3. Import Collections

 
The board is numbered like the laptop's keyboards number pad. So the player can make their move in the game board by entering the number from the laptop keyboard number pad.
 
Result:

How is it different from competition

When compared to other tic tac toe gaming programs I created by using simple python programming. This program is very simple to execute and use. You can easily understand and play this game. We can run the function with the help of coordinates. We can mention the 3 levels that we want to play.

Who are your customers

As we know it is a most favorite game of all time for kids, but it is not only made for kids, who like to play this game such as students, employees, housewives, and all the people because it has three levels from easy to hard. It is a time passing game. Kids will love this game on python as it is new for them. We set three levels in this game, so people can randomly select and play based on their interest.

Project Phases and Schedule

Planning: First, I look over the rules of the game. Then the way of giving input to the system.  

Software Installation: Before we start the project, First of all we need to install Python 3.7 and all the required python packages.

Designing: Then I decided to import the important libraries such as itertool, random, collection libraries for the program to run Tic-Tac-Toe.

Construction: I have constructed it with a simple mechanism. I used python programming to develop this game and used coordinates for input. After setting the coordinate We implemented three stages to play this game that is easy, intermediate, and complex. Then I ran and tested the program. The program runs properly.

Resources Required

Software requirements: Python 3.7 - Underneath the Python Releases for Windows find Latest Python 3 Release – Python 3.7. 4 (latest stable release as of now is Python 3.7. The advantages of Python 3.7 are Easier access to debuggers through a new breakpoint() built-in, Simple class creation using data classes, Customized access to module attributes, Improved support for type hinting and Higher precision timing functions. 

Anaconda tool: Anaconda may be a free and open-source distribution of the Python and R programming languages for scientific computing (data science, machine learning applications, large-scale processing, prediction analysis, etc.). You can download anaconda tool for Python by clicking this link - https://anaconda.org

It is available for free

Github link:

https://github.com/kevinbernard3777/tictactoe.git

Download:
Project Code Code copy
/* Your file Name : tictactoe.ipynb */
/* Your coding Language : python */
/* Your code snippet start here */
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Input command: > start user easy\n",
      "---------\n",
      "|       |\n",
      "|       |\n",
      "|       |\n",
      "---------\n",
      "Enter the coordinates: (x y) > 2 2\n",
      "---------\n",
      "|       |\n",
      "|   X   |\n",
      "|       |\n",
      "---------\n",
      "Making move level \"easy\"\n",
      "---------\n",
      "|       |\n",
      "|   X   |\n",
      "|     O |\n",
      "---------\n",
      "Enter the coordinates: (x y) > 1 3 \n",
      "---------\n",
      "| X     |\n",
      "|   X   |\n",
      "|     O |\n",
      "---------\n",
      "Making move level \"easy\"\n",
      "---------\n",
      "| X     |\n",
      "| O X   |\n",
      "|     O |\n",
      "---------\n",
      "Enter the coordinates: (x y) > 3 3\n",
      "---------\n",
      "| X   X |\n",
      "| O X   |\n",
      "|     O |\n",
      "---------\n",
      "Making move level \"easy\"\n",
      "---------\n",
      "| X   X |\n",
      "| O X O |\n",
      "|     O |\n",
      "---------\n",
      "Enter the coordinates: (x y) > 2 3\n",
      "---------\n",
      "| X X X |\n",
      "| O X O |\n",
      "|     O |\n",
      "---------\n",
      "X wins\n"
     ]
    }
   ],
   "source": [
    "from itertools import product\n",
    "from random import choice\n",
    "from collections import Counter\n",
    "\n",
    "\n",
    "class OccupiedCell(Exception): pass\n",
    "\n",
    "\n",
    "class Field:\n",
    "    coords = sorted(product(range(1, 4), repeat=2), key=lambda a: (- a[1], a[0]))\n",
    "\n",
    "    def __init__(self, start=None):\n",
    "        if start is None:\n",
    "            self.cells = dict(zip(Field.coords, [' ' for _ in range(9)]))\n",
    "        else:\n",
    "            self.cells = dict(zip(Field.coords, start))\n",
    "        self.is_X_turn = bool(Counter(self.cells.values())[' '] % 2)\n",
    "        self.state = 'Game not finished'\n",
    "\n",
    "    def __str__(self):\n",
    "        return ('---------\\n'\n",
    "                '| {} {} {} |\\n'\n",
    "                '| {} {} {} |\\n'\n",
    "                '| {} {} {} |\\n'\n",
    "                '---------').format(*self.cells.values())\n",
    "\n",
    "    @property\n",
    "    def free_cells(self):\n",
    "        return [key for key in self.cells if self.cells[key] == ' ']\n",
    "\n",
    "    def get_symbol(self, current=True):\n",
    "        return ('X' if self.is_X_turn else 'O') if current else ('O' if self.is_X_turn else 'X')\n",
    "\n",
    "    def evaluate(self, coord):\n",
    "        return any(map(lambda a: len(set(a)) == 1 and ' ' not in set(a),\n",
    "                       [[self.cells[(coord[0]), n] for n in range(1, 4)],\n",
    "                        [self.cells[n, (coord[1])] for n in range(1, 4)],\n",
    "                        [self.cells[n, n] for n in range(1, 4)],\n",
    "                        [self.cells[n, 4 - n] for n in range(1, 4)]\n",
    "                        ]))\n",
    "\n",
    "    def update(self, coord, with_current_symbol=True, raise_OccupiedCell=True):\n",
    "        if any(n < 1 or n > 3 for n in [*coord]):\n",
    "            raise IndexError\n",
    "        if raise_OccupiedCell and not self.cells[coord] == ' ':\n",
    "            raise OccupiedCell\n",
    "\n",
    "        symbol = self.get_symbol(with_current_symbol)\n",
    "        self.cells[coord] = symbol\n",
    "        self.is_X_turn = not self.is_X_turn\n",
    "        if self.evaluate(coord):\n",
    "            self.state = \"{} wins\".format(symbol)\n",
    "            return True\n",
    "        elif not Counter(self.cells.values())[' ']:\n",
    "            self.state = 'Draw'\n",
    "        return False\n",
    "\n",
    "\n",
    "class Game:\n",
    "    def __init__(self):\n",
    "        self.players = []\n",
    "        self.field = None\n",
    "        self.main()\n",
    "\n",
    "    def user_moves(self):\n",
    "        while True:\n",
    "            try:\n",
    "                x, y = [int(n) for n in input('Enter the coordinates: (x y) > ').split()]\n",
    "            except ValueError:\n",
    "                print('You should enter numbers!')\n",
    "                continue\n",
    "            try:\n",
    "                self.field.update((x, y))\n",
    "            except IndexError:\n",
    "                print('Coordinates should be from 1 to 3!')\n",
    "                continue\n",
    "            except OccupiedCell:\n",
    "                print('This cell is occupied! Choose another one!')\n",
    "                continue\n",
    "            return True\n",
    "\n",
    "    def make_random_move(self, coords=None):\n",
    "        coord = choice(self.field.free_cells) if coords is None else choice(coords)\n",
    "        self.field.update(coord)\n",
    "\n",
    "    def bot_easy(self):\n",
    "        print('Making move level \"easy\"')\n",
    "        self.make_random_move()\n",
    "\n",
    "    def get_candidate_moves(self, field=None):\n",
    "        if field is None:\n",
    "            field = self.field\n",
    "        scenarios = {cell: Field(field.cells.values()) for cell in field.free_cells}\n",
    "        return [cell for cell, field_obj in scenarios.items() if field_obj.update(cell)] or \\\n",
    "               [cell for cell, field_obj in scenarios.items() if field_obj.update(cell, True, False)]\n",
    "\n",
    "    def bot_medium(self):\n",
    "        print('Making move level \"medium\"')\n",
    "        candidate_moves = self.get_candidate_moves()\n",
    "        return self.make_random_move(candidate_moves) if candidate_moves else self.make_random_move()\n",
    "\n",
    "    def minimax(self, field=None, deep=0):\n",
    "        if field is None:\n",
    "            field = self.field\n",
    "        branches = {}\n",
    "        for cell in field.free_cells:\n",
    "            scenario = Field(field.cells.values())\n",
    "            if scenario.update(cell):\n",
    "                branches[cell] = -1 if deep % 2 else 1\n",
    "            elif scenario.state == 'Draw':\n",
    "                branches[cell] = 0\n",
    "            else:\n",
    "                branches[cell] = self.minimax(scenario, deep + 1)\n",
    "        if deep:\n",
    "            return min(branches.values()) if deep % 2 else max(branches.values())\n",
    "        else:\n",
    "            return {\n",
    "                1: [cell for cell in branches if branches[cell] == 1],\n",
    "                0: [cell for cell in branches if branches[cell] == 0],\n",
    "                -1: [cell for cell in branches if branches[cell] == -1]\n",
    "            }\n",
    "\n",
    "    def bot_hard(self):\n",
    "        print('Making move level \"hard\"')\n",
    "        all_moves = self.minimax()\n",
    "        if all_moves[1]:\n",
    "            return self.make_random_move(all_moves[1])\n",
    "        if all_moves[0]:\n",
    "            return self.make_random_move(all_moves[0])\n",
    "        if all_moves[-1]:\n",
    "            return self.make_random_move(all_moves[-1])\n",
    "\n",
    "    @classmethod\n",
    "    def player_move(cls, key):\n",
    "        player_move = {\n",
    "            'user': cls.user_moves,\n",
    "            'easy': cls.bot_easy,\n",
    "            'medium': cls.bot_medium,\n",
    "            'hard': cls.bot_hard\n",
    "        }\n",
    "        return player_move[key]\n",
    "\n",
    "    def play(self):\n",
    "        print(self.field)\n",
    "        for turn in range(9 - len(self.field.free_cells), 9):\n",
    "            Game.player_move(self.players[turn % 2])(self)\n",
    "            print(self.field)\n",
    "            if not self.field.state == 'Game not finished':\n",
    "                print(self.field.state)\n",
    "                break\n",
    "\n",
    "    def set_players(self, command):\n",
    "        try:\n",
    "            start_command, first_player, second_player = command.split()\n",
    "            if all(player in ['user', 'easy', 'medium', 'hard'] for player in [first_player, second_player]):\n",
    "                self.players = [first_player, second_player]\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        except ValueError:\n",
    "            return False\n",
    "\n",
    "    def main(self):\n",
    "        while True:\n",
    "            command = input('Input command: > ')\n",
    "            if command == 'exit':\n",
    "                break\n",
    "            elif self.set_players(command):\n",
    "                self.field = Field()\n",
    "                self.play()\n",
    "            else:\n",
    "                print('Bad parameters!')\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    Game()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
View on Github
tictactoe

Comments

Leave a Comment

Post a Comment

Are you Interested in this project?


Do you need help with a similar project? We can guide you. Please Click the Contact Us button.


Contact Us

Social Sharing