Skip to content

Commit

Permalink
finished drawing board state and attaching event handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
slior committed Sep 5, 2020
1 parent e8a35c6 commit 384fd01
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 23 deletions.
7 changes: 5 additions & 2 deletions mancala/src/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ class Board
isPlayer1Cell(boardCell) { return boardCell >= 1 && boardCell <= this.cellCount/2-1; }
isPlayer2Cell(boardCell) { return boardCell >= this.cellCount/2+1 && boardCell <= this.cellCount-1; }

isPlayer1Home(boardCell) { return boardCell == 0; }
isPlayer2Home(boardCell) { return boardCell == this.cellCount/2; }
isPlayer1Home(boardCell) { return boardCell == this.player1Home(); }
isPlayer2Home(boardCell) { return boardCell == this.player2Home(); }

player1Home() { return 0; }
player2Home() { return this.cellCount/2; }

totalCellCount() { return this.cellCount; }
}
Expand Down
84 changes: 66 additions & 18 deletions mancala/src/drawing.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
const {fabric} = require("fabric")
const {range,dbg, ERR} = require("./util.js")
const {range,dbg, ERR, maybe,None} = require("./util.js")


let CELL_SIZE = 50;

let TOP_LEFT = { x : 50, y : 50};
let stoneUIElement = [];


function initCanvas(canvasEl)
{
Expand All @@ -11,6 +18,15 @@ function initCanvas(canvasEl)
return ret;
}

function initDrawingElements(cellCount)
{
range(1,cellCount).forEach( _ => stoneUIElement.push(None));
}

function rememberUIObj(boardCell,el) { stoneUIElement[boardCell] = maybe(el); }
function forgetUIObj(boardCell) { stoneUIElement[boardCell] = None; }
function uiObjAt(boardCell) { return stoneUIElement[boardCell]; }

