Spaces:
Running
Running
uploading api
Browse files- .gitignore +1 -0
- Procfile +1 -0
- README.md +2 -10
- binary_map.json +1 -0
- main.py +43 -0
- models/fixed_model.h5 +3 -0
- models/fixed_model.json +1 -0
- models/random_model.h5 +3 -0
- models/random_model.json +1 -0
- requirements.txt +0 -0
- utility.py +212 -0
- web/README.md +11 -0
- web/arrows.png +0 -0
- web/index.html +180 -0
- web/script.js +386 -0
- web/snake.png +0 -0
- web/style.css +280 -0
- web/swipe.js +157 -0
.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
Procfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
web: gunicorn -w 3 -k uvicorn.workers.UvicornWorker main:app
|
README.md
CHANGED
|
@@ -1,10 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
emoji: 🌍
|
| 4 |
-
colorFrom: yellow
|
| 5 |
-
colorTo: purple
|
| 6 |
-
sdk: docker
|
| 7 |
-
pinned: false
|
| 8 |
-
---
|
| 9 |
-
|
| 10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
+
# FAST API
|
| 2 |
+
This API is used as backend for the game [Intelli Snake 2](https://geetu040.github.io/intelli-snake-2/)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
binary_map.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
main.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
import json, utility
|
| 3 |
+
|
| 4 |
+
app = FastAPI()
|
| 5 |
+
|
| 6 |
+
# ADDING ORIGINS
|
| 7 |
+
from fastapi.middleware.cors import CORSMiddleware
|
| 8 |
+
origins = [
|
| 9 |
+
"http://127.0.0.1:5500", # local host
|
| 10 |
+
"https://geetu040.github.io", # where app is hosted
|
| 11 |
+
]
|
| 12 |
+
app.add_middleware(
|
| 13 |
+
CORSMiddleware,
|
| 14 |
+
allow_origins=origins,
|
| 15 |
+
allow_credentials=True,
|
| 16 |
+
allow_methods=["*"],
|
| 17 |
+
allow_headers=["*"],
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
+
@app.get("/")
|
| 21 |
+
def index():
|
| 22 |
+
return {"Hello": "World"}
|
| 23 |
+
|
| 24 |
+
@app.get("/intelli-snake/map-{info}")
|
| 25 |
+
def intelliSnake2_map(info:str):
|
| 26 |
+
returned_info = utility.load_map( json.loads(info) )
|
| 27 |
+
return json.dumps(returned_info)
|
| 28 |
+
|
| 29 |
+
@app.get("/intelli-snake/automate-{info}")
|
| 30 |
+
def automate(info:str):
|
| 31 |
+
predicted_dirs = utility.automate( json.loads(info) )
|
| 32 |
+
return predicted_dirs
|
| 33 |
+
|
| 34 |
+
@app.get("/intelli-snake/automate_faster-{info}")
|
| 35 |
+
def automate_faster(info:str):
|
| 36 |
+
returned_infos = utility.automate_faster( json.loads(info) )
|
| 37 |
+
return json.dumps(returned_infos)
|
| 38 |
+
|
| 39 |
+
@app.get("/intelli-snake/write-{content}")
|
| 40 |
+
def write(content:str):
|
| 41 |
+
with open("latest_dataset.txt", "a") as f:
|
| 42 |
+
f.write(content)
|
| 43 |
+
return "nothing"
|
models/fixed_model.h5
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b9c9405985f5de402e6569cec16a58da0ae422471cf1e7934fa75b1ccbe00b29
|
| 3 |
+
size 1704248
|
models/fixed_model.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"class_name": "Functional", "config": {"name": "model_12", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_34"}, "name": "input_34", "inbound_nodes": []}, {"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_35"}, "name": "input_35", "inbound_nodes": []}, {"class_name": "Sequential", "config": {"name": "sequential_45", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_161_input"}}, {"class_name": "Dense", "config": {"name": "dense_161", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_162", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_163", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_45", "inbound_nodes": [[["input_34", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "sequential_46", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_165_input"}}, {"class_name": "Dense", "config": {"name": "dense_165", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_166", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_167", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_46", "inbound_nodes": [[["input_35", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_164", "trainable": true, "dtype": "float32", "units": 10, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_164", "inbound_nodes": [[["sequential_45", 1, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_168", "trainable": true, "dtype": "float32", "units": 10, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_168", "inbound_nodes": [[["sequential_46", 1, 0, {}]]]}, {"class_name": "Concatenate", "config": {"name": "concatenate_12", "trainable": true, "dtype": "float32", "axis": -1}, "name": "concatenate_12", "inbound_nodes": [[["dense_164", 0, 0, {}], ["dense_168", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "sequential_47", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 20], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_169_input"}}, {"class_name": "Dense", "config": {"name": "dense_169", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_170", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_171", "trainable": true, "dtype": "float32", "units": 200, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_18", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_172", "trainable": true, "dtype": "float32", "units": 800, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_19", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_173", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_47", "inbound_nodes": [[["concatenate_12", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_174", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_174", "inbound_nodes": [[["sequential_47", 1, 0, {}]]]}], "input_layers": [["input_34", 0, 0], ["input_35", 0, 0]], "output_layers": [["dense_174", 0, 0]]}, "keras_version": "2.8.0", "backend": "tensorflow"}
|
models/random_model.h5
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9613b076879d31b05005a0fe8c6b4f55913a8f95288cf128932b863aa94557c7
|
| 3 |
+
size 2961704
|
models/random_model.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"class_name": "Functional", "config": {"name": "random_model", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_poss"}, "name": "input_poss", "inbound_nodes": []}, {"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_dirs"}, "name": "input_dirs", "inbound_nodes": []}, {"class_name": "InputLayer", "config": {"batch_input_shape": [null, 31, 28, 1], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_imgs"}, "name": "input_imgs", "inbound_nodes": []}, {"class_name": "Functional", "config": {"name": "model_12", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_34"}, "name": "input_34", "inbound_nodes": []}, {"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_35"}, "name": "input_35", "inbound_nodes": []}, {"class_name": "Sequential", "config": {"name": "sequential_45", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_161_input"}}, {"class_name": "Dense", "config": {"name": "dense_161", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_162", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_163", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_45", "inbound_nodes": [[["input_34", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "sequential_46", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_165_input"}}, {"class_name": "Dense", "config": {"name": "dense_165", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_166", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_167", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_46", "inbound_nodes": [[["input_35", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_164", "trainable": true, "dtype": "float32", "units": 10, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_164", "inbound_nodes": [[["sequential_45", 1, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_168", "trainable": true, "dtype": "float32", "units": 10, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_168", "inbound_nodes": [[["sequential_46", 1, 0, {}]]]}, {"class_name": "Concatenate", "config": {"name": "concatenate_12", "trainable": true, "dtype": "float32", "axis": -1}, "name": "concatenate_12", "inbound_nodes": [[["dense_164", 0, 0, {}], ["dense_168", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "sequential_47", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 20], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_169_input"}}, {"class_name": "Dense", "config": {"name": "dense_169", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_170", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_171", "trainable": true, "dtype": "float32", "units": 200, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_18", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_172", "trainable": true, "dtype": "float32", "units": 800, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_19", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_173", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "sequential_47", "inbound_nodes": [[["concatenate_12", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_174", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_174", "inbound_nodes": [[["sequential_47", 1, 0, {}]]]}], "input_layers": [["input_34", 0, 0], ["input_35", 0, 0]], "output_layers": [["dense_174", 0, 0]]}, "name": "model_12", "inbound_nodes": [[["input_poss", 0, 0, {}], ["input_dirs", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "model_imgs", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 31, 28, 1], "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_14_input"}}, {"class_name": "Conv2D", "config": {"name": "conv2d_14", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_15", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "AveragePooling2D", "config": {"name": "average_pooling2d_14", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "AveragePooling2D", "config": {"name": "average_pooling2d_15", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_7", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "Flatten", "config": {"name": "flatten_31", "trainable": true, "dtype": "float32", "data_format": "channels_last"}}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_15", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_16", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_71", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "name": "model_imgs", "inbound_nodes": [[["input_imgs", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "model_tsfr", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 4], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_72_input"}}, {"class_name": "Dense", "config": {"name": "dense_72", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_17", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_73", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_18", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_74", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_19", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}]}, "name": "model_tsfr", "inbound_nodes": [[["model_12", 1, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "output_imgs", "trainable": true, "dtype": "float32", "units": 10, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "output_imgs", "inbound_nodes": [[["model_imgs", 1, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "output_tsfr", "trainable": true, "dtype": "float32", "units": 10, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "output_tsfr", "inbound_nodes": [[["model_tsfr", 1, 0, {}]]]}, {"class_name": "Concatenate", "config": {"name": "input_conc", "trainable": true, "dtype": "float32", "axis": -1}, "name": "input_conc", "inbound_nodes": [[["output_imgs", 0, 0, {}], ["output_tsfr", 0, 0, {}]]]}, {"class_name": "Sequential", "config": {"name": "model_conc", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 20], "dtype": "float32", "sparse": false, "ragged": false, "name": "dense_75_input"}}, {"class_name": "Dense", "config": {"name": "dense_75", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_16", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_20", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_76", "trainable": true, "dtype": "float32", "units": 400, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_17", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_21", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_77", "trainable": true, "dtype": "float32", "units": 80, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_18", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}}]}, "name": "model_conc", "inbound_nodes": [[["input_conc", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "output_conc", "trainable": true, "dtype": "float32", "units": 4, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "output_conc", "inbound_nodes": [[["model_conc", 1, 0, {}]]]}], "input_layers": [["input_imgs", 0, 0], ["input_poss", 0, 0], ["input_dirs", 0, 0]], "output_layers": [["output_conc", 0, 0]]}, "keras_version": "2.8.0", "backend": "tensorflow"}
|
requirements.txt
ADDED
|
Binary file (178 Bytes). View file
|
|
|
utility.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json, random
|
| 2 |
+
import numpy as np
|
| 3 |
+
from keras.models import model_from_json
|
| 4 |
+
|
| 5 |
+
# GETTING THE MODELS
|
| 6 |
+
with open("models/random_model.json", "r") as f:
|
| 7 |
+
random_model = model_from_json(f.read())
|
| 8 |
+
random_model.load_weights("models/random_model.h5")
|
| 9 |
+
|
| 10 |
+
with open("models/fixed_model.json", "r") as f:
|
| 11 |
+
fixed_model = model_from_json(f.read())
|
| 12 |
+
fixed_model.load_weights("models/fixed_model.h5")
|
| 13 |
+
|
| 14 |
+
models = {
|
| 15 |
+
"fixed": fixed_model,
|
| 16 |
+
"random": random_model,
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
# GETTING THE MAP
|
| 20 |
+
with open("binary_map.json", "r") as f:
|
| 21 |
+
fixed_map = json.loads(f.read())
|
| 22 |
+
rows = 31
|
| 23 |
+
cols = 28
|
| 24 |
+
|
| 25 |
+
# FUNCTTIONS FOR AUTOMATION
|
| 26 |
+
|
| 27 |
+
def automate_faster(info):
|
| 28 |
+
infos = []
|
| 29 |
+
for i in range(info['automated_infos_count']):
|
| 30 |
+
dirs = automate(info, stringify_dirs=False)
|
| 31 |
+
for dir in dirs:
|
| 32 |
+
if move(info, dir): break
|
| 33 |
+
info['second_pref_count'] += 1
|
| 34 |
+
print("SECOND PREFERENCE USED")
|
| 35 |
+
|
| 36 |
+
new_info = {}
|
| 37 |
+
for key, value in info.items():
|
| 38 |
+
if key == 'map':
|
| 39 |
+
new_info[key] = value.copy()
|
| 40 |
+
else:
|
| 41 |
+
new_info[key] = value
|
| 42 |
+
|
| 43 |
+
infos.append(new_info)
|
| 44 |
+
|
| 45 |
+
return infos
|
| 46 |
+
|
| 47 |
+
def move(info, dir):
|
| 48 |
+
h = info['map'].index(3)
|
| 49 |
+
|
| 50 |
+
if dir == 0: n = h-cols
|
| 51 |
+
if dir == 1: n = h-1
|
| 52 |
+
if dir == 2: n = h+cols
|
| 53 |
+
if dir == 3: n = h+1
|
| 54 |
+
|
| 55 |
+
# IF FOOD IS EATEN
|
| 56 |
+
if (info['map'][n] == 2):
|
| 57 |
+
# updating board
|
| 58 |
+
info['score'] += 1
|
| 59 |
+
info['parts'] += 1
|
| 60 |
+
info['steps'] = 0
|
| 61 |
+
info['map'][n] = info['parts']+3
|
| 62 |
+
# placing food randomly
|
| 63 |
+
if info['map_type'] == 'random':
|
| 64 |
+
info = load_map(info)
|
| 65 |
+
return info
|
| 66 |
+
else:
|
| 67 |
+
info = randomize(info, head=False, food=True)
|
| 68 |
+
|
| 69 |
+
# r = random.randint(0, 31*28-1)
|
| 70 |
+
# while (info['map'][r] != 0): r = random.randint(0, 31*28-1)
|
| 71 |
+
# info['map'][r] = 2
|
| 72 |
+
|
| 73 |
+
# IF SNAKE HITS THE BODY
|
| 74 |
+
if (info['map'][n] > 4 and info['map'][n] != info['parts']+3 and not info['evade_bite']):
|
| 75 |
+
parts_to_remove = (info['parts']+3) - info['map'][n]
|
| 76 |
+
for i in range(parts_to_remove):
|
| 77 |
+
info['map'][info['map'].index(info['parts']-i+3)] = 0
|
| 78 |
+
info['parts'] -= parts_to_remove
|
| 79 |
+
info['fouls'] += 1
|
| 80 |
+
|
| 81 |
+
# MOVING THE BODY
|
| 82 |
+
if ( info['map'][n] != 1 and info['map'][n] != 3 and info['map'][n] != 4 ):
|
| 83 |
+
for i in range(info['parts']+1):
|
| 84 |
+
try:
|
| 85 |
+
cache_n = info['map'].index(3+i)
|
| 86 |
+
info['map'][cache_n] = 0
|
| 87 |
+
info['map'][n] = 3+i
|
| 88 |
+
n = cache_n
|
| 89 |
+
except:
|
| 90 |
+
info['map'][n] = 3+i
|
| 91 |
+
|
| 92 |
+
info['steps'] += 1
|
| 93 |
+
if info['steps'] > info['steps_limit']:
|
| 94 |
+
info['steps'] = 0
|
| 95 |
+
info['fouls'] += 1
|
| 96 |
+
# placing food randomly
|
| 97 |
+
info = randomize(info, head=False, food=True)
|
| 98 |
+
|
| 99 |
+
return True
|
| 100 |
+
|
| 101 |
+
return False
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def automate(info, stringify_dirs=True):
|
| 105 |
+
x = preprocessing(info['map'], info['map_type'])
|
| 106 |
+
y = models[info['map_type']].predict(x)
|
| 107 |
+
dirs = postprocess(y)
|
| 108 |
+
if stringify_dirs: return str(dirs)
|
| 109 |
+
else: return dirs
|
| 110 |
+
|
| 111 |
+
def preprocessing(x, type):
|
| 112 |
+
x = np.array(x).reshape(31, 28, 1)
|
| 113 |
+
food_x, food_y = np.where(x == 2)[1], np.where(x == 2)[0]
|
| 114 |
+
head_x, head_y = np.where(x == 3)[1], np.where(x == 3)[0]
|
| 115 |
+
possible_dirs = np.array([[0, 0, 0, 0]])
|
| 116 |
+
try: possible_dirs[0, 0] = int(x[head_y-1, head_x] == 0 or x[head_y-1, head_x] == 2)
|
| 117 |
+
except: pass
|
| 118 |
+
try: possible_dirs[0, 1] = int(x[head_y, head_x-1] == 0 or x[head_y, head_x-1] == 2)
|
| 119 |
+
except: pass
|
| 120 |
+
try: possible_dirs[0, 2] = int(x[head_y+1, head_x] == 0 or x[head_y+1, head_x] == 2)
|
| 121 |
+
except: pass
|
| 122 |
+
try: possible_dirs[0, 3] = int(x[head_y, head_x+1] == 0 or x[head_y, head_x+1] == 2)
|
| 123 |
+
except: pass
|
| 124 |
+
|
| 125 |
+
possitions = np.array([[head_x[0]/27, head_y[0]/30, food_x[0]/27, food_y[0]/30]])
|
| 126 |
+
if type == 'random':
|
| 127 |
+
maps = np.where(x == 1, 1, 0).reshape(1, 31, 28, 1)
|
| 128 |
+
x = [maps, possitions, possible_dirs]
|
| 129 |
+
elif type == 'fixed':
|
| 130 |
+
x = [possitions, possible_dirs]
|
| 131 |
+
return x
|
| 132 |
+
|
| 133 |
+
def postprocess(y):
|
| 134 |
+
dirs = [0, 0, 0, 0]
|
| 135 |
+
y = y[0]
|
| 136 |
+
for i in range(4):
|
| 137 |
+
dirs[i] = np.argmax(y)
|
| 138 |
+
y[np.argmax(y)] = -1
|
| 139 |
+
return dirs
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
# FUNCTIONS FOR MAPS
|
| 144 |
+
|
| 145 |
+
def load_map(info):
|
| 146 |
+
if info['map_type'] == 'fixed':
|
| 147 |
+
info['map'] = fixed_map[:]
|
| 148 |
+
elif info['map_type'] == 'random':
|
| 149 |
+
info['map'] = [1]*rows*cols
|
| 150 |
+
info['map'] = add_rects(info['map'], times=8, cross=False, d=8)
|
| 151 |
+
info = randomize(info, head=True, food=True)
|
| 152 |
+
return info
|
| 153 |
+
|
| 154 |
+
def randomize(info, head, food):
|
| 155 |
+
|
| 156 |
+
if food:
|
| 157 |
+
# finding possition
|
| 158 |
+
r = random.randint(0, rows*cols -1)
|
| 159 |
+
while info['map'][r] != 0:
|
| 160 |
+
r = random.randint(0, rows*cols-1)
|
| 161 |
+
# removing previous
|
| 162 |
+
try: info['map'][info['map'].index(2)] = 0
|
| 163 |
+
except: pass
|
| 164 |
+
# adding new
|
| 165 |
+
info['map'][r] = 2
|
| 166 |
+
|
| 167 |
+
if head:
|
| 168 |
+
# removing previous
|
| 169 |
+
for i in range(info['parts']+1):
|
| 170 |
+
try:info['map'][info['map'].index(3+i)] = 0
|
| 171 |
+
except: pass
|
| 172 |
+
# finding possition
|
| 173 |
+
r = random.randint(0, rows*cols -1)
|
| 174 |
+
while info['map'][r] != 0:
|
| 175 |
+
r = random.randint(0, rows*cols-1)
|
| 176 |
+
# adding head
|
| 177 |
+
info['map'][r] = 3
|
| 178 |
+
# adding body
|
| 179 |
+
prev = r
|
| 180 |
+
for part in range(info['parts']):
|
| 181 |
+
dirs = [prev-1, prev+1, prev-cols, prev+cols]
|
| 182 |
+
r = random.choice(dirs)
|
| 183 |
+
while info['map'][r] != 0:
|
| 184 |
+
dirs.remove(r)
|
| 185 |
+
if len(dirs) == 0:
|
| 186 |
+
return randomize(info, head, food)
|
| 187 |
+
r = random.choice(dirs)
|
| 188 |
+
info['map'][r] = 4+part
|
| 189 |
+
prev = r
|
| 190 |
+
if info['map'][info['map'].index(3)+1] != 0 and info['map'][info['map'].index(3)-1] != 0 and info['map'][info['map'].index(3)+cols] != 0 and info['map'][info['map'].index(3)-cols] != 0:
|
| 191 |
+
return randomize(info, head, food)
|
| 192 |
+
return info
|
| 193 |
+
|
| 194 |
+
def add_rects(map, times=1, d=5, cross=False):
|
| 195 |
+
map = np.array(map).reshape(rows, cols)
|
| 196 |
+
x1, y1 = random.randint(1, cols-2-d), random.randint(1, rows-2-d)
|
| 197 |
+
x2, y2 = random.randint(x1+d, cols-2), random.randint(y1+d, rows-2)
|
| 198 |
+
|
| 199 |
+
for x in range(x2-x1+1):
|
| 200 |
+
map[y1, x1+x] = 0
|
| 201 |
+
map[y2, x1+x] = 0
|
| 202 |
+
if cross:
|
| 203 |
+
map[(y1+y2)//2, x1+x] = 0
|
| 204 |
+
for y in range(y2-y1+1):
|
| 205 |
+
map[y1+y, x2] = 0
|
| 206 |
+
map[y1+y, x1] = 0
|
| 207 |
+
if cross:
|
| 208 |
+
map[y1+y, (x1+x2)//2] = 0
|
| 209 |
+
|
| 210 |
+
if times == 1: return map.ravel().tolist()
|
| 211 |
+
else: return add_rects(map=map, times=times-1, d=d, cross=cross)
|
| 212 |
+
|
web/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Intelli Snake 2
|
| 2 |
+
#### Python | Machine Learning | Deep Learning | Keras | Tensorflow | Scikit-learn | FAST API | Web Designing | Web Development
|
| 3 |
+
[Play Game](https://geetu040.github.io/intelli-snake-2/)
|
| 4 |
+
|
| 5 |
+
[Backend API](https://github.com/geetu040/intelli-snake-2)
|
| 6 |
+
|
| 7 |
+
Previous Versions:
|
| 8 |
+
|
| 9 |
+
[Intelli Snake](https://intelli-snake.herokuapp.com/)
|
| 10 |
+
|
| 11 |
+
[The Fetcher](https://the-fetcher.herokuapp.com/)
|
web/arrows.png
ADDED
|
web/index.html
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="UTF-8">
|
| 6 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
| 7 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 8 |
+
<title>Intelli Snake 2</title>
|
| 9 |
+
<link rel="shortcut icon" href="snake.png">
|
| 10 |
+
<style>
|
| 11 |
+
:root {
|
| 12 |
+
--rows: 31;
|
| 13 |
+
--cols: 28;
|
| 14 |
+
--win_size: 98vmin;
|
| 15 |
+
}
|
| 16 |
+
</style>
|
| 17 |
+
<link rel="stylesheet" href="style.css">
|
| 18 |
+
</head>
|
| 19 |
+
|
| 20 |
+
<body>
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
<div class="container">
|
| 24 |
+
<div class="sub-container">
|
| 25 |
+
<div class="top">
|
| 26 |
+
<div id="score">Score: <span id="score_span">0</span></div>
|
| 27 |
+
<div id="fouls">Fouls: <span id="fouls_span">0</span></div>
|
| 28 |
+
<div id="fouls">Steps: <span id="steps_span">0</span></div>
|
| 29 |
+
</div>
|
| 30 |
+
<div class="game">
|
| 31 |
+
|
| 32 |
+
<div id="loading" class="lds-hourglass"></div>
|
| 33 |
+
<div id="ins">
|
| 34 |
+
|
| 35 |
+
<b class="heading1">Instructions</b> <br>
|
| 36 |
+
<ul>
|
| 37 |
+
<li> Use arrow keys
|
| 38 |
+
<img src="arrows.png" alt="" width="6%">
|
| 39 |
+
to move the Snake
|
| 40 |
+
</li>
|
| 41 |
+
<li> Press Space at any time to pause the game </li>
|
| 42 |
+
<li> On Touch systems swipe the screen to control movement </li>
|
| 43 |
+
<li> Help Snake fetch the food and score higher! </li>
|
| 44 |
+
<li> You can automate the snake to catch food by itself </li>
|
| 45 |
+
<li> The game is based on the idea: <a href="https://the-fetcher.herokuapp.com/"
|
| 46 |
+
target="new">The Fetcher</a> </li>
|
| 47 |
+
<li> Intelli Snake 2 is an efficient version of: <a href="https://intelli-snake.herokuapp.com/"
|
| 48 |
+
target="new">Intelli Snake</a> </li>
|
| 49 |
+
</ul> <br>
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
<b class="heading1">Fouls</b> <br>
|
| 53 |
+
A foul is commited when the Snake
|
| 54 |
+
<ul>
|
| 55 |
+
<li> eats itself </li>
|
| 56 |
+
<li> hits the wall (collision needs to be enabled) </li>
|
| 57 |
+
<li> fails to catch food in 60 steps </li>
|
| 58 |
+
</ul> <br>
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
<b class="heading1">Automation</b> <br>
|
| 62 |
+
Two options are available for automation
|
| 63 |
+
<ul><br>
|
| 64 |
+
<li> <b> Fast Automation </b>
|
| 65 |
+
<ul>
|
| 66 |
+
<li>Snake moves faster than regular</li>
|
| 67 |
+
<li> An Asynchronous Http request is sent which returns the next
|
| 68 |
+
50 steps</li>
|
| 69 |
+
<li>Snake then moves through the loaded steps, meanwhile more requests are sent for more
|
| 70 |
+
steps</li>
|
| 71 |
+
<li>Snake moves and requests are sent in parallel</li>
|
| 72 |
+
</ul>
|
| 73 |
+
</li> <br>
|
| 74 |
+
<li> <b> Automate </b>
|
| 75 |
+
<ul>
|
| 76 |
+
<li>Snake moves at regular speed</li>
|
| 77 |
+
<li>At each step a synchronous Http request is sent which returns with the next step
|
| 78 |
+
</li>
|
| 79 |
+
<li>Snake waits for a request at each step</li>
|
| 80 |
+
</ul>
|
| 81 |
+
</li>
|
| 82 |
+
</ul>
|
| 83 |
+
|
| 84 |
+
<br>
|
| 85 |
+
<hr><br>
|
| 86 |
+
<b class="heading1"> AI behind Automation </b> <br>
|
| 87 |
+
<ul>
|
| 88 |
+
<li> For automation we have 2 models built on Deep Neural Networks and Convolutianl Neural
|
| 89 |
+
Networks </li>
|
| 90 |
+
<li> Both the models are based on keras API, using tensorflow, implementing Functional API and
|
| 91 |
+
Sequential models. </li>
|
| 92 |
+
<li> The models return an array of directions sorted by preference </li>
|
| 93 |
+
<li> Snake then uses the first direction with most preference </li>
|
| 94 |
+
<li> If the first preferred direction doestnot help, snake uses the next preference</li>
|
| 95 |
+
<li> Since the Random Model has lesser accuracy, you'll find it commiting more fouls </li>
|
| 96 |
+
</ul>
|
| 97 |
+
<br>
|
| 98 |
+
<ul>
|
| 99 |
+
<li>
|
| 100 |
+
<b>Fixed Model</b> <span>[Accuracy: 99.72%]</span> <br>
|
| 101 |
+
<ul>
|
| 102 |
+
<li>
|
| 103 |
+
It takes 2 inputs
|
| 104 |
+
<ul>
|
| 105 |
+
<li> Possition of snake and food </li>
|
| 106 |
+
<li> Available directions </li>
|
| 107 |
+
</ul>
|
| 108 |
+
</li>
|
| 109 |
+
<li> It is based on Functional API and Sequential Models </li>
|
| 110 |
+
<li> Deep Neural Networks are involved </li>
|
| 111 |
+
</ul>
|
| 112 |
+
</li> <br>
|
| 113 |
+
<li>
|
| 114 |
+
<b>Random Model</b> <span>[Accuracy: 94.59%]</span> <br>
|
| 115 |
+
<ul>
|
| 116 |
+
<li>
|
| 117 |
+
It takes 3 inputs
|
| 118 |
+
<ul>
|
| 119 |
+
<li> Image of the Map </li>
|
| 120 |
+
<li> Possition of snake and food </li>
|
| 121 |
+
<li> Available directions </li>
|
| 122 |
+
</ul>
|
| 123 |
+
</li>
|
| 124 |
+
<li> Deep Neural Networks, along with Convolutianl Neural Networks are involved </li>
|
| 125 |
+
<li> It is based on Functional API, Sequential Model and Transfer Model (using Fixed
|
| 126 |
+
Model as base) </li>
|
| 127 |
+
<li> Input 2 and Input 3 are transferred to Fixed Model, the output is then used with
|
| 128 |
+
Input 1 by Sequential Models and Functional API which then generate a final output
|
| 129 |
+
</li>
|
| 130 |
+
|
| 131 |
+
</ul>
|
| 132 |
+
</li>
|
| 133 |
+
</ul>
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
<br>
|
| 137 |
+
<hr>
|
| 138 |
+
To see the summary of models and the complete back end <br>
|
| 139 |
+
visit: <a href="https://github.com/geetu040/intelli-snake-2" target="new">Github Repository</a>
|
| 140 |
+
|
| 141 |
+
</div>
|
| 142 |
+
|
| 143 |
+
<!-- {% for y in range(params.rows) %}
|
| 144 |
+
{% for x in range(params.cols) %}
|
| 145 |
+
<div class="game-item"></div>
|
| 146 |
+
{% endfor %}
|
| 147 |
+
{% endfor %} -->
|
| 148 |
+
|
| 149 |
+
</div>
|
| 150 |
+
</div>
|
| 151 |
+
<div class="right">
|
| 152 |
+
<button id="btn_fast_automation">Fast Automation</button>
|
| 153 |
+
<button id="btn_pause_auto">Automate</button>
|
| 154 |
+
<button id="btn_next_map">Random Map</button>
|
| 155 |
+
<button id="btn_speeder">Slower</button>
|
| 156 |
+
<button id="btn_collide">Enable Collision</button>
|
| 157 |
+
<button id="btn_replace">Replace Food</button>
|
| 158 |
+
<button id="btn_guide">Guide</button>
|
| 159 |
+
</div>
|
| 160 |
+
</div>
|
| 161 |
+
|
| 162 |
+
<!-- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> -->
|
| 163 |
+
<!-- <script type="text/javascript" src="https://livejs.com/live.js"></script> -->
|
| 164 |
+
<script>
|
| 165 |
+
rows = 31
|
| 166 |
+
cols = 28
|
| 167 |
+
win_size = 98
|
| 168 |
+
|
| 169 |
+
for (let i=0; i<rows*cols; i++) {
|
| 170 |
+
let gameItem = document.createElement("div");
|
| 171 |
+
gameItem.classList.add("game-item")
|
| 172 |
+
document.getElementsByClassName("game")[0].appendChild(gameItem);
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
</script>
|
| 176 |
+
<script src="swipe.js"></script>
|
| 177 |
+
<script src="script.js"></script>
|
| 178 |
+
</body>
|
| 179 |
+
|
| 180 |
+
</html>
|
web/script.js
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// const API_URL = "http://127.0.0.1:8000/intelli-snake-2/"
|
| 2 |
+
const API_URL = "https://intelli-snake-2-api.herokuapp.com/intelli-snake-2/"
|
| 3 |
+
|
| 4 |
+
let loaded_infos = []
|
| 5 |
+
interval_var_fast = 0
|
| 6 |
+
let start_auto = 1
|
| 7 |
+
let mult = 1
|
| 8 |
+
|
| 9 |
+
// WRITING IN A FILE
|
| 10 |
+
let file_writing = 0
|
| 11 |
+
let content = ''
|
| 12 |
+
let data_line
|
| 13 |
+
|
| 14 |
+
class Game {
|
| 15 |
+
constructor () {
|
| 16 |
+
// initializing constants and variables
|
| 17 |
+
this.game_items = document.getElementsByClassName("game-item")
|
| 18 |
+
this.info = {
|
| 19 |
+
"map_type": "none",
|
| 20 |
+
"map": 0,
|
| 21 |
+
"parts": 2,
|
| 22 |
+
"evade_bite": 0,
|
| 23 |
+
"allowcollisions": 0,
|
| 24 |
+
"score": 0,
|
| 25 |
+
"fouls": 0,
|
| 26 |
+
"interval_var": 0,
|
| 27 |
+
"cache_dir": null,
|
| 28 |
+
"prev_dir": null,
|
| 29 |
+
"second_pref_count": 0,
|
| 30 |
+
"mode": "paused",
|
| 31 |
+
"steps": 0,
|
| 32 |
+
"steps_limit": 60,
|
| 33 |
+
"slow_time": 600,
|
| 34 |
+
"fast_time": 200,
|
| 35 |
+
"time": 200,
|
| 36 |
+
"automated_infos_count": 50,
|
| 37 |
+
"automated_time_update_freq": 1,
|
| 38 |
+
"overflow_infos": 0,
|
| 39 |
+
}
|
| 40 |
+
// intializing the game
|
| 41 |
+
this.get_map("fixed")
|
| 42 |
+
btn_pause_auto.innerText = "Automate"
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
set_game_interval(func) {
|
| 47 |
+
clearInterval(this.info.interval_var)
|
| 48 |
+
this.info.interval_var = setInterval(func, this.info.time)
|
| 49 |
+
}
|
| 50 |
+
auto_key_move() {
|
| 51 |
+
if (this.info.cache_dir != null) {
|
| 52 |
+
if(game.move(this.info.cache_dir)) {this.info.prev_dir = this.info.cache_dir}
|
| 53 |
+
else {game.move(this.info.prev_dir)}
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
move(dir) {
|
| 59 |
+
if (file_writing) {data_line = "\n" + JSON.stringify(this.info.map)}
|
| 60 |
+
|
| 61 |
+
let h = this.info.map.indexOf(3)
|
| 62 |
+
let n = 31*28
|
| 63 |
+
if (dir == 0) { n = h - cols }
|
| 64 |
+
else if (dir == 1) { n = h - 1 }
|
| 65 |
+
else if (dir == 2) { n = h + cols }
|
| 66 |
+
else if (dir == 3) { n = h + 1 }
|
| 67 |
+
|
| 68 |
+
// IF FOOD IS EATEN
|
| 69 |
+
if (this.info.map[n] == 2) {
|
| 70 |
+
this.info.score++
|
| 71 |
+
this.info.parts++
|
| 72 |
+
this.info.steps = 0
|
| 73 |
+
if (this.info.map_type == "random" && file_writing) {
|
| 74 |
+
// LOADING NEW RANDOM MAP AFTER EATEN
|
| 75 |
+
this.pause_game()
|
| 76 |
+
this.get_map("random")
|
| 77 |
+
return true
|
| 78 |
+
}
|
| 79 |
+
this.info.map[n] = this.info.parts+3
|
| 80 |
+
let r = Math.floor(Math.random() * (31*28))
|
| 81 |
+
while (this.info.map[r] != 0) { r = Math.floor(Math.random() * (31*28)) }
|
| 82 |
+
this.info.map[r] = 2
|
| 83 |
+
this.pause_game()
|
| 84 |
+
}
|
| 85 |
+
// CHECKING FOR FOUL WHEN HIT THE WALL
|
| 86 |
+
if (this.info.map[n] == 1 && this.info.allowcollisions) { this.info.fouls++ }
|
| 87 |
+
// IF SNAKE HITS THE BODY
|
| 88 |
+
if (this.info.map[n] > 4 && this.info.map[n] != this.info.parts+3 && !this.info.evade_bite) {
|
| 89 |
+
let parts_to_remove = (this.info.parts+3) - this.info.map[n]
|
| 90 |
+
for (let i=0; i<parts_to_remove; i++) { this.info.map[this.info.map.indexOf(this.info.parts-i+3)] = 0 }
|
| 91 |
+
this.info.parts -= parts_to_remove
|
| 92 |
+
this.info.fouls++
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
// MOVING THE BODY
|
| 96 |
+
if (this.can_move(n, dir)) {
|
| 97 |
+
let cache_n;
|
| 98 |
+
for (let part=0; part<=this.info.parts; part++) {
|
| 99 |
+
cache_n = this.info.map.indexOf(3+part)
|
| 100 |
+
this.info.map[this.info.map.indexOf(3+part)] = 0
|
| 101 |
+
this.info.map[n] = 3+part
|
| 102 |
+
n = cache_n
|
| 103 |
+
}
|
| 104 |
+
this.update_map()
|
| 105 |
+
this.info.steps++
|
| 106 |
+
if (this.info.steps > this.info.steps_limit) { btn_replace.click();this.info.steps=0;this.info.fouls++ }
|
| 107 |
+
|
| 108 |
+
if (file_writing) {
|
| 109 |
+
data_line += "," + String(dir)
|
| 110 |
+
content += data_line
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
return true
|
| 114 |
+
} else {return false}
|
| 115 |
+
}
|
| 116 |
+
can_move(next_step, dir) {
|
| 117 |
+
let next_item = this.info.map[next_step]
|
| 118 |
+
// IF SNAKE GOES OUT OF BOUNDARIES
|
| 119 |
+
if (next_step < 0 || next_step > 31*28-1) {return false}
|
| 120 |
+
if (dir == 1 && next_step % 28 == 27) {return false}
|
| 121 |
+
if (dir == 3 && next_step % 28 == 0) {return false}
|
| 122 |
+
// ILLEGAL STEP INSIDE THE BOUNDARIES
|
| 123 |
+
switch (next_item) {
|
| 124 |
+
case 0: return true
|
| 125 |
+
case 1: if (this.info.allowcollisions) {return true} return false
|
| 126 |
+
case 2: return true
|
| 127 |
+
case 3: return false
|
| 128 |
+
case 4: return false
|
| 129 |
+
default: return true;
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
automate_faster(time) {
|
| 134 |
+
clearInterval(interval_var_fast)
|
| 135 |
+
interval_var_fast = setInterval(() => {
|
| 136 |
+
if (loaded_infos.length > 1) {
|
| 137 |
+
this.info = loaded_infos[0]
|
| 138 |
+
this.update_map()
|
| 139 |
+
loaded_infos.shift()
|
| 140 |
+
} else { console.log('\n ==== OUT OF INFOS ==== \n') }
|
| 141 |
+
}, time);
|
| 142 |
+
}
|
| 143 |
+
load_automated_infos() {
|
| 144 |
+
let time_i = Date.now()
|
| 145 |
+
|
| 146 |
+
fetch(API_URL + `automate_faster-${JSON.stringify(loaded_infos[loaded_infos.length-1])}`)
|
| 147 |
+
.then(response => response.json())
|
| 148 |
+
.then(data => {
|
| 149 |
+
let returned_infos = JSON.parse(data)
|
| 150 |
+
if (btn_fast_automation.innerText == "Fast Automation") {if(btn_guide.innerText == "Guide"){btn_fast_automation.disabled = false};return}
|
| 151 |
+
loading.style.setProperty("visibility", "hidden")
|
| 152 |
+
// adding more infos
|
| 153 |
+
if (loaded_infos.length < 200 || this.info['overflow_infos']) {loaded_infos = loaded_infos.concat(returned_infos)}
|
| 154 |
+
console.log("ADDED NEW INFOS")
|
| 155 |
+
console.table(`infos count: ${loaded_infos.length}`)
|
| 156 |
+
|
| 157 |
+
// Finding optimal time for interval
|
| 158 |
+
let time_f = Date.now()
|
| 159 |
+
let fast_time = (time_f - time_i)/(this.info.automated_infos_count*mult)
|
| 160 |
+
if (this.info.automated_time_update_freq) { game.automate_faster(fast_time) }
|
| 161 |
+
else {if (start_auto == 1) {game.automate_faster(fast_time); start_auto=0;}}
|
| 162 |
+
console.log(`FAST TIME: ${fast_time}`)
|
| 163 |
+
|
| 164 |
+
console.log("\n")
|
| 165 |
+
this.load_automated_infos()
|
| 166 |
+
});
|
| 167 |
+
}
|
| 168 |
+
automate() {
|
| 169 |
+
|
| 170 |
+
fetch(API_URL + `automate-${JSON.stringify(this.info)}`)
|
| 171 |
+
.then(response => response.json())
|
| 172 |
+
.then(data => {
|
| 173 |
+
let pred_dirs = JSON.parse(data) // predicted directions sorted by preference
|
| 174 |
+
for (let i=0; i<4; i++) { if (this.move(pred_dirs[i])) { this.info.second_pref_count += i; break } }
|
| 175 |
+
|
| 176 |
+
});
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
get_map(map_type) {
|
| 182 |
+
// getting the maps
|
| 183 |
+
loading.style.setProperty("visibility", "visible")
|
| 184 |
+
this.info.map_type = map_type
|
| 185 |
+
this.info.steps = 0
|
| 186 |
+
|
| 187 |
+
fetch(API_URL + `map-${JSON.stringify(this.info)}`)
|
| 188 |
+
.then(response => response.json())
|
| 189 |
+
.then(data => {
|
| 190 |
+
this.info = JSON.parse(data)
|
| 191 |
+
loading.style.setProperty("visibility", "hidden")
|
| 192 |
+
this.update_map()
|
| 193 |
+
});
|
| 194 |
+
}
|
| 195 |
+
update_map() {
|
| 196 |
+
// APPLYING LIST TO VISUAL GRID
|
| 197 |
+
for (let i=0; i<rows*cols; i++) {
|
| 198 |
+
this.game_items[i].classList.remove('wall')
|
| 199 |
+
this.game_items[i].classList.remove('empty')
|
| 200 |
+
this.game_items[i].classList.remove('food')
|
| 201 |
+
this.game_items[i].classList.remove('head')
|
| 202 |
+
this.game_items[i].classList.remove('body')
|
| 203 |
+
switch (this.info.map[i]) {
|
| 204 |
+
case 0: this.game_items[i].classList.add("empty"); break
|
| 205 |
+
case 1: this.game_items[i].classList.add("wall"); break
|
| 206 |
+
case 2: this.game_items[i].classList.add("food"); break
|
| 207 |
+
case 3: this.game_items[i].classList.add("head"); break
|
| 208 |
+
default: this.game_items[i].classList.add("body"); break
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
// UPDATING THE BOARD
|
| 212 |
+
score_span.innerText = this.info.score
|
| 213 |
+
fouls_span.innerText = this.info.fouls
|
| 214 |
+
steps_span.innerText = this.info.steps
|
| 215 |
+
}
|
| 216 |
+
pause_game() {
|
| 217 |
+
clearInterval(this.info.interval_var)
|
| 218 |
+
clearInterval(interval_var_fast)
|
| 219 |
+
btn_fast_automation.innerText = "Fast Automation"
|
| 220 |
+
btn_pause_auto.innerText = "Automate"
|
| 221 |
+
this.info.mode = "paused"
|
| 222 |
+
loaded_infos = []
|
| 223 |
+
start_auto = 1
|
| 224 |
+
this.info.cache_dir = null
|
| 225 |
+
btn_next_map.disabled = false
|
| 226 |
+
btn_speeder.disabled = false
|
| 227 |
+
if (this.info.map_type == "fixed") {btn_collide.disabled = false}
|
| 228 |
+
btn_replace.disabled = false
|
| 229 |
+
// btn_fast_automation.disabled = false
|
| 230 |
+
btn_pause_auto.disabled = false
|
| 231 |
+
loading.style.setProperty("visibility", "hidden")
|
| 232 |
+
|
| 233 |
+
}
|
| 234 |
+
}
|
| 235 |
+
let game = new Game()
|
| 236 |
+
// KEYBOARD EVENTS
|
| 237 |
+
document.onkeydown = (event)=> {
|
| 238 |
+
// writing in a file
|
| 239 |
+
if (event.key == 'Backspace' && file_writing) {
|
| 240 |
+
content = ''
|
| 241 |
+
}
|
| 242 |
+
if (event.key == 'Enter' && file_writing) {
|
| 243 |
+
fetch(API_URL + `write-${content}`)
|
| 244 |
+
.then(response => response.json())
|
| 245 |
+
.then(data => {
|
| 246 |
+
content = ''
|
| 247 |
+
return
|
| 248 |
+
});
|
| 249 |
+
}
|
| 250 |
+
// controls
|
| 251 |
+
if (event.key == 'ArrowRight') { game.info.cache_dir = 3 }
|
| 252 |
+
if (event.key == 'ArrowLeft') { game.info.cache_dir = 1 }
|
| 253 |
+
if (event.key == 'ArrowUp') { game.info.cache_dir = 0 }
|
| 254 |
+
if (event.key == 'ArrowDown') { game.info.cache_dir = 2 }
|
| 255 |
+
if (event.key == ' ') { game.pause_game(); return }
|
| 256 |
+
if (game.info.mode == "paused") {
|
| 257 |
+
// PLAY THE GAME WITH KEYS
|
| 258 |
+
game.set_game_interval(()=>{ game.auto_key_move() })
|
| 259 |
+
game.info.mode = "key"
|
| 260 |
+
}
|
| 261 |
+
}
|
| 262 |
+
// SWIPE EVENTS
|
| 263 |
+
document.addEventListener('swiped-up', function(e) { document.onkeydown({key: 'ArrowUp'})} );
|
| 264 |
+
document.addEventListener('swiped-left', function(e) { document.onkeydown({key: 'ArrowLeft'})} );
|
| 265 |
+
document.addEventListener('swiped-down', function(e) { document.onkeydown({key: 'ArrowDown'})} );
|
| 266 |
+
document.addEventListener('swiped-right', function(e) { document.onkeydown({key: 'ArrowRight'})} );
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
// BUTTONS
|
| 270 |
+
btn_fast_automation.onclick = ()=>{
|
| 271 |
+
if (btn_fast_automation.innerText == "Fast Automation") {
|
| 272 |
+
game.pause_game()
|
| 273 |
+
btn_fast_automation.innerText = "Pause"
|
| 274 |
+
// FAST AUTOMATE
|
| 275 |
+
loading.style.setProperty("visibility", "visible")
|
| 276 |
+
loaded_infos = loaded_infos.concat(game.info)
|
| 277 |
+
game.load_automated_infos();
|
| 278 |
+
|
| 279 |
+
btn_next_map.disabled = true
|
| 280 |
+
btn_speeder.disabled = true
|
| 281 |
+
btn_collide.disabled = true
|
| 282 |
+
btn_replace.disabled = true
|
| 283 |
+
} else {
|
| 284 |
+
game.pause_game();
|
| 285 |
+
btn_fast_automation.disabled = true
|
| 286 |
+
}
|
| 287 |
+
}
|
| 288 |
+
btn_pause_auto.onclick = () => {
|
| 289 |
+
if (btn_pause_auto.innerText == "Automate") {
|
| 290 |
+
if (btn_fast_automation.innerText == "Pause") {btn_fast_automation.disabled = true}
|
| 291 |
+
game.pause_game()
|
| 292 |
+
// AUTOMATE THE GAME
|
| 293 |
+
btn_pause_auto.innerText = "Pause"
|
| 294 |
+
game.set_game_interval(()=>{ game.automate() })
|
| 295 |
+
game.info.mode = "automated"
|
| 296 |
+
btn_speeder.disabled = true
|
| 297 |
+
} else {game.pause_game()}
|
| 298 |
+
}
|
| 299 |
+
btn_next_map.onclick = ()=>{
|
| 300 |
+
game.info.steps = 0
|
| 301 |
+
game.info.score = 0
|
| 302 |
+
game.info.fouls = 0
|
| 303 |
+
if (btn_next_map.innerText == "Random Map") {
|
| 304 |
+
// GETTING RANDOM MAP
|
| 305 |
+
game.get_map("random")
|
| 306 |
+
btn_next_map.innerText = 'Fixed Map'
|
| 307 |
+
btn_collide.innerText = 'Disable Collision'
|
| 308 |
+
btn_collide.click()
|
| 309 |
+
btn_collide.disabled = true
|
| 310 |
+
} else {
|
| 311 |
+
// GETTING FIXED MAP
|
| 312 |
+
game.get_map("fixed")
|
| 313 |
+
btn_next_map.innerText = 'Random Map'
|
| 314 |
+
btn_collide.disabled = false
|
| 315 |
+
}
|
| 316 |
+
game.pause_game()
|
| 317 |
+
}
|
| 318 |
+
btn_speeder.onclick = () => {
|
| 319 |
+
if (btn_speeder.innerText == 'Slower') {
|
| 320 |
+
// SLOW IT
|
| 321 |
+
game.info.time = game.info.slow_time
|
| 322 |
+
btn_speeder.innerText = 'Faster'
|
| 323 |
+
} else {
|
| 324 |
+
// FAST IT
|
| 325 |
+
game.info.time = game.info.fast_time
|
| 326 |
+
btn_speeder.innerText = 'Slower'
|
| 327 |
+
}
|
| 328 |
+
if (game.info.mode == "automated") {
|
| 329 |
+
game.pause_game()
|
| 330 |
+
btn_pause_auto.click()
|
| 331 |
+
} else if (game.info.mode == "key") {
|
| 332 |
+
game.pause_game()
|
| 333 |
+
}
|
| 334 |
+
}
|
| 335 |
+
btn_collide.onclick = () => {
|
| 336 |
+
if (btn_collide.innerText == 'Enable Collision') {
|
| 337 |
+
// Enable Collision
|
| 338 |
+
game.info.allowcollisions = 1
|
| 339 |
+
btn_collide.innerText = 'Disable Collision'
|
| 340 |
+
} else {
|
| 341 |
+
// Disable Collision
|
| 342 |
+
game.info.allowcollisions = 0
|
| 343 |
+
btn_collide.innerText = 'Enable Collision'
|
| 344 |
+
}
|
| 345 |
+
}
|
| 346 |
+
btn_replace.onclick = () => {
|
| 347 |
+
game.info.map[game.info.map.indexOf(2)] = 0
|
| 348 |
+
let r = Math.floor(Math.random() * (31*28))
|
| 349 |
+
while (game.info.map[r] != 0) { r = Math.floor(Math.random() * (31*28)) }
|
| 350 |
+
game.info.map[r] = 2
|
| 351 |
+
game.update_map()
|
| 352 |
+
}
|
| 353 |
+
btn_guide.onclick = ()=>{
|
| 354 |
+
game.pause_game()
|
| 355 |
+
if (btn_guide.innerText == "Guide") {
|
| 356 |
+
// SHOWING GUIDE
|
| 357 |
+
ins.style.setProperty('display', 'block')
|
| 358 |
+
btn_guide.innerText = "Close"
|
| 359 |
+
btn_fast_automation.disabled = true
|
| 360 |
+
btn_pause_auto.disabled = true
|
| 361 |
+
btn_next_map.disabled = true
|
| 362 |
+
btn_speeder.disabled = true
|
| 363 |
+
btn_collide.disabled = true
|
| 364 |
+
btn_replace.disabled = true
|
| 365 |
+
} else {
|
| 366 |
+
// CLOSING GUIDE
|
| 367 |
+
ins.style.setProperty('display', 'none')
|
| 368 |
+
btn_guide.innerText = "Guide"
|
| 369 |
+
btn_fast_automation.disabled = false
|
| 370 |
+
}
|
| 371 |
+
}
|
| 372 |
+
document.querySelector("body").style.setProperty("height", `${window.innerHeight}px`)
|
| 373 |
+
document.querySelector(":root").style.setProperty(
|
| 374 |
+
"--win_size",
|
| 375 |
+
`${(win_size/100) * ((window.innerHeight < window.innerWidth)? window.innerHeight: window.innerWidth)}px`
|
| 376 |
+
)
|
| 377 |
+
|
| 378 |
+
window.addEventListener("resize", () => {
|
| 379 |
+
document.querySelector("body").style.setProperty("height", `${window.innerHeight}px`)
|
| 380 |
+
document.querySelector(":root").style.setProperty(
|
| 381 |
+
"--win_size",
|
| 382 |
+
`${(win_size/100) * ((window.innerHeight < window.innerWidth)? window.innerHeight: window.innerWidth)}px`
|
| 383 |
+
)
|
| 384 |
+
});
|
| 385 |
+
|
| 386 |
+
|
web/snake.png
ADDED
|
web/style.css
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
* {
|
| 2 |
+
margin: 0;
|
| 3 |
+
padding: 0;
|
| 4 |
+
box-sizing: border-box;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
:root {
|
| 8 |
+
--screen_ratio: 11vmin;
|
| 9 |
+
--top_size: 8%;
|
| 10 |
+
--right_size: 18%;
|
| 11 |
+
--border_size: 0.4vmin;
|
| 12 |
+
--ins_size: 95%;
|
| 13 |
+
--loading_size: 10vmin;
|
| 14 |
+
|
| 15 |
+
--food_size: 100%;
|
| 16 |
+
--head_size: 100%;
|
| 17 |
+
--body_size: 100%;
|
| 18 |
+
|
| 19 |
+
--bg_color_lighterer: rgb(240, 239, 239);
|
| 20 |
+
--bg_color_lighter: rgb(229, 226, 226);
|
| 21 |
+
--bg_color_light: rgb(187, 186, 186);
|
| 22 |
+
--bg_color_norm: rgb(117, 116, 116);
|
| 23 |
+
--bg_color_dark: rgb(87, 86, 86);
|
| 24 |
+
--bg_color_darker: rgb(51, 50, 50);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
body {
|
| 28 |
+
background-color: var(--bg_color_lighter);
|
| 29 |
+
overflow: hidden;
|
| 30 |
+
box-sizing: border-box;
|
| 31 |
+
width: 100vw;
|
| 32 |
+
/* height: 100vh; */
|
| 33 |
+
display: flex;
|
| 34 |
+
justify-content: center;
|
| 35 |
+
align-items: center;
|
| 36 |
+
/* border: 2px solid rgba(255, 0, 0, 0.533); */
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
#ins {
|
| 40 |
+
position: absolute;
|
| 41 |
+
width: var(--ins_size);
|
| 42 |
+
height: var(--ins_size);
|
| 43 |
+
overflow-y: scroll;
|
| 44 |
+
left: calc(50% - var(--ins_size)/2);
|
| 45 |
+
top: calc(50% - var(--ins_size)/2);
|
| 46 |
+
z-index: 3;
|
| 47 |
+
padding: 2%;
|
| 48 |
+
font-size: 2.25vmin;
|
| 49 |
+
background-color: var(--bg_color_lighterer);
|
| 50 |
+
color: var(--bg_color_darker);
|
| 51 |
+
border: 0.3vmin solid var(--bg_color_darker);
|
| 52 |
+
outline: 0.3vmin solid var(--bg_color_dark);
|
| 53 |
+
font-family: monospace;
|
| 54 |
+
display: none;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
#ins>ul {
|
| 58 |
+
padding-left: 3%;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
#ins>b {
|
| 62 |
+
background-color: inherit;
|
| 63 |
+
color: black;
|
| 64 |
+
text-decoration: double;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
a {
|
| 68 |
+
color: black;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
li>span {
|
| 72 |
+
background-color: var(--bg_color_lighter);
|
| 73 |
+
}
|
| 74 |
+
#ins>.heading1 {
|
| 75 |
+
background-color: var(--bg_color_lighter);
|
| 76 |
+
}
|
| 77 |
+
.big-container {
|
| 78 |
+
/* border: 2px solid rgba(0, 0, 255, 0.438); */
|
| 79 |
+
box-sizing: border-box;
|
| 80 |
+
width: 100vw;
|
| 81 |
+
/* height: 100vh; */
|
| 82 |
+
display: flex;
|
| 83 |
+
justify-content: center;
|
| 84 |
+
align-items: center;
|
| 85 |
+
}
|
| 86 |
+
.container {
|
| 87 |
+
border: var(--border_size) solid black;
|
| 88 |
+
width: var(--win_size);
|
| 89 |
+
height: calc(var(--win_size) - var(--screen_ratio));
|
| 90 |
+
/* margin: calc((100vmin - var(--win_size) + var(--screen_ratio) - var(--top_size)/3)/2) auto; */
|
| 91 |
+
/* margin-top: calc(10vh) ;
|
| 92 |
+
margin-left: auto;
|
| 93 |
+
margin-right: auto; */
|
| 94 |
+
display: flex;
|
| 95 |
+
flex-direction: row;
|
| 96 |
+
background-color: var(--bg_color_lighterer);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.sub-container {
|
| 100 |
+
border-right: var(--border_size) solid var(--bg_color_darker);
|
| 101 |
+
display: flex;
|
| 102 |
+
flex-direction: column;
|
| 103 |
+
width: calc(100% - var(--right_size));
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.top {
|
| 107 |
+
width: 100%;
|
| 108 |
+
height: var(--top_size);
|
| 109 |
+
display: flex;
|
| 110 |
+
justify-content: space-evenly;
|
| 111 |
+
padding: var(--border_size);
|
| 112 |
+
background-color: var(--bg_color_light);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
.top>div {
|
| 116 |
+
font-weight: bolder;
|
| 117 |
+
font-family: monospace;
|
| 118 |
+
font-family: 'Courier New', Courier, monospace;
|
| 119 |
+
font-size: 2.8vmin;
|
| 120 |
+
background-color: var(--bg_color_lighterer);
|
| 121 |
+
color: var(--bg_color_darker);
|
| 122 |
+
border: 0.3vmin solid var(--bg_color_darker);
|
| 123 |
+
padding: 0% 7%;
|
| 124 |
+
display: flex;
|
| 125 |
+
align-items: center;
|
| 126 |
+
width: 30%;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
.top>div:hover {
|
| 130 |
+
cursor: default;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
.game {
|
| 134 |
+
padding: 0.2%;
|
| 135 |
+
height: 100%;
|
| 136 |
+
border-top: var(--border_size) solid var(--bg_color_darker);
|
| 137 |
+
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
.right {
|
| 141 |
+
width: var(--right_size);
|
| 142 |
+
display: flex;
|
| 143 |
+
flex-direction: column;
|
| 144 |
+
justify-content: space-around;
|
| 145 |
+
padding: 0.8%;
|
| 146 |
+
background-color: var(--bg_color_lighter);
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
.right>button {
|
| 150 |
+
font-weight: bolder;
|
| 151 |
+
font-family: monospace;
|
| 152 |
+
font-family: 'Courier New', Courier, monospace;
|
| 153 |
+
font-size: 2.5vmin;
|
| 154 |
+
width: 100%;
|
| 155 |
+
height: 8%;
|
| 156 |
+
border: 0.3vmin solid var(--bg_color_dark);
|
| 157 |
+
background-color: white;
|
| 158 |
+
position: relative;
|
| 159 |
+
overflow: hidden;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
.right>button:hover {
|
| 163 |
+
outline: 0.1vmin solid var(--bg_color_dark);
|
| 164 |
+
box-shadow: 3px 3px 3px var(--bg_color_norm);
|
| 165 |
+
background-color: var(--bg_color_light);
|
| 166 |
+
color: black;
|
| 167 |
+
cursor: pointer;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
.right>button:disabled {
|
| 171 |
+
cursor: not-allowed;
|
| 172 |
+
color: inherit;
|
| 173 |
+
color: var(--bg_color_dark);
|
| 174 |
+
background-color: var(--bg_color_lighterer);
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
.right>button:disabled:hover {
|
| 178 |
+
background-color: inherit;
|
| 179 |
+
box-shadow: none;
|
| 180 |
+
outline: none;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
.game {
|
| 184 |
+
display: flex;
|
| 185 |
+
flex-wrap: wrap;
|
| 186 |
+
position: relative;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
.game>div {
|
| 190 |
+
width: calc((100%/var(--cols)));
|
| 191 |
+
height: calc((100%/var(--rows)));
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
.wall {
|
| 195 |
+
box-sizing: border-box;
|
| 196 |
+
margin: 0;
|
| 197 |
+
background-color: var(--bg_color_norm);
|
| 198 |
+
border-radius: 10%;
|
| 199 |
+
border: 0.05vmin solid black;
|
| 200 |
+
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
.empty {
|
| 204 |
+
background-color: var(--bg_color_lighterer);
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.food {
|
| 208 |
+
box-sizing: border-box;
|
| 209 |
+
background-color: aqua;
|
| 210 |
+
border: 0.3vmin solid black;
|
| 211 |
+
outline: 0.4vmin solid rgb(130, 213, 213);
|
| 212 |
+
border-radius: 45%;
|
| 213 |
+
z-index: 1;
|
| 214 |
+
margin: calc(((50% - var(--food_size)/2)/var(--rows))) calc(((50% - var(--food_size)/2)/var(--cols)));
|
| 215 |
+
width: calc((var(--food_size)/var(--cols))) !important;
|
| 216 |
+
height: calc((var(--food_size)/var(--rows))) !important;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.head {
|
| 220 |
+
background-color: rgb(255, 0, 0);
|
| 221 |
+
border: 0.3vmin solid black;
|
| 222 |
+
outline: 0.45vmin solid rgb(169, 81, 81);
|
| 223 |
+
border-radius: 50%;
|
| 224 |
+
z-index: 2;
|
| 225 |
+
margin: calc(((50% - var(--head_size)/2)/var(--rows))) calc(((50% - var(--head_size)/2)/var(--cols)));
|
| 226 |
+
width: calc((var(--head_size)/var(--cols))) !important;
|
| 227 |
+
height: calc((var(--head_size)/var(--rows))) !important;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
.body {
|
| 231 |
+
box-sizing: border-box;
|
| 232 |
+
background: rgb(249, 0, 0);
|
| 233 |
+
background: radial-gradient(circle, rgba(183, 1, 1, 0.492) 41%, rgba(116, 119, 33, 0.3) 58%);
|
| 234 |
+
border: 0.1vmin solid black;
|
| 235 |
+
outline: 0.2vmin solid red;
|
| 236 |
+
border-radius: 50%;
|
| 237 |
+
z-index: 1;
|
| 238 |
+
margin: calc(((50% - var(--body_size)/2)/var(--rows)));
|
| 239 |
+
width: calc((var(--body_size)/var(--cols))) !important;
|
| 240 |
+
height: calc((var(--body_size)/var(--rows))) !important;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
#loading {
|
| 244 |
+
position: absolute;
|
| 245 |
+
left: calc((50% - var(--loading_size)));
|
| 246 |
+
top: calc((50% - var(--loading_size) - calc(100% / var(--rows))));
|
| 247 |
+
visibility: hidden;
|
| 248 |
+
}
|
| 249 |
+
.lds-hourglass {
|
| 250 |
+
display: inline-block;
|
| 251 |
+
position: relative;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
.lds-hourglass:after {
|
| 255 |
+
content: " ";
|
| 256 |
+
display: block;
|
| 257 |
+
border-radius: 50%;
|
| 258 |
+
width: 0;
|
| 259 |
+
height: 0;
|
| 260 |
+
margin: 0;
|
| 261 |
+
border: var(--loading_size) solid;
|
| 262 |
+
border-color: rgba(0, 0, 0, 0.355) transparent;
|
| 263 |
+
animation: lds-hourglass 1.2s infinite;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
@keyframes lds-hourglass {
|
| 267 |
+
0% {
|
| 268 |
+
transform: rotate(0);
|
| 269 |
+
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
50% {
|
| 273 |
+
transform: rotate(900deg);
|
| 274 |
+
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
100% {
|
| 278 |
+
transform: rotate(1800deg);
|
| 279 |
+
}
|
| 280 |
+
}
|
web/swipe.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*!
|
| 2 |
+
* swiped-events.js - v@version@
|
| 3 |
+
* Pure JavaScript swipe events
|
| 4 |
+
* https://github.com/john-doherty/swiped-events
|
| 5 |
+
* @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element
|
| 6 |
+
* @author John Doherty <www.johndoherty.info>
|
| 7 |
+
* @license MIT
|
| 8 |
+
*/
|
| 9 |
+
(function (window, document) {
|
| 10 |
+
|
| 11 |
+
'use strict';
|
| 12 |
+
|
| 13 |
+
// patch CustomEvent to allow constructor creation (IE/Chrome)
|
| 14 |
+
if (typeof window.CustomEvent !== 'function') {
|
| 15 |
+
|
| 16 |
+
window.CustomEvent = function (event, params) {
|
| 17 |
+
|
| 18 |
+
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
| 19 |
+
|
| 20 |
+
var evt = document.createEvent('CustomEvent');
|
| 21 |
+
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
| 22 |
+
return evt;
|
| 23 |
+
};
|
| 24 |
+
|
| 25 |
+
window.CustomEvent.prototype = window.Event.prototype;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
document.addEventListener('touchstart', handleTouchStart, false);
|
| 29 |
+
document.addEventListener('touchmove', handleTouchMove, false);
|
| 30 |
+
document.addEventListener('touchend', handleTouchEnd, false);
|
| 31 |
+
|
| 32 |
+
var xDown = null;
|
| 33 |
+
var yDown = null;
|
| 34 |
+
var xDiff = null;
|
| 35 |
+
var yDiff = null;
|
| 36 |
+
var timeDown = null;
|
| 37 |
+
var startEl = null;
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* Fires swiped event if swipe detected on touchend
|
| 41 |
+
* @param {object} e - browser event object
|
| 42 |
+
* @returns {void}
|
| 43 |
+
*/
|
| 44 |
+
function handleTouchEnd(e) {
|
| 45 |
+
|
| 46 |
+
// if the user released on a different target, cancel!
|
| 47 |
+
if (startEl !== e.target) return;
|
| 48 |
+
|
| 49 |
+
var swipeThreshold = parseInt(getNearestAttribute(startEl, 'data-swipe-threshold', '20'), 10); // default 20px
|
| 50 |
+
var swipeTimeout = parseInt(getNearestAttribute(startEl, 'data-swipe-timeout', '500'), 10); // default 500ms
|
| 51 |
+
var timeDiff = Date.now() - timeDown;
|
| 52 |
+
var eventType = '';
|
| 53 |
+
var changedTouches = e.changedTouches || e.touches || [];
|
| 54 |
+
|
| 55 |
+
if (Math.abs(xDiff) > Math.abs(yDiff)) { // most significant
|
| 56 |
+
if (Math.abs(xDiff) > swipeThreshold && timeDiff < swipeTimeout) {
|
| 57 |
+
if (xDiff > 0) {
|
| 58 |
+
eventType = 'swiped-left';
|
| 59 |
+
}
|
| 60 |
+
else {
|
| 61 |
+
eventType = 'swiped-right';
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
else if (Math.abs(yDiff) > swipeThreshold && timeDiff < swipeTimeout) {
|
| 66 |
+
if (yDiff > 0) {
|
| 67 |
+
eventType = 'swiped-up';
|
| 68 |
+
}
|
| 69 |
+
else {
|
| 70 |
+
eventType = 'swiped-down';
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
if (eventType !== '') {
|
| 75 |
+
|
| 76 |
+
var eventData = {
|
| 77 |
+
dir: eventType.replace(/swiped-/, ''),
|
| 78 |
+
touchType: (changedTouches[0] || {}).touchType || 'direct',
|
| 79 |
+
xStart: parseInt(xDown, 10),
|
| 80 |
+
xEnd: parseInt((changedTouches[0] || {}).clientX || -1, 10),
|
| 81 |
+
yStart: parseInt(yDown, 10),
|
| 82 |
+
yEnd: parseInt((changedTouches[0] || {}).clientY || -1, 10)
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
// fire `swiped` event event on the element that started the swipe
|
| 86 |
+
startEl.dispatchEvent(new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData }));
|
| 87 |
+
|
| 88 |
+
// fire `swiped-dir` event on the element that started the swipe
|
| 89 |
+
startEl.dispatchEvent(new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData }));
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
// reset values
|
| 93 |
+
xDown = null;
|
| 94 |
+
yDown = null;
|
| 95 |
+
timeDown = null;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/**
|
| 99 |
+
* Records current location on touchstart event
|
| 100 |
+
* @param {object} e - browser event object
|
| 101 |
+
* @returns {void}
|
| 102 |
+
*/
|
| 103 |
+
function handleTouchStart(e) {
|
| 104 |
+
|
| 105 |
+
// if the element has data-swipe-ignore="true" we stop listening for swipe events
|
| 106 |
+
if (e.target.getAttribute('data-swipe-ignore') === 'true') return;
|
| 107 |
+
|
| 108 |
+
startEl = e.target;
|
| 109 |
+
|
| 110 |
+
timeDown = Date.now();
|
| 111 |
+
xDown = e.touches[0].clientX;
|
| 112 |
+
yDown = e.touches[0].clientY;
|
| 113 |
+
xDiff = 0;
|
| 114 |
+
yDiff = 0;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
/**
|
| 118 |
+
* Records location diff in px on touchmove event
|
| 119 |
+
* @param {object} e - browser event object
|
| 120 |
+
* @returns {void}
|
| 121 |
+
*/
|
| 122 |
+
function handleTouchMove(e) {
|
| 123 |
+
|
| 124 |
+
if (!xDown || !yDown) return;
|
| 125 |
+
|
| 126 |
+
var xUp = e.touches[0].clientX;
|
| 127 |
+
var yUp = e.touches[0].clientY;
|
| 128 |
+
|
| 129 |
+
xDiff = xDown - xUp;
|
| 130 |
+
yDiff = yDown - yUp;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
/**
|
| 134 |
+
* Gets attribute off HTML element or nearest parent
|
| 135 |
+
* @param {object} el - HTML element to retrieve attribute from
|
| 136 |
+
* @param {string} attributeName - name of the attribute
|
| 137 |
+
* @param {any} defaultValue - default value to return if no match found
|
| 138 |
+
* @returns {any} attribute value or defaultValue
|
| 139 |
+
*/
|
| 140 |
+
function getNearestAttribute(el, attributeName, defaultValue) {
|
| 141 |
+
|
| 142 |
+
// walk up the dom tree looking for attributeName
|
| 143 |
+
while (el && el !== document.documentElement) {
|
| 144 |
+
|
| 145 |
+
var attributeValue = el.getAttribute(attributeName);
|
| 146 |
+
|
| 147 |
+
if (attributeValue) {
|
| 148 |
+
return attributeValue;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
el = el.parentNode;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
return defaultValue;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
}(window, document));
|