├── favicon.png
├── img
├── car.png
└── background.png
├── screenshot.png
├── css
└── main.css
├── manifest.json
├── js
├── aux.js
├── Perceptron.js
├── main.js
└── data.js
├── LICENSE
├── index.html
├── sw.js
└── README.md
/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/victorqribeiro/carGamePerceptron/HEAD/favicon.png
--------------------------------------------------------------------------------
/img/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/victorqribeiro/carGamePerceptron/HEAD/img/car.png
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/victorqribeiro/carGamePerceptron/HEAD/screenshot.png
--------------------------------------------------------------------------------
/img/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/victorqribeiro/carGamePerceptron/HEAD/img/background.png
--------------------------------------------------------------------------------
/css/main.css:
--------------------------------------------------------------------------------
1 | html, body{
2 | margin: 0;
3 | padding: 0;
4 | display: flex;
5 | align-items: center;
6 | justify-content: center;
7 | height: 100%;
8 | }
9 | canvas{
10 | max-width: 100%;
11 | background: url('../img/background.png') center center no-repeat;
12 | background-size: cover;
13 | }
14 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "carGamePerceptron",
3 | "short_name": "carGamePerceptron",
4 | "description": "A Neural Network experiment",
5 | "start_url": "index.html",
6 | "display": "standalone",
7 | "orientation": "portrait",
8 | "background_color": "#FFF",
9 | "theme_color": "#FFF",
10 | "icons": [
11 | {
12 | "src": "favicon.png",
13 | "sizes": "256x256",
14 | "type": "image/png",
15 | "density": 1
16 | },
17 | {
18 | "src": "favicon.png",
19 | "sizes": "512x512",
20 | "type": "image/png",
21 | "density": 1
22 | }
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/js/aux.js:
--------------------------------------------------------------------------------
1 | if('serviceWorker' in navigator) {
2 | navigator.serviceWorker
3 | .register('/carGamePerceptron/sw.js', {scope: './'})
4 | .then(response => response)
5 | .catch(reason => reason);
6 | }
7 |
8 | let deferredPrompt;
9 | const addBtn = document.createElement('button');
10 |
11 | window.addEventListener('beforeinstallprompt', (e) => {
12 | e.preventDefault();
13 | deferredPrompt = e;
14 | addBtn.style.display = 'block';
15 | addBtn.addEventListener('click', (e) => {
16 | addBtn.style.display = 'none';
17 | deferredPrompt.prompt();
18 | deferredPrompt.userChoice.then((choiceResult) => {
19 | deferredPrompt = null;
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/js/Perceptron.js:
--------------------------------------------------------------------------------
1 | class Perceptron {
2 |
3 | constructor(size, learningRate, iterations){
4 | this.weights = Array(++size).fill(0);
5 | this.lr = learningRate || 0.01;
6 | this.it = iterations || 10;
7 | }
8 |
9 | predict(inputs){
10 | let activation = this.weights[0];
11 | for(let i = 0; i < inputs.length; i++){
12 | activation += this.weights[i+1] * inputs[i];
13 | }
14 | return activation >= 0 ? 1 : 0;
15 | }
16 |
17 | fit(input, target){
18 | let prediction, error, it = 0;
19 | while(it < this.it){
20 | for(let i=0; i < input.length; i++){
21 | prediction = this.predict( input[i] );
22 | error = target[i] - prediction;
23 | this.weights[0] += this.lr * error;
24 | for(let j=0; j < input[i].length; j++){
25 | this.weights[j+1] += this.lr * error * input[i][j];
26 | }
27 | }
28 | it += 1;
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Victor Ribeiro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | carGamePerceptron
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/sw.js:
--------------------------------------------------------------------------------
1 | const filesToCache = [
2 | './',
3 | './index.html',
4 | './js/main.js',
5 | './js/data.js',
6 | './js/Perceptron.js',
7 | './css/main.css',
8 | './img/car.png',
9 | './img/background.png',
10 | './favicon.png',
11 | './manifest.json'
12 | ];
13 |
14 | const staticCacheName = 'carGamePerceptron-v1';
15 |
16 | self.addEventListener('install', event => {
17 | event.waitUntil(
18 | caches.open(staticCacheName)
19 | .then(cache => {
20 | return cache.addAll(filesToCache);
21 | })
22 | );
23 | });
24 |
25 | self.addEventListener('fetch', event => {
26 | event.respondWith(
27 | caches.match(event.request)
28 | .then(response => {
29 | if (response) {
30 | return response;
31 | }
32 |
33 | return fetch(event.request)
34 |
35 | .then(response => {
36 | return caches.open(staticCacheName).then(cache => {
37 | cache.put(event.request.url, response.clone());
38 | return response;
39 | });
40 | });
41 |
42 | }).catch(error => {})
43 | );
44 | });
45 |
46 | self.addEventListener('activate', event => {
47 |
48 | const cacheWhitelist = [staticCacheName];
49 |
50 | event.waitUntil(
51 | caches.keys().then(cacheNames => {
52 | return Promise.all(
53 | cacheNames.map(cacheName => {
54 | if (cacheWhitelist.indexOf(cacheName) === -1) {
55 | return caches.delete(cacheName);
56 | }
57 | })
58 | );
59 | })
60 | );
61 | });
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Excuse me, would you let my Neural Network drive?
3 |
4 | A Neural Network experiment involving a JavaScript game: can a perceptron drive a car?
5 |
6 | [](http://www.youtube.com/watch?v=g0WV3qWcVuA)
7 |
8 | A live version of the code is hosted [here](https://victorribeiro.com/carGamePerceptron)
9 |
10 | # About
11 |
12 | Not so long ago I published the [simplest perceptron you'll ever see](https://github.com/victorqribeiro/perceptron), code I wrote after a machine learning class, a while back. Ever since that I've been meaning to do something cool with it. So, browsing some [more old codes](http://jsfiddle.net/user/victorqribeiro) I found a [little game](https://github.com/victorqribeiro/carGame) I made when I was studing fake 3D perspective, so I thought: can my perceptron play this game?
13 |
14 | So I gave the game code a little brushing, wrote some more code to capture the data of me playing it (I played until I got a score of 33 points) and feed it to my neural net. After that I just played with the learning rate and iterations and let it play the game on it's own.
15 |
16 | A [Neuroevolution](https://en.wikipedia.org/wiki/Neuroevolution) you say? Yes, I thought about that. I have a fully conected multilayer perceptron, that I'm about to realease, So I'm saving the ideia of evolving a neural net with genetic algorithm for that.
17 |
18 | Quick reminder that the game is not fair. Sometimes two cars comes in parallel with each other, so not even a human could beat it.
19 |
20 | # Questions?
21 |
22 | If you have any questions about the code or how I implemented it, or even how I got the data to feed the neural network (features), please feel free to contact me. (I left some comments on the code)
23 |
--------------------------------------------------------------------------------
/js/main.js:
--------------------------------------------------------------------------------
1 | /* nn stuff */
2 |
3 | const nn = new Perceptron( x[0].length, 0.01, 15000 );
4 |
5 | nn.fit( x, y );
6 |
7 | /* game stuff */
8 |
9 | const size = Math.min(innerWidth, innerHeight);
10 | const canvas = document.createElement("canvas");
11 | canvas.width = w = size;
12 | canvas.height = h = size;
13 | const c = canvas.getContext("2d");
14 |
15 | c.translate(w/2,h-h/2.5);
16 |
17 | document.body.appendChild(canvas);
18 | const car = new Image(), fov = 300;
19 |
20 | let points = [], score = 0, p, colide;
21 |
22 | /*
23 | let i, _x, _y;
24 | */
25 |
26 | function init(){
27 |
28 | /*
29 | i = 0;
30 | _x = [];
31 | _y = [];
32 | */
33 |
34 | car.src = 'img/car.png';
35 | car.onload = ()=>draw();
36 |
37 | points = [];
38 | score = 0;
39 |
40 | for(let i = 0; i < 2; i++){
41 | points.push({
42 | x: Math.random() > 0.5 ? -40 : 5,
43 | y: 0,
44 | z: Math.random()*200,
45 | w: 30,
46 | speed: Math.random() + 0.5
47 | });
48 | }
49 |
50 | p = {
51 | x: 0,
52 | y: 0,
53 | z: -230,
54 | lane: 1,
55 | laneToBe: 1,
56 | isChangingLane: false,
57 | collide: function(r){
58 | return ( (this.x > r.x && this.x < r.x+r.w) ||
59 | (this.x+r.w > r.x && this.x+r.w < r.x+r.w) ) &&
60 | (r.z > this.z && r.z < this.z+5);
61 | }
62 | };
63 |
64 |
65 | }
66 |
67 | const _sort = (a,b)=>{
68 | if(a.z < b.z){
69 | return 1;
70 | }else if(b.z < a.z){
71 | return -1;
72 | }else{
73 | return 0;
74 | }
75 | };
76 |
77 | function draw(){
78 |
79 | points.sort( _sort );
80 |
81 | /* this portion of the code get the data for training the neural network every 30 frames
82 | if(i % 30 == 0){
83 | _x.push( [ points[1].x < 0 ? 0 : 1, points[1].z, points[1].speed, points[0].x < 0 ? 0 : 1, points[0].z, points[0].speed ] );
84 | _y.push( p.lane )
85 | }
86 | i++;
87 | */
88 |
89 | if( p.lane != p.laneToBe){
90 | p.isChangingLane = true;
91 | let x;
92 | if( p.laneToBe == 0 ){
93 | x = -1;
94 | }else{
95 | x = 1;
96 | }
97 | p.x += x;
98 | if( p.x == -35 ){
99 | p.lane = 0;
100 | p.isChangingLane = false;
101 | }else if( p.x == 4 ){
102 | p.lane = 1;
103 | p.isChangingLane = false;
104 | }
105 | }
106 |
107 | c.clearRect(-w,-h,w*2,h*2);
108 | colide = false;
109 | for(let i = 0; i < points.length; i++){
110 | points[i].z -= points[i].speed;
111 | let s = fov / (fov+points[i].z);
112 | c.save();
113 | c.scale(s,s);
114 | c.translate(points[i].x,points[i].y);
115 | c.drawImage(car,0,0,30,30);
116 | c.restore();
117 | if(points[i].z < p.z-20){
118 | points[i].z = 200;
119 | points[i].x = Math.random() > 0.5 ? -40 : 5;
120 | score++;
121 | }
122 | if(p.collide(points[i])){
123 | colide = true;
124 | break;
125 | }
126 | }
127 | c.save();
128 | let sp = fov / (fov + p.z);
129 | c.scale(sp,sp);
130 | c.translate(p.x,p.y);
131 | c.drawImage(car,0,0,30,30);
132 | c.restore();
133 | c.font = "30px Arial";
134 | c.fillText("Score: "+score, -w/2+10, -h/2 );
135 |
136 | const move = nn.predict( [ points[1].x < 0 ? 0 : 1, points[1].z, points[1].speed, points[0].x < 0 ? 0 : 1, points[0].z, points[0].speed ] );
137 |
138 | if(!p.isChangingLane)
139 | p.laneToBe = move;
140 |
141 | if(!colide)
142 | requestAnimationFrame(draw);
143 | }
144 |
145 | document.body.addEventListener('click', function(){
146 | if( colide )
147 | init();
148 | });
149 |
150 | init();
151 |
--------------------------------------------------------------------------------
/js/data.js:
--------------------------------------------------------------------------------
1 | const x = [[0,104.98653759724385,0.508096235591929,0,169.88276536858967,1.1732416053556067],
2 | [0,89.74365052948579,0.508096235591929,0,134.6855172079217,1.1732416053556067],
3 | [0,74.50076346172773,0.508096235591929,0,99.48826904725335,1.1732416053556067],
4 | [0,59.25787639396974,0.508096235591929,0,64.29102088658495,1.1732416053556067],
5 | [0,29.09377272591675,1.1732416053556067,0,44.01498932621189,0.508096235591929],
6 | [0,-6.103475434751446,1.1732416053556067,0,28.77210225845404,0.508096235591929],
7 | [0,-41.30072359541965,1.1732416053556067,0,13.529215190696192,0.508096235591929],
8 | [0,-76.49797175608792,1.1732416053556067,0,-1.7136718770616728,0.508096235591929],
9 | [0,-111.69521991675633,1.1732416053556067,0,-16.956558944819534,0.508096235591929],
10 | [0,-146.8924680774245,1.1732416053556067,0,-32.19944601257738,0.508096235591929],
11 | [0,-182.08971623809248,1.1732416053556067,0,-47.44233308033523,0.508096235591929],
12 | [0,-217.28696439876046,1.1732416053556067,0,-62.68522014809308,0.508096235591929],
13 | [0,-77.92810721585113,0.508096235591929,1,197.6535167892888,1.1732416053556067],
14 | [0,-93.17099428360919,0.508096235591929,1,162.45626862862082,1.1732416053556067],
15 | [0,-108.41388135136725,0.508096235591929,1,127.25902046795282,1.1732416053556067],
16 | [0,-123.65676841912531,0.508096235591929,1,92.06177230728441,1.1732416053556067],
17 | [0,-138.89965548688306,0.508096235591929,1,56.864524146616056,1.1732416053556067],
18 | [0,-154.1425425546407,0.508096235591929,1,21.66727598594786,1.1732416053556067],
19 | [0,-169.38542962239833,0.508096235591929,1,-13.529972174720337,1.1732416053556067],
20 | [0,-184.62831669015597,0.508096235591929,1,-48.72722033538854,1.1732416053556067],
21 | [0,-199.8712037579136,0.508096235591929,1,-83.92446849605685,1.1732416053556067],
22 | [0,-215.11409082567124,0.508096235591929,1,-119.12171665672525,1.1732416053556067],
23 | [0,-230.35697789342888,0.508096235591929,1,-154.31896481739335,1.1732416053556067],
24 | [0,-245.5998649611865,0.508096235591929,1,-189.51621297806133,1.1732416053556067],
25 | [1,-224.71346113872931,1.1732416053556067,1,189.32997905256966,0.508096235591929],
26 | [1,174.08709198481202,0.508096235591929,0,190.6140671571552,1.1732416053556067],
27 | [0,155.41681899648722,1.1732416053556067,1,158.84420491705438,0.508096235591929],
28 | [0,120.21957083581914,1.1732416053556067,1,143.60131784929675,0.508096235591929],
29 | [0,85.02232267515073,1.1732416053556067,1,128.3584307815391,0.508096235591929],
30 | [0,49.82507451448242,1.1732416053556067,1,113.11554371378105,0.508096235591929],
31 | [0,14.627826353814221,1.1732416053556067,1,97.87265664602299,0.508096235591929],
32 | [0,-20.569421806853978,1.1732416053556067,1,82.62976957826493,0.508096235591929],
33 | [0,-55.766669967522176,1.1732416053556067,1,67.38688251050687,0.508096235591929],
34 | [0,-90.96391812819053,1.1732416053556067,1,52.143995442748974,0.508096235591929],
35 | [0,-126.16116628885894,1.1732416053556067,1,36.901108374991125,0.508096235591929],
36 | [0,-161.35841444952695,1.1732416053556067,1,21.658221307233276,0.508096235591929],
37 | [0,-196.55566261019493,1.1732416053556067,1,6.415334239475424,0.508096235591929],
38 | [0,-231.7529107708629,1.1732416053556067,1,-8.827552828282448,0.508096235591929],
39 | [1,-24.0704398960403,0.508096235591929,1,183.5746175250216,1.1732416053556067],
40 | [1,-39.31332696379815,0.508096235591929,1,148.37736936435363,1.1732416053556067],
41 | [1,-54.556214031555996,0.508096235591929,1,113.18012120368546,1.1732416053556067],
42 | [1,-69.79910109931393,0.508096235591929,1,77.98287304301705,1.1732416053556067],
43 | [1,-85.04198816707199,0.508096235591929,1,42.78562488234878,1.1732416053556067],
44 | [1,-100.28487523483005,0.508096235591929,1,7.588376721680582,1.1732416053556067],
45 | [1,-115.52776230258812,0.508096235591929,1,-27.608871438987617,1.1732416053556067],
46 | [1,-130.7706493703461,0.508096235591929,1,-62.806119599655815,1.1732416053556067],
47 | [1,-146.01353643810373,0.508096235591929,1,-98.00336776032421,1.1732416053556067],
48 | [1,-161.25642350586136,0.508096235591929,1,-133.20061592099256,1.1732416053556067],
49 | [1,-176.499310573619,0.508096235591929,1,-168.39786408166054,1.1732416053556067],
50 | [1,-203.59511224232853,1.1732416053556067,1,-191.74219764137663,0.508096235591929],
51 | [1,-238.7923604029965,1.1732416053556067,1,-206.98508470913427,0.508096235591929],
52 | [1,-222.2279717768919,0.508096235591929,1,176.535167892888,1.1732416053556067],
53 | [1,-237.47085884464954,0.508096235591929,1,141.33791973222003,1.1732416053556067],
54 | [1,106.14067157155178,1.1732416053556067,0,197.4595188220404,0.508096235591929],
55 | [1,70.94342341088337,1.1732416053556067,0,182.21663175428276,0.508096235591929],
56 | [1,35.74617525021514,1.1732416053556067,0,166.97374468652512,0.508096235591929],
57 | [1,0.5489270895469427,1.1732416053556067,0,151.7308576187675,0.508096235591929],
58 | [1,-34.64832107112126,1.1732416053556067,0,136.48797055100985,0.508096235591929],
59 | [1,-69.84556923178948,1.1732416053556067,0,121.24508348325202,0.508096235591929],
60 | [1,-105.04281739245789,1.1732416053556067,0,106.00219641549396,0.508096235591929],
61 | [1,-140.24006555312616,1.1732416053556067,0,90.7593093477359,0.508096235591929],
62 | [1,-175.43731371379414,1.1732416053556067,0,75.51642227997783,0.508096235591929],
63 | [1,-210.63456187446212,1.1732416053556067,0,60.27353521221983,0.508096235591929],
64 | [1,-245.8318100351301,1.1732416053556067,0,45.03064814446198,0.508096235591929],
65 | [0,29.78776107670413,0.508096235591929,0,169.49571826075442,1.1732416053556067],
66 | [0,14.54487400894628,0.508096235591929,0,134.29847010008643,1.1732416053556067],
67 | [0,-0.6980130588115832,0.508096235591929,0,99.1012219394181,1.1732416053556067],
68 | [0,-15.940900126569444,0.508096235591929,0,63.903973778749695,1.1732416053556067],
69 | [0,-31.183787194327294,0.508096235591929,0,28.7067256180815,1.1732416053556067],
70 | [0,-46.42667426208514,0.508096235591929,0,-6.490522542586697,1.1732416053556067],
71 | [0,-61.66956132984299,0.508096235591929,0,-41.6877707032549,1.1732416053556067],
72 | [0,-76.91244839760103,0.508096235591929,0,-76.88501886392316,1.1732416053556067],
73 | [0,-112.08226702459157,1.1732416053556067,0,-92.15533546535909,0.508096235591929],
74 | [0,-147.27951518525975,1.1732416053556067,0,-107.39822253311715,0.508096235591929],
75 | [0,-182.47676334592774,1.1732416053556067,0,-122.64110960087521,0.508096235591929],
76 | [0,-217.67401150659572,1.1732416053556067,0,-137.883996668633,0.508096235591929],
77 | [0,-153.12688373639062,0.508096235591929,0,197.6535167892888,1.1732416053556067],
78 | [0,-168.36977080414826,0.508096235591929,0,162.45626862862082,1.1732416053556067],
79 | [0,-183.6126578719059,0.508096235591929,0,127.25902046795282,1.1732416053556067],
80 | [0,-198.85554493966353,0.508096235591929,0,92.06177230728441,1.1732416053556067],
81 | [0,-214.09843200742117,0.508096235591929,0,56.864524146616056,1.1732416053556067],
82 | [0,-229.3413190751788,0.508096235591929,0,21.66727598594786,1.1732416053556067],
83 | [0,-244.58420614293644,0.508096235591929,0,-13.529972174720337,1.1732416053556067],
84 | [0,-48.72722033538854,1.1732416053556067,1,190.3461715237535,0.508096235591929],
85 | [0,-83.92446849605685,1.1732416053556067,1,175.10328445599586,0.508096235591929],
86 | [0,-119.12171665672525,1.1732416053556067,1,159.86039738823823,0.508096235591929],
87 | [0,-154.31896481739335,1.1732416053556067,1,144.6175103204806,0.508096235591929],
88 | [0,-189.51621297806133,1.1732416053556067,1,129.37462325272296,0.508096235591929],
89 | [0,-224.71346113872931,1.1732416053556067,1,114.13173618496492,0.508096235591929],
90 | [1,98.88884911720686,0.508096235591929,1,190.6140671571552,1.1732416053556067],
91 | [1,83.6459620494488,0.508096235591929,1,155.41681899648722,1.1732416053556067],
92 | [1,68.40307498169074,0.508096235591929,1,120.21957083581914,1.1732416053556067],
93 | [1,53.16018791393283,0.508096235591929,1,85.02232267515073,1.1732416053556067],
94 | [1,37.91730084617498,0.508096235591929,1,49.82507451448242,1.1732416053556067],
95 | [1,14.627826353814221,1.1732416053556067,1,22.674413778417133,0.508096235591929],
96 | [1,-20.569421806853978,1.1732416053556067,1,7.431526710659282,0.508096235591929],
97 | [1,-55.766669967522176,1.1732416053556067,1,-7.811360357098591,0.508096235591929],
98 | [1,-90.96391812819053,1.1732416053556067,1,-23.05424742485644,0.508096235591929],
99 | [1,-126.16116628885894,1.1732416053556067,1,-38.29713449261429,0.508096235591929],
100 | [1,-161.35841444952695,1.1732416053556067,1,-53.54002156037214,0.508096235591929],
101 | [1,-196.55566261019493,1.1732416053556067,1,-68.78290862813006,0.508096235591929],
102 | [1,-231.7529107708629,1.1732416053556067,1,-84.02579569588812,0.508096235591929],
103 | [1,-99.26868276364618,0.508096235591929,1,183.5746175250216,1.1732416053556067],
104 | [1,-114.51156983140424,0.508096235591929,1,148.37736936435363,1.1732416053556067],
105 | [1,-129.75445689916225,0.508096235591929,1,113.18012120368546,1.1732416053556067],
106 | [1,-144.99734396691989,0.508096235591929,1,77.98287304301705,1.1732416053556067],
107 | [1,-160.24023103467752,0.508096235591929,1,42.78562488234878,1.1732416053556067],
108 | [1,-175.48311810243516,0.508096235591929,1,7.588376721680582,1.1732416053556067],
109 | [1,-190.7260051701928,0.508096235591929,1,-27.608871438987617,1.1732416053556067],
110 | [1,-205.96889223795043,0.508096235591929,1,-62.806119599655815,1.1732416053556067],
111 | [1,-221.21177930570806,0.508096235591929,1,-98.00336776032421,1.1732416053556067],
112 | [1,-236.4546663734657,0.508096235591929,1,-133.20061592099256,1.1732416053556067],
113 | [1,-168.39786408166054,1.1732416053556067,1,198.47571129322424,0.508096235591929],
114 | [1,-203.59511224232853,1.1732416053556067,1,183.2328242254666,0.508096235591929],
115 | [1,-238.7923604029965,1.1732416053556067,1,167.98993715770897,0.508096235591929],
116 | [1,152.74705008995133,0.508096235591929,1,176.535167892888,1.1732416053556067],
117 | [1,137.5041630221937,0.508096235591929,1,141.33791973222003,1.1732416053556067],
118 | [1,106.14067157155178,1.1732416053556067,1,122.26127595443589,0.508096235591929],
119 | [1,70.94342341088337,1.1732416053556067,1,107.01838888667783,0.508096235591929],
120 | [1,35.74617525021514,1.1732416053556067,1,91.77550181891976,0.508096235591929],
121 | [1,0.5489270895469427,1.1732416053556067,1,76.5326147511617,0.508096235591929],
122 | [1,-34.64832107112126,1.1732416053556067,1,61.28972768340368,0.508096235591929],
123 | [1,-69.84556923178948,1.1732416053556067,1,46.046840615645834,0.508096235591929],
124 | [1,-105.04281739245789,1.1732416053556067,1,30.803953547887986,0.508096235591929],
125 | [1,-140.24006555312616,1.1732416053556067,1,15.561066480130137,0.508096235591929],
126 | [1,-175.43731371379414,1.1732416053556067,1,0.31817941237227476,0.508096235591929],
127 | [1,-210.63456187446212,1.1732416053556067,1,-14.924707655385587,0.508096235591929],
128 | [1,-245.8318100351301,1.1732416053556067,1,-30.167594723143438,0.508096235591929],
129 | [1,-45.41048179090129,0.508096235591929,1,169.49571826075442,1.1732416053556067],
130 | [1,-60.653368858659135,0.508096235591929,1,134.29847010008643,1.1732416053556067],
131 | [1,-75.89625592641715,0.508096235591929,1,99.1012219394181,1.1732416053556067],
132 | [1,-91.13914299417522,0.508096235591929,1,63.903973778749695,1.1732416053556067],
133 | [1,-106.38203006193328,0.508096235591929,1,28.7067256180815,1.1732416053556067],
134 | [1,-121.62491712969134,0.508096235591929,1,-6.490522542586697,1.1732416053556067],
135 | [1,-136.86780419744915,0.508096235591929,1,-41.6877707032549,1.1732416053556067],
136 | [1,-152.11069126520678,0.508096235591929,1,-76.88501886392316,1.1732416053556067],
137 | [1,-167.35357833296442,0.508096235591929,1,-112.08226702459157,1.1732416053556067],
138 | [1,-182.59646540072205,0.508096235591929,1,-147.27951518525975,1.1732416053556067],
139 | [1,-197.8393524684797,0.508096235591929,1,-182.47676334592774,1.1732416053556067],
140 | [1,-217.67401150659572,1.1732416053556067,1,-213.08223953623732,0.508096235591929],
141 | [1,-228.32512660399496,0.508096235591929,0,197.6535167892888,1.1732416053556067],
142 | [1,-243.5680136717526,0.508096235591929,0,162.45626862862082,1.1732416053556067],
143 | [0,127.25902046795282,1.1732416053556067,0,191.36236399493734,0.508096235591929],
144 | [0,92.06177230728441,1.1732416053556067,0,176.1194769271797,0.508096235591929],
145 | [0,56.864524146616056,1.1732416053556067,0,160.87658985942207,0.508096235591929],
146 | [0,21.66727598594786,1.1732416053556067,0,145.63370279166443,0.508096235591929],
147 | [0,-13.529972174720337,1.1732416053556067,0,130.3908157239068,0.508096235591929],
148 | [0,-48.72722033538854,1.1732416053556067,0,115.14792865614879,0.508096235591929],
149 | [0,-83.92446849605685,1.1732416053556067,0,99.90504158839073,0.508096235591929],
150 | [0,-119.12171665672525,1.1732416053556067,0,84.66215452063267,0.508096235591929],
151 | [0,-154.31896481739335,1.1732416053556067,0,69.4192674528746,0.508096235591929],
152 | [0,-189.51621297806133,1.1732416053556067,0,54.17638038511669,0.508096235591929],
153 | [0,-224.71346113872931,1.1732416053556067,0,38.93349331735884,0.508096235591929],
154 | [0,23.69060624960099,0.508096235591929,1,190.6140671571552,1.1732416053556067],
155 | [0,8.44771918184314,0.508096235591929,1,155.41681899648722,1.1732416053556067],
156 | [0,-6.795167885914733,0.508096235591929,1,120.21957083581914,1.1732416053556067],
157 | [0,-22.038054953672585,0.508096235591929,1,85.02232267515073,1.1732416053556067],
158 | [0,-37.280942021430434,0.508096235591929,1,49.82507451448242,1.1732416053556067],
159 | [0,-52.52382908918828,0.508096235591929,1,14.627826353814221,1.1732416053556067],
160 | [0,-67.76671615694619,0.508096235591929,1,-20.569421806853978,1.1732416053556067],
161 | [0,-83.00960322470425,0.508096235591929,1,-55.766669967522176,1.1732416053556067],
162 | [0,-98.25249029246231,0.508096235591929,1,-90.96391812819053,1.1732416053556067],
163 | [1,-126.16116628885894,1.1732416053556067,0,-113.49537736022037,0.508096235591929],
164 | [1,-161.35841444952695,1.1732416053556067,0,-128.7382644279784,0.508096235591929],
165 | [1,-196.55566261019493,1.1732416053556067,0,-143.98115149573604,0.508096235591929],
166 | [1,-231.7529107708629,1.1732416053556067,0,-159.22403856349368,0.508096235591929],
167 | [0,-174.4669256312513,0.508096235591929,1,183.5746175250216,1.1732416053556067],
168 | [0,-189.70981269900895,0.508096235591929,1,148.37736936435363,1.1732416053556067],
169 | [0,-204.95269976676659,0.508096235591929,1,113.18012120368546,1.1732416053556067],
170 | [0,-220.19558683452422,0.508096235591929,1,77.98287304301705,1.1732416053556067],
171 | [0,-235.43847390228186,0.508096235591929,1,42.78562488234878,1.1732416053556067],
172 | [1,7.588376721680582,1.1732416053556067,0,199.49190376440808,0.508096235591929],
173 | [1,-27.608871438987617,1.1732416053556067,0,184.24901669665044,0.508096235591929],
174 | [1,-62.806119599655815,1.1732416053556067,0,169.0061296288928,0.508096235591929],
175 | [1,-98.00336776032421,1.1732416053556067,0,153.76324256113517,0.508096235591929],
176 | [1,-133.20061592099256,1.1732416053556067,0,138.52035549337754,0.508096235591929],
177 | [1,-168.39786408166054,1.1732416053556067,0,123.27746842561976,0.508096235591929],
178 | [1,-203.59511224232853,1.1732416053556067,0,108.0345813578617,0.508096235591929],
179 | [1,-238.7923604029965,1.1732416053556067,0,92.79169429010364,0.508096235591929],
180 | [0,77.54880722234557,0.508096235591929,0,176.535167892888,1.1732416053556067],
181 | [0,62.30592015458754,0.508096235591929,0,141.33791973222003,1.1732416053556067],
182 | [0,47.06303308682969,0.508096235591929,0,106.14067157155178,1.1732416053556067],
183 | [0,31.820146019071842,0.508096235591929,0,70.94342341088337,1.1732416053556067],
184 | [0,16.577258951313993,0.508096235591929,0,35.74617525021514,1.1732416053556067],
185 | [0,0.5489270895469427,1.1732416053556067,0,1.3343718835561327,0.508096235591929],
186 | [0,-34.64832107112126,1.1732416053556067,0,-13.90851518420173,0.508096235591929],
187 | [0,-69.84556923178948,1.1732416053556067,0,-29.15140225195958,0.508096235591929],
188 | [0,-105.04281739245789,1.1732416053556067,0,-44.39428931971743,0.508096235591929],
189 | [0,-140.24006555312616,1.1732416053556067,0,-59.63717638747528,0.508096235591929],
190 | [0,-175.43731371379414,1.1732416053556067,0,-74.88006345523328,0.508096235591929],
191 | [0,-210.63456187446212,1.1732416053556067,0,-90.12295052299135,0.508096235591929],
192 | [0,-245.8318100351301,1.1732416053556067,0,-105.36583759074941,0.508096235591929],
193 | [0,-120.60872465850747,0.508096235591929,0,169.49571826075442,1.1732416053556067],
194 | [0,-135.8516117262653,0.508096235591929,0,134.29847010008643,1.1732416053556067],
195 | [0,-151.09449879402294,0.508096235591929,0,99.1012219394181,1.1732416053556067],
196 | [0,-166.33738586178058,0.508096235591929,0,63.903973778749695,1.1732416053556067],
197 | [0,-181.5802729295382,0.508096235591929,0,28.7067256180815,1.1732416053556067],
198 | [0,-196.82315999729585,0.508096235591929,0,-6.490522542586697,1.1732416053556067],
199 | [0,-212.06604706505348,0.508096235591929,0,-41.6877707032549,1.1732416053556067],
200 | [0,-227.30893413281112,0.508096235591929,0,-76.88501886392316,1.1732416053556067],
201 | [0,-242.55182120056875,0.508096235591929,0,-112.08226702459157,1.1732416053556067],
202 | [0,-147.27951518525975,1.1732416053556067,0,192.37855646612118,0.508096235591929],
203 | [0,-182.47676334592774,1.1732416053556067,0,177.13566939836355,0.508096235591929],
204 | [0,-217.67401150659572,1.1732416053556067,0,161.8927823306059,0.508096235591929],
205 | [0,146.64989526284828,0.508096235591929,0,197.6535167892888,1.1732416053556067],
206 | [0,131.40700819509064,0.508096235591929,0,162.45626862862082,1.1732416053556067],
207 | [0,116.16412112733266,0.508096235591929,0,127.25902046795282,1.1732416053556067],
208 | [0,92.06177230728441,1.1732416053556067,0,100.9212340595746,0.508096235591929],
209 | [0,56.864524146616056,1.1732416053556067,0,85.67834699181654,0.508096235591929],
210 | [0,21.66727598594786,1.1732416053556067,0,70.43545992405848,0.508096235591929],
211 | [0,-13.529972174720337,1.1732416053556067,0,55.19257285630054,0.508096235591929],
212 | [0,-48.72722033538854,1.1732416053556067,0,39.949685788542695,0.508096235591929],
213 | [0,-83.92446849605685,1.1732416053556067,0,24.706798720784846,0.508096235591929],
214 | [0,-119.12171665672525,1.1732416053556067,0,9.463911653026997,0.508096235591929],
215 | [0,-154.31896481739335,1.1732416053556067,0,-5.7789754147308745,0.508096235591929],
216 | [0,-189.51621297806133,1.1732416053556067,0,-21.02186248248873,0.508096235591929],
217 | [0,-224.71346113872931,1.1732416053556067,0,-36.26474955024658,0.508096235591929],
218 | [0,-51.507636618004426,0.508096235591929,0,190.6140671571552,1.1732416053556067],
219 | [0,-66.75052368576232,0.508096235591929,0,155.41681899648722,1.1732416053556067],
220 | [0,-81.99341075352038,0.508096235591929,0,120.21957083581914,1.1732416053556067],
221 | [0,-97.23629782127844,0.508096235591929,0,85.02232267515073,1.1732416053556067],
222 | [0,-112.4791848890365,0.508096235591929,0,49.82507451448242,1.1732416053556067],
223 | [0,-127.72207195679457,0.508096235591929,0,14.627826353814221,1.1732416053556067],
224 | [0,-142.9649590245522,0.508096235591929,0,-20.569421806853978,1.1732416053556067],
225 | [0,-158.20784609230984,0.508096235591929,0,-55.766669967522176,1.1732416053556067],
226 | [0,-173.45073316006747,0.508096235591929,0,-90.96391812819053,1.1732416053556067],
227 | [0,-188.6936202278251,0.508096235591929,0,-126.16116628885894,1.1732416053556067],
228 | [0,-203.93650729558274,0.508096235591929,0,-161.35841444952695,1.1732416053556067],
229 | [0,-219.17939436334038,0.508096235591929,0,-196.55566261019493,1.1732416053556067],
230 | [0,-234.422281431098,0.508096235591929,0,-231.7529107708629,1.1732416053556067],
231 | [0,-249.66516849885565,0.508096235591929,1,183.5746175250216,1.1732416053556067],
232 | [1,148.37736936435363,1.1732416053556067,0,185.26520916783429,0.508096235591929],
233 | [1,113.18012120368546,1.1732416053556067,0,170.02232210007665,0.508096235591929],
234 | [1,77.98287304301705,1.1732416053556067,0,154.77943503231901,0.508096235591929],
235 | [1,42.78562488234878,1.1732416053556067,0,139.53654796456138,0.508096235591929],
236 | [1,7.588376721680582,1.1732416053556067,0,124.29366089680363,0.508096235591929],
237 | [1,-27.608871438987617,1.1732416053556067,0,109.05077382904557,0.508096235591929],
238 | [1,-62.806119599655815,1.1732416053556067,0,93.8078867612875,0.508096235591929],
239 | [1,-98.00336776032421,1.1732416053556067,0,78.56499969352944,0.508096235591929],
240 | [1,-133.20061592099256,1.1732416053556067,0,63.322112625771396,0.508096235591929],
241 | [1,-168.39786408166054,1.1732416053556067,0,48.07922555801355,0.508096235591929],
242 | [1,-203.59511224232853,1.1732416053556067,0,32.8363384902557,0.508096235591929],
243 | [1,-238.7923604029965,1.1732416053556067,0,17.59345142249785,0.508096235591929],
244 | [0,2.3505643547399906,0.508096235591929,1,176.535167892888,1.1732416053556067],
245 | [0,-12.892322713017874,0.508096235591929,1,141.33791973222003,1.1732416053556067],
246 | [0,-28.135209780775725,0.508096235591929,1,106.14067157155178,1.1732416053556067],
247 | [0,-43.37809684853357,0.508096235591929,1,70.94342341088337,1.1732416053556067],
248 | [0,-58.62098391629142,0.508096235591929,1,35.74617525021514,1.1732416053556067],
249 | [0,-73.86387098404941,0.508096235591929,1,0.5489270895469427,1.1732416053556067],
250 | [0,-89.10675805180747,0.508096235591929,1,-34.64832107112126,1.1732416053556067],
251 | [0,-104.34964511956554,0.508096235591929,1,-69.84556923178948,1.1732416053556067],
252 | [0,-119.5925321873236,0.508096235591929,1,-105.04281739245789,1.1732416053556067],
253 | [1,-140.24006555312616,1.1732416053556067,0,-134.83541925508146,0.508096235591929],
254 | [1,-175.43731371379414,1.1732416053556067,0,-150.0783063228391,0.508096235591929],
255 | [1,-210.63456187446212,1.1732416053556067,0,-165.32119339059673,0.508096235591929],
256 | [1,-245.8318100351301,1.1732416053556067,0,-180.56408045835437,0.508096235591929],
257 | [0,-195.806967526112,0.508096235591929,0,169.49571826075442,1.1732416053556067],
258 | [0,-211.04985459386964,0.508096235591929,0,134.29847010008643,1.1732416053556067],
259 | [0,-226.29274166162728,0.508096235591929,0,99.1012219394181,1.1732416053556067],
260 | [0,-241.5356287293849,0.508096235591929,0,63.903973778749695,1.1732416053556067],
261 | [0,28.7067256180815,1.1732416053556067,0,193.39474893730502,0.508096235591929],
262 | [0,-6.490522542586697,1.1732416053556067,0,178.1518618695474,0.508096235591929],
263 | [0,-41.6877707032549,1.1732416053556067,0,162.90897480178975,0.508096235591929],
264 | [0,-76.88501886392316,1.1732416053556067,0,147.66608773403212,0.508096235591929],
265 | [0,-112.08226702459157,1.1732416053556067,0,132.42320066627448,0.508096235591929],
266 | [0,-147.27951518525975,1.1732416053556067,0,117.18031359851653,0.508096235591929],
267 | [0,-182.47676334592774,1.1732416053556067,0,101.93742653075847,0.508096235591929],
268 | [0,-217.67401150659572,1.1732416053556067,0,86.69453946300041,0.508096235591929],
269 | [0,71.45165239524235,0.508096235591929,0,197.6535167892888,1.1732416053556067],
270 | [0,56.2087653274844,0.508096235591929,0,162.45626862862082,1.1732416053556067],
271 | [0,40.96587825972655,0.508096235591929,0,127.25902046795282,1.1732416053556067],
272 | [0,25.722991191968703,0.508096235591929,0,92.06177230728441,1.1732416053556067],
273 | [0,10.480104124210854,0.508096235591929,0,56.864524146616056,1.1732416053556067],
274 | [0,-4.762782943547016,0.508096235591929,0,21.66727598594786,1.1732416053556067],
275 | [0,-20.005670011304872,0.508096235591929,0,-13.529972174720337,1.1732416053556067],
276 | [0,-48.72722033538854,1.1732416053556067,0,-35.24855707906272,0.508096235591929],
277 | [0,-83.92446849605685,1.1732416053556067,0,-50.49144414682057,0.508096235591929],
278 | [0,-119.12171665672525,1.1732416053556067,0,-65.73433121457845,0.508096235591929],
279 | [0,-154.31896481739335,1.1732416053556067,0,-80.97721828233651,0.508096235591929],
280 | [0,-189.51621297806133,1.1732416053556067,0,-96.22010535009457,0.508096235591929],
281 | [0,-224.71346113872931,1.1732416053556067,0,-111.46299241785263,0.508096235591929],
282 | [0,-126.7058794856107,0.508096235591929,1,190.6140671571552,1.1732416053556067],
283 | [0,-141.94876655336836,0.508096235591929,1,155.41681899648722,1.1732416053556067],
284 | [0,-157.191653621126,0.508096235591929,1,120.21957083581914,1.1732416053556067],
285 | [0,-172.43454068888363,0.508096235591929,1,85.02232267515073,1.1732416053556067],
286 | [0,-187.67742775664126,0.508096235591929,1,49.82507451448242,1.1732416053556067],
287 | [0,-202.9203148243989,0.508096235591929,1,14.627826353814221,1.1732416053556067],
288 | [0,-218.16320189215654,0.508096235591929,1,-20.569421806853978,1.1732416053556067],
289 | [0,-233.40608895991417,0.508096235591929,1,-55.766669967522176,1.1732416053556067],
290 | [0,-248.6489760276718,0.508096235591929,1,-90.96391812819053,1.1732416053556067],
291 | [1,-126.16116628885894,1.1732416053556067,1,186.28140163901813,0.508096235591929],
292 | [1,-161.35841444952695,1.1732416053556067,1,171.0385145712605,0.508096235591929],
293 | [1,-196.55566261019493,1.1732416053556067,1,155.79562750350286,0.508096235591929],
294 | [1,-231.7529107708629,1.1732416053556067,1,140.55274043574522,0.508096235591929],
295 | [1,125.3098533679875,0.508096235591929,1,183.5746175250216,1.1732416053556067],
296 | [1,110.06696630022944,0.508096235591929,1,148.37736936435363,1.1732416053556067],
297 | [1,94.82407923247138,0.508096235591929,1,113.18012120368546,1.1732416053556067],
298 | [1,77.98287304301705,1.1732416053556067,1,79.58119216471331,0.508096235591929],
299 | [1,42.78562488234878,1.1732416053556067,1,64.33830509695525,0.508096235591929],
300 | [1,7.588376721680582,1.1732416053556067,1,49.095418029197404,0.508096235591929],
301 | [1,-27.608871438987617,1.1732416053556067,1,33.852530961439555,0.508096235591929],
302 | [1,-62.806119599655815,1.1732416053556067,1,18.609643893681707,0.508096235591929],
303 | [1,-98.00336776032421,1.1732416053556067,1,3.366756825923849,0.508096235591929],
304 | [1,-133.20061592099256,1.1732416053556067,1,-11.876130241834018,0.508096235591929],
305 | [1,-168.39786408166054,1.1732416053556067,1,-27.119017309591868,0.508096235591929],
306 | [1,-203.59511224232853,1.1732416053556067,1,-42.36190437734972,0.508096235591929],
307 | [1,-238.7923604029965,1.1732416053556067,1,-57.604791445107566,0.508096235591929],
308 | [1,-72.84767851286554,0.508096235591929,0,176.535167892888,1.1732416053556067],
309 | [1,-88.0905655806236,0.508096235591929,0,141.33791973222003,1.1732416053556067],
310 | [1,-103.33345264838167,0.508096235591929,0,106.14067157155178,1.1732416053556067],
311 | [1,-118.57633971613973,0.508096235591929,0,70.94342341088337,1.1732416053556067],
312 | [1,-133.81922678389762,0.508096235591929,0,35.74617525021514,1.1732416053556067],
313 | [1,-149.06211385165525,0.508096235591929,0,0.5489270895469427,1.1732416053556067],
314 | [1,-164.3050009194129,0.508096235591929,0,-34.64832107112126,1.1732416053556067],
315 | [1,-179.54788798717053,0.508096235591929,0,-69.84556923178948,1.1732416053556067],
316 | [1,-194.79077505492816,0.508096235591929,0,-105.04281739245789,1.1732416053556067],
317 | [1,-210.0336621226858,0.508096235591929,0,-140.24006555312616,1.1732416053556067],
318 | [1,-225.27654919044343,0.508096235591929,0,-175.43731371379414,1.1732416053556067]];
319 |
320 | const y = [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,
321 | 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,1,1,
322 | 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,
323 | 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,0,0,0,0,0,0,0,0,0,0,0,1,
324 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,
325 | 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,1,1,1,1,1,1,1,
326 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,
327 | 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,
328 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
329 |
--------------------------------------------------------------------------------