マルバツゲーム
Posted feedbacks - Scala
お昼休みにさくっとやってみました。
Playerクラスを継承したクラスをつくることでPlayerを差し替えることができます。
10000回を3回ほどやってみて
player1 won: 5190
player2 won: 2410
draw : 2400
player1 won: 5190
player2 won: 2411
draw : 2399
player1 won: 5152
player2 won: 2383
draw : 2465
というかんじでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | import java.util.Random
class TicTacToe(val size:int, val players:List[Player]) {
protected val field = new Array[Array[char]](size,size)
val len = size*size
val lines = _stline((v,v2) => (v,v2))++_stline((v,v2) => (v2,v))++
List(((size-1).until(-1,-1)).map(v=>(v,v))) ++
List((0 until size).map(v=>(v,v)))
def _stline(f:(int,int) => Pair[int,int]) =
(0 until size).map(v => (0 until size).map(v2 => f(v,v2)))
override def toString = {
val sep = List.make(size*4+1, "-").mkString("\n", "", "\n")
field.map{_.mkString("| ", " | ", " |")}.mkString(sep,sep,sep)
}
def start:Option[Player] = {
for(val i<-(0 until size); val j<-(0 until size)) { field(i)(j) = ' '}
Stream.const(players).flatMap(v=>v).take(len).find {player =>
val p = player.put(this)
if(!available_?(p)) error("Oops!")
field(p._1)(p._2) = player.mark
judge
}
}
def judge = lines.exists(l => l.forall(!available_?(_)) &&
l.forall(v => field(l(0)._1)(l(0)._2) == field(v._1)(v._2)))
def available_?(pos:Pair[int,int]) = field(pos._1)(pos._2) equals ' '
}
abstract class Player{
val mark:char
val name:String
def put(ttt:TicTacToe):Pair[int,int]
}
class RandomPlayer(override val mark:char, override val name:String) extends Player{
val rnd = new Random
override def put(ttt:TicTacToe) = {
def _n = (rnd.nextInt(ttt.size), rnd.nextInt(ttt.size))
def next(v:Pair[int,int]):Stream[Pair[int,int]] = Stream.cons(v, next(_n))
next(_n).find(ttt.available_?).get
}
}
object Main extends Application{
val ttt = new TicTacToe(3, List(new RandomPlayer('○', "1"), new RandomPlayer('×', "2")))
val result = Array.make(3,0)
(1 to 10000) foreach { i =>
ttt.start match {
case Some(p) if p.name equals "1" => result(0) += 1
case Some(p) if p.name equals "2" => result(1) += 1
case _ => result(2) += 1
}
}
println("player1 won:\t"+result(0)+"\n"+"player2 won:\t"+result(1)+"\n"+"draw :\t"+result(2))
}
|



syat
#6190()
Rating4/4=1.00
マルバツゲームは3×3の格子に交互に○と×を書き込み、先に縦・横・斜めに記号をそろえたほうが勝ちというおなじみのゲームです。
「毎ターン乱数を使って手を決めるランダムプレイヤー同士を対戦させる」というのが今回のお題です。 1万回対戦させ、勝ち・負け・引き分けの数を表示してください。 そして先手が有利であることを確かめてください。
良い手を思考するプレイヤーについては別のお題にしようと思っています。 プレイヤーを簡単に差し換えることができる設計を目指してください。
[ reply ]