Compare commits

...

3 commits

Author SHA1 Message Date
3a483049a4 add simple make move
checks for legality of move and player turn after submission
2024-06-23 19:25:57 -04:00
3b2927de24 add events, new_game and join_room
naively allows for a game to be started by first two users to join a room
2024-06-23 18:22:53 -04:00
a23c93317b add minor lines to readme 2024-06-23 16:54:27 -04:00
2 changed files with 118 additions and 33 deletions

View file

@ -10,9 +10,14 @@ assuming nix flake
nix develop nix develop
# or if using direnv # or if using direnv
echo "use flake ." > .envrc echo "use flake ." > .envrc
direnv allow
# endif
npm run dev npm run dev
# runs dev server on localhost:4000 # runs dev server on localhost:4000
# instances run on incremntal ports # instances run on incremntal ports
# refresh page to reflect changes # refresh page to reflect changes
npm run build
# builds new xdc as dist/webxdc-go.xdc
``` ```

View file

@ -69,6 +69,7 @@ const gameState = { // pre-init values (render prior to any player input)
komi: null, // komi depends on handicap stones + player rank komi: null, // komi depends on handicap stones + player rank
handicap: null, handicap: null,
boardSize: null, boardSize: null,
players: new Set (),
playerState: { playerState: {
bCaptures: null, bCaptures: null,
wCaptures: null, wCaptures: null,
@ -271,6 +272,31 @@ boardSizeEl.addEventListener('click', clickBoardSize);
gameStartEl.addEventListener('click', clickSubmitStart); gameStartEl.addEventListener('click', clickSubmitStart);
/*----- FUNCTIONS ----------------------------------*/ /*----- FUNCTIONS ----------------------------------*/
/*----- webxdc functions -----*/
function sendUpdate(update, descr) {
window.webxdc.sendUpdate(update, descr);
}
const userName = window.webxdc.selfName;
window.webxdc.setUpdateListener((update) => {
let { payload, summary } = update;
switch (payload.event) {
case 'make_move':
makeMove (payload);
break;
case 'new_game':
initGame (payload);
break;
case 'join_room':
updateRoom (payload);
break;
default:
console.log ("couldn't recognize update event");
}
});
/*----- init functions -----*/ /*----- init functions -----*/
init(); init();
@ -288,11 +314,27 @@ function init() {
gameState.gameRecord = []; gameState.gameRecord = [];
boardState = []; boardState = [];
gameState.gameMeta.start = false; gameState.gameMeta.start = false;
joinRoom ();
startMenu(); startMenu();
}; };
function joinRoom () {
const update = {
payload: {
event: "join_room",
player: userName
}
};
const descr = `${userName} joined room`;
sendUpdate (update, descr);
}
function updateRoom (payload) {
gameState.players.add (payload .player);
}
function getDate() { function getDate() {
let d = new Date; let d = new Date;
return `${d.getFullYear()}-${String(d.getMonth()+1).charAt(-1)||0}${String(d.getMonth()+1).charAt(-0)}-${String(d.getDate()).charAt(-1)||0}${String(d.getDate()+1).charAt(-0)}`; return `${d.getFullYear()}-${String(d.getMonth()+1).charAt(-1)||0}${String(d.getMonth()+1).charAt(-0)}-${String(d.getDate()).charAt(-1)||0}${String(d.getDate()+1).charAt(-0)}`;
} }
@ -300,24 +342,36 @@ function startMenu() {
modalEl.style.visibility = 'visible'; modalEl.style.visibility = 'visible';
renderMenu(); renderMenu();
} }
function clickSubmitStart(evt) { function clickSubmitStart(evt) {
if (gameState.gameMeta.start) return init(); let players = gameState.players.values ();
evt.preventDefault(); const update = {
evt.stopPropagation(); payload: {
gameState.playerMeta.b.name = blackNameInputEl.value || 'black'; event: "new_game",
gameState.playerMeta.w.name = whiteNameInputEl.value || 'white'; players: [players.next ().value, players.next ().value],
modalEl.style.visibility = 'hidden'; },
return initGame(); // document: "",
summary: "start game",
};
const descr = `${userName} started game`;
sendUpdate(update, descr);
if (gameState.gameMeta.start) return init();
evt.preventDefault();
evt.stopPropagation();
return null;
} }
function initGame() { function initGame(payload) {
gameState.winner = null; gameState.playerMeta.b.name = payload.players [0] || 'black';
gameState.pass = null; gameState.playerMeta.w.name = payload.players [1] || 'white';
gameState.turn = gameState.handicap ? -1 : 1; modalEl.style.visibility = 'hidden';
gameState.gameMeta.start = true; gameState.winner = null;
initBoard(); gameState.pass = null;
renderBoardInit(); gameState.turn = gameState.handicap ? -1 : 1;
renderGame(); gameState.gameMeta.start = true;
initBoard();
renderBoardInit();
renderGame();
} }
function initBoard() { function initBoard() {
@ -404,7 +458,6 @@ function clickUpdatePlayerMeta(evt) {
if (evt.target.name == 'black-rank-certain') gameState.playerMeta.b.rankCertain = !gameState.playerMeta.b.rankCertain; if (evt.target.name == 'black-rank-certain') gameState.playerMeta.b.rankCertain = !gameState.playerMeta.b.rankCertain;
if (evt.target.name == 'white-rank-certain') gameState.playerMeta.w.rankCertain = !gameState.playerMeta.w.rankCertain; if (evt.target.name == 'white-rank-certain') gameState.playerMeta.w.rankCertain = !gameState.playerMeta.w.rankCertain;
renderMenu(); renderMenu();
} }
function clickBoardSize(evt) { function clickBoardSize(evt) {
@ -437,23 +490,40 @@ function clickCloseMenu(evt) {
/*----- gameplay functions -----*/ /*----- gameplay functions -----*/
function clickBoard(evt) { function clickBoard(evt) {
evt.stopPropagation(); evt.stopPropagation();
if (gameState.pass > 1 || gameState.winner) return editTerritory(evt); if (gameState.pass > 1 || gameState.winner) return editTerritory(evt);
// checks for placement and pushes to cell // checks for placement and pushes to cell
let placement = [ parseInt(evt.target.closest('td').id.split('-')[0]), parseInt(evt.target.closest('td').id.split('-')[1]) ]; let placement = [
let point = findPointFromIdx(placement); parseInt(evt.target.closest('td').id.split('-')[0]),
//checks that this placement was marked as legal parseInt(evt.target.closest('td').id.split('-')[1])
if ( !checkLegal(point) ) return null; ];
clearKo(); let update = {
clearPass(); payload: {
resolveCaptures(point); event: 'make_move',
point.stone = gameState.turn; placement,
point.joinGroup(); player: userName
playSound(point); }
clearCaptures(); };
gameState.gameRecord.push(`${STONES_DATA[gameState.turn]}: ${point.pos}`); let descr = `${userName} move at ${placement}`;
gameState.turn*= -1; return sendUpdate (update, descr);
renderGame(); }
function makeMove (payload) {
let { placement, player } = payload;
let point = findPointFromIdx(placement);
if (!checkLegal (point)) return;
if (!checkTurn (player)) return;
clearKo();
clearPass();
resolveCaptures(point);
point.stone = gameState.turn;
point.joinGroup();
playSound(point);
clearCaptures();
gameState.gameRecord.push(`${STONES_DATA[gameState.turn]}: ${point.pos}`);
gameState.turn*= -1;
renderGame();
return;
} }
function clearKo() { function clearKo() {
@ -495,6 +565,16 @@ function checkLegal(point) {
return true; return true;
} }
function checkTurn (player) {
if (gameState.turn == 1) {
return gameState.playerMeta.b.name == player;
}
if (gameState.turn == -1) {
return gameState.playerMeta.w.name == player;
}
return false;
}
function clearOverlay() { function clearOverlay() {
for (let point in boardState) { for (let point in boardState) {
point = boardState[point]; point = boardState[point];