import javax.sound.sampled.ReverbType
import Cell.Percent
import scala.util.Random
trait Revealable {
var caster: Option[Cell] = None
def reveal()(implicit isBomb : Boolean, bombCount : Int)
def subscribe(caster:Cell): Unit ={
this.caster.map { _.onClick() }
}
def click(){ caster.onClick()}
}
class Cell(val revealable : Revealable, _top : => Option[Cell], _bot : => Option[Cell],
_right : => Option[Cell], _left : => Option[Cell])(implicit bombChance: Percent)
{
revealable.subscribe(this);
lazy val top :Option[Cell] = _top
lazy val bot :Option[Cell] = _bot
lazy val right :Option[Cell] = _right
lazy val left :Option[Cell] = _left
val neighbours = List[Option[Cell]](
top, bot, right, left,
top flatMap {_.left} orElse None,
top flatMap {_.right} orElse None,
bot flatMap {_.left} orElse None,
bot flatMap {_.right} orElse None
)
implicit lazy val isBomb = Random.nextDouble() < bombChance.value
implicit lazy val bombCount = neighbours count { _ exists { _.isBomb }}
def onClick() = {
revealable.reveal()
if(!isBomb && bombCount == 0) neighbours map { _ map { _.isBomb }}
}
def check() : Unit = {
if(bombCount == 0)
{
revealable.reveal()
neighbours.flatten.map {_.check()}
}
}
}
object Cell {
case class Percent(value: Int) {
require( value <= 100 && value >= 0, "Must be 0..100")
}
def produceMatrix(width: Int, height : Int)(fillWith : => Revealable)(implicit bombChance: Percent) = {
var arr: Array[Array[Cell]] = Array(Array())
def get(x:Int, y: Int) = arr lift x flatMap { _ lift y }
arr = Array.tabulate(height, width) {
(x, y) => new Cell(fillWith,
get(x, y-1),
get(x, y+1),
get(x+1, y),
get(x-1, y)
)
}
arr
}
}