Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
FreshPenguin112
GitHub Repository: FreshPenguin112/bookmarklets
Path: blob/main/tic.js
5051 views
1
var turn=Math.random()<1/2 ? 0 : 1;
2
3
4
var unit=100/11;
5
6
7
var menu=document.createElement('div');
8
menu.style.position='fixed';
9
menu.style.top='50%';
10
menu.style.left='50%';
11
menu.style.height=9*unit+'vmin';
12
menu.style.width=9*unit+'vmin';
13
menu.style.transform='translate(-50%,-50%)';
14
menu.style.zIndex=9999;
15
menu.innerHTML='<a style=\'background:white;position:absolute;left:100%;cursor:pointer\' onClick=\'menu.remove()\'>exit</a>';
16
document.body.appendChild(menu);
17
18
19
var board=document.createElement('div');
20
board.style.background='rgba(255,255,255,0.9)';
21
board.style.position='absolute';
22
board.style.top=0;
23
board.style.left=0;
24
board.style.height=9*unit+'vmin';
25
board.style.width=9*unit+'vmin';
26
board.mark=null;
27
menu.appendChild(board);
28
29
30
BOXES=[];
31
boxes=[[],[],[],[],[],[],[],[],[]];
32
33
for(var i=0;i<3;i++){
34
for(var j=0;j<3;j++){
35
var BOX=document.createElement('div');
36
BOX.style.position='absolute';
37
BOX.style.top=i*100/3+'%';
38
BOX.style.left=j*100/3+'%';
39
BOX.style.height=100/3+'%';
40
BOX.style.width=100/3+'%';
41
BOX.mark=null;
42
43
for(var k=0;k<3;k++){
44
for(var l=0;l<3;l++){
45
var box=document.createElement('div');
46
47
box.setAttribute('onMouseOver','this.style.background=\'rgba(0,0,0,0.25)\'');
48
box.setAttribute('onMouseOut','this.style.background=\'transparent\'');
49
box.setAttribute('onClick','pick(this)');
50
51
box.style.position='absolute';
52
box.style.top=k*100/3+'%';
53
box.style.left=l*100/3+'%';
54
box.style.height=100/3+'%';
55
box.style.width=100/3+'%';
56
57
box.macro=3*i+j;
58
box.micro=3*k+l;
59
box.mark=null;
60
boxes[3*i+j].push(box);
61
62
if(box.macro%2==0){
63
box.style.boxShadow='0 0 1vmin black inset';
64
}
65
else{
66
box.style.boxShadow='0 0 1vmin gray inset';
67
}
68
69
BOX.appendChild(box);
70
}
71
}
72
BOXES.push(BOX);
73
board.appendChild(BOX);
74
}
75
}
76
77
78
79
// Check for victories.
80
function check(m){
81
var checkmark=0;
82
if(m[0].mark!=null){
83
if((m[0].mark==m[1].mark && m[1].mark==m[2].mark) || (m[0].mark==m[3].mark && m[3].mark==m[6].mark)){
84
checkmark=1;
85
}
86
}
87
if(m[4].mark!=null){
88
if((m[3].mark==m[4].mark && m[4].mark==m[5].mark) || (m[1].mark==m[4].mark && m[4].mark==m[7].mark) || (m[0].mark==m[4].mark && m[4].mark==m[8].mark) || (m[2].mark==m[4].mark && m[4].mark==m[6].mark)){
89
checkmark=1;
90
}
91
}
92
if(m[8].mark!=null){
93
if((m[6].mark==m[7].mark && m[7].mark==m[8].mark) || (m[2].mark==m[5].mark && m[5].mark==m[8].mark)){
94
checkmark=1;
95
}
96
}
97
98
if(checkmark){
99
marker(m[0].parentNode);
100
}
101
else{
102
if(m[0].mark!=null && m[1].mark!=null && m[2].mark!=null && m[3].mark!=null && m[4].mark!=null && m[5].mark!=null && m[6].mark!=null && m[7].mark!=null && m[8].mark!=null){
103
draw(m[0].parentNode);
104
}
105
}
106
}
107
108
109
function draw(obj){
110
// Disable the tied box.
111
obj.mark=2;
112
disable(obj);
113
obj.style.pointerEvents='none';
114
}
115
116
117
function marker(obj){
118
// Place an O.
119
if(turn==0){
120
var o=document.createElement('div');
121
o.style.boxSizing='border-box';
122
o.style.position='absolute';
123
o.style.top='10%';
124
o.style.left='10%';
125
o.style.height='80%';
126
o.style.width='80%';
127
// Set O border size based on nested box level, because for some reason percentage isn't supported.
128
var inBOXES=0;
129
for(var i=0;i<9;i++){
130
if(obj==BOXES[i]){
131
inBOXES=1;
132
break;
133
}
134
}
135
o.style.border=unit*(obj==board ? 9 : (inBOXES ? 3 : 1))/5+'vmin solid black';
136
o.style.borderRadius='50%';
137
obj.appendChild(o);
138
}
139
// Place an X.
140
else{
141
var x1=document.createElement('div');
142
x1.style.boxSizing='border-box';
143
x1.style.background='black';
144
x1.style.position='absolute';
145
x1.style.top='10%';
146
x1.style.left='40%';
147
x1.style.height='80%';
148
x1.style.width='20%';
149
x1.style.transform='rotate(45deg)';
150
obj.appendChild(x1);
151
var x2=x1.cloneNode();
152
x2.style.transform='rotate(-45deg)';
153
obj.appendChild(x2);
154
}
155
156
obj.mark=turn;
157
disable(obj);
158
obj.style.pointerEvents='none';
159
}
160
161
function pick(b){
162
163
marker(b);
164
165
166
check(boxes[b.macro]);
167
check(BOXES);
168
169
170
turn>0 ? turn=0 : turn=1;
171
172
173
if(BOXES[b.micro].mark==null){
174
175
for(i=0;i<9;i++){
176
for(var j=0;j<9;j++){
177
disable(boxes[i][j]);
178
}
179
}
180
181
for(i=0;i<9;i++){
182
183
if(board.mark==null){
184
enable(boxes[b.micro][i]);
185
}
186
}
187
}
188
else{
189
for(i=0;i<9;i++){
190
for(var j=0;j<9;j++){
191
// Forces won macro boxes to stay disabled.
192
if(board.mark==null){
193
enable(boxes[i][j]);
194
}
195
}
196
}
197
}
198
disable(b);
199
}
200
201
function disable(b){
202
b.style.background='rgba(0,0,0,0.25)';
203
b.setAttribute('onMouseOver','');
204
b.setAttribute('onMouseOut','');
205
b.setAttribute('onClick','');
206
}
207
208
function enable(b){
209
// Forces won boxes to stay disabled.
210
if(b.mark==null){
211
b.style.background='transparent';
212
}
213
b.setAttribute('onMouseOver','this.style.background=\'rgba(0,0,0,0.25)\'');
214
b.setAttribute('onMouseOut','this.style.background=\'transparent\'');
215
b.setAttribute('onClick','pick(this)');
216
}
217
218