HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2011
0115
モフモフクイズのランダム出題について8解決


モフモフ

リンク

2011/1/15(Sat) 22:34:53|NO.36622

はじめまして、みなさんよろしくお願いします^^

クイズのスクリプトを作成していて、ランダム出題させる事はできるのですが、
正解を入力しても不正解になってしまいます。

rndを使わなければ問題ないのですが、自分的に推測すると問題が出題されると
同時に答えが入力されていないと(変数に入っていないと)判定がされないのではと思っています。

出題は外部ファイルから出題させています。


【出題のテキスト】
答え,,,,問題

【スクリプト】

///メニュー項目 text="0" point=10 : i=0 noteload "Lesson1_Lv1.txt"//参照ファイル。 mmplay 0 goto *main /// *main //バグ対策・マイナス終了 if point=-1{ pos 150,200 mes "ポイントがマイナス値です^−^;\n   終了します!" wait 200 end } /// ///メッセージの表示方法 clrobj pos 400,2 mes "Point : "+point pos 10,2 noteget y,sc split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) pos 20,180 mes moj(0) mes moj(1) mes moj(2) mes moj(3) mes moj(4) sc+ : i=i+strsize /// //入力フォーム pos 50,150 input text,150,20,50 objsel 0 noteget y,sc-2 split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) if text=kotae{ ans=1//正解フラグ } if text!kotae{ ans=2 } if text=0{ ans=0 } //フラグの処理 switch ans //判定対象の変数 case 0 swbreak case 1 mmplay 2 swbreak case 2 mmplay 3 point-1 swbreak swend /// ///ランダム出題(仮) randomize sc=rnd(9) /// //クリアフラグ if fura=9{ pos 100,200 mes "おめでとう! クリアです^−^v" pos 150,220 objsize 100,20 button "メニューへ戻る",*start stop } /// ///ポイントの処理 if point=-1{//Pointが0になると終了 goto,*start } /// //keyが押されたときの処理 onkey *keys stop *keys check1=wparam if check1==13 : cls : goto,*main ///



この記事に返信する


玄冬

リンク

2011/1/16(Sun) 02:26:01|NO.36624

モフモフさんの貼られたスクリプトは*startとnoteselがないので、動きませんでした。
スクリプトを貼る際は、最低限コピペすれば動く&質問に不必要な部分は削る(mmplayなど)して頂くと回答しやすいです。

ぱっと見る限り
ランダム化を毎回rnd(9)としているようですが、これでは重複が起こるのでは?

スクリプト動かなかったので良くわかりませんがこういうのですか?

#module #deffunc f_array_shafful array p_LIST, local l_temp, local l_n foreach p_LIST l_n = cnt + rnd(length(p_LIST) - cnt) l_temp = p_LIST(l_n) p_LIST(l_n) = p_LIST(cnt) p_LIST(cnt) = l_temp loop return #global randomize a_Q = "zero","one", "two", "three" sdim a_A, 50, 5, length(a_Q) a_A(0,0) = "ゼロ", "れい", "レイ", "零", "ぜろ" a_A(0,1) = "いち", "イチ", "壱", "一" a_A(0,2) = "に", "ニ", "二", "弐" a_A(0,3) = "さん", "サン", "三", "参" sdim a_RES, 50,length(a_Q) repeat length(a_Q) a_ORDER(cnt) = cnt loop f_array_shafful a_ORDER(cnt) v_n = -1 *main v_n++ if length(a_Q) <= v_n : goto *last cls color mes "第"+(v_n+1)+"問:"+ a_Q(a_ORDER(v_n)) +"を日本語にせよ。" input a_RES(a_ORDER(v_n)) button "解答!", *check stop *check cls v_check = 0 repeat length(a_A) if a_RES(a_ORDER(v_n)) ! "" & a_RES(a_ORDER(v_n)) = a_A(cnt, a_ORDER(v_n)) : v_check++:break loop if v_check : color $ff : mes "○":v_point += 10 : else :color 0,0,$ff : mes "×" button "次の問題へ", *main stop *last cls mes "あなたの得点は"+v_point+"点です。" wait 50 end



ORZ

リンク

2011/1/16(Sun) 11:48:35|NO.36626

結局何が聞きたいのか書かれていないので、きちんと質問の内容を書くこと。

それはさておき、答えを2回読み込んだり無駄な処理があるように思う。
2回目に回答を読み込むときにずれたりするだろうから、もう一度プログラムの流れを自分で整理してみること。



モフモフ

リンク

2011/1/16(Sun) 12:13:07|NO.36627

玄冬さん、ORZさん、レスありがとうございます。

ご指摘のとおり動作確認を怠りました^^;
内容としては、玄冬さんが作っていただいたスクリプトが理想的です。
ただ、自分は初心者なので玄冬さんが書いていただいたスクリプトを理解するには、
かなり時間を要すると思います^^;

