{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tic Tac Toe \n",
    "\n",
    "This is the solution for the Milestone Project! A two player game made within a Jupyter Notebook. Feel free to download the notebook to understand how it works!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First some imports we'll need to use for displaying output and set the global variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Specifically for the iPython Notebook environment for clearing output.\n",
    "from IPython.display import clear_output\n",
    "\n",
    "# Global variables\n",
    "board = [' '] * 10\n",
    "game_state = True\n",
    "announce = ''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next make a function that will reset the board, in this case we'll store values as a list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Note: Game will ignore the 0 index\n",
    "def reset_board():\n",
    "    global board,game_state\n",
    "    board = [' '] * 10\n",
    "    game_state = True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now create a function to display the board, I'll use the num pad as the board reference. \n",
    "Note: Should probably just make board and player classes later...."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def display_board():\n",
    "    ''' This function prints out the board so the numpad can be used as a reference '''\n",
    "    # Clear current cell output\n",
    "    clear_output()\n",
    "    # Print board\n",
    "    print \"  \"+board[7]+\" |\"+board[8]+\" | \"+board[9]+\" \"\n",
    "    print \"------------\"\n",
    "    print \"  \"+board[4]+\" |\"+board[5]+\" | \"+board[6]+\" \"\n",
    "    print \"------------\"\n",
    "    print \"  \"+board[1]+\" |\"+board[2]+\" | \"+board[3]+\" \"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a function to check for a win by comparing inputs in the board list. Note: Maybe should just have a list of winning combos and cycle through them?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def win_check(board, player):\n",
    "    ''' Check Horizontals,Verticals, and Diagonals for a win '''\n",
    "    if (board[7]  ==  board[8] ==  board[9] == player) or \\\n",
    "        (board[4] ==  board[5] ==  board[6] == player) or \\\n",
    "        (board[1] ==  board[2] ==  board[3] == player) or \\\n",
    "        (board[7] ==  board[4] ==  board[1] == player) or \\\n",
    "        (board[8] ==  board[5] ==  board[2] == player) or \\\n",
    "        (board[9] ==  board[6] ==  board[3] == player) or \\\n",
    "        (board[1] ==  board[5] ==  board[9] == player) or \\\n",
    "        (board[3] ==  board[5] ==  board[7] == player):\n",
    "        return True\n",
    "    else:\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define function to check if the board is already full in case of a tie. (This is straightforward with our board stored as a list)\n",
    "Just remember index 0 is always empty."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def full_board_check(board):\n",
    "    ''' Function to check if any remaining blanks are in the board '''\n",
    "    if \" \" in board[1:]:\n",
    "        return False\n",
    "    else:\n",
    "        return True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now define a function to get player input and do various checks on it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def ask_player(mark):\n",
    "    ''' Asks player where to place X or O mark, checks validity '''\n",
    "    global board\n",
    "    req = 'Choose where to place your: ' + mark\n",
    "    while True:\n",
    "        try:\n",
    "            choice = int(raw_input(req))\n",
    "        except ValueError:\n",
    "            print(\"Sorry, please input a number between 1-9.\")\n",
    "            continue\n",
    "\n",
    "        if choice not in range(1,10):\n",
    "            print(\"Sorry, please input a number between 1-9.\")\n",
    "            continue\n",
    "\n",
    "        if board[choice] == \" \":\n",
    "            board[choice] = mark\n",
    "            break\n",
    "        else:\n",
    "            print \"That space isn't empty!\"\n",
    "            continue\n",
    "            \n",
    "    \n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now have a function that takes in the player's choice (via the ask_player function) then returns the game_state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def player_choice(mark):\n",
    "    global board,game_state,announce\n",
    "    #Set game blank game announcement\n",
    "    announce = ''\n",
    "    #Get Player Input\n",
    "    mark = str(mark)\n",
    "    # Validate input\n",
    "    ask_player(mark)\n",
    "\n",
    "    #Check for player win\n",
    "    if win_check(board,mark):\n",
    "        clear_output()\n",
    "        display_board()\n",
    "        announce = mark +\" wins! Congratulations\"\n",
    "        game_state = False\n",
    "    \n",
    "    #Show board\n",
    "    clear_output()\n",
    "    display_board()\n",
    "\n",
    "    #Check for a tie \n",
    "    if full_board_check(board):\n",
    "        announce = \"Tie!\"\n",
    "        game_state = False\n",
    "        \n",
    "    return game_state,announce\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally put it all together in a function to play the game."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def play_game():\n",
    "    reset_board()\n",
    "    global announce\n",
    "    \n",
    "    # Set marks\n",
    "    X='X'\n",
    "    O='O'\n",
    "    while True:\n",
    "        # Show board\n",
    "        clear_output()\n",
    "        display_board()\n",
    "        \n",
    "        # Player X turn\n",
    "        game_state,announce = player_choice(X)\n",
    "        print announce\n",
    "        if game_state == False:\n",
    "            break\n",
    "            \n",
    "        # Player O turn\n",
    "        game_state,announce = player_choice(O)\n",
    "        print announce\n",
    "        if game_state == False:\n",
    "            break\n",
    "    \n",
    "    # Ask player for a rematch\n",
    "    rematch = raw_input('Would you like to play again? y/n')\n",
    "    if rematch == 'y':\n",
    "        play_game()\n",
    "    else:\n",
    "        print \"Thanks for playing!\"\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's play!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  O |X |   \n",
      "------------\n",
      "  X |X | O \n",
      "------------\n",
      "  O |X |   \n",
      "X wins! Congratulations\n",
      "Would you like to play again? y/nn\n",
      "Thanks for playing!\n"
     ]
    }
   ],
   "source": [
    "play_game()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}