add data structures, basic style
This commit is contained in:
parent
d5b56f25c9
commit
8f07e5bfcd
5 changed files with 356 additions and 66 deletions
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#### Minimum Deliverable Product
|
||||
|
||||
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
|
||||
* * displays how to play in open screen
|
||||
* 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
|
||||
* correctly removes captured stones and adds them to capturing player's score
|
||||
* logs game record
|
||||
* maintains a one move game state history for 'undo mismove'
|
||||
* allows players to pass or resign
|
||||
* * ends game upon 2 consecutive passes
|
||||
* calculates estimated score at game end
|
||||
|
@ -21,6 +20,7 @@ a working game of go for a 9x9 board that
|
|||
|
||||
stretch goals
|
||||
* uses stone placement GUI for resign and pass
|
||||
* maintains a one move game state history for 'undo mismove'
|
||||
* converts string to .sgf format
|
||||
* allows users to edit game info mid game
|
||||
* add stone placement sounds
|
||||
|
|
103
css/main.css
103
css/main.css
|
@ -1,5 +1,6 @@
|
|||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-screen {
|
||||
|
@ -12,4 +13,106 @@
|
|||
"record record record options" <- displays numbered record (stretch!), new game, get game record(stretch!)
|
||||
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%);
|
||||
}
|
137
index.html
137
index.html
|
@ -5,26 +5,127 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<link rel="stylesheet" href="css/reset.css" type="stylesheet">
|
||||
<link rel="stylesheet" href="css/main.css" type="stylesheet">
|
||||
<script src="js/main.js"></script>
|
||||
<title>Go Cats</title>
|
||||
<link href="css/main.css" rel="stylesheet" type="text/css" /> <script src="js/main.js"></script>
|
||||
<title>Browser Go</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="menu" class="full-screen">
|
||||
<!-- for displaying new game screen and status during game -->
|
||||
<div id="menu" class="full-screen">
|
||||
<!-- 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>
|
||||
<!-- 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"></div>
|
||||
<div id="white-caps" class="caps"></div>
|
||||
</div>
|
||||
<div id="board"></div>
|
||||
<div id="black-pos" class="player-pos">
|
||||
<div id="black-bowl" class="bowl"></div>
|
||||
<div id="black-caps" class="caps"></div>
|
||||
<div id="kifu"></div>
|
||||
</div>
|
||||
</content>
|
||||
<div id="board-space">
|
||||
<table id="board">
|
||||
<tr id="row-0">
|
||||
<td id="0,0"></td>
|
||||
<td id="0,1"></td>
|
||||
<td id="0,2"></td>
|
||||
<td id="0,3"></td>
|
||||
<td id="0,4"></td>
|
||||
<td id="0,5"></td>
|
||||
<td id="0,6"></td>
|
||||
<td id="0,7"></td>
|
||||
<td id="0,8"></td>
|
||||
</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>
|
||||
</html>
|
164
js/main.js
164
js/main.js
|
@ -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)
|
||||
// bCaptures, wCaptures, gameInfo object, playerInfo object, turn, pass, gameRecord,
|
||||
// handicapStones, deadShapes{}
|
||||
// boardState [point objects-contain overlay] lastState (created from boardState)
|
||||
// groups?
|
||||
// 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
|
||||
let boardState;
|
||||
|
||||
// define boardState and overlay as 2d 9x9 arrays
|
||||
// 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,
|
||||
// Class Point {
|
||||
// rPos: 1,
|
||||
// cPos: 1,
|
||||
// neighbors: {
|
||||
// top: null,
|
||||
// btm: null,
|
||||
// lft: null,
|
||||
// rgt: null
|
||||
// }
|
||||
// checkLegal: function() {
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// cached elements
|
||||
// store #menu for displaying game info
|
||||
// store
|
||||
// modeling 1,1 point for
|
||||
// define boardState and overlay as 2d 9x9 arrays
|
||||
// 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
|
||||
// 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
|
||||
// initialize game
|
||||
// set handicap stones
|
||||
// render
|
||||
// render board
|
||||
//render moves
|
||||
//render preview
|
||||
// render captures
|
||||
// render player turn marker
|
||||
// game-end
|
||||
// render dead group suggestion
|
||||
// render territory counts
|
||||
// checkLegalMove
|
||||
// clear overlay
|
||||
// if move is not '0', move is illegal (opposing player or 'k' for ko)
|
||||
// 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
|
||||
// functions
|
||||
// initialize game
|
||||
// set handicap stones
|
||||
// render
|
||||
// render board
|
||||
//render moves
|
||||
//render preview
|
||||
// render captures
|
||||
// render player turn marker
|
||||
// game-end
|
||||
// render dead group suggestion
|
||||
// render territory counts
|
||||
// checkLegalMove
|
||||
// clear overlay
|
||||
// if move is not '0', move is illegal (opposing player or 'k' for ko)
|
||||
// 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
|
||||
// cycle through player group marking points as overlay: 'chk' || 'hold'
|
||||
// if any neighboring point is '0' ternminate cycle and mark point as 'l'
|
||||
|
|
Loading…
Reference in a new issue