microservices/template_snakeapi_service/notebooks/notebook.ipynb
2025-05-01 11:10:32 -07:00

363 lines
15 KiB
Text

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "a9683468",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Defaulting to user installation because normal site-packages is not writeable\n",
"Requirement already satisfied: flask in /home/student/.local/lib/python3.10/site-packages (2.3.2)\n",
"Requirement already satisfied: Jinja2>=3.1.2 in /home/student/.local/lib/python3.10/site-packages (from flask) (3.1.4)\n",
"Requirement already satisfied: itsdangerous>=2.1.2 in /home/student/.local/lib/python3.10/site-packages (from flask) (2.2.0)\n",
"Requirement already satisfied: Werkzeug>=2.3.3 in /home/student/.local/lib/python3.10/site-packages (from flask) (3.0.3)\n",
"Requirement already satisfied: click>=8.1.3 in /home/student/.local/lib/python3.10/site-packages (from flask) (8.1.7)\n",
"Requirement already satisfied: blinker>=1.6.2 in /home/student/.local/lib/python3.10/site-packages (from flask) (1.8.2)\n",
"Requirement already satisfied: MarkupSafe>=2.0 in /home/student/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)\n"
]
}
],
"source": [
"!pip install flask"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "aeee415d",
"metadata": {},
"outputs": [],
"source": [
"import logging\n",
"import os\n",
"import typing\n",
"import flask\n",
"\n",
"from flask import Flask\n",
"from flask import request\n",
"\n",
"print(\"Starting Battlesnake Server...\")\n",
"\n",
"def run_server(handlers: typing.Dict):\n",
" app = Flask(__name__)\n",
"\n",
" @app.get(\"/\")\n",
" def on_info():\n",
" print(\"info\")\n",
" return handlers[\"info\"]()\n",
"\n",
" @app.post(\"/start\")\n",
" def on_start():\n",
" print(\"go!\")\n",
" game_state = request.get_json()\n",
" handlers[\"start\"](game_state)\n",
" return \"ok\"\n",
"\n",
" @app.post(\"/move\")\n",
" def on_move():\n",
" game_state = request.get_json()\n",
" return handlers[\"move\"](game_state)\n",
"\n",
" @app.post(\"/end\")\n",
" def on_end():\n",
"# This isn't being called by the CLI atm\n",
"# print(request.get_json())\n",
"# end_game = request.get_json()\n",
"# print(end_game[\"death\"])\n",
" handlers[\"end\"](end_game)\n",
" return \"ok\"\n",
"\n",
" @app.after_request\n",
" def identify_server(response):\n",
" response.headers.set(\n",
" \"server\", \"battlesnake/github/starter-snake-python\"\n",
" )\n",
" return response\n",
"\n",
"\n",
" host = \"::\"\n",
" port = int(os.environ.get(\"PORT\", \"8000\"))\n",
"\n",
" logging.getLogger(\"werkzeug\").setLevel(logging.ERROR)\n",
"\n",
" print(f\"\\nRunning Battlesnake at http://{host}:{port}\")\n",
" app.run(host=host, port=port)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "11a8ff03",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"# Welcome to\n",
"# __________ __ __ .__ __\n",
"# \\______ \\_____ _/ |__/ |_| | ____ ______ ____ _____ | | __ ____\n",
"# | | _/\\__ \\\\ __\\ __\\ | _/ __ \\ / ___// \\\\__ \\ | |/ // __ \\\n",
"# | | \\ / __ \\| | | | | |_\\ ___/ \\___ \\| | \\/ __ \\| <\\ ___/\n",
"# |________/(______/__| |__| |____/\\_____>______>___|__(______/__|__\\\\_____>\n",
"#\n",
"# This file can be a nice home for your Battlesnake logic and helper functions.\n",
"#\n",
"# To get you started we've included code to prevent your Battlesnake from moving backwards.\n",
"# For more info see docs.battlesnake.com\n",
"\n",
"import random\n",
"import typing\n",
"\n",
"# info is called when you create your Battlesnake on play.battlesnake.com\n",
"# and controls your Battlesnake's appearance\n",
"# TIP: If you open your Battlesnake URL in a browser you should see this data\n",
"def info() -> typing.Dict:\n",
" print(\"INFO\")\n",
"#MMMM CUSTOMIZATIONS\n",
" return {\n",
" \"apiversion\": \"1\",\n",
" \"author\": \"MaybeMadelyn\", # TODO: Your Battlesnake Username\n",
" \"color\": \"#d5dbdb\", # TODO: Choose color\n",
" \"head\": \"default\", # TODO: Choose head\n",
" \"tail\": \"default\", # TODO: Choose tail\n",
" }\n",
"\n",
"\n",
"# start is called when your Battlesnake begins a game\n",
"def start(game_state: typing.Dict):\n",
" global start_snake_count\n",
" start_snake_count = len(game_state['board']['snakes'])\n",
" print(\"GAME START with \", start_snake_count,\" snakes\")\n",
"\n",
"\n",
"# end is called when your Battlesnake finishes a game\n",
"# this is not happening right now :/\n",
"def end(end_game: typing.Dict):\n",
"# ending = end_game['death']\n",
" print(\"GAME OVER. You died by: \",ending) \n",
"\n",
" \n",
"def search(targets, my_head, move_points, points):\n",
" if targets:\n",
" closest = targets[0]\n",
" distance = 100\n",
" \n",
" for target in targets:\n",
" x_distance = abs(my_head[\"x\"] - target[\"x\"])\n",
" y_distance = abs(my_head[\"y\"] - target[\"y\"])\n",
" \n",
" if x_distance + y_distance < distance:\n",
" closest = target\n",
" distance = x_distance + y_distance\n",
" \n",
" if closest[\"x\"] < my_head[\"x\"]:\n",
" move_points[\"left\"] += points\n",
" if closest[\"x\"] > my_head[\"x\"]:\n",
" move_points[\"right\"] += points\n",
" if closest[\"y\"] < my_head[\"y\"]:\n",
" move_points[\"down\"] += points\n",
" if closest[\"y\"] > my_head[\"y\"]:\n",
" move_points[\"up\"] += points\n",
" \n",
" \n",
"def search_head(targets, my_head, move_points, points):\n",
" if targets:\n",
" closest = targets[0]\n",
" distance = 100\n",
" \n",
" for target in targets:\n",
" x_distance = abs(my_head[\"x\"] - target[\"x\"])\n",
" y_distance = abs(my_head[\"y\"] - target[\"y\"])\n",
" \n",
" if x_distance + y_distance < distance:\n",
" closest = target\n",
" distance = x_distance + y_distance\n",
" \n",
" if closest[\"x\"] < my_head[\"x\"]:\n",
" move_points[\"left\"] += points\n",
" if closest[\"x\"] > my_head[\"x\"]:\n",
" move_points[\"right\"] += points\n",
" if closest[\"y\"] < my_head[\"y\"]:\n",
" move_points[\"down\"] += points\n",
" if closest[\"y\"] > my_head[\"y\"]:\n",
" move_points[\"up\"] += points\n",
" \n",
"\n",
" search(game_state[\"board\"][\"food\"], my_head, move_points, 20)\n",
" search(game_state[\"board\"][\"snakes\"], my_head, move_points, 20) \n",
"#mmmm FLOODFILL FUNCTION\n",
"def floodfill(snakes,start):\n",
" empty_spaces = 0\n",
" visited = []\n",
" to_visit = [start] \n",
" unsafe = []\n",
" for snake in snakes:\n",
" for body_part in snake[\"body\"]:\n",
" unsafe.append(body_part) #mmmm APPEND means adding something to the list\n",
" in_bounds = True\n",
" while to_visit: \n",
" in_bounds = not(to_visit[0][\"y\"] < 0 or to_visit[0][\"y\"] > 10 or to_visit[0][\"x\"] < 0 or to_visit[0][\"x\"] > 10)\n",
" if to_visit[0] not in unsafe and in_bounds and to_visit[0] not in visited:\n",
" empty_spaces += 1\n",
" to_visit.append({\"x\": to_visit[0][\"x\"] +1, \"y\": to_visit[0][\"y\"]})\n",
" to_visit.append({\"x\": to_visit[0][\"x\"] -1, \"y\": to_visit[0][\"y\"]})\n",
" to_visit.append({\"x\": to_visit[0][\"x\"], \"y\": to_visit[0][\"y\"] +1})\n",
" to_visit.append({\"x\": to_visit[0][\"x\"], \"y\": to_visit[0][\"y\"] -1})\n",
" \n",
" visited.append(to_visit[0])\n",
" to_visit.pop(0)\n",
" \n",
" return empty_spaces\n",
"\n",
" \n",
"# move is called on every turn and returns your next move\n",
"# Valid moves are \"up\", \"down\", \"left\", or \"right\"\n",
"# See https://docs.battlesnake.com/api/example-move for available data\n",
"def move(game_state: typing.Dict) -> typing.Dict:\n",
"\n",
" move_points = {\"up\": 10, \"down\": 10, \"left\": 10, \"right\": 10}\n",
" moves = [\"up\", \"down\", \"left\", \"right\"]\n",
"\n",
" # We've included code to prevent your Battlesnake from moving backwards\n",
" my_head = game_state[\"you\"][\"body\"][0] # Coordinates of your head\n",
" my_neck = game_state[\"you\"][\"body\"][1] # Coordinates of your \"neck\"\n",
" my_body = game_state['you']['body']\n",
"\n",
" if my_neck[\"x\"] < my_head[\"x\"]: # Neck is left of head, don't move left\n",
" move_points[\"left\"] = 0\n",
"\n",
" elif my_neck[\"x\"] > my_head[\"x\"]: # Neck is right of head, don't move right\n",
" move_points[\"right\"] = 0\n",
"\n",
" elif my_neck[\"y\"] < my_head[\"y\"]: # Neck is below head, don't move down\n",
" move_points[\"down\"] = 0\n",
"\n",
" elif my_neck[\"y\"] > my_head[\"y\"]: # Neck is above head, don't move up\n",
" move_points[\"up\"] = 0\n",
"\n",
" #MMMM MAKE SURE YOU DONT HIT THE WALL\n",
"\n",
" game_height = game_state[\"board\"][\"height\"]\n",
" game_width = game_state[\"board\"][\"width\"]\n",
" \n",
" \n",
" if my_head[\"y\"] == game_height - 1:\n",
" move_points[\"up\"] -= 1000\n",
" \n",
" if my_head[\"y\"] == 0:\n",
" move_points[\"down\"] -= 1000\n",
" \n",
" if my_head[\"x\"] == game_width - 1:\n",
" move_points[\"right\"] -= 1000\n",
" print(\"DONT GO RIGHT!\")\n",
" print(f\"Right points: {move_points['right']}\")\n",
"\n",
" if my_head[\"x\"] == 0:\n",
" move_points[\"left\"] -= 1000\n",
" \n",
" \n",
" #MMMM DONT RUN INTO YOURSELF\n",
" \n",
" for body_part in my_body:\n",
" if body_part[\"y\"] == my_head[\"y\"]+1 and body_part[\"x\"] == my_head[\"x\"]:\n",
" move_points[\"up\"] -= 1000\n",
" \n",
" if body_part[\"y\"] == my_head[\"y\"]-1 and body_part[\"x\"] == my_head[\"x\"]:\n",
" move_points[\"down\"] -= 1000\n",
" \n",
" if body_part[\"x\"] == my_head[\"x\"]+1 and body_part[\"y\"] == my_head[\"y\"]:\n",
" move_points[\"right\"] -= 1000\n",
" \n",
" if body_part[\"x\"] == my_head[\"x\"]-1 and body_part[\"y\"] == my_head[\"y\"]:\n",
" move_points[\"left\"] -= 1000\n",
" \n",
" #MMMM DONT RUN INTO OTHER SNAKES\n",
" \n",
" all_snakes = game_state[\"board\"][\"snakes\"]\n",
" for snakes in all_snakes:\n",
" for body_part in snakes[\"body\"]:\n",
" if body_part[\"y\"] == my_head[\"y\"]+1 and body_part[\"x\"] == my_head[\"x\"]:\n",
" move_points[\"up\"] -= 1000\n",
"\n",
" if body_part[\"y\"] == my_head[\"y\"]-1 and body_part[\"x\"] == my_head[\"x\"]:\n",
" move_points[\"down\"] -= 1000\n",
"\n",
" if body_part[\"x\"] == my_head[\"x\"]+1 and body_part[\"y\"] == my_head[\"y\"]:\n",
" move_points[\"right\"] -= 1000\n",
"\n",
" if body_part[\"x\"] == my_head[\"x\"]-1 and body_part[\"y\"] == my_head[\"y\"]:\n",
" move_points[\"left\"] -= 1000\n",
" \n",
" move_points[\"right\"] += floodfill(all_snakes, {\"x\": my_head[\"x\"] +1, \"y\": my_head[\"y\"]})\n",
" move_points[\"left\"] += floodfill(all_snakes, {\"x\": my_head[\"x\"] -1, \"y\": my_head[\"y\"]})\n",
" move_points[\"up\"] += floodfill(all_snakes, {\"x\": my_head[\"x\"] , \"y\": my_head[\"y\"] +1})\n",
" move_points[\"down\"] += floodfill(all_snakes, {\"x\": my_head[\"x\"] , \"y\": my_head[\"y\"] -1})\n",
"\n",
" \n",
" #mmmm EAT SOME FOOD \n",
" #bfs\n",
" \n",
" # Compare all of the moves to create a list of all moves with the highest score\n",
" print(f\"Right points: {move_points['right']}\")\n",
" best_moves = []\n",
" for move, points in move_points.items():\n",
" if len(best_moves) == 0:\n",
" best_moves.append(move)\n",
" else:\n",
" for good_move in best_moves:\n",
" if points > move_points[good_move]:\n",
" best_moves.clear()\n",
" best_moves.append(move)\n",
" elif points == move_points[good_move]:\n",
" best_moves.append(move)\n",
" break\n",
" \n",
" # Choose a random move from the best choices\n",
" print(f\"Right points: {move_points['right']}\")\n",
" next_move = random.choice(best_moves)\n",
" # TODO: Step 4 - Move towards food instead of random, to regain health and survive longer\n",
" # food = game_state['board']['food']\n",
"\n",
" print(f\"MOVE {game_state['turn']}: {next_move}\")\n",
" print(f\"MOVE {game_state['turn']} POINTS: UP - {move_points['up']}, DOWN - {move_points['down']}, LEFT - {move_points['left']}, RIGHT - {move_points['right']}\")\n",
" return {\"move\": next_move}\n",
"\n",
"run_server({\"info\": info, \"start\": start, \"move\": move, \"end\": end})\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "845e510c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}