Commit inicial
This commit is contained in:
commit
5678ee9bd4
7 changed files with 218 additions and 0 deletions
BIN
black.png
Normal file
BIN
black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 395 KiB |
BIN
board.webp
Normal file
BIN
board.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
102
index.html
Normal file
102
index.html
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>五目並べ</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--square-size: 40px;
|
||||||
|
--table-size: 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0px 8px 0px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--table-size), 1fr);
|
||||||
|
grid-template-rows: repeat(var(--table-size), 1fr);
|
||||||
|
width: calc(var(--table-size)*var(--square-size));
|
||||||
|
height: calc(var(--table-size)*var(--square-size));
|
||||||
|
margin: auto;
|
||||||
|
background-image: url("board.webp");
|
||||||
|
background-size: contain;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.square {
|
||||||
|
/* background-color: grey; */
|
||||||
|
width: var(--square-size);
|
||||||
|
height: var(--square-size);
|
||||||
|
/* border: 1px solid black; */
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
&:is(.white, .black) {
|
||||||
|
animation-duration: 0.1s;
|
||||||
|
animation-name: grow-shrink;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:is(.hover-white, .hover-black) {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.white,
|
||||||
|
&.hover-white {
|
||||||
|
background-image: url("white.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.black,
|
||||||
|
&.hover-black {
|
||||||
|
background-image: url("black.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes grow-shrink {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
scale: 200%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
scale: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main></main>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Options</legend>
|
||||||
|
<button>Undo move</button>
|
||||||
|
</fieldset>
|
||||||
|
<script src="index.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
101
index.js
Normal file
101
index.js
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
|
||||||
|
let main = document.querySelector('main'); if (!main) throw '';
|
||||||
|
|
||||||
|
const tableSize = 19;
|
||||||
|
const directions = [[1, 0], [1, 1], [0, 1], [-1, 1]];
|
||||||
|
// let turn = true;
|
||||||
|
|
||||||
|
/** @typedef {'white' | 'black' | undefined} Square */
|
||||||
|
/** @typedef {{squares: Square[], whiteTurn: boolean}} State */
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
let state = {squares: Array(tableSize*tableSize), whiteTurn: true};
|
||||||
|
|
||||||
|
/** @type {State[]} */
|
||||||
|
let hist = [];
|
||||||
|
|
||||||
|
/** @type {HTMLDivElement[]} */
|
||||||
|
let squares = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param x {number}
|
||||||
|
* @param y {number}
|
||||||
|
* @returns HTMLDivElement
|
||||||
|
*/
|
||||||
|
function get(x, y) {
|
||||||
|
return squares[y * 19 + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
function testWin() {
|
||||||
|
for (let by = 0; by < tableSize; by++) {
|
||||||
|
for (let bx = 0; bx < tableSize; bx++) {
|
||||||
|
let a = get(bx, by);
|
||||||
|
if (a.classList.length < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const [dx, dy] of directions) {
|
||||||
|
let aColor = a.classList[1];
|
||||||
|
let sequence = 1;
|
||||||
|
for (let [x, y] = [bx+dx, by+dy]; x >= 0 && x < tableSize && y >= 0 && y < tableSize; [x, y] = [x + dx, y + dy]) {
|
||||||
|
let b = get(x, y);
|
||||||
|
if (b.classList.length < 2) {
|
||||||
|
aColor = 'skip'; // gambiarra;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let bColor = b.classList[1];
|
||||||
|
if (aColor != bColor) {
|
||||||
|
aColor = 'skip'; // gambiarra;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sequence += 1;
|
||||||
|
}
|
||||||
|
if (sequence > 4) {
|
||||||
|
alert('vitória!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns State */
|
||||||
|
function cloneState() {
|
||||||
|
/** @type {State} */
|
||||||
|
let ret = {squares: Array(tableSize*tableSize), whiteTurn: state.whiteTurn};
|
||||||
|
for (let i = 0; i < tableSize*tableSize; i++) {
|
||||||
|
let square = squares[i];
|
||||||
|
let a = square.classList.values().find((x) => x === 'white')
|
||||||
|
|| square.classList.values().find((x) => x === 'black')
|
||||||
|
ret.squares[i] = a;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 19 * 19; i++) {
|
||||||
|
let d = document.createElement('div');
|
||||||
|
d.classList.add('square');
|
||||||
|
d.onclick = () => {
|
||||||
|
if (d.classList.contains('white') || d.classList.contains('black') ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d.classList.add(state.whiteTurn ? 'white' : 'black');
|
||||||
|
d.classList.remove('hover-white', 'hover-black')
|
||||||
|
state.whiteTurn = !state.whiteTurn;
|
||||||
|
testWin();
|
||||||
|
hist.push(cloneState());
|
||||||
|
};
|
||||||
|
d.onmouseenter = () => {
|
||||||
|
if (d.classList.contains('white') || d.classList.contains('black') ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d.classList.add(state.whiteTurn ? 'hover-white' : 'hover-black');
|
||||||
|
}
|
||||||
|
d.onmouseleave = () => {
|
||||||
|
if (d.classList.contains('white') || d.classList.contains('black') ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d.classList.remove('hover-white', 'hover-black')
|
||||||
|
}
|
||||||
|
main.append(d);
|
||||||
|
squares.push(d);
|
||||||
|
}
|
||||||
15
jsconfig.json
Normal file
15
jsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"app/*": ["./*"]
|
||||||
|
},
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"checkJs": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "docs", "thinking"]
|
||||||
|
}
|
||||||
BIN
white.png
Normal file
BIN
white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 350 KiB |
Loading…
Add table
Add a link
Reference in a new issue