fork(1) download
  1. #lang racket
  2.  
  3. ;;; ゲームの環境情報
  4. (struct world (stones player) #:transparent)
  5.  
  6. ;;; メッセージ分離方式
  7. (define *messages* '((init . "石の数 (10以上) :")
  8. (number-of-stones . "石の数: ~a~%")
  9. (prompt . "プレイヤー~aの番です~%何個取る (1〜3個) ?")
  10. (winner . "プレイヤー~aの勝ち~%")))
  11.  
  12. ;;; 入力の最小値と最大値
  13. (define-values (*min* *max*) (values 0 4))
  14.  
  15. ;;; Eval
  16. (define (world-go x env)
  17. (let ((stones (- (world-stones env) x))
  18. (player (if (= (world-player env) 1)
  19. 2
  20. 1)))
  21. (world stones player)))
  22.  
  23. ;;;; Eval(短縮版)
  24. ;(define (world-go x env)
  25. ; (world (- (world-stones env) x)
  26. ; (if (= (world-player env) 1)
  27. ; 2
  28. ; 1)))
  29.  
  30. ;;; Read
  31. (define (input env prompt)
  32. (display (format prompt (world-player env)))
  33. (let ((num (read)))
  34. (if (and (number? num) (> num *min*) (< num *max*))
  35. num
  36. (input env prompt))))
  37.  
  38. ;;; Read-Eval-Print Loop
  39. (define (nim env)
  40. (display (format (cdr (assq 'number-of-stones *messages*))
  41. (world-stones env)))
  42. (if (game-ends? env)
  43. (display (format (cdr (assq 'winner *messages*)) (winner env)))
  44. (nim (world-go (input env (cdr (assq 'prompt *messages*))) env))))
  45.  
  46. ;;; REPL 用補助関数
  47. ;; ゲーム終了判定
  48. (define (game-ends? env)
  49. (< (world-stones env) 2))
  50.  
  51. ;; ゲーム勝者表示
  52. (define (winner env)
  53. (let ((player (world-player env)))
  54. (if (zero? (world-stones env))
  55. player
  56. (if (= player 1)
  57. 2
  58. 1))))
  59.  
  60. ;;; 初期化
  61. (define (init)
  62. (display (cdr (assq 'init *messages*)))
  63. (let ((num (read)))
  64. (if (and (number? num) (> num 9))
  65. (world num 1)
  66. (init))))
  67.  
  68. ;;; ローカル関数使用版
  69. ;(define (nim env)
  70. ; (define (winner env)
  71. ; (let ((player (world-player env)))
  72. ; (if (zero? (world-stones env))
  73. ; player
  74. ; (if (= player 1)
  75. ; 2
  76. ; 1))))
  77. ; (define (game-ends? env)
  78. ; (< (world-stones env) 2))
  79. ; (let loop ((env env))
  80. ; (display (format (cdr (assq 'number-of-stones *messages*))
  81. ; (world-stones env)))
  82. ; (if (game-ends? env)
  83. ; (display (format (cdr (assq 'winner *messages*)) (winner env)))
  84. ; (loop (world-go (input env (cdr (assq 'prompt *messages*))) env)))))
  85.  
  86. ;;;; Read(コンピュータが参加する版)
  87. ;(define (input env prompt)
  88. ; (display (format (cdr (assq 'prompt *messages*)) (world-player env)))
  89. ; ;;; ここを改造
  90. ; (let ((num (if (= (world-player env) 1)
  91. ; (read)
  92. ; (let ((result (add1 (random 3))))
  93. ; (display result) ;; read の仕様に合わせて、一旦出力して
  94. ; (newline) ;; 改行する
  95. ; result))))
  96. ; (if (and (number? num) (> num *min*) (< num *max*))
  97. ; num
  98. ; (input env prompt))))
  99.  
  100. ;;; ゲーム実行
  101. (nim (init))
Success #stdin #stdout 0.64s 96892KB
stdin
15
stdout
Standard output is empty