function drawLineOn(cnvs,x1,y1,x2,y2,color)
{
let l = new fabric.Line([x1,y1,x2,y2], {
Expand All @@ -22,10 +38,6 @@ function drawLineOn(cnvs,x1,y1,x2,y2,color)

}

let CELL_SIZE = 50;

let TOP_LEFT = { x : 50, y : 50};

function boardWidthInCells(cellCount) {
let playerCellCount = cellCount/2-1;
return playerCellCount+2; // +2 for player home cells
Expand Down Expand Up @@ -71,31 +83,43 @@ function drawBoard(cnvs,cellCount)

}



function drawBoardState(cnvs,board)
{
dbg("drawing board state")
let FONT_SIZE = 20;
let MARGIN = 5
board.forAllCells(boardCell => {
let stonesInCell = board.stonesIn(boardCell);
switch (true)
{
case board.isPlayer1Home(boardCell) : drawPlayer1Home(stonesInCell); break;
case board.isPlayer2Home(boardCell) : drawPlayer2Home(stonesInCell); break;
case board.isPlayer1Cell(boardCell) || board.isPlayer2Cell(boardCell): drawCell(boardCell,stonesInCell); break;
case board.isPlayer1Home(boardCell) : drawOrRemove(boardCell,stonesInCell,(_,stoneCount) => { drawPlayer1Home(stoneCount); }); break;
case board.isPlayer2Home(boardCell) : drawOrRemove(boardCell,stonesInCell,(_,stoneCount) => { drawPlayer2Home(stoneCount); }); break;
case board.isPlayer1Cell(boardCell) || board.isPlayer2Cell(boardCell):
drawOrRemove(boardCell,stonesInCell,(boardCell,stoneCount) => { drawCell(boardCell,stoneCount); });
break;
default : ERR ("Invalid board cell when drawing state: " + boardCell); break;
}
})

function drawPlayer1Home(stoneCount)
{
dbg("drawing player 1 home: " + stoneCount)
drawText(stoneCount,TOP_LEFT.x + CELL_SIZE / 2 - FONT_SIZE/2,TOP_LEFT.y + CELL_SIZE * 1.5 - FONT_SIZE/2)
rememberUIObj(board.player1Home(),
drawStones(stoneCount,
TOP_LEFT.x + CELL_SIZE / 2 - FONT_SIZE/2-MARGIN,
TOP_LEFT.y + CELL_SIZE * 1.5 - FONT_SIZE/2-MARGIN));
}

function drawPlayer2Home(stoneCount)
{
dbg("drawing player 2 home: " + stoneCount)
drawText(stoneCount,TOP_LEFT.x + boardWidthInCells(board.totalCellCount()) * CELL_SIZE - CELL_SIZE/2 - FONT_SIZE/2,TOP_LEFT.y + CELL_SIZE*1.5-FONT_SIZE/2)
rememberUIObj(board.player2Home(),
drawStones(stoneCount,
/* left = */TOP_LEFT.x + boardWidthInCells(board.totalCellCount()) * CELL_SIZE - CELL_SIZE/2 - FONT_SIZE/2-MARGIN,
/* top = */TOP_LEFT.y + CELL_SIZE*1.5-FONT_SIZE/2-MARGIN));

}

function drawCell(boardCell,stoneCount)
Expand All @@ -105,28 +129,52 @@ function drawBoardState(cnvs,board)
switch (true)
{
case board.isPlayer1Cell(boardCell) :
top = CELL_SIZE /2 - FONT_SIZE/2;
left = boardCell * CELL_SIZE + CELL_SIZE/2 - FONT_SIZE/2;
top = CELL_SIZE /2 - FONT_SIZE/2 - MARGIN;
left = boardCell * CELL_SIZE + CELL_SIZE/2 - FONT_SIZE/2 - MARGIN;
break;
case board.isPlayer2Cell(boardCell) :
top = CELL_SIZE * 2.5 - FONT_SIZE/2;
left = (board.totalCellCount() - boardCell) * CELL_SIZE + CELL_SIZE/2 - FONT_SIZE/2;
top = CELL_SIZE * 2.5 - FONT_SIZE/2 - MARGIN;
left = (board.totalCellCount() - boardCell) * CELL_SIZE + CELL_SIZE/2 - FONT_SIZE/2 - MARGIN;
break;
default : ERR("Invalid board cell: must be either player 1 or player 2 cell");
}
drawText(stoneCount,TOP_LEFT.x + left,TOP_LEFT.y + top);
rememberUIObj(boardCell,drawStones(stoneCount,TOP_LEFT.x + left,TOP_LEFT.y + top));
}

function drawOrRemove(boardCell,stoneCount,drawFunc)
{
if (stoneCount > 0)
{
drawFunc(boardCell,stoneCount);
uiObjAt(boardCell).ifPresent(uiObj => {uiObj.on('mousedown', _ => {dbg('Clicked cell: ' + boardCell + '!')})})

}
else removeDrawingAt(boardCell);
}

function drawText(txt,left,top)
function removeDrawingAt(boardCell)
{
dbg("drawing " + txt + " at " + top + "," + left);
cnvs.add(new fabric.Text(txt+'',{fontSize : FONT_SIZE, left : left, top : top, selectable : false}))
uiObjAt(boardCell).ifPresent(uiObj => {
cnvs.remove(uiObj);
forgetUIObj(boardCell);
});
}

function drawStones(stoneCount,left,top)
{
let c = new fabric.Circle({originX : 'center',originY : 'center', radius : FONT_SIZE/2+MARGIN, fill : 'white',stroke : 'blue'})
let t = new fabric.Text(stoneCount+'',{fontSize : FONT_SIZE, originX : 'center',originY : 'center', selectable : false});
let g = new fabric.Group([c,t], {left : left, top : top, selectable : false});
cnvs.add(g);
return g;
}

}

module.exports = {
drawLineOn : drawLineOn
, drawBoard : drawBoard
, initCanvas : initCanvas
, drawBoardState : drawBoardState
, initDrawingElements : initDrawingElements
}
5 changes: 3 additions & 2 deletions mancala/src/game.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


const {initCanvas,drawBoard,drawBoardState} = require("./drawing.js")
const {initCanvas,drawBoard,drawBoardState,initDrawingElements} = require("./drawing.js")
const {Board} = require("./board.js")

const CELL_COUNT = 14;
Expand All @@ -9,7 +9,8 @@ let board = new Board(CELL_COUNT)

function initGame(cnvsELID)
{
let cnvs = initCanvas(cnvsELID)
let cnvs = initCanvas(cnvsELID);
initDrawingElements(board.totalCellCount());
drawBoard(cnvs,CELL_COUNT);
drawBoardState(cnvs,board);
}
Expand Down
37 changes: 36 additions & 1 deletion mancala/src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,43 @@ function ERR(msg) { throw new Error(msg); }

function dbg(msg) { console.log(msg || 'MISSING DBG MSG') }

let None = {}
None.map = f => None;
None.ifPresent = f => {} //do nothing

class Some
{
constructor(v)
{
this.value = v;
}

map(f)
{
if (f)
{
let r = f(this.value);
return r ? new Some(r) : None;
}
else return None;
}

ifPresent(f)
{
this.map(f); //same as map, but don't care about the result;
}
}

function maybe(o)
{
return o !== undefined && o !== null ? new Some(o) : None;
}

module.exports = {
range : range
, ERR : ERR
, dbg : dbg
}
, maybe : maybe
, None : None
}

0 comments on commit 384fd01

Please sign in to comment.