JSFiddle - React, Tailwind, and code Playground

by Max Loeb

SCSS

$cell-size = 80px;
.grid {
  height:$cell-size * 6;
  width:$cell-size * 6;
  background-color:black;
  box-sizing: border-box;
  position:relative;
  margin-bottom: 20px;
}

.game-frame {
  display: flex;
  margin-bottom: 12px;
  border-bottom:4px solid #999;
  table {
    margin-left: 20px;
    font-size: 16px;
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border-collapse: collapse;
    border-spacing: 0;
    border: 1px solid #ccc;
    
    tr:nth-child(odd) {
       background-color: #eee;
    }
    
    td {
      padding:6px;
    }
  }
}

.cell {
	float: left;
  display: flex;
  align-items: center;
  position:relative;
	color: #ccc;
	padding: 1px;
 	height: $cell-size;
 	width: $cell-size;
  justify-content: center;
	background-color: #eee;
  	border: 1px solid #999;
  	box-sizing: border-box;
	&.treasure {
		background-image: url('https://vignette2.wikia.nocookie.net/my-mario-list/images/6/6d/Coin.png/revision/latest?cb=20130113020535');
		background-size:$cell-size * .7;
		background-repeat:no-repeat;
		background-position:$cell-size * .1;
	}	
	
	&.checked {
		background-color:#666 !important; 
	}
	
	&.checked-nearby {
		background-color: #abb;
	}
  .move-number {
    font-size:48px;
    color: #0c0;
  }
 
}

TypeScript

const COL = 0;
const ROW = 1;
class Game {
    height:number = 6;
    width:number  = 6;
    root:any;
	cells:boolean[][];
	treasure:number[];
	numMoves:number = 0;
    
    constructor($parent) {
      	this.root = $("<div class='grid'></div>");
        $parent.append(this.root);
    		this.cells = [];
				this.treasure = [];
				this.drawCells();
    }  
	
	public placeTreasure(column, row) {
		this.treasure = [column,row]; 
    var that = this;
		this._visitCross(column, row, (c,r) => {
			that.findSquare(c,r).addClass("treasure");
			return true;
		});	
	}
	
	protected _visitCross(col,row,cb) { 
		var cont = true;
		if( col > 0) {
			cont = cb(col-1,row)	
		};
		
		if(!cont) {
			return;
		}
			
		if(row > 0){
			cont = cb(col, row-1);
		}

		if(!cont) {
			return;
		}
			
		if (col < this.width-1) {
			cont = cb(col+1,row);  
		}

		if(!cont) {
			return;
		}
			
		if (row < this.height-1) { 
			cont = cb(col, row+1)
		};
			
			
			
		if(!cont) {
			return;
		}
			
		cont = cb(col,row);
	}
			
  public drawStrategy(moveSet) {
  	for(var i=0; i < moveSet.length; i++) {
    	const move = moveSet[i];
    	const cell = this.findSquare(move[COL], move[ROW]);
      cell.html("<span class='move-number'>"+(i+1)+"</span>");
    }
  }    
      
	protected findSquare(column, row) {
		return this.root.find('.cell-'+column+"-" + row);
	}
			
	protected foundTreasure(column, row) {
		return ((row == this.treasure[ROW]) && (column == this.treasure[COL]));	
	}		
			
	protected treasureNearby(column, row) {
		var rocks = false;	
		this._visitCross(this.treasure[COL], this.treasure[ROW], (trColumn, trRow) => {
			if(trRow==row && trColumn == column) {
				// we've landed on surrounding not-quite treasure.  
				rocks = true;
				return false;
			} 
			return true;
		});
		return rocks;	
	}		
	protected isPossibility(column, row) {
		var res = true;	
		var that = this;
		
		this._visitCross(column, row, (c, r) => {
			if(column == c && row == r) {
				return...