Created
December 28, 2019 04:17
-
-
Save rakuishi/e0fbaaf3f6d433e830f1bd29794a0224 to your computer and use it in GitHub Desktop.
群れは意識をもつ 個の自由と集団の秩序
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
margin: 0; | |
padding: 0; | |
} | |
.ant-box { | |
position: relative; | |
width: 400px; | |
height: 400px; | |
border: 1px solid #ddd; | |
} | |
.ant, .candy { | |
position: absolute; | |
width: 20px; | |
height: 20px; | |
font-size: 20px; | |
} | |
.candy { | |
background-color: #FD95FF; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
<link rel="stylesheet" href="normalize.css" /> | |
<link rel="stylesheet" href="index.css" /> | |
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> | |
</head> | |
<body> | |
<div id="app"> | |
<div class="ant-box"> | |
<div v-for="candy in candies"> | |
<candy v-bind:candy="candy" v-bind:key="candy.id" /> | |
</div> | |
<div v-for="ant in ants"> | |
<ant v-bind:ant="ant" v-bind:key="ant.id" /> | |
</div> | |
</div> | |
<button v-on:click="proceed">Proceed</button> | |
</div> | |
<script src="index.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
~ アリの大きさ 20px | |
~ ボックスの格子の数 20 | |
~ アリは基本的に前回の進行方向を再利用しようとするが、1/6 の確率でランダムに方向を変える | |
~ 左上から時計回りに 0~7 の進行方向を保持する | |
~ 周囲 8 マスにアメがある場合はそちらに移動する | |
*/ | |
Vue.component("ant", { | |
props: ["ant"], | |
template: | |
'<div class="ant" v-bind:style="{ top: 20 * ant.x, left: 20 * ant.y }">🐜</div>', | |
}) | |
Vue.component("candy", { | |
props: ["candy"], | |
template: | |
'<div class="candy" v-bind:style="{ top: 20 * candy.x, left: 20 * candy.y }">🍬</div>', | |
}) | |
var app = new Vue({ | |
el: "#app", | |
data: { | |
ants: [], | |
candies: [], | |
}, | |
created() { | |
this.setupPositions(this.candies, 10) | |
this.setupPositions(this.ants, 20) | |
}, | |
methods: { | |
setupPositions(objects, length) { | |
while (objects.length < length) { | |
let x = this.getRandomPosition() | |
let y = this.getRandomPosition() | |
const result = objects.filter(position => position.x == x && position.y == y) | |
if (result.length != 0) continue | |
objects.push({ id: objects.length, x: x, y: y }) | |
} | |
}, | |
getRandomPosition() { | |
return Math.floor(Math.random() * 20) | |
}, | |
calculateAntsBehavior(ant) { | |
if (this.isEatingCandy(ant)) | |
return | |
let candy = this.getNearbyCandy(ant) | |
if (candy != null && this.isEmpty(candy.x, candy.y)) { | |
ant.x = candy.x | |
ant.y = candy.y | |
return | |
} | |
if (ant.vector == undefined || (ant.vector && Math.floor(Math.random() * 6) == 0)) { | |
ant.vector = Math.floor(Math.random() * 8) | |
} | |
var position | |
while (-1) { | |
position = this.getPosition(ant.x, ant.y, ant.vector) | |
if (this.hitBox(position.x, position.y)) { | |
ant.vector = Math.floor(Math.random() * 8) | |
continue | |
} | |
break | |
} | |
if (this.hitAnt(position.x, position.y)) | |
return | |
ant.x = position.x | |
ant.y = position.y | |
}, | |
hitBox(x, y) { | |
return x < 0 || x >= 20 || y < 0 || y >= 20 | |
}, | |
hitAnt(x, y) { | |
for (let ant of this.ants) { | |
if (x == ant.x && y == ant.y) | |
return true | |
} | |
return false | |
}, | |
isEatingCandy(ant) { | |
for (let candy of this.candies) { | |
if (candy.x == ant.x && candy.y == ant.y) { | |
return true | |
} | |
} | |
return false | |
}, | |
getNearbyCandy(ant) { | |
for (let candy of this.candies) { | |
if (candy.x - 1 <= ant.x && ant.x <= candy.x + 1 | |
&& candy.y - 1 <= ant.y && ant.y <= candy.y + 1) { | |
return candy | |
} | |
} | |
return null | |
}, | |
isEmpty(x, y) { | |
for (let ant of this.ants) { | |
if (x == ant.x && y == ant.y) | |
return false | |
} | |
return true | |
}, | |
getPosition(x, y, vector) { | |
switch (vector) { | |
case 0: return { x: x - 1, y: y + 1 } | |
case 1: return { x: x - 0, y: y + 1 } | |
case 2: return { x: x + 1, y: y + 1 } | |
case 3: return { x: x - 1, y: y + 0 } | |
case 4: return { x: x - 1, y: y - 1 } | |
case 5: return { x: x - 0, y: y - 1 } | |
case 6: return { x: x - 1, y: y - 1 } | |
case 7: return { x: x - 1, y: y + 0 } | |
} | |
}, | |
proceed() { | |
for (let ant of this.ants) { | |
this.calculateAntsBehavior(ant) | |
} | |
}, | |
} | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* http://meyerweb.com/eric/tools/css/reset/ | |
v2.0 | 20110126 | |
License: none (public domain) | |
*/ | |
body { | |
background-color: white; | |
cursor: default; | |
box-sizing: border-box; | |
} | |
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ | |
html { | |
font-family: sans-serif; | |
line-height: 1.15; | |
-ms-text-size-adjust: 100%; | |
-webkit-text-size-adjust: 100%; | |
} | |
article, | |
aside, | |
footer, | |
header, | |
nav, | |
section { | |
display: block; | |
} | |
h1 { | |
font-size: 2em; | |
margin: 0.67em 0; | |
} | |
figcaption, | |
figure, | |
main { | |
display: block; | |
} | |
figure { | |
margin: 1em 40px; | |
} | |
hr { | |
box-sizing: content-box; | |
height: 0; | |
overflow: visible; | |
} | |
pre { | |
font-family: monospace, monospace; | |
font-size: 1em; | |
} | |
a { | |
background-color: transparent; | |
-webkit-text-decoration-skip: objects; | |
} | |
a:active, | |
a:hover { | |
outline-width: 0; | |
} | |
abbr[title] { | |
border-bottom: none; | |
text-decoration: underline; | |
text-decoration: underline dotted; | |
} | |
b, | |
strong { | |
font-weight: inherit; | |
} | |
b, | |
strong { | |
font-weight: bolder; | |
} | |
code, | |
kbd, | |
samp { | |
font-family: monospace, monospace; | |
font-size: 1em; | |
} | |
dfn { | |
font-style: italic; | |
} | |
mark { | |
background-color: #ff0; | |
color: #000; | |
} | |
small { | |
font-size: 80%; | |
} | |
sub, | |
sup { | |
font-size: 75%; | |
line-height: 0; | |
position: relative; | |
vertical-align: baseline; | |
} | |
sub { | |
bottom: -0.25em; | |
} | |
sup { | |
top: -0.5em; | |
} | |
audio, | |
video { | |
display: inline-block; | |
} | |
audio:not([controls]) { | |
display: none; | |
height: 0; | |
} | |
img { | |
border-style: none; | |
} | |
svg:not(:root) { | |
overflow: hidden; | |
} | |
button, | |
input, | |
optgroup, | |
select, | |
textarea { | |
font-family: sans-serif; | |
font-size: 100%; | |
line-height: 1.15; | |
margin: 0; | |
} | |
button, | |
input { | |
overflow: visible; | |
} | |
button, | |
select { | |
text-transform: none; | |
} | |
button, | |
html [type="button"], | |
[type="reset"], | |
[type="submit"] { | |
-webkit-appearance: button; | |
} | |
button::-moz-focus-inner, | |
[type="button"]::-moz-focus-inner, | |
[type="reset"]::-moz-focus-inner, | |
[type="submit"]::-moz-focus-inner { | |
border-style: none; | |
padding: 0; | |
} | |
button:-moz-focusring, | |
[type="button"]:-moz-focusring, | |
[type="reset"]:-moz-focusring, | |
[type="submit"]:-moz-focusring { | |
outline: 1px dotted ButtonText; | |
} | |
fieldset { | |
border: 1px solid #c0c0c0; | |
margin: 0 2px; | |
padding: 0.35em 0.625em 0.75em; | |
} | |
legend { | |
box-sizing: border-box; | |
color: inherit; | |
display: table; | |
max-width: 100%; | |
padding: 0; | |
white-space: normal; | |
} | |
progress { | |
display: inline-block; | |
vertical-align: baseline; | |
} | |
textarea { | |
overflow: auto; | |
} | |
[type="checkbox"], | |
[type="radio"] { | |
box-sizing: border-box; | |
padding: 0; | |
} | |
[type="number"]::-webkit-inner-spin-button, | |
[type="number"]::-webkit-outer-spin-button { | |
height: auto; | |
} | |
[type="search"] { | |
-webkit-appearance: textfield; | |
outline-offset: -2px; | |
} | |
[type="search"]::-webkit-search-cancel-button, | |
[type="search"]::-webkit-search-decoration { | |
-webkit-appearance: none; | |
} | |
::-webkit-file-upload-button { | |
-webkit-appearance: button; | |
font: inherit; | |
} | |
details, | |
menu { | |
display: block; | |
} | |
summary { | |
display: list-item; | |
} | |
canvas { | |
display: inline-block; | |
} | |
template { | |
display: none; | |
} | |
[hidden] { | |
display: none; | |
} | |
input:focus, | |
input.__focus { | |
outline: 4px solid rgba(117, 170, 255, 0.5); | |
} | |
button:focus, | |
button.__focus { | |
outline: 4px solid rgba(117, 170, 255, 0.5); | |
} | |
button:active, | |
button.__active { | |
-ms-transform: scale(0.97); | |
transform: scale(0.97); | |
} | |
::-moz-selection { | |
background-color: #75aaff; | |
} | |
::selection { | |
background-color: #75aaff; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment