LoginSignup
8
0

More than 1 year has passed since last update.

Serverless Framework でじゃんけんのLINEbotを作る(リファクタリング編)

Last updated at Posted at 2021-07-25

概要

一つ前に投稿した記事のリファクタリング編です。
じゃんけんの勝ち負けを判定するロジックが美しくなかったので、数学的に処理しました。

アジェンダ

  1. 問題の実装
  2. 数学的処理
  3. リファクタリング

1. 問題の実装

janken.jsの抜粋
/**
 * じゃんけんの勝ち負けを判定します。
 * @param {string} userHand - ユーザの出した手
 * @param {string} cpHand - コンピュータの出した手
 * @return {string} - message 判定結果
 */
//TODO ロジックが美しくない。数学的に処理する方法を後日の記事にする。
function hantei(userHand, cpHand){
  let message = ''

  if(userHand == 'グー'){
    if(cpHand == 'グー'){
      message = 'あいこです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else if(cpHand == 'チョキ'){
      message = 'あなたの勝ちです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }
  }else if(userHand == 'チョキ'){
    if(cpHand == 'チョキ'){
      message = 'あいこです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else if(cpHand == 'パー'){
      message = 'あなたの勝ちです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }
  }else{
    if(cpHand == 'パー'){
      message = 'あいこです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else if(cpHand == 'グー'){
      message = 'あなたの勝ちです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた:'+userHand + '、CP:'+ cpHand +')'
    }
  }
  return message
}

うーむ、いかにも美しくないですよね。if文の中にif文があって、とても気持ち悪い。:confounded:
なので、数学的に処理してリファクタリングしましょう!!!

2. 数学的処理

では数学的に処理しましょう。グーやパーなどのテキストデータだと処理しにくいので、数値に変換します。数値に変換した後は法則を見つけるだけです!!詳細は下記の画像の通りです。
9F1F04C5-EED1-4A8B-94E6-6935CBFC2F26_1_105_c.jpeg
はい、画像の通り、判定方法は((自分-相手)+3)%3の結果を見れば判定できることがわかりましたね。では実装していきましょう。

3.リファクタリング

janken.js
'use strict';

// パッケージのインストール
const line = require('@line/bot-sdk');

// LINEアクセストークンの設定
const config = {
  channelAccessToken: 'アクセストークン',
  channelSecret: 'シークレットトークン',
};

// インスタンス化
const client = new line.Client(config);

exports.webhook = async (event, context) => {

  /* リクエストボディ*/
  const body = JSON.parse(event.body)
  /* Lineのevent情報*/
  const response = body.events[0]
  /* ユーザの出した手を取得*/
  const userHand = response.message.text
  /* コンピュータの出した手を取得 */
  const cpHand = getCpHand()

  let message = hantei(userHand, cpHand)
  /* メッセージ送信のために必要な情報 */
  const replyToken = response.replyToken
  console.log('replyToken:' + replyToken)
  const post = {
    type: 'text',
    text: message,
  }

  try {
    await client.replyMessage(replyToken, post)
  } catch (err) {
    console.log(err)
  }
};

/**
 * コンピュータの手を決定します。
 * @return {string} cpHand - コンピュータの手
 */
 function getCpHand(){
  /**ランダム数値を取得(範囲:0~2) */
  let num = Math.floor(Math.random() * 3)
  let cpHand = ''
  if(num ==0){
    cpHand = 'グー'
  }else if(num ==1){
    cpHand = 'チョキ'
  }else{
    cpHand = 'パー'
  }
  return cpHand
}

/**
 * じゃんけんの勝ち負けを判定します。
 * @param {string} userHand - ユーザの出した手
 * @param {string} cpHand - コンピュータの出した手
 * @return {string} - message 判定結果
 */
function hantei(userHand, cpHand){
  let message = ''
  /**ユーザの手を数値化する。(グー:0、チョキ:1、パー:2) */
  const userHandNum = transformHand(userHand)
  /**コンピュータの手を数値化する。(グー:0、チョキ:1、パー:2) */
  const cpHandNum = transformHand(cpHand)
  /**判定値を算出((自分の手 - 相手の手)+3)%3 */
  const hanteiNum = ((userHandNum - cpHandNum)+3)%3

  if(hanteiNum == 0){
    message = 'あいこです。(あなた:'+userHand + '、CP:'+ cpHand +')'
  }else if(hanteiNum == 1){
    message = 'あなたの負けです。(あなた:'+userHand + '、CP:'+ cpHand +')'
  }else{
    message = 'あなたの勝ちです。(あなた:'+userHand + '、CP:'+ cpHand +')'
  }
  return message
}
/**
 * じゃんけんの手を数値化します。
 * @param {string} userHand - ユーザの出した手
 * @return {num} - userHandNum ユーザの手の数値
 */
function transformHand(userHand){
  let userHandNum 
  if(userHand == 'グー'){
    userHandNum = 0
  } else if(userHand == 'チョキ'){
    userHandNum = 1
  }else{
    userHandNum = 2
  }
  return userHandNum
}
8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0