重複についても課題なのですが、とりあえずランダム出題をさせることを目的としています。

質問内容としては、ユーザーが入力したtextとkotaeを一致させるにはどうしたらよいかという事です。
ORZさんの仰るとおり無駄な処理があるんだろうとは思っていのですが、具体的にどの辺りが無駄なのかがわからなかったので
もう一度処理の流れを確認したいと思います^^;

お手数をお掛けして申し訳ないですが、修正したスクリプトを載せましたのでご教授お願いします。


【スクリプト内容】

sdim buf,32000 buf="price,,,,名詞:値段\npopulation,,,,名詞:人口\nbark,,,,動詞:吠える\npolitician,,,,名詞:政治家\nclever,,,,形容詞:利口な、賢い\nexpedition,,,,名詞:探検" notesel buf //スタート画面 *start sc=0//インデックスの初期化 objsize 95,20 //ボタンのサイズ pos 1,251 button "単語の綴り",*tuduri stop /// ///メニュー項目 *tuduri text="0" point=10 goto *main /// *main //バグ対策・マイナス終了 if point=-1{ pos 150,200 mes "ポイントがマイナス値です^−^;\n   終了します!" wait 200 end } /// ///メッセージの表示方法 clrobj pos 0,0 mes "Point : "+point noteget y,sc split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) pos 20,180 mes moj(0) mes moj(1) mes moj(2) mes moj(3) mes moj(4) sc+ : i=i+strsize /// //入力フォーム pos 50,150 input text,150,20,50 objsel 0 noteget y,sc-2 split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) if text=kotae{ ans=1//正解フラグ } if text!kotae{ ans=2 } if text=0{ ans=0 } /// //フラグの処理 switch ans //判定対象の変数 case 0 swbreak case 1 pos 100,100 mes "正解!" swbreak case 2 pos 100,100 mes "不正解!" point-1 swbreak swend /// ///ランダム出題(仮) randomize sc=rnd(5) /// //keyが押されたときの処理 onkey *keys stop *keys check1=wparam if check1==13 : cls : goto,*main ///



ORZ

リンク

2011/1/16(Sun) 12:31:39|NO.36628

動作うんぬんは知らんが明らかに劣化しているのでソースはきちんとインデントすること。
別にレスがついたからあわててレスすることはない。

noteget y,sc split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) /*---略---*/ sc+ : i=i+strsize /*---略---*/ //入力フォーム pos 50,150 input text,150,20,50 objsel 0 noteget y,sc-2 split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4)
一回目で回答を読みだしているにも関わらず、入力フォームのとこでもう一度答え読みだしている。
一回目で得られた回答をどっか変数に保管しておけば、読み込む場所を間違うなんてミスは防げる。
それでもわからないとかなんとかいっちゃう場合は

sc=0 mes sc sc+ mes sc mes sc-2
を実行しなさい。



ORZ

リンク

2011/1/16(Sun) 12:40:54|NO.36629

いま実行してみて思ったんだけどプログラムの流れが根本的におかしいことがわかった。
プログラムの流れが
・最初の問題を決める
・表示する
・入力ボックスを出す
・採点する
・次の問題を決める
・止まる

となっている。これでは正解できる確率がそもそも1/問題数になる。これを
・問題を決める
・表示する
・入力ボックスを出す
・とまる
・採点する
・問題を決める、に戻る

としなければならない。どのサンプルを見ててこういう結論に至ったのかわからんが
もっと簡単なクイズサンプルとか無かったの?



ORZ

リンク

2011/1/16(Sun) 13:02:31|NO.36630

ということで無駄を消しつつ書いた。

sdim buf,32000 buf="price,,,,名詞:値段\npopulation,,,,名詞:人口\nbark,,,,動詞:吠える\npolitician,,,,名詞:政治家\nclever,,,,形容詞:利口な、賢い\nexpedition,,,,名詞:探検" notesel buf objsize 95,20 //ボタンのサイズ randomize point=10 *main text="" pos 0,0 mes "Point : "+point gosub *randomselect gosub *getq gosub *inputform onkey *keys stop *getq noteget y,sc split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) pos 20,180 mes moj(0) return *inputform //入力フォーム pos 50,150 input text,150,20,50 objsel 0 return *saiten if text=kotae{ ans=1//正解フラグ } if text!kotae{ ans=2 } if text=0{ ans=0 } /// //フラグの処理 switch ans //判定対象の変数 case 0 swbreak case 1 pos 100,100 mes "正解!" swbreak case 2 pos 100,100 mes "不正解!" swbreak swend return *keys check1=wparam if check1==13 :{ cls gosub *saiten goto *main } stop *randomselect sc=rnd(5) return
最初は大まかな機能ごとにサブルーチン化してメインループから飛ぶとよいと
少なくとも俺が持ってるHSP2.55プログラミング入門には書いてある。
こうすると意味不明なコメントを入れながらメインにだらだら書くより少しはわかりやすいかも。
サンプルをよく探せばいいものはどっかにあるはずなので探すこと。もし「ここを見ながらつくったらこうなったんです><」
というサイトがあるなら、そこの管理人をぶん殴っておきなさい。



