From ef9fdf39ca9e0ca49271ac110be1d4498cb9a509 Mon Sep 17 00:00:00 2001 From: Philipp Horstenkamp Date: Tue, 31 Jan 2023 20:31:57 +0100 Subject: [PATCH] Added functionality to execute a turn --- main.ipynb | 171 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 30 deletions(-) diff --git a/main.ipynb b/main.ipynb index ee4eec0..9013f86 100644 --- a/main.ipynb +++ b/main.ipynb @@ -58,35 +58,27 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, - "outputs": [], - "source": [ - "def get_new_games(number_of_games:int):\n", - " empty = np.zeros([number_of_games, 8,8], dtype=int)\n", - " empty[:, 3:5, 3:5] = np.array([[-1,1], [1, -1]])\n", - " return empty" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, "outputs": [ { "data": { - "text/plain": "array([[[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]],\n\n [[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]]])" + "text/plain": "array([[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 1, -1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]])" }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "get_new_games(10)" + "def get_new_games(number_of_games:int):\n", + " empty = np.zeros([number_of_games, 8,8], dtype=int)\n", + " empty[:, 3:5, 3:5] = np.array([[-1,1], [1, -1]])\n", + " return empty\n", + "get_new_games(1)[0]" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -100,37 +92,43 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": {}, + "outputs": [], + "source": [ + "def get_new_games(number_of_games:int):\n", + " empty = np.zeros([number_of_games, 8,8], dtype=int)\n", + " empty[:, 3:5, 3:5] = np.array([[-1,1], [1, -1]])\n", + " return empty" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "8.58 ms ± 214 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", - "82.7 ms ± 2.17 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" + "17.2 ms ± 3.53 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", + "169 ms ± 33.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" ] }, { "data": { "text/plain": "array([[[False, False, False, False, False, False, False, False],\n [False, False, False, False, False, False, False, False],\n [False, False, False, True, False, False, False, False],\n [False, False, True, False, False, False, False, False],\n [False, False, False, False, False, True, False, False],\n [False, False, False, False, True, False, False, False],\n [False, False, False, False, False, False, False, False],\n [False, False, False, False, False, False, False, False]]])" }, - "execution_count": 16, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "def get_new_games(number_of_games:int):\n", - " empty = np.zeros([number_of_games, 8,8], dtype=int)\n", - " empty[:, 3:5, 3:5] = np.array([[-1,1], [1, -1]])\n", - " return empty\n", - "\n", "def recursive_steps(_array, rec_direction, rec_position, step_one=True):\n", " rec_position = rec_position + rec_direction\n", " if np.any((rec_position >= 8) | ( rec_position < 0)):\n", " return False\n", - " next_field = _array[rec_position[0], rec_position[1]]\n", + " next_field = _array[tuple(rec_position.tolist())]\n", " if next_field == 0:\n", " return False\n", " if next_field == -1:\n", @@ -152,17 +150,20 @@ "%timeit get_possible_turns(get_new_games(10))\n", "%timeit get_possible_turns(get_new_games(100))\n", "get_possible_turns(get_new_games(3))[:1]" - ] + ], + "metadata": { + "collapsed": false + } }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "outputs": [ { "data": { "text/plain": "(array([2, 2, 2]), array([2, 2, 2]))" }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -178,7 +179,117 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, + "outputs": [], + "source": [ + "def move_possible(board:np.ndarray, move: np.ndarray) -> bool:\n", + " if np.all(move == -1):\n", + " return np.all(get_possible_turns(board))\n", + " return any(recursive_steps(board[:, :], direction, move) for direction in DIRECTIONS)\n", + "\n", + "def moves_possible(boards:np.ndarray, moves: np.ndarray) -> np.ndarray:\n", + " arr_moves_possible = np.zeros(boards.shape[0], dtype=bool)\n", + " for game in range(boards.shape[0]):\n", + " if np.all(moves[game] == -1):\n", + " arr_moves_possible[game, :, :] = np.all(get_possible_turns(boards[game, : , :]))\n", + " arr_moves_possible[game, :, :] = any(recursive_steps(boards[game, :, :], direction, moves[game]) for direction in DIRECTIONS)\n", + " return arr_moves_possible" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 11, + "outputs": [ + { + "data": { + "text/plain": "array([[ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, -1, 0, 0, 0, 0],\n [ 0, 0, 0, -1, -1, 0, 0, 0],\n [ 0, 0, 0, -1, 1, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0],\n [ 0, 0, 0, 0, 0, 0, 0, 0]])" + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class InvalidTurn(ValueError):\n", + " pass\n", + "\n", + "\n", + "def to_moves(boards: np.ndarray, moves: np.ndarray) -> np.ndarray:\n", + "\n", + " def _do_directional_move(board: np.ndarray, rec_move: np.ndarray, rev_direction, step_one=True) -> bool:\n", + " rec_position = rec_move + rev_direction\n", + " if np.any((rec_position >= 8) | (rec_position < 0)):\n", + " return False\n", + " next_field = board[tuple(rec_position.tolist())]\n", + " if next_field == 0:\n", + " return False\n", + " if next_field == 1:\n", + " return not step_one\n", + " if next_field == -1:\n", + " if _do_directional_move(board, rec_position, rev_direction, step_one=False):\n", + " board[tuple(rec_position.tolist())] = 1\n", + " return True\n", + " return False\n", + "\n", + " def _do_move(_board: np.ndarray, move: np.ndarray) -> None:\n", + " if _board[tuple(move.tolist())] != 0:\n", + " raise InvalidTurn\n", + " action = False\n", + " for direction in DIRECTIONS:\n", + " if _do_directional_move(_board, move, direction):\n", + " action = True\n", + " if not action:\n", + " raise InvalidTurn()\n", + " _board[tuple(move.tolist())] = 1\n", + "\n", + " for game in range(boards.shape[0]):\n", + " _do_move(boards[game], moves[game])\n", + "boards = get_new_games(10)\n", + "to_moves(boards, np.array([[2,3]] * 10))\n", + "boards = boards * -1\n", + "boards[0]" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 12, + "outputs": [], + "source": [ + "to_moves(get_new_games(10), np.array([[2,3]] * 10))" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 13, + "outputs": [ + { + "data": { + "text/plain": "array([[4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3],\n [4, 3]])" + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.array([[4,3]] * 10)" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": 13, "outputs": [], "source": [], "metadata": {