add data structures, basic style

This commit is contained in:
Sorrel Bri 2019-08-02 14:14:23 -07:00
parent d5b56f25c9
commit 8f07e5bfcd
5 changed files with 356 additions and 66 deletions

14
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/js/main.js"
}
]
}

View file

@ -2,7 +2,7 @@
#### Minimum Deliverable Product #### Minimum Deliverable Product
a working game of go for a 9x9 board that a working game of go for a 9x9 board that
* displays well on mobile * displays well on mobile or desktop
* initiates a game with suggested handicap and komi according to rank input * initiates a game with suggested handicap and komi according to rank input
* * displays how to play in open screen * * displays how to play in open screen
* lets the user know whose turn it is * lets the user know whose turn it is
@ -11,7 +11,6 @@ a working game of go for a 9x9 board that
* * implement a search algorithm to avoid moving into dead space * * implement a search algorithm to avoid moving into dead space
* correctly removes captured stones and adds them to capturing player's score * correctly removes captured stones and adds them to capturing player's score
* logs game record * logs game record
* maintains a one move game state history for 'undo mismove'
* allows players to pass or resign * allows players to pass or resign
* * ends game upon 2 consecutive passes * * ends game upon 2 consecutive passes
* calculates estimated score at game end * calculates estimated score at game end
@ -21,6 +20,7 @@ a working game of go for a 9x9 board that
stretch goals stretch goals
* uses stone placement GUI for resign and pass * uses stone placement GUI for resign and pass
* maintains a one move game state history for 'undo mismove'
* converts string to .sgf format * converts string to .sgf format
* allows users to edit game info mid game * allows users to edit game info mid game
* add stone placement sounds * add stone placement sounds

View file

@ -1,5 +1,6 @@
* { * {
box-sizing: border-box; box-sizing: border-box;
margin: 0;
} }
.full-screen { .full-screen {
@ -12,4 +13,106 @@
"record record record options" <- displays numbered record (stretch!), new game, get game record(stretch!) "record record record options" <- displays numbered record (stretch!), new game, get game record(stretch!)
pre-game record will display instructions pre-game record will display instructions
*/ */
}
content {
background-color: #61a6c2;
display: grid;
grid-template-columns: 100vmin;
grid-template-rows: 1fr 100vmin 1fr;
grid-template-areas:
"white-pos"
"board-space"
"black-pos"
}
.player-pos {
display: flex;
align-content: center;
align-items: center;
justify-content: space-between;
}
.player-pos#white-pos {
grid-area: white-pos;
}
.player-pos#black-pos {
grid-area: black-pos;
flex-direction: row-reverse;
}
#kifu {
order: 0;
}
.bowl {
order: -1;
margin: 20px;
height: 8vh;
width: 8vh;
border: solid black;
border-radius: 50%;
}
.caps {
order: 1;
}
#board-space {
margin: 0 auto;
grid-area: board-space;
display: flex;
flex-direction: column;
background-color: #EAB24E;
width: 90vmin;
height: 90vmin;
padding: 1vmin;
}
table {
display: flex;
align-items: stretch;
justify-content: space-between;
height: 81vmin;
width: 81min;
margin: auto;
}
td {
height: 9vmin;
width: 9vmin;
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;
}
td[id^="0,"] {
background: conic-gradient( 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%);
}
#row-8 td {
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) 74%, #000 75%, rgba(0,0,0,0) 76%, rgba(0,0,0,0) 99%, #000 100%);
}
td[id$="0"] {
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) 99%, #000 100%);
}
td[id$="8"] {
background: conic-gradient(#000 0%, rgba(0,0,0,0) 1%, 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%);
}
td[id="0,0"] {
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%);
}
td#0,8 {
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%);
}
td#8,0 {
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%);
}
td#8,8 {
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%);
} }

View file

