{
 "metadata": {
  "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.3-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3",
   "language": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 727,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 728,
   "metadata": {},
   "outputs": [],
   "source": [
    "BOARD_WIDTH = 10\n",
    "BOARD_HEIGHT = 10\n",
    "\n",
    "SHIPS = [ (\"BATTLESHIP\", 5),\n",
    "          (\"CRUISER\", 3),\n",
    "          (\"DESTROYER<A>\", 2),\n",
    "          (\"DESTROYER<B>\", 2) ]\n",
    "          \n",
    "VALID_MOVES = [[-1, 0],\n",
    "               [-1, 1],\n",
    "               [ 0, 1],\n",
    "               [ 1, 1],\n",
    "               [ 1, 0],\n",
    "               [ 1,-1],\n",
    "               [ 0,-1],\n",
    "               [-1,-1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 729,
   "metadata": {},
   "outputs": [],
   "source": [
    "# random number functions\n",
    "#\n",
    "# seed the random number generator\n",
    "random.seed()\n",
    "\n",
    "# random_x_y\n",
    "#\n",
    "# generate a valid x,y coordinate on the board\n",
    "# returns: x,y\n",
    "#   x: integer between 1 and BOARD_HEIGHT\n",
    "#   y: integer between 1 and BOARD WIDTH\n",
    "def random_x_y():\n",
    "    x = random.randrange(1,BOARD_WIDTH+1)\n",
    "    y = random.randrange(1,BOARD_HEIGHT+1)\n",
    "    return (x,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 730,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "5 3\n"
     ]
    }
   ],
   "source": [
    "x,y = random_x_y()\n",
    "print (x,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 731,
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: add an optional starting coordinate for testing\n",
    "#       purposes\n",
    "def generate_ship_coordinates(ship):\n",
    "    \n",
    "    # randomly generate starting x,y coordinates\n",
    "    start_x, start_y = random_x_y()\n",
    "\n",
    "    # using starting coordinates and the ship type,\n",
    "    # generate a vector of possible directions the ship \n",
    "    # could be placed. directions are numbered 0-7 along\n",
    "    # points of the compass (N, NE, E, SE, S, SW, W, NW)\n",
    "    # clockwise. a vector of valid directions where the\n",
    "    # ship does not go off the board is determined\n",
    "    ship_len = SHIPS[ship][1] - 1\n",
    "    dirs = [False for x in range(8)]\n",
    "    dirs[0] = (start_x - ship_len) >=1\n",
    "    dirs[2] = (start_y + ship_len) <= BOARD_WIDTH\n",
    "    dirs[1] = dirs[0] and dirs[2]\n",
    "    dirs[4] = (start_x + ship_len) <= BOARD_HEIGHT\n",
    "    dirs[3] = dirs[2] and dirs[4]\n",
    "    dirs[6] = (start_y - ship_len) >= 1\n",
    "    dirs[5] = dirs[4] and dirs[6]\n",
    "    dirs[7] = dirs[6] and dirs[0]\n",
    "    directions = [p for p in range(len(dirs)) if dirs[p]]\n",
    "\n",
    "    # using the vector of valid directions, pick a\n",
    "    # random direction to place the ship\n",
    "    dir_idx = random.randrange(len(directions))\n",
    "    direction = directions[dir_idx]\n",
    "\n",
    "    # using the starting x,y, direction and ship\n",
    "    # type, return the coordinates of each point \n",
    "    # of the ship. VALID_MOVES is a staic array\n",
    "    # of coordinate offsets to walk from starting\n",
    "    # coordinate to the end coordinate in the \n",
    "    # chosen direction\n",
    "    ship_len = SHIPS[ship][1] - 1\n",
    "    d_x = VALID_MOVES[direction][0]\n",
    "    d_y = VALID_MOVES[direction][1]\n",
    "\n",
    "    coords = [(start_x,start_y)]\n",
    "    x_coord = start_x\n",
    "    y_coord = start_y\n",
    "    for i in range(ship_len):\n",
    "        x_coord = x_coord + d_x\n",
    "        y_coord = y_coord + d_y\n",
    "        coords.append((x_coord,y_coord))\n",
    "    return coords\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 732,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "BATTLESHIP       5 [(10, 2), (10, 3), (10, 4), (10, 5), (10, 6)]\nCRUISER          3 [(9, 4), (8, 4), (7, 4)]\nDESTROYER<A>     2 [(2, 5), (1, 5)]\nDESTROYER<B>     2 [(7, 8), (7, 9)]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "for ship in range(len(SHIPS)):\n",
    "    coords = generate_ship_coordinates(ship)\n",
    "    print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 733,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_blank_board():\n",
    "    return [ [ None for y in range(BOARD_WIDTH)] \n",
    "                    for x in range(BOARD_HEIGHT)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 734,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "    1  2  3  4  5  6  7  8  9 10\n 1                              \n 2                              \n 3                              \n 4                              \n 5                              \n 6                              \n 7                              \n 8                              \n 9                              \n10                              \n"
     ]
    }
   ],
   "source": [
    "def print_board(board):\n",
    "\n",
    "    # print board header (column numbers)\n",
    "    print('  ',end='')\n",
    "    for z in range(BOARD_WIDTH):\n",
    "        print(f'{z+1:3}',end='')\n",
    "    print('')\n",
    "\n",
    "    for x in range(len(board)):\n",
    "        print(f'{x+1:2}',end='')\n",
    "        for y in range(len(board[x])):\n",
    "            if(board[x][y] is None):\n",
    "                print(f\"{' ':3}\",end='')\n",
    "            else:\n",
    "                print(f\"{board[x][y]:3}\",end='')\n",
    "        print('')\n",
    "\n",
    "computer_board = create_blank_board()\n",
    "print_board(computer_board)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 735,
   "metadata": {},
   "outputs": [],
   "source": [
    "def place_ship(board,coords,ship):\n",
    "    for coord in coords:\n",
    "        board[coord[0]-1][coord[1]-1] = ship"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 736,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "DESTROYER<B>     2 [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]\n    1  2  3  4  5  6  7  8  9 10\n 1     0                        \n 2        0                     \n 3           0                  \n 4              0               \n 5                 0            \n 6                              \n 7                              \n 8                              \n 9                              \n10                              \n"
     ]
    }
   ],
   "source": [
    "# test place_ship\n",
    "board = create_blank_board()\n",
    "coords = generate_ship_coordinates(0)\n",
    "print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)\n",
    "place_ship(board,coords,0)\n",
    "print_board(board)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 737,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "    1  2  3  4  5  6  7  8  9 10\n",
      " 1                              \n",
      " 2              1               \n",
      " 3                 1  2         \n",
      " 4                    1  2      \n",
      " 5  0                           \n",
      " 6     0                        \n",
      " 7        0                     \n",
      " 8           0                  \n",
      " 9              0           3   \n",
      "10                       3      \n"
     ]
    }
   ],
   "source": [
    "# NOTE: A little quirk that exists here and in the orginal\n",
    "#       game: Ships are allowed to cross each other!\n",
    "#       For example: 2 destroyers, length 2, one at\n",
    "#       [(1,1),(2,2)] and other at [(2,1),(1,2)]\n",
    "\n",
    "def generate_board():\n",
    "    board = create_blank_board()\n",
    "\n",
    "    for ship in range(len(SHIPS)):\n",
    "        placed = False\n",
    "        coords = []\n",
    "        while not placed:\n",
    "            coords = generate_ship_coordinates(ship)\n",
    "            clear = True\n",
    "            for coord in coords:\n",
    "                if board[coord[0]-1][coord[1]-1] is not None:\n",
    "                    clear = False\n",
    "                    break\n",
    "            if clear:\n",
    "                placed = True\n",
    "        place_ship(board,coords,ship)\n",
    "    return board\n",
    "\n",
    "print_board(generate_board())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 738,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "[(4, 1), (3, 6), (6, 10), (10, 6), (4, 5)]\n"
     ]
    }
   ],
   "source": [
    "def generate_shots(number):\n",
    "    shots = []\n",
    "    for i in range(number):\n",
    "        shots.append(random_x_y())\n",
    "    return shots\n",
    "\n",
    "shots = generate_shots(5)\n",
    "print(shots)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}