|
|
|
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
| |
|
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
///
| |
|
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
を実行しなさい。
|
|
2011/1/16(Sun) 12:40:54|NO.36629
いま実行してみて思ったんだけどプログラムの流れが根本的におかしいことがわかった。
プログラムの流れが
・最初の問題を決める
・表示する
・入力ボックスを出す
・採点する
・次の問題を決める
・止まる
となっている。これでは正解できる確率がそもそも1/問題数になる。これを
・問題を決める
・表示する
・入力ボックスを出す
・とまる
・採点する
・問題を決める、に戻る
としなければならない。どのサンプルを見ててこういう結論に至ったのかわからんが
もっと簡単なクイズサンプルとか無かったの?
|
|
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
|
|