Spaces:
Sleeping
Sleeping
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));
|