So here's a general overview of what I'll be going over this week. I've divided AYO into about 5 components.
- The board - This represents the wood (or eWood since this wood is intelligent). The wood can carry out arbitrary operations during the game like counting and moving (sowing) seeds.
- The Rules - This represents a kind of 10 commandments. The board references it when moving seeds and other components reference it as need be
- The Config - This represents the configuration of the game at any point in time. It stores the number of seeds each player has, the player whose current turn it is to play, how many houses a player has won, etc. Obviously the game starts with a new config
- The Game - This actually is a misnomer. It should be called the referee or umpire. This component starts the game, receives input from the user, and calls the other components as needed.
- I said about 5 didn't I?
Here's the complete source code (buggy and quaint) as it is right now.
object Game {Mankala
def start = {
val s = List(0,0)
val h = List(Set(0,1,2,3,4,5), Set(6,7,8,9,10,11))
val l = List(4,4,4,4,4,4,4,4,4,4,4,4)
move(Config(s, h, 0, l))
}
def move(cfg:Config):Unit = {
if(!Rules.hasHouse(cfg.getHouses)){
//print message alerting player of change of turn
move(cfg.changeTurn)
}
Board.draw(cfg.list)
println("\nPlayer "+(cfg.turn+1)+"\n"+cfg)
//get current player's choice... player can only select his own house and if it has seeds
val choice = getInput(cfg.getHouses.filter(cfg.list(_) != 0))
val (list, index) = plant(choice, cfg.list) //playout the choice
val ncfg =
if(Rules.canKeep(list(index)))
cfg.setList(list).plusStone(4).updateList(index,0)
else
cfg.setList(list)
val ocfg = houseKeeping(0, ncfg)
val pcfg = houseKeeping(1, ocfg)
if(!Rules.gameOver(pcfg.list))
move(pcfg.changeTurn)
else
println("Game Over: \n"+pcfg)
}
/**
* get current player's choice
* if the choice is not valid display message and prompt user again
*/
def getInput(restrictions:Set[Int]):Int = {
print("Please start move ["+restrictions.foldLeft("")(_+","+_)+"]: ")
val x = readInt
if(restrictions.contains(Board.position(x)))
Board.position(x)
else
getInput(restrictions)
}
def plant(pos:Int, l:List[Int]):(List[Int],Int)={
val (listn, index) =
Board.roll(pos+1, l(pos), {l.slice(0,pos):::List(0):::l.slice(pos+1,l.size)}.toArray)
if(Rules.canMove(listn(index)-1) && !Rules.canKeep(listn(index)))
plant(index, listn)
else
(listn, index)
}
def houseKeeping(turn:Int, cfg:Config, houses:List[Int]):Config={
//Board.draw(cfg.list)
//println(">>> "+houses)
if(houses.isEmpty)
return cfg
else{
var nConfig =
if(Rules.canKeep(cfg.list(houses.head)))
cfg.updateList(houses.head, 0).plusStone(4, turn)
else
cfg
houseKeeping(turn, nConfig, houses.tail)Mankala
}
}
def houseKeeping(turn:Int, cfg:Config):Config = houseKeeping(turn, cfg, cfg.houses(turn).toList)
}
case class Config(stones:List[Int], houses:List[Set[Int]], turn:Int, list:List[Int]){
def this() = this(List(0,0), List(Set(0,1,2,3,4,5), Set(6,7,8,9,10,11)), 0, List(4,4,4,4,4,4,4,4,4,4,4,4))
def plusStone(count:Int):Config = plusStone(count, turn)
def plusStone(count:Int, player:Int) = {
val s = stones.toArray
s(player) += count
Config(s.toList, houses, turn, list)
}
def updateList(l:List[Int], index:Int, value:Int):List[Int] =
l.slice(0,index):::List(0):::l.slice(index+1,l.size)
def updateList(index:Int, value:Int):Config =Mankala
Config(stones, houses, turn, updateList(list, index, value))
def setList(l:List[Int]) =
Config(stones, houses, turn, l)
def changeTurn =
Config(stones, houses, (turn+1)%2, list)
def getHouses = houses(turn)
def getHouses(nTurn:Int) = houses(nTurn%2)
}
object Board {
def draw(list:List[Int]):Unit = {
println
list.slice(6,list.size).reverse.foreach(x => print(x+"\t"))
println
list.slice(0, 6).foreach(x => print(x+"\t"))
println
}
def position(i:Int) = (i+12)%12
def roll(index:Int, stoneBuffer:Int, list:Array[Int]):(List[Int],Int) =
if(stoneBuffer==0)
(list.toList, position(index-1))
else{
list(position(index)) += 1; draw(list.toList)
roll(index+1, stoneBuffer-1, list)
}
}
object Rules {
def canMove(plantedSeeds:Int) = plantedSeeds!=0
def canKeep(plantedSeeds:Int) = plantedSeeds==4
def hasHouse(houses:Set[Int]) = !houses.isEmpty
def gameOver(list:List[Int]) = list.reduceLeft(_+_) < 4
}
object Ayo {
def main(args : Array[String]) : Unit = {
Game.start
}
}
No comments:
Post a Comment