{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0ca26a9f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training completed!\n",
      "\n",
      "Q-Table:\n",
      "[[[ 39.45851     54.9539      39.45851     54.9539    ]\n",
      "  [ 43.79574345  40.6046745   48.45514701  62.171     ]\n",
      "  [ 40.9368      48.174596    54.86139792  70.19      ]\n",
      "  [ 60.63647971  79.1         62.06822093  47.352     ]]\n",
      "\n",
      " [[ 48.45851     62.171       45.9539      45.9539    ]\n",
      "  [  0.           0.           0.           0.        ]\n",
      "  [  0.           0.           0.           0.        ]\n",
      "  [ 55.82176     89.          69.4568704   70.0749958 ]]\n",
      "\n",
      " [[ 54.9539      54.9539      53.171       70.19      ]\n",
      "  [ 61.19        61.19        62.171       79.1       ]\n",
      "  [ 70.1         89.          70.19        89.        ]\n",
      "  [ 79.1        100.          79.1         80.        ]]\n",
      "\n",
      " [[ 62.171       43.795744    45.52166791  34.58354951]\n",
      "  [  0.           0.           0.           0.        ]\n",
      "  [ 79.1         80.          80.         100.        ]\n",
      "  [  0.           0.           0.           0.        ]]]\n",
      "\n",
      "Learned Path:\n",
      "[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (3, 2), (3, 3)]\n"
     ]
    }
   ],
   "source": [
    "# Reinforcement Learning \n",
    "# Maze Environment\n",
    "\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "# Create a 4x4 maze\n",
    "maze = np.array([\n",
    "    [0, 0, 0, 0],\n",
    "    [0, 1, 1, 0],\n",
    "    [0, 0, 0, 0],\n",
    "    [0, 1, 0, 0]\n",
    "])\n",
    "\n",
    "# 0 = Free path\n",
    "# 1 = Wall\n",
    "\n",
    "rows, cols = maze.shape\n",
    "\n",
    "# Start and goal positions\n",
    "start = (0, 0)\n",
    "goal = (3, 3)\n",
    "\n",
    "# Actions: Up, Down, Left, Right\n",
    "actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n",
    "\n",
    "# Q-table\n",
    "q_table = np.zeros((rows, cols, 4))\n",
    "\n",
    "# Learning parameters\n",
    "learning_rate = 0.8\n",
    "discount = 0.9\n",
    "epsilon = 0.2\n",
    "\n",
    "# Training\n",
    "for episode in range(1000):\n",
    "\n",
    "    state = start\n",
    "\n",
    "    for step in range(100):\n",
    "\n",
    "        # Choose action\n",
    "        if random.random() < epsilon:\n",
    "            action = random.randint(0, 3)\n",
    "        else:\n",
    "            action = np.argmax(q_table[state[0], state[1]])\n",
    "\n",
    "        # Calculate new position\n",
    "        new_row = state[0] + actions[action][0]\n",
    "        new_col = state[1] + actions[action][1]\n",
    "\n",
    "        # Check whether move is valid\n",
    "        if (new_row < 0 or new_row >= rows or\n",
    "            new_col < 0 or new_col >= cols or\n",
    "            maze[new_row, new_col] == 1):\n",
    "\n",
    "            reward = -10\n",
    "            next_state = state\n",
    "\n",
    "        else:\n",
    "            next_state = (new_row, new_col)\n",
    "\n",
    "            if next_state == goal:\n",
    "                reward = 100\n",
    "            else:\n",
    "                reward = -1\n",
    "\n",
    "        # Update Q-value\n",
    "        old_value = q_table[state[0], state[1], action]\n",
    "\n",
    "        next_max = np.max(\n",
    "            q_table[next_state[0], next_state[1]]\n",
    "        )\n",
    "\n",
    "        new_value = old_value + learning_rate * (\n",
    "            reward + discount * next_max - old_value\n",
    "        )\n",
    "\n",
    "        q_table[state[0], state[1], action] = new_value\n",
    "\n",
    "        state = next_state\n",
    "\n",
    "        # Stop if goal is reached\n",
    "        if state == goal:\n",
    "            break\n",
    "\n",
    "# Display learned Q-table\n",
    "print(\"Training completed!\")\n",
    "print(\"\\nQ-Table:\")\n",
    "print(q_table)\n",
    "\n",
    "# Test the learned path\n",
    "state = start\n",
    "path = [state]\n",
    "\n",
    "for step in range(20):\n",
    "\n",
    "    action = np.argmax(\n",
    "        q_table[state[0], state[1]]\n",
    "    )\n",
    "\n",
    "    new_row = state[0] + actions[action][0]\n",
    "    new_col = state[1] + actions[action][1]\n",
    "\n",
    "    if (new_row < 0 or new_row >= rows or\n",
    "        new_col < 0 or new_col >= cols or\n",
    "        maze[new_row, new_col] == 1):\n",
    "\n",
    "        break\n",
    "\n",
    "    state = (new_row, new_col)\n",
    "    path.append(state)\n",
    "\n",
    "    if state == goal:\n",
    "        break\n",
    "\n",
    "print(\"\\nLearned Path:\")\n",
    "print(path)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
