begin endgame logic, render dame
This commit is contained in:
parent
da8d360a5f
commit
358bfe20d4
3 changed files with 153 additions and 60 deletions
90
css/main.css
90
css/main.css
|
@ -1,9 +1,10 @@
|
|||
@import url('https://fonts.googleapis.com/css?family=La+Belle+Aurore|Raleway:300,600');
|
||||
@import url('https://fonts.googleapis.com/css?family=La+Belle+Aurore|Raleway:300|Raleway:600');
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
font-family: 'Raleway', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -19,13 +20,15 @@ body {
|
|||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
visibility: hidden;
|
||||
overflow-y: scroll;
|
||||
|
||||
}
|
||||
|
||||
#menu {
|
||||
position: relative;
|
||||
background-color: rgb(250, 2250, 255, 0.9);
|
||||
padding: 1vmin;
|
||||
display: grid;
|
||||
|
@ -37,6 +40,7 @@ body {
|
|||
"record"
|
||||
"submit";
|
||||
font: 14px 'La Belle Aurore', cursive;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
#menu .menu-subblock {
|
||||
|
@ -56,7 +60,7 @@ body {
|
|||
font-weight: 300;
|
||||
}
|
||||
|
||||
h4.menu-heading {
|
||||
h4 {
|
||||
font-weight: 600;
|
||||
margin: 1em .25em 0 .25em;
|
||||
font-size: 110%;
|
||||
|
@ -100,7 +104,7 @@ div[data-player-meta] label {
|
|||
|
||||
#instructions, #game-record{
|
||||
border: 2px solid black;
|
||||
height: 100%
|
||||
height: 1;
|
||||
}
|
||||
|
||||
#instructions:::-webkit-scrollbar-track {
|
||||
|
@ -148,6 +152,7 @@ content {
|
|||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex: 5;
|
||||
height: 9vmin;
|
||||
}
|
||||
|
||||
.player-pos#white-pos {
|
||||
|
@ -221,8 +226,9 @@ content {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.name-space p {
|
||||
margin-bottom: 2vh;
|
||||
.name-space h4 {
|
||||
font-size: 120%;
|
||||
color: rgb(255,240,230)
|
||||
}
|
||||
|
||||
#board-space {
|
||||
|
@ -291,6 +297,13 @@ content {
|
|||
background: conic-gradient(#000 0%, rgba(0,0,0,0) 1%, rgba(0,0,0,0) 74%, #000 75%, rgba(0,0,0,0) 76%, rgba(0,0,0,0) 99%, #000 100%);
|
||||
}
|
||||
|
||||
#board-space td * * div.hoshi { /* to be added later */
|
||||
background: radial-gradient(circle farthest-corner at center, #000 0%, #000 30%, rgba(0,0,0,0) 50%);
|
||||
z-index: 3;
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
|
||||
td .stone {
|
||||
width: 85%;
|
||||
height: 85%;
|
||||
|
@ -331,8 +344,8 @@ td .dot[data-dot="black"] {
|
|||
td .dot[data-dot="none"] {
|
||||
background-color: transparent;
|
||||
}
|
||||
td .dot .dame {
|
||||
|
||||
td .dot[data-dot="dame"] {
|
||||
background-color: purple;
|
||||
}
|
||||
td .dot .seki {
|
||||
|
||||
|
@ -351,3 +364,64 @@ td .dot .seki {
|
|||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 500px) {
|
||||
.player-pos {
|
||||
height: 14vh;
|
||||
}
|
||||
|
||||
#kifu {
|
||||
order: 0;
|
||||
height: 12vh;
|
||||
width: 9vh;
|
||||
background-color: #FFF;
|
||||
transform: rotate(-20deg);
|
||||
}
|
||||
|
||||
.bowl {
|
||||
margin: 2vh;
|
||||
height: 12vh;
|
||||
width: 12vh;
|
||||
}
|
||||
|
||||
.caps-space {
|
||||
margin: 1vh;
|
||||
height: 8vh;
|
||||
width: 8vh;
|
||||
}
|
||||
|
||||
#board-space {
|
||||
margin: 0 auto;
|
||||
/* grid-area: board-space; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #EAB24E;
|
||||
/* width: 90vmin; */
|
||||
/* height: 90vmin; */
|
||||
padding: 1vmin;
|
||||
z-index: 1;
|
||||
box-shadow: -2vmin 4vmin 3vmin rgba(145, 92, 23, 0.5);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#board-space table {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: space-between;
|
||||
height: 72vmin;
|
||||
width: 72min;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#board-space td {
|
||||
height: 8vmin;
|
||||
width: 8vmin;
|
||||
background: conic-gradient(#000 0%, rgba(0,0,0,0) 1%, rgba(0,0,0,0) 24%, #000 25%, rgba(0,0,0,0) 26%, rgba(0,0,0,0) 49%, #000 50%, rgba(0,0,0,0) 51%, rgba(0,0,0,0) 74%, #000 75%, rgba(0,0,0,0) 76%, rgba(0,0,0,0) 99%, #000 100%);
|
||||
border-radius: 50% solid black;
|
||||
color: black;
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
49
index.html
49
index.html
|
@ -28,49 +28,6 @@
|
|||
<h4 class="menu-heading">Black</h4>
|
||||
<span class="menu-heading">Name:</span><input type="text" name="black-name">
|
||||
<span class="menu-heading">Rank:</span><input type="number" id="black-rank" max="38" steps="1" placeholder="15" name="black-rank">
|
||||
<!-- <div id=> -->
|
||||
<!-- <datalist class="rank-tick">
|
||||
<span>30k</span>
|
||||
<span>29k</span>
|
||||
<span>28k</span>
|
||||
<span>27k</span>
|
||||
<span>26k</span>
|
||||
<span>25k</span>
|
||||
<span>24k</span>
|
||||
<span>23k</span>
|
||||
<span>22k</span>
|
||||
<span>21k</span>
|
||||
<span>20k</span>
|
||||
<span>19k</span>
|
||||
<span>18k</span>
|
||||
<span>17k</span>
|
||||
<span>16k</span>
|
||||
<span>15k</span>
|
||||
<span>14k</span>
|
||||
<span>13k</span>
|
||||
<span>12k</span>
|
||||
<span>11k</span>
|
||||
<span>10k</span>
|
||||
<span>9k</span>
|
||||
<span>8k</span>
|
||||
<span>7k</span>
|
||||
<span>6k</span>
|
||||
<span>5k</span>
|
||||
<span>4k</span>
|
||||
<span>3k</span>
|
||||
<span>2k</span>
|
||||
<span>1k</span>
|
||||
<span>1d</span>
|
||||
<span>2d</span>
|
||||
<span>3d</span>
|
||||
<span>4d</span>
|
||||
<span>5d</span>
|
||||
<span>6d</span>
|
||||
<span>7d</span>
|
||||
<span>8d</span>
|
||||
<span>9d</span>
|
||||
</ul>
|
||||
</div> -->
|
||||
<input type="checkbox" name="black-rank-certain"><label for="black-rank-certain">Rank Certainty</label>
|
||||
</div>
|
||||
<div data-player-meta="white">
|
||||
|
@ -100,9 +57,9 @@
|
|||
</div>
|
||||
<content>
|
||||
<div id="white-pos" class="player-pos">
|
||||
<div id="white-bowl" class="bowl"><p>Pass?</p></div>
|
||||
<div id="white-bowl" class="bowl"><p>Pass?</p><div id="stone-image"></div></div>
|
||||
<div id="white-player-space" class="name-space">
|
||||
<p id="white-player-name">Test Name rk</p>
|
||||
<h4 id="white-player-name">Test Name rk</h4>
|
||||
<div id="white-caps-space" class="caps-space"><p id="white-caps"></p></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -374,7 +331,7 @@
|
|||
<div id="black-pos" class="player-pos">
|
||||
<div id="black-bowl" class="bowl"><p>Pass?</p></div>
|
||||
<div id="black-player-space" class="name-space">
|
||||
<p id="black-player-name">Test Name rk</p>
|
||||
<h4 id="black-player-name">Test Name rk</h4>
|
||||
<div id="black-caps-space" class="caps-space"><p id="black-caps"></p></div>
|
||||
</div> <div id="kifu">
|
||||
<table>
|
||||
|
|
70
js/main.js
70
js/main.js
|
@ -15,6 +15,11 @@ const DOTS_DATA = {
|
|||
's': 'seki'
|
||||
}
|
||||
|
||||
const ranks = ['30k', '29k', '28k', '27k', '26k', '25k', '24k', '23k', '22k', '21k', '20k',
|
||||
'19k', '18k', '17k', '16k', '15k', '14k', '13k', '12k', '11k', '10k',
|
||||
'9k', '8k', '7k', '6k', '5k', '4k', '3k', '2k', '1k',
|
||||
'1d', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d']
|
||||
|
||||
const gameState = {
|
||||
winner: null,
|
||||
turn: 1, // turn logic depends on handicap stones
|
||||
|
@ -65,6 +70,7 @@ class Point {
|
|||
this.pos = [ x, y ]
|
||||
this.stone = 0; // this is where move placement will go 0, 1, -1 'k'
|
||||
this.legal;
|
||||
this.territory;
|
||||
this.capturing = [];
|
||||
this.groupMembers = [];
|
||||
this.neighbors = {
|
||||
|
@ -101,8 +107,13 @@ class Point {
|
|||
for (let frn of frns) {
|
||||
this.groupMembers.push(frn);
|
||||
}
|
||||
console.log(this);
|
||||
console.log(this.groupMembers)
|
||||
// this.groupMembers = Array.from(new Set(this.groupMembers));
|
||||
if (!this.groupMembers.length) return;
|
||||
for (let grpMem in this.groupMembers) {
|
||||
debugger;
|
||||
console.log(this);
|
||||
this.groupMembers = Array.from(new Set(this.groupMembers.concat(this.groupMembers[grpMem].groupMembers)));
|
||||
}
|
||||
for (let grpMem in this.groupMembers) {
|
||||
|
@ -120,6 +131,7 @@ class Point {
|
|||
this.capturing = this.capturing.concat(opp.groupMembers);
|
||||
};
|
||||
}
|
||||
this.capturing = Array.from(new Set(this.capturing));
|
||||
return this.capturing;
|
||||
}
|
||||
checkGroup = () => { // liberty is true when called by move false when called by check Capture
|
||||
|
@ -155,7 +167,7 @@ const handiSliderEl = document.querySelector('input[name="handicap-slider"]');
|
|||
// ::hover-over on board to preview move (with legal move logic)
|
||||
document.getElementById('board').addEventListener('mousemove', hoverPreview);
|
||||
// click on board to play move
|
||||
document.getElementById('board').addEventListener('click', clickPlaceStone);
|
||||
document.getElementById('board').addEventListener('click', clickBoard);
|
||||
// ::hover-over on either bowl for pass, one-level undo options (CSS implementation)
|
||||
// click on menu items
|
||||
// click on kifu to display game menu
|
||||
|
@ -220,6 +232,7 @@ function playerResign() {
|
|||
|
||||
function hoverPreview(evt) {
|
||||
evt.stopPropagation();
|
||||
if (gameState.pass > 1 || gameState.winner) return;
|
||||
// renders preview stone if move is legal
|
||||
let hover = [ parseInt(evt.target.closest('td').id[0]), parseInt(evt.target.closest('td').id[2]) ];
|
||||
let point = findPointFromIdx(hover);
|
||||
|
@ -265,11 +278,18 @@ function resolveCaptures(point) {
|
|||
}
|
||||
|
||||
function checkKo(point, cap) {
|
||||
if (point.getLiberties().length === 1 && cap.checkNeighbors(stone => stone.stone === gameState.turn * -1)) return true;
|
||||
console.log(point);
|
||||
console.log(point.getLiberties());
|
||||
console.log(cap);
|
||||
console.log(cap.checkNeighbors());
|
||||
console.log(`${STONES_DATA[gameState.turn]}: ${point.pos[0]},${point.pos[1]}`)
|
||||
if (!point.getLiberties().length && cap.checkNeighbors().filter(stone => stone.stone === gameState.turn * -1)
|
||||
&& point.capturing.length === 1) return true;
|
||||
}
|
||||
|
||||
function clickPlaceStone(evt) {
|
||||
function clickBoard(evt) {
|
||||
evt.stopPropagation();
|
||||
if (gameState.pass > 1 || gameState.winner) return;
|
||||
// checks for placement and pushes to cell
|
||||
let placement = [ parseInt(evt.target.closest('td').id[0]), parseInt(evt.target.closest('td').id[2]) ];
|
||||
let point = findPointFromIdx(placement);
|
||||
|
@ -423,15 +443,33 @@ function init() {
|
|||
};
|
||||
|
||||
function render(hoverPoint) {
|
||||
if (gameState.winner || gameState.pass > 1) {
|
||||
renderTerritory();
|
||||
}
|
||||
gameState.gameRecord.length? renderTurn() : renderFirstTurn();
|
||||
renderBoard();
|
||||
renderCaps();
|
||||
}
|
||||
|
||||
function renderTerritory() {
|
||||
console.log('rendering territory')
|
||||
boardState.forEach(val => {
|
||||
let stoneElem = document.getElementById(`${val.pos[0]}-${val.pos[1]}`).childNodes[1].childNodes[0];
|
||||
console.log(stoneElem)
|
||||
stoneElem.setAttribute("data-dot", DOTS_DATA[val.territory]);
|
||||
})
|
||||
console.log('rendering finished')
|
||||
}
|
||||
|
||||
function renderFirstTurn() {
|
||||
document.getElementById(`${STONES_DATA[gameState.turn]}-bowl`).toggleAttribute('data-turn');
|
||||
}
|
||||
function renderTurn() {
|
||||
if (gameState.winner || gameState.pass > 1) document.querySelectorAll(`.bowl`).forEach(bowl => {
|
||||
bowl.removeAttribute('data-turn');
|
||||
bowl.toggleAttribute('data-turn');
|
||||
|
||||
});
|
||||
document.querySelectorAll(`.bowl`).forEach(bowl => bowl.toggleAttribute('data-turn'));
|
||||
}
|
||||
|
||||
|
@ -455,8 +493,32 @@ function renderPreview(hoverPoint) {
|
|||
})
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
function endGameSetTerritory() {
|
||||
console.log('ending game');
|
||||
boardState.forEach(pt => {
|
||||
pt.territory = pt.stone ? 'd' : 'd'
|
||||
console.log(pt);
|
||||
});
|
||||
}
|
||||
|
||||
function endGame() {
|
||||
endGameSetTerritory()
|
||||
|
||||
// join all remaining groups
|
||||
// check remaining groups life
|
||||
// search empty spaces on board for deadShapes
|
||||
// compare spaces to rotations of deadShapes[...]
|
||||
// 'd' if empty spaces
|
||||
|
||||
render();
|
||||
// return dead group suggestion
|
||||
// users can flip status of any dead group overlay( 1, -1 )
|
||||
// confirm state
|
||||
// calculate score = points in overlay for each player + captures
|
||||
// render final board state with dead groups removed
|
||||
// log game record
|
||||
// stringify according to .sgf format
|
||||
// log as text
|
||||
}
|
||||
|
||||
// functions
|
||||
|
|
Loading…
Reference in a new issue