あのねノート

せんせいあのね、パソコンで字が書けるようになったよ

Racketでじゃんけん

あーこの夏結局何もしてないや、とりあえず簡単なのを書こうということでじゃんけんをしようと思いました。
入力された手とコンピュータが乱数で出した手の組み合わせで勝敗を判断して返すだけです。

#lang racket
;;グー=0, チョキ=1, パー=2
;;勝ち負けを判断するプログラム
(define (duel player com) ;入力をplayer, こちらをcomとして勝敗を返す
  (cond
    ((= player 0) ;playerがグーを出した時
     (cond
       ((= com 0)
        0) ;あいこなので増減0
       ((= com 1)
        1) ;playerの勝ちなので1増える
       ((= com 2)
        -1) ;playerの負けなので1減る
       ))
    ((= player 1) ;playerチョキ
     (cond
       ((= com 0)
        -1)
       ((= com 1)
        0)
       ((= com 2)
        1)
       )
     )
    ((= player 2) ;playerグー
     (cond
       ((= com 0)
        1)
       ((= com 1)
        -1)
       ((= com 2)
        0)
      ))
     ))

(define (jancom) ;comの手を乱数で決める
  (random 3))

(define (play) ;入力からplayerの手を判断する
  (let
      ((player (read)))
    (cond
      ((equal? player 'グー)
       0)
      ((equal? player 'チョキ)
       1)
      ((equal? player 'パー)
       2)
      (else "グー、チョキ、パーのいずれかを入力してください")
      )
      ))

(define (hand n) ;出した手を表す数字を文字列に変換する
  (cond
    ((= n 0)
     'グー)
    ((= n 1)
     'チョキ)
    ((= n 2)
     'パー)
    )
  )

(define (result n) ;結果を表す数値を文字列に変換する
  (cond
    ((= n -1)
     '負け)
    ((= n 0)
     'あいこ)
    ((= n 1)
     '勝ち)
    )
  )

(define (janken)
  (begin
    (display "グー、チョキ、パーのいずれかを入力してください\n")
    (let*
        ((com (jancom)) ;comの手の番号
         (player (play)) ;playerの手の番号
         (resultnum (duel player com)) ;結果の番号
         (comhand (hand com)) ;comの手を文字化
         (res (result resultnum))) ;結果を文字化
      (fprintf (current-output-port)
               "comは~aを出したのでじゃんけん結果は~aです。\n"
               comhand res)
      )
    )
  )

せっかく手を数値で定義してるんだから数字の大小で勝敗を出せたんじゃないかと思いました。これだったらわざわざ手を数字にしなくてもシンボルの組み合わせでいいじゃん。
→足した余りで一発判定できるやんか!!!もう!

コンピュータがただただ乱数で手を出してくる感じになっていますが何かしら学習するみたいな感じにしたいと思いました(学科の他コースの人が前に課題で作ったって言ってた)。

さておき実行するとこうなります。

> (janken)
グー、チョキ、パーのいずれかを入力してください
グー
comはパーを出したのでじゃんけん結果は負けです。

母に見せたら目覚ましじゃんけんじゃんと言われました。それな。