|
 |
|
2015/3/3(Tue) 15:14:14|NO.67648
フォルダに入っている画像をランダムに1枚表示し
画像が何か答えるクイズゲームを作っています
答えはファイル名から抽出し3択という仕様です
例:ハードディスクの画像が表示されたら
1.ハードディスク
2.メモリ
3.CPU
といった具合にしたいのですが、今のコードですと
1.ハードディスク.jpg
2.ハードディスク.jpg
3.メモリ.jpg
答えが被ってしまうことがあります。
被らないようにするにはどのように修正するのがいいでしょうか?
よろしくお願いします
#include "hsp3util.as" ;フォント命令を使うのに使用
;準備
celload "waku.png",1
x=30 : y=490
randomize
currentdir = dir_cur
dir = "写真\\" ;パスの\を\\に変えるのを忘れずに
chdir dir ;カレントフォルダの移動
list = ""
dirlist list,"*.jpg",1;写真フォルダのファイル名一覧を取得
filenum = stat ;取得したファイル数//17
;chdir currentdir ;実行ファイルのあるカレントディレクトリに移動する。 C:Userizutani\Desktop\問題
notesel list
*問題
time = 0
noteget filename,rnd(filenum)
picload filename
pos 10,420
gmode 2
celput 1 ;ウインドウコピー
pos 30,460
color 255,255,255
text 100 : font "MS Pゴシック", 30, 1
color 255,0,0
emes "これは何ですか?"
pos 0,0
location = rnd(3)+1 ;問題の位置をランダムに変える
gosub *monndai
gosub *選択待ち
gosub *判定
goto *問題
stop
*選択待ち
ans = 0
pos 300,500
getkey key1,97 ; テンキー「1」の入力チェック
getkey key2,98 ; テンキー「2」の入力チェック
getkey key3,99 ; テンキー「3」の入力チェック
wait 10
TIME ++ ;問題を解くのに掛った時間
title "タイマー" + TIME;残り時間を表示
if key1=1{ ; キー「1」が押されていたら
mes "1番のキーが押されました"
ans = 1 ; 解答は1
return
}
if key2=1{ ; キー「2」が押されていたら
mes "2番のキーが押されました"
ans = 2 ; 解答は2
return
}
if key3=1{ ; キー「2」が押されていたら
mes "3番のキーが押されました"
ans = 3 ; 解答は3
return
}
await 16 ; 待ち時間
goto *選択待ち ; 「*選択待ち」へジャンプ
*判定
if( ans == location) : mes "正解"
await 100
return
*monndai
color 255,255,255
if( location = 1 ) : pos 30,490 : mes filename + "←"
if( location = 2 ) : pos 30,520 : mes filename + "←"
if( location = 3 ) : pos 30,550 : mes filename + "←"
*monndai2
y+=30
pos x,y
noteget filename2,rnd(filenum)
if( filename2 == filename ) : goto *monndai2
if( location = 1 ) : pos 30,520 : mes filename2
if( location = 2 ) : pos 30,550 : mes filename2
if( location = 3 ) : pos 30,490 : mes filename2
*monndai3
y+=30
noteget filename3,rnd(filenum)
if( filename3 == filename2 ) : goto *monndai3
if( filename3 == filename ) : goto *monndai3
if( location = 1 ) : pos 30,550 : mes filename3
if( location = 2 ) : pos 30,490 : mes filename3
if( location = 3 ) : pos 30,520 : mes filename2
return

