Comment detail

マルバツゲーム (Nested Flatten)
・状態遷移を相互再帰で書く
・Gaucheで最近になって文書化されたshuffleを使う
・盤面のベクタを副作用で上書きするのが普通だけど、副作用が嫌なので棋譜のリストを持ってみました。

結果
 player1 won: 5787
 player2 won: 2909
 draw: 1304
 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
(use srfi-1)
(use gauche.sequence)

(define (win? l)
  (any (cut lset<= = <> l)
       '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))))

(let new-game ((win 0)
               (lose 0)
               (draw 0))
  (if (<= 10000 (+ win lose draw))
    (format #t " player1 won: ~a\n player2 won: ~a\n draw: ~a\n" win lose draw)
    (letrec ((p1-turn (lambda (p1 p2)
                        (if (win? p2)
                          (new-game win (+ 1 lose) draw)
                          (let ((vacant (lset-difference = '(0 1 2 3 4 5 6 7 8) (append p1 p2))))
                            (if (null? vacant)
                              (new-game win lose (+ 1 draw))
                              (p2-turn (cons (car (shuffle vacant)) p1) p2))))))
             (p2-turn (lambda (p1 p2)
                        (if (win? p1)
                          (new-game (+ 1 win) lose draw)
                          (let ((vacant (lset-difference = '(0 1 2 3 4 5 6 7 8) (append p1 p2))))
                            (if (null? vacant)
                              (new-game win lose (+ 1 draw))
                              (p1-turn p1 (cons (car (shuffle vacant)) p2))))))))
      (p1-turn '() '()))))
オマケです。せっかく書いたので。問題の趣旨にあってないし、ゴルフとしても中途半端です。
結果
 player1 won: 5907
 player2 won: 2872
 draw: 1221
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
(use srfi-1)
(use gauche.sequence)

(define (win? l)
  (any (cut lset<= = <> l)
       '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))))

(let omake ((win 0)
            (lose 0)
            (draw 0))
  (if (<= 10000 (+ win lose draw))
    (format #t " player1 won: ~a\n player2 won: ~a\n draw: ~a\n" win lose draw)
    (receive (p1 p2) (split-at (shuffle '(0 1 2 3 4 5 6 7 8)) 5)
      (or (and-let* ((i (list-index win? (list (cddr p1) (cdr p2) (cdr p1) p2 p1))))
            (if (even? i)
              (omake (+ 1 win) lose draw)
              (omake win (+ 1 lose) draw)))
          (omake win lose (+ 1 draw))))))

Index

Feed

Other

Link

Pathtraq

loading...