@ -5,26 +5,127 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/reset.css" type="stylesheet"> <link rel="stylesheet" href="css/reset.css" type="stylesheet">
<link rel="stylesheet" href="css/main.css" type="stylesheet"> <link href="css/main.css" rel="stylesheet" type="text/css" /> <script src="js/main.js"></script>
<script src="js/main.js"></script> <title>Browser Go</title>
<title>Go Cats</title>
</head> </head>
<body> <body>
<div id="menu" class="full-screen"> <div id="menu" class="full-screen">
<!-- for displaying new game screen and status during game --> <!-- for displaying new game screen and status during game -->
</div>
<!-- may need add'l .full-screen or other div for board overlay -->
<content>
<div id="white-pos" class="player-pos">
<div id="white-bowl" class="bowl">White Bowl</div>
<div id="white-caps" class="caps">White Captures</div>
</div> </div>
<!-- may need add'l .full-screen or other div for board overlay --> <div id="board-space">
<content> <table id="board">
<div id="white-pos" class="player-pos"> <tr id="row-0">
<div id="white-bowl" class="bowl"></div> <td id="0,0"></td>
<div id="white-caps" class="caps"></div> <td id="0,1"></td>
</div> <td id="0,2"></td>
<div id="board"></div> <td id="0,3"></td>
<div id="black-pos" class="player-pos"> <td id="0,4"></td>
<div id="black-bowl" class="bowl"></div> <td id="0,5"></td>
<div id="black-caps" class="caps"></div> <td id="0,6"></td>
<div id="kifu"></div> <td id="0,7"></td>
</div> <td id="0,8"></td>
</content> </tr>
<tr id="row-1">
<td id="1,0"></td>
<td id="1,1"></td>
<td id="1,2"></td>
<td id="1,3"></td>
<td id="1,4"></td>
<td id="1,5"></td>
<td id="1,6"></td>
<td id="1,7"></td>
<td id="1,8"></td>
</tr>
<tr id="row-2">
<td id="2,0"></td>
<td id="2,1"></td>
<td id="2,2"></td>
<td id="2,3"></td>
<td id="2,4"></td>
<td id="2,5"></td>
<td id="2,6"></td>
<td id="2,7"></td>
<td id="2,8"></td>
</tr>
<tr id="row-3">
<td id="3,0"></td>
<td id="3,1"></td>
<td id="3,2"></td>
<td id="3,3"></td>
<td id="3,4"></td>
<td id="3,5"></td>
<td id="3,6"></td>
<td id="3,7"></td>
<td id="3,8"></td>
</tr>
<tr id="row-4">
<td id="4,0"></td>
<td id="4,1"></td>
<td id="4,2"></td>
<td id="4,3"></td>
<td id="4,4"></td>
<td id="4,5"></td>
<td id="4,6"></td>
<td id="4,7"></td>
<td id="4,8"></td>
</tr>
<tr id="row-5">
<td id="5,0"></td>
<td id="5,1"></td>
<td id="5,2"></td>
<td id="5,3"></td>
<td id="5,4"></td>
<td id="5,5"></td>
<td id="5,6"></td>
<td id="5,7"></td>
<td id="5,8"></td>
</tr>
<tr id="row-6">
<td id="6,0"></td>
<td id="6,1"></td>
<td id="6,2"></td>
<td id="6,3"></td>
<td id="6,4"></td>
<td id="6,5"></td>
<td id="6,6"></td>
<td id="6,7"></td>
<td id="6,8"></td>
</tr>
<tr id="row-7">
<td id="7,0"></td>
<td id="7,1"></td>
<td id="7,2"></td>
<td id="7,3"></td>
<td id="7,4"></td>
<td id="7,5"></td>
<td id="7,6"></td>
<td id="7,7"></td>
<td id="7,8"></td>
</tr>
<tr id="row-8">
<td id="8,0"></td>
<td id="8,1"></td>
<td id="8,2"></td>
<td id="8,3"></td>
<td id="8,4"></td>
<td id="8,5"></td>
<td id="8,6"></td>
<td id="8,7"></td>
<td id="8,8"></td>
</tr>
</table>
</div>
<div id="black-pos" class="player-pos">
<div id="black-bowl" class="bowl">Black Bowl</div>
<div id="black-caps" class="caps">Black Captures</div>
<div id="kifu">kifu</div>
</div>
</content>
</body> </body>
</html> </html>

View file

