特定の文字を抽出して​プログラムを制御する​方法と、テーブルに複​数の単語を格納する方​法についてご教授お願​いいたします。

2 views (last 30 days)
Yuu
Yuu on 5 Dec 2019
Commented: Yuu on 17 Jan 2020
 以前、こちらにてしりとりを行うプログラムをMathWorksのstaff様にご教授いただきました。現在、そのプログラムをカスタマイズしている最中ですが、分からない事ができたため、質問いたします。
  •  質問は2点あり、1つは、しりとりを行うにあたり、文字の終わりが長音(ー)の時は、その一つ前の文字を抽出するようにしたいのですが、以下のコードでは一つ前の文字を抽出する事ができません。
T.End = cellfun(@(x) {x(end-1)}, T.Tango);を実行すると、一文字前の文字を抽出してくれるため、if文が起動していない事が原因だと推測できますが、修正する事はできませんでした。
どのように手を加えると、単語の終わりが長音の場合、一つ前の文字を抽出するように修正できるかご教授願います。
% 最後が長音の場合一文字前の文字を抽出
if T_d.End =="ー"
T_d.End = cellfun(@(x) {x(end-1)}, T_d.Tango);
end
 また、上記のコード同様に関数cellfunを使用しコンピュータが選択した単語や、ユーザーが入力した単語の最後の文字が「ン」として抽出された時に、しりとりを終了させるように記述するるもりなのです。しかし、この書き方で、長音の一つ前の文字を抽出する事や、「ン」を抽出した時にしりとりを終了させるようにする事ができない場合、他の記述方法はありますでしょうか。
  •  2つ目は、しりとりを人間とコンピュータと交互にできるようにユーザーにより入力された単語を格納するテーブルを作成しました。テーブルを作成した理由は、同じ単語を二度使えないようにするためです。しかし、現在のコードではユーザー入力された単語が上書きされてテーブルには一文字しか格納されません。コードは以下のように記述しています。
% ユーザーが入力した単語を格納するテーブルの作成
User_Input=table;
% しりとりを行うプログラム
for kk = 1:20
% ユーザーが単語を入力する
prompt = ' Your turn : ';
UI= input(prompt,'s'); % CommandWindowでユーザー入力
% テーブルU_Inputに文字を格納する
User_Input.Tango = string(UI);
% ユーザー入力した単語の最初と最後を抽出
User_Input.Start = cellfun(@(x) {x(1)}, User_Input.Tango);
User_Input.End = cellfun(@(x) {x(end)}, User_Input.Tango);
以下が実際に、テーブルに単語を格納している部分です。
% 使った単語を記録するための列(ユーザーが入力した単語)この書き方だとUser_Input内は一つの単語で上書きされる事になる
User_Input.Used = false(height(User_Input));
% 一度使用した単語以外を探す
pt = find(strcmp(User_Input.End,T_d.Start) & ~T_d.Used & ~User_Input.Used);
if isempty(pt)
disp(' Com : I could accept this Loss. ');
break;
end
pt = pt(randi(numel(pt))); %"ン"で終わる単語を選ぶ確率の調整必要
fprintf(' Com : %s \n',T_d.Tango{pt});
T_d.Used(pt) = true;
end
上記のfor文内でも、テーブルに複数の単語を格納する事ができるようにはどのように書き直すとよろしいでしょうか。
実際に使用しているmファイルと、csvファイルを添付いたしますので参考にしてください。
よろしくお願いいたします。

Accepted Answer

Akira Agata
Akira Agata on 6 Dec 2019
前回に引き続き、ちょっと面白そうなので少し考えてみました。
ざっと以下のようなプログラムになるかと思います。
ご質問の2点については、コメント欄に「★」をつけた部分になります。参考になれば幸いです。
% テーブルd(ictionary)の作成
T_d = readtable('list.csv','ReadVariableNames',false);
% 単語の列を抽出
T_d = T_d(:,{'Var2'});
T_d.Properties.VariableNames = {'Tango'};
% 重複を消す(一応)
[~,ia] = unique(T_d.Tango);
T_d = T_d(ia,:);
% 始めと終わりの文字の抽出
T_d.Start = cellfun(@(x) {x(1)}, T_d.Tango);
T_d.End = cellfun(@(x) {x(end)}, T_d.Tango);
% ★最後が長音の場合一文字前の文字を抽出
idx = strcmp(T_d.End,'ー');
T_d.End(idx) = cellfun(@(x) {x(end-1)}, T_d.Tango(idx));
% 使った単語を記録するための列(コンピュータ側)
T_d.Used = false(height(T_d),1);
% ランダムで最初の単語を選択(人が入力する形式に変更予定)
pt = randi(height(T_d));
fprintf(' Com : %s \n',T_d.Tango{pt});
T_d.Used(pt) = true;
% ★ユーザーが入力した単語を格納するテーブルを準備
varNames = T_d.Properties.VariableNames;
User_Input = table(...
'Size', [0 4],...
'VariableTypes',{'cell','cell','cell','logical'},...
'VariableNames',varNames);
% しりとりを行うプログラム
for kk = 1:20
% ★単語の最後の文字をピックアップ
curChar = T_d.End(pt);
% ★「ン」だったらアウト!
if strcmp(curChar,'ン')
errordlg('Game Over!','End');
break;
end
% ユーザーが単語を入力する
prompt = ' Your turn : ';
UI= input(prompt,'s'); % CommandWindowでユーザー入力
% ちゃんとしりとりになってなかったらアウト!
if ~strcmp(UI(1), curChar)
errordlg('Game Over!','End');
break;
end
% ★単語の最後の文字をピックアップ
curChar = UI(end);
% ★「ン」だったらアウト!
if strcmp(curChar,'ン')
errordlg('Game Over!','End');
end
% ★テーブルに追加
if strcmp(UI(end),'ー')
User_Input = [User_Input; {UI, UI(1), UI(end-1), true}]; %#ok
else
User_Input = [User_Input; {UI, UI(1), UI(end), true}]; %#ok
end
% 一度使用した単語以外を探す(注:User_Inputは使用済みの単語しか入っていないためUser_Input.Usedは確認しなくて良い)
pt = find(strcmp(User_Input.End(end),T_d.Start) & ~T_d.Used);
if isempty(pt)
disp(' Com : I could accept this Loss. ');
break;
end
pt = pt(randi(numel(pt))); %"ン"で終わる単語を選ぶ確率の調整必要
fprintf(' Com : %s \n',T_d.Tango{pt});
T_d.Used(pt) = true;
end
  1 Comment
Yuu
Yuu on 17 Jan 2020
いつもお世話になっております。
ご連絡遅くなり申し訳ございません。早速、プログラムを組んでみたいと思います。
ありがとうございました。

Sign in to comment.

More Answers (0)

Categories

Find more on 起動と終了 in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!