| |
|
2015/3/3(Tue) 15:52:47|NO.67649
問題を簡単化して考えましょう。
ファイルがどうの名前がどうのという問題はひとまず忘れて数の問題に落としこみます。
何事もまず数の問題から出発です。(電算機ってそういうものでしょ。)
10個の非負整数 0,1,2,…,9 の中から
rnd 関数を使って3つの数を重複せずにランダム(っぽく)に選び出すだけの手続きを考えてみましょう。
これができれば、10とか3といった数をm,nとして一般化し、作りたいゲームに応用するだけです。
配列変数を利用するとよいでしょう。
[ヒント]
rnd(10)で同じ値が2度以上出たら2度目以降その値は無視して、まだ一度も出たことのない値が出るまで試行を繰り返す。
rndを信用すれば無限ループにはならないはず。
もっとエレガントなやり方もありそうですが、とりあえずこれでやってみてはどうでしょうか?
|
|
2015/3/3(Tue) 23:22:20|NO.67665
これはランダムよりシャッフルの方が良いと思う
randomize
notesel list
dirlist list,"*.jpg",1
filenum = stat
mes list
repeat filenum //シャッフル
noteget filename,cnt
notedel cnt
noteadd filename,rnd(filenum),0
loop
pos 200,0
mes list
|
|
2015/3/4(Wed) 00:00:22|NO.67668
>暇人 さん
お見事です。
note系命令はそういうところが便利ですからね。
>ノダッシー さん
一番最初に与えたヒントでは実はマズいのです。
母集団の要素数が10000、サンプル数が9000等のように大きな数になってくると
無限ループを回避できても、フリーズの危険が出てきます。
ノダッシー さんに気づいて突っ込んでほしかったのですが、正解が提示されてしまったのでこのへんにしときます。
ちなみに、配列でシャッフルするならmemcpyがおすすめです。
repeat〜loopで1要素ずつスライドするより低コストです。
また、シャッフルでなくてもランダム入れ替えという手もあります。
母集団から重複を許してランダムに2つ要素を選んで入れ替えるという操作を適当回数(サンプル数/2 + 1 回くらいでいいんじゃないでしょうか)繰り返してください。
|
|
2015/3/4(Wed) 13:15:06|NO.67671
FunnyMakerさん暇人さん返信ありがとうございます
暇人さんの提示して頂いたシャッフルを使えば問題をダブらずに出題できるところまでは出来たのですが
解答(ファイル名から3つ抽出)を被らないようにするにはどうしたらいいでしょうか?
文字列の比較または、他に方法がありましたお願いします
フォルダには
1_ハードディスク.jpg
2_ハードディスク.jpg
3_aキバン.jpg
4_aキバン.jpg
5_aキバン.jpg
6_bキバン.jpg
7_bキバン.jpg
8_cキバン.jpg
9_スクラップ.jpg
10_スクラップ.jpg
11_プラスチック.jpg
12_プラスチック.jpg
13_プラスチック.jpg
14_プラスチック.jpg
15_フレキ.jpg
16_ゴウキン.jpg
17_ゴウキン.jpg
と、今後も追加する予定です
|
|
2015/3/4(Wed) 13:18:32|NO.67672
この場合
ハードディスクの画像が表示され
選択肢に
1_ハードディスク.jpg
2_ハードディスク.jpg
12_プラスチック
のようにハードディスクが2つ出てしまうのが好ましくありません
設計をこうした方がいい等アドバイス的なものでも構わないので何かありましたらご教示下さい
|
|
2015/3/4(Wed) 13:29:35|NO.67673
ん? なんか不思議ですね。
例えば、
「1_ハードディスク.jpg」と「2_ハードディスク.jpg」の「1」,「2」というのはどういう意味ですか?
問題番号のことですか?
|
|
2015/3/4(Wed) 16:43:13|NO.67675
識別子2個で区別したらどうですか?
1_A_ハードディスク.jpg
2_A_ハードディスク.jpg
として"_"でsplitかけるみたいな
|
|
2015/3/4(Wed) 17:14:22|NO.67676
識別子2個あるのもあるみたいなんで識別子3個にするとか
1_A_x_ハードディスク.jpg
2_A_x_ハードディスク.jpg
3_B_a_キバン.jpg
4_B_a_キバン.jpg
5_B_a_キバン.jpg
6_C_b_キバン.jpg
7_C_b_キバン.jpg
8_D_c_キバン.jpg
9_E_x_スクラップ.jpg
10_E_x_スクラップ.jpg
11_E_x_プラスチック.jpg
12_E_x_プラスチック.jpg
13_E_x_プラスチック.jpg
14_E_x_プラスチック.jpg
15_F_x_フレキ.jpg
16_G_x_ゴウキン.jpg
17_G_x_ゴウキン.jpg
|
|
2015/3/4(Wed) 20:00:20|NO.67691
シャッフルでもやってるが
選択肢として使ったのはnotedelで削除しちゃえば良い
font "MS Pゴシック", 30, 1
randomize
notesel list
dirlist list,"*.jpg",1
filenum = stat
repeat filenum //シャッフル
noteget filename,cnt
notedel cnt
noteadd filename,rnd(filenum),0
loop
mno=0
*問題
if mno=filenum {title "正解数"+anscnt+"/"+filenum+" 終了":stop}
notesel list
title "問題数"+(mno+1)+"/"+filenum
noteget filename,mno
gradf 0,0,640,480,1,$004488,$112244
//picload filename
list_tmp=list //一旦リストをコピー
notesel list_tmp //note系を使うので
notedel mno //問題に使ったのは削除
dmans=rnd(notemax) //不正解の選択肢ナンバー
noteget filename2,dmans //不正解の名前
notedel dmans //取り出したので削除
dmans=rnd(notemax)
noteget filename3,dmans
color 255,0,0
pos 50,200
mes "これは何ですか?"
color 255,255,255
location = rnd(3)+1 ;問題の位置をランダムに変える
repeat 3
pos 30,300+((cnt+location-1)\3)*30
if cnt=0 {mes filename+"←"}
if cnt=1 {mes filename2}
if cnt=2 {mes filename3}
loop
TIME=0
repeat
wait 10
title "正解数"+anscnt+"/"+filenum+" タイム "+TIME
TIME++
getkey key1,97 ; テンキー「1」の入力チェック
getkey key2,98 ; テンキー「2」の入力チェック
getkey key3,99 ; テンキー「3」の入力チェック
pos 0,420
if key1=1{ ; キー「1」が押されていたら
mes "1番のキーが押されました"
ans = 1 ; 解答は1
break
}
if key2=1{ ; キー「2」が押されていたら
mes "2番のキーが押されました"
ans = 2 ; 解答は2
break
}
if key3=1{ ; キー「2」が押されていたら
mes "3番のキーが押されました"
ans = 3 ; 解答は3
break
}
loop
if( ans == location) {mes "正解":anscnt++}else{mes "不正解"}
await 1000
mno++ //次の問題にシフト
goto *問題

| |
|
2015/3/5(Thu) 15:03:22|NO.67702
FunnyMakerさん
y.tackさん
暇人さん
アドバイスと素敵なスクリプトありがとうございました
|
|