@ -1,58 +1,130 @@
// global constants declared /*----- constants -----*/
// game state object {gameMeta object, playerMeta object, turn, pass, gameRecord, bCaptures, wCaptures}
const gameState = {
winner: null,
turn: null, // turn logic depends on handicap stones
pass: null,
komi: null, // komi depends on handicap stones
handicap: null,
playerState: {
bCaptures: null,
wCaptures: null
},
gameMeta: { // declared at game start and not editable after
date: null// contains metadata
},
playerMeta: { // editable during game
b: {
name: null,
rank: null,
rankCertain: false
},
w: {
name: null,
rank: null,
rankCertain: false
},
},
gameRecord : []
}
// boardState, lastState, overlay (copy of boardState holding pre-move object, game end group state) // boardState [point objects-contain overlay] lastState (created from boardState)
// bCaptures, wCaptures, gameInfo object, playerInfo object, turn, pass, gameRecord, // groups?
// handicapStones, deadShapes{} // deadShapes{}
// index represents handicap placement, eg handiPlace[1] = { (3, 3), (7, 7) }
const handiPlace = [ 0,
[ { rPos: 3, cPos: 3 }, { rPos: 7, cPos: 7 } ],
[ { rPos: 3, cPos: 3 }, { rPos: 7, cPos: 7 }, { rPos: 3, cPos: 7 } ],
[ { rPos: 3, cPos: 3 }, { rPos: 7, cPos: 7 }, { rPos: 3, cPos: 7 }, { rPos: 7, cPos: 3 } ]];
/*----- app's state (variables) -----*/
// define initial game state // define initial game state
let boardState;
// define boardState and overlay as 2d 9x9 arrays // Class Point {
// boardState accepts values of 0, 1, -1 // rPos: 1,
// overlay accepts values of 0, 1, -1, 'k', 'd', 'chk', 'hold', 'l', 'x' // cPos: 1,
// 'k' represents komi, in-game integers represent move previews, // neighbors: {
// 'chk', 'hold', 'x' and 'l' represent points checked during checkLegalMove run // top: null,
// game-end integer represent points of territory, 'd' represents dame, // btm: null,
// lft: null,
// rgt: null
// }
// checkLegal: function() {
// }
// }
// cached elements // modeling 1,1 point for
// store #menu for displaying game info // define boardState and overlay as 2d 9x9 arrays
// store // boardState accepts values of 0, 1, -1
// overlay accepts values of 0, 1, -1, 'k', 'd', 'chk', 'hold', 'l', 'x'
// 'k' represents komi, in-game integers represent move previews,
// 'chk', 'hold', 'x' and 'l' represent points checked during checkLegalMove run
// game-end integer represent points of territory, 'd' represents dame,
/*----- cached element references -----*/
// store #menu for displaying game info
// store
/*----- event listeners -----*/
// input listeners for player names, ranks, rank certainty (editable during game)
//input lister for handicap + komi (only editable pre-game)
// ::hover-over on board to preview move (with legal move logic)
// click on board to play move
// ::hover-over on either bowl for pass, one-level undo options (CSS implementation)
// click on menu items
// click on kifu to display game menu
/*----- functions -----*/
init();
function init() {
gameState.winner = null;
// gameState.turn = ? : ; // get turn from consequences of player input
gameState.pass = null;
// gameState.komi = ; // get komi from player input
// gameState.handicap = ; // get handicap from player input
gameState.playerState.bCaptures = 0;
gameState.playerState.wCaptures = 0;
// gameState.gameMeta.date = // get from browser window
// get any future meta from player input
// gameState.playerMeta.b // get from player input
// gameState.playerMeta.w // get from player input
gameState.gameRecord = []; // clear game record from previous game
// gameState.boardState // create board from user input
};
// set event listeners // functions
// input listeners for player names, ranks, rank certainty (editable during game) // initialize game
//input lister for handicap + komi (only editable pre-game) // set handicap stones
// ::hover-over on board to preview move (with legal move logic) // render
// click on board to play move // render board
// ::hover-over on either bowl for pass, one-level undo options (CSS implementation) //render moves
// click on menu items //render preview
// click on kifu to display game menu // render captures
// render player turn marker
// functions // game-end
// initialize game // render dead group suggestion
// set handicap stones // render territory counts
// render // checkLegalMove
// render board // clear overlay
//render moves // if move is not '0', move is illegal (opposing player or 'k' for ko)
//render preview // iterate through neighboring points in clockwise order
// render captures // if anyone is '0' move is legal - call render preview
// render player turn marker // if neighboring point is opposing player
// game-end // cycle through opposing player group marking points as overlay: 'chk' when checked and
// render dead group suggestion // overlay: 'hold' if they are neighboring points of opposing player color
// render territory counts // if any neighboring point is '0' terminate cycle and move to next neighboring point of original move
// checkLegalMove // if there are unchecked points of 'hold' return
// clear overlay // if no boardState: 0 points, move is legal overlay: 'l'
// if move is not '0', move is illegal (opposing player or 'k' for ko) // set all 'chk' to 'x' to represent stones that will be captured upon move
// iterate through neighboring points in clockwise order
// if anyone is '0' move is legal - call render preview
// if neighboring point is opposing player
// cycle through opposing player group marking points as overlay: 'chk' when checked and
// overlay: 'hold' if they are neighboring points of opposing player color
// if any neighboring point is '0' terminate cycle and move to next neighboring point of original move
// if there are unchecked points of 'hold' return
// if no boardState: 0 points, move is legal overlay: 'l'
// set all 'chk' to 'x' to represent stones that will be captured upon move
// if neighboring point is player's // if neighboring point is player's
// cycle through player group marking points as overlay: 'chk' || 'hold' // cycle through player group marking points as overlay: 'chk' || 'hold'
// if any neighboring point is '0' ternminate cycle and mark point as 'l' // if any neighboring point is '0' ternminate cycle and mark point as 'l'