by NoWest » 2009年8月11日(火) 21:02
オセロですか。
なかなか面白そうなことをしているんですね。
オセロのアルゴリズムの研究でもしない限り、速度はあんまり気にしなくても
良い気がしますが、ゲームだとサクサク感も重要だったりしますよね。
あまり、役に立たないと思いますが、
こんな方法もあると言うことだけご紹介しておきます。
Select Case文を使用して関数を呼び出す方法は
線形探索法という
探索アルゴリズムと同等の構造をしていて、
呼び出されている関数に偏りがあった場合、
条件判断の回数が増減しますので
全体の計算速度がかなり遅くなったり、逆に速くなったりします。
一方、takさんが紹介されたプログラムは
ハッシュ法と呼ばれる
探索アルゴリズムを応用した、関数の呼び出し方です。
この場合、呼び出そうとする関数を一発で配列から取り出せるので、
最も高速な方法だと言えます。
ただし、配列を予め用意しないといけませんのでプログラムが大きくなります。
これを踏まえて、私の作ったプログラムを見てください。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
#N88BASIC
Dim f As DWord
Dim ff As DWord
Dim i As Long
*start
f=0
ff=0
i=0
Input "0~63の数値を入力してください>",f
if f > 63 then
Print "入力された数値は範囲内にありません"
goto *start
End If
Sub PRT(i As Long, ff As DWord)
Print Ex"分岐までの比較回数",i
Print Ex"入力された数値",ff
End Sub
i++
If f AND 32 Then
i++
ff+=32
If f AND 16 Then
i++
ff+=16
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
Else
i++
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
End If
Else
i++
If f AND 16 Then
i++
ff+=16
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
Else
i++
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
End If
End If
goto *start
これは特殊な条件がそろわないと使えない分岐方法ですが、
今回のように0~63の間で分岐する場合、
どの数値を入力しても、条件判断回数が6回となり、
安定して使えます。
一般にアルゴリズムは
時間と空間のトレードオフといわれています。
SelectCaseを使う方法では速度が遅い分、リソースの量は少なくてすみます。
配列と関数ポインタの場合は、速度が速い分、配列という形で
メモリーのリソースを余分に消費している訳です。
プログラムはほんの少しの工夫で速くなったり、プログラムを小さくできるので
奥が深いですね。
アルゴリズムも書籍でいろいろと紹介されているので、
一読してみると面白いと思いますよ。
オセロですか。
なかなか面白そうなことをしているんですね。
オセロのアルゴリズムの研究でもしない限り、速度はあんまり気にしなくても
良い気がしますが、ゲームだとサクサク感も重要だったりしますよね。
あまり、役に立たないと思いますが、
こんな方法もあると言うことだけご紹介しておきます。
Select Case文を使用して関数を呼び出す方法は[b]線形探索法[/b]という
探索アルゴリズムと同等の構造をしていて、
呼び出されている関数に偏りがあった場合、
条件判断の回数が増減しますので
全体の計算速度がかなり遅くなったり、逆に速くなったりします。
一方、takさんが紹介されたプログラムは[b]ハッシュ法[/b]と呼ばれる
探索アルゴリズムを応用した、関数の呼び出し方です。
この場合、呼び出そうとする関数を一発で配列から取り出せるので、
最も高速な方法だと言えます。
ただし、配列を予め用意しないといけませんのでプログラムが大きくなります。
これを踏まえて、私の作ったプログラムを見てください。
[hide][code]#N88BASIC
Dim f As DWord
Dim ff As DWord
Dim i As Long
*start
f=0
ff=0
i=0
Input "0~63の数値を入力してください>",f
if f > 63 then
Print "入力された数値は範囲内にありません"
goto *start
End If
Sub PRT(i As Long, ff As DWord)
Print Ex"分岐までの比較回数",i
Print Ex"入力された数値",ff
End Sub
i++
If f AND 32 Then
i++
ff+=32
If f AND 16 Then
i++
ff+=16
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
Else
i++
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
End If
Else
i++
If f AND 16 Then
i++
ff+=16
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
Else
i++
If f AND 8 Then
i++
ff+=8
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
Else
i++
If f AND 4 Then
i++
ff+=4
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
Else
i++
If f AND 2 Then
i++
ff+=2
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
Else
i++
If f AND 1 Then
ff+=1
PRT(i,ff)
Else
PRT(i,ff)
End If
End If
End If
End If
End If
End If
goto *start
[/code][/hide]
これは特殊な条件がそろわないと使えない分岐方法ですが、
今回のように0~63の間で分岐する場合、
どの数値を入力しても、条件判断回数が6回となり、
安定して使えます。
一般にアルゴリズムは[b]時間と空間のトレードオフ[/b]といわれています。
SelectCaseを使う方法では速度が遅い分、リソースの量は少なくてすみます。
配列と関数ポインタの場合は、速度が速い分、配列という形で
メモリーのリソースを余分に消費している訳です。
プログラムはほんの少しの工夫で速くなったり、プログラムを小さくできるので
奥が深いですね。
アルゴリズムも書籍でいろいろと紹介されているので、
一読してみると面白いと思いますよ。