LoginSignup
8
3

More than 3 years have passed since last update.

C++で湯婆婆を実装してみる

Last updated at Posted at 2020-11-08

はじめに

@Nemesis さんの Javaで湯婆婆を実装してみる が話題になっていたので便乗しました。

コード

yubaba.cpp
#include <algorithm>
#include <codecvt>
#include <iostream>
#include <locale>
#include <random>
#include <string>

using std::cout;
using std::endl;

int main()
{
  setlocale(LC_ALL, "ja_JP.UTF-8");

  std::string name_u8;
  std::u32string name;
  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
  std::random_device rnd;

  cout << "契約書だよ。そこに名前を書きな。" << endl;
  getline(std::cin, name_u8);
  cout << "フン。" << name_u8 << "というのかい。贅沢な名だねぇ。" << endl;

  name = utf32conv.from_bytes(name_u8); //名前を奪いやすくするためにUTF-32に変換
  name = name.substr(rnd() % name.size(), 1); // 適当な一字を拾って名前を奪う
  name_u8 = utf32conv.to_bytes(name); // UTF-8に戻す

  cout << "今からお前の名前は" << name_u8 << "だ。"
    "いいかい、" << name_u8 << "だよ。分かったら返事をするんだ、" << name_u8 << "!!" << endl;

  return 0;
}

Wandbox で湯婆婆を実行してみる

実行結果

千尋

契約書だよ。そこに名前を書きな。
千尋
フン。千尋というのかい。贅沢な名だねぇ。
今からお前の名前は尋だ。いいかい、尋だよ。分かったら返事をするんだ、尋!!

Chihiro

契約書だよ。そこに名前を書きな。
Chihiro
フン。Chihiroというのかい。贅沢な名だねぇ。
今からお前の名前はrだ。いいかい、rだよ。分かったら返事をするんだ、r!!

解説

名前を入力してもらう

getline(std::cin, name_u8);

std::cin >> name_u8; としてそのまま入力を受けてもいいのですが、それだと何か入力しないと受け付けてもらえないので、getline() を使用しました。

名前を奪う

name = utf32conv.from_bytes(name_u8); //名前を奪いやすくするためにUTF-32に変換
name = name.substr(rnd() % name.size(), 1); // 適当な一字を拾って名前を奪う
name_u8 = utf32conv.to_bytes(name); // UTF-8に戻す

入力されたマルチバイトな文字列から文字を抜き取るのには工夫が必要なため、一旦 1 文字あたりのバイト数が固定の UTF-32 に変換し、扱いやすくしてから一字奪っています。
一字奪うときの乱数生成機には random_device クラスを使い、剰余演算で入力された文字列の中から奪えるように調整しています。

※剰余演算で調整すると偏りができるので、等確率な乱数を求めるなら uniform_int_distribution クラスを使って値を絞ったほうが良いです。

おまけ

未入力時は rnd() % name.size() の箇所で浮動小数点例外が発生し、ちゃんとクラッシュします。

契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
浮動小数点例外
8
3
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
3