1+ const random = ( ( ) => {
2+ const float = ( n = 1 ) => n * Math . random ( )
3+
4+ const int = ( n = 1 ) => Math . floor ( float ( n ) ) ;
5+
6+ const boolean = ( ) => Math . random ( ) < 0.5 ;
7+
8+ const color = ( ) => `#${ ( Math . random ( ) * 0xFFFFFF << 0 ) . toString ( 16 ) . padStart ( 6 , "0" ) } ` ;
9+
10+ return {
11+ float,
12+ int,
13+ boolean,
14+ color,
15+ } ;
16+ } ) ( ) ;
17+
18+ const algAntFarm = ( ( ) => {
19+ let intervalId ;
20+ let numberOfSteps = 0 ;
21+ let panicSpeedMultiplier = 1 ;
22+ let ants = [ ] ;
23+ let panicId ;
24+
25+ const Ant = ( { point, color : c } = { } ) => {
26+ const color = c ?? random . color ( ) ;
27+
28+ if ( ! point ) {
29+ const x = random . int ( width ) ;
30+ const y = random . int ( height ) ;
31+
32+ point = { x, y } ;
33+ }
34+
35+ const move = ( ) => {
36+ const start = { ...point } ;
37+ const s = algAntFarm . antSpeed * panicSpeedMultiplier ;
38+
39+ point . x += ( random . boolean ( ) ? 1 : - 1 ) * random . int ( s ) ;
40+ point . y += ( random . boolean ( ) ? 1 : - 1 ) * random . int ( s ) ;
41+
42+ if ( point . x > width ) {
43+ point . x = width ;
44+ } else if ( point . x < 0 ) {
45+ point . x = 0 ;
46+ }
47+
48+ if ( point . y > height ) {
49+ point . y = height ;
50+ } else if ( point . y < 0 ) {
51+ point . y = 0 ;
52+ }
53+
54+ ctx . lineWidth = algAntFarm . lineWidth ;
55+ ctx . strokeStyle = color ;
56+ ctx . beginPath ( ) ;
57+ ctx . moveTo ( start . x , start . y ) ;
58+ ctx . lineTo ( point . x , point . y ) ;
59+ ctx . stroke ( ) ;
60+ } ;
61+
62+ return {
63+ move,
64+ } ;
65+ } ;
66+
67+ const createAnts = ( n ) => Array . from ( { length : n } , ( ) => Ant ( ) ) ;
68+
69+ const drawOneStep = ( ) => {
70+ if ( numberOfSteps > algAntFarm . maxNumberOfSteps ) {
71+ pause ( ) ;
72+
73+ return false ;
74+ }
75+
76+ if ( algAntFarm . numberOfAnts > ants . length ) {
77+ ants = ants . concat ( createAnts ( algAntFarm . numberOfAnts - ants . length ) ) ;
78+ } else if ( algAntFarm . numberOfAnts < ants . length ) {
79+ ants = ants . slice ( 0 , algAntFarm . numberOfAnts ) ;
80+ }
81+
82+ ants . forEach ( ant => ant . move ( ) ) ;
83+ numberOfSteps += 1 ;
84+
85+ intervalId = setTimeout ( drawOneStep , algAntFarm . speed ) ;
86+ } ;
87+
88+ const handlePanic = ( ) => {
89+ panicSpeedMultiplier = panicSpeedMultiplier + random . float ( algAntFarm . maxPanicSpeedMultiplier - panicSpeedMultiplier ) ;
90+ clearInterval ( panicId ) ;
91+
92+ panicId = setInterval ( ( ) => {
93+ const n = panicSpeedMultiplier - random . float ( ) ;
94+ if ( n < 1 ) {
95+ panicSpeedMultiplier = 1 ;
96+ clearInterval ( panicId )
97+ } else {
98+ panicSpeedMultiplier = n ;
99+ }
100+ } , 1000 ) ;
101+ } ;
102+
103+ const start = ( ) => {
104+ c . addEventListener ( 'dblclick' , handlePanic ) ;
105+ intervalId = setTimeout ( drawOneStep , algAntFarm . speed ) ;
106+ } ;
107+
108+ const pause = ( ) => {
109+ clearInterval ( intervalId ) ;
110+ c . removeEventListener ( 'dblclick' , handlePanic ) ;
111+ } ;
112+
113+ const reset = ( ) => {
114+ pause ( ) ;
115+
116+ numberOfSteps = 0 ;
117+ ants = createAnts ( algAntFarm . numberOfAnts ) ;
118+ } ;
119+
120+ const initialize = ( ) => {
121+ reset ( ) ;
122+ } ;
123+
124+ return {
125+ start,
126+ pause,
127+ reset,
128+ initialize,
129+ } ;
130+ } ) ( ) ;
0 commit comments