玄冬

リンク

2011/1/16(Sun) 17:51:32|NO.36638

モフモフさんが書いたスクリプトの画面構成はできるだけ変えずに
私が最初に書いたランダム化を移植して見ました。
気になった所や手を加えたところは
全て;!でコメントしてあります。
参考にして頂けると幸いです。

>>最初は大まかな機能ごとにサブルーチン化してメインループから飛ぶとよい
構造化プログラミングの基本ですね。
その通りだと思います。

小さいプログラムで細かく分けすぎると、
却って見づらくなることもあるので
今回は*mainを分割しませんでしたが、
スクリプトをこれ以上大きくするのであれば、
ORZさんのスクリプトを参考にmainを
分割することをお勧めいたします。


#module ;!配列の順番をランダムに入れ替える命令 例 0,1,2,3→3,1,0,2など #deffunc f_array_shafful array p_LIST, local l_temp, local l_n foreach p_LIST l_n = cnt + rnd(length(p_LIST) - cnt) l_temp = p_LIST(l_n) p_LIST(l_n) = p_LIST(cnt) p_LIST(cnt) = l_temp loop return #global randomize ;!起動につき1回で十分 sdim buf,32000 buf="price,,,,名詞:値段\npopulation,,,,名詞:人口\nbark,,,,動詞:吠える\npolitician,,,,名詞:政治家\nclever,,,,形容詞:利口な、賢い\nexpedition,,,,名詞:探検" notesel buf ;!ランダム化 dim ORDER,notemax ;!順番制御用配列。notemaxはnoteselの行数(詳しくはF1参照のこと) repeat notemax ;!ORDER=0,1,2,3,…と同等。問題文(行)の数だけ数が入る ORDER(cnt) = cnt loop f_array_shafful ORDER ;!順番をシャッフル *start ;スタート画面 cls point=10 loop_cnt = 0 ;!今何問目なのかを入れておく pos 1,251 button "単語の綴り", *main stop *main sc = ORDER(loop_cnt) ;!シャッフルした行数をscに代入 loop_cnt++ ;!更新 text = "" ;!textの初期値を空白に変更 ;課題取り出し noteget y,sc split y,",",kotae,bgm,pic,fura,moj(0), moj(1), moj(2) ,moj(3),moj(4) ;画面表示 cls ;画面クリアをclsに変更 if point < 0{ ;!何らかの不具合でいきなり-2になったとき=-1ではとまらないので<0に変更 pos 150,200 mes "ポイントがマイナス値です^−^;\n   終了します!" wait 200 end } pos 0,0 mes "Point : "+ point pos 20,180 mes "第"+loop_cnt+"問" ;!loop_cntの挙動チェックのため勝手に加えました。いらなきゃ消して下さい mes moj(0) mes moj(1) mes moj(2) mes moj(3) mes moj(4) pos 50,150 input text, 150, 20, 50 onkey *check ;!ジャンプ先の名称変更…意味なし stop *check if wparam = 13 & text ! "" { ;!if text=0をtextの空欄判定と解釈、最初に持ってきました。enterキーの判定も同時に if text = kotae { ;!ansをswitchに渡すより判定時に直接処理したほうがよろしいかと pos 100,100 mes "正解!" } else { ;!elseに変更 pos 100,100 mes "不正解!" point - 1 } if notemax <= loop_cnt : goto *last : else : goto *main ;!出題数が問題数を超えたら*lastに、まだなら*mainに } stop *last ;!一番最初のスクリプトより移植 cls pos 100,200 mes "おめでとう! クリアです^−^v" pos 150,220 objsize 100,20 button "メニューへ戻る", *start ;!*startの位置は変えてないので戻るたびにlvが上がるようにする際はもっと上にスタートを移して下さい。 stop stop



モフモフ

リンク

2011/1/16(Sun) 18:26:18|NO.36641

ORZさん、玄冬さん、大変わかりやすい解説ありがとうございます^^

一応、HSP3.2の入門書を一読はしたのですが、クイズのサンプルはなかったのでノベルゲームのスクリプトを改良して作成しました^^;
他者のスクリプトも見たのですが、難解なスクリプトだったのでシンプル(自分的には)にできないだろうか? ということで、
リファレンスマニュアル片手にコツコツ作っていました。(ぜんぜんシンプルじゃなかったですね>< むしろカオスな状態でw)

今一度、基本に戻ってプログラムの勉強をしたいと思います^^
貴重な時間を割いて、解説及びスクリプトの作成をしていただいてありがとうございましたm(_ _)m



ONION software Copyright 1997-2023(c) All rights reserved.