Gadget ›› FreeGadget

プログラム言語 FreeBasic


FreeGadget

構文

Sub FreeGadget(ByVal gadget As Long)

内容

ガジェットを削除して、メモリリソースを解放します。

オプション

gadget - ガジェットの識別子(番号)

プラットホーム

Windows , Linux


例1:

'FreeGadget

#Include "window9.bi"

Dim As integer hwnd,event
hwnd=OpenWindow("1",300,100,250,150)
ButtonGadget(1,10,10,80,80,"click!")
Dim counter As Integer

Do while counter = 0
   event=WaitEvent()
   If event=EventClose Then End
   If event=EventGadget Then
      FreeGadget(1)
      ButtonImageGadget(1,10,10,80,80)
      SetImageGadget(1,Load_image("merlin.gif"))
      counter = counter + 1
   EndIf
Loop

Do while counter = 1
   event=WaitEvent()
   If event=EventClose Then End
   If event=EventGadget Then
      FreeGadget(1)
      ButtonImageGadget(1,10,10,80,80)
      SetImageGadget(1,Load_image("Transpar.png"))
   EndIf
Loop

クリックすると→クリック後クリックすると→クリック後

画像切替えの例

例2:

プログラムに使う画像ファイル→MontyHallGame.zip

イベント駆動型プログラムを作って私が学んだことは、
1.それぞれのイベント Loop を、それぞれ Sub として切り出す。
2.そのイベントをトリガーにしたい処理は、Sub をコールする部分で、Do While 〜 Loop を使って、イベントの呼び出しを限定する。
こうすると、望まないイベントで、プログラムが期待しない動作を開始しないようにできる、ということです。
'MontyHallGame
'モンティ・ホールが司会を務めるゲーム
'Makoto WATANBE
'2020/05/02 rev. 2020/05/19
'Creative Commons 4.0 Attribution-NonCommercial-ShareAlike
'http://rosettacode.org/wiki/Monty_Hall_problem#FreeBASIC

#include "window9.bi"

Dim Shared hwnd As Integer
Dim Shared event9 As Integer
Dim Shared strategy As String
Dim Shared Counter As Integer
Dim Shared i As Integer
Dim Shared j As Integer
Dim Shared Monty(10) As Integer
Dim Shared Client() As Integer
Dim Shared Client1st As Integer
Dim Shared Acquisition As Integer
Dim Shared goat As Integer
Dim Shared GadgetNo As Integer
Dim Shared Hint As String
Dim Shared goatImage As Integer
Dim Shared carImage As Integer
Dim Shared carSImage As Integer
goatImage = Load_image("goat_yagiS.png")
carImage = Load_image("car.png")
carSImage = Load_image("carS.png")
Dim Shared strategyStart As String

Dim MontyHall As String = "1つの扉には景品(自動車)が隠されており、他の2つの扉には景品がありません。" & Chr(13) & Chr(10) _
& "あなたは3つの扉のうちの1つを選びます。でも、すぐには開けません。" & Chr(13) & Chr(10) _
& "モンティは他の2つの扉のうちの1つを開けますが、そこには景品ではなくヤギがいます。" & Chr(13) & Chr(10) _
& "この時点で、2つの閉じた扉があり、そのうちの1つはあなたが選択した扉です。" & Chr(13) & Chr(10) _
& "“あなたは扉の選択を変えることができますが、どうしますか?”"

'***********************************************************

Function RndDice(me As Integer) As Integer
   Randomize
   RndDice = Int(Rnd * me) + 1
End Function

'***********************************************************

Sub ChooseStrategy()
   Do
      event9 = WaitEvent
      Select Case event9
         Case EventClose
            End
         Case EventGadget
            Select Case EventNumber
               Case 1
                  strategy = "myself"
               Case 2
                  strategy = "stay"
               Case 3
                  strategy = "switch"
               Case 31  'Start
                  If strategy <> "" Then
                     strategyStart = strategy
                     Exit Do
                  EndIf
               Case 99
                  End
            End Select
      End Select
      Print "ChooseStrategy loop. strategy = "; strategy
   Loop
End Sub

'***********************************************************

Sub Select1stDoor()
   SetGadgetText(21,"3つの扉のうち1 つをマウスでクリックします。その後、「ヒント」ボタンを押します。")
   Do
      event9 = WaitEvent
      If Hint ="" Then
         Select Case event9
            Case EventClose
               End
            Case EventGadget
               Select Case EventNumber
                  Case 51
                     Client(Counter) = 1
                  Case 52     
                     Client(Counter) = 2
                  Case 53
                     Client(Counter) = 3
                  Case 99
                     End
               End Select
               If Client(Counter) > 0 Then 
                  Exit Do
               EndIf
         End Select   
      EndIf
      Print "Select1stDoor. strategy = "; strategy
   Loop
End Sub

'***********************************************************

Sub ClickHintForStaySwitch()
   Do
      event9 = WaitEvent
      Select Case event9
         Case EventClose
            End
         Case EventGadget
            Select Case EventNumber
               Case 99
                  End
               Case 32  'Hint
                  Hint ="finish"
                  Select Case Monty(Counter)
                     Case 1
                        FreeGadget(51)
                        FreeGadget(52)
                        FreeGadget(53)
                        ButtonImageGadget(51,50,280,150,200,carImage,BS_BITMAP)
                        ButtonImageGadget(52,250,280,150,200,goatImage,BS_BITMAP)
                        ButtonImageGadget(53,450,280,150,200,goatImage,BS_BITMAP)
                     Case 2
                        FreeGadget(51)
                        FreeGadget(52)
                        FreeGadget(53)
                        ButtonImageGadget(51,50,280,150,200,goatImage,BS_BITMAP)
                        ButtonImageGadget(52,250,280,150,200,carImage,BS_BITMAP)
                        ButtonImageGadget(53,450,280,150,200,goatImage,BS_BITMAP)  
                     Case 3
                        FreeGadget(51)
                        FreeGadget(52)
                        FreeGadget(53)
                        ButtonImageGadget(51,50,280,150,200,goatImage,BS_BITMAP)
                        ButtonImageGadget(52,250,280,150,200,goatImage,BS_BITMAP)
                        ButtonImageGadget(53,450,280,150,200,carImage,BS_BITMAP)
                  End Select
               Case Else
                  Exit Do
            End Select
         
            Print "Hint = "; Hint
            If counter < 10 Then
               SetGadgetText(21,"あなたは「維持 / 交換」戦略です。次に進むために、開いているドアのいずれかをクリックしてください。")
            Else
               SetGadgetText(21,"10 回終りました。右上の「終了」か「繰り返し」ボタンを押してください。")
            End If
      End Select
      Print "ClickHintForStaySwitch loop. ; "; strategy; " ; Client(Counter) = ";Client(Counter); " ; Hint = "; Hint
   Loop

End Sub

'***********************************************************

Sub ClickHintForMyself()
   Do
      event9 = WaitEvent
      Select Case event9
         Case EventClose
            End
         Case EventGadget
            Select Case EventNumber
               Case 99
                  End
               Case 32  'Hint
                  Select Case goat
                     Case 1
                        FreeGadget(51)
                        ButtonImageGadget(51,50,280,150,200,goatImage,BS_BITMAP)
                        Hint ="finish"
                     Case 2
                        FreeGadget(52)
                        ButtonImageGadget(52,250,280,150,200,goatImage,BS_BITMAP)
                        Hint ="finish"
                     Case 3
                        FreeGadget(53)
                        ButtonImageGadget(53,450,280,150,200,goatImage,BS_BITMAP)
                        Hint ="finish"
                  End Select
               Case Else
                  Exit Do
            End Select
      End Select
      Print "ClickHintForMyself loop. Hint = "; Hint; " Client(Counter) = ";Client(Counter)
      If Hint ="finish" Then Exit Do
   Loop
End Sub

'***********************************************************

Sub Select2ndDoorForMyself()
   Do
      event9 = WaitEvent
      Select Case event9
         Case EventClose
            End
         Case EventGadget   
            Select Case EventNumber
               Case 99
                  End
               Case 51
                  FreeGadget(51)
                  Client(Counter) = 1
                  If GadgetNo = EventNumber Then
                     ButtonImageGadget(51,50,280,150,200,carImage,BS_BITMAP)
                  Else
                     ButtonImageGadget(51,50,280,150,200,goatImage,BS_BITMAP)
                  EndIf
                  Hint = "Result"
               Case 52
                  FreeGadget(52)
                  Client(Counter) = 2
                  If GadgetNo = EventNumber Then
                     ButtonImageGadget(52,250,280,150,200,carImage,BS_BITMAP)
                  Else
                     ButtonImageGadget(52,250,280,150,200,goatImage,BS_BITMAP)
                  EndIf
                  Hint = "Result"
               Case 53
                  FreeGadget(53)
                  Client(Counter) = 3
                  If GadgetNo = EventNumber Then
                     ButtonImageGadget(53,450,280,150,200,carImage,BS_BITMAP)
                  Else
                     ButtonImageGadget(53,450,280,150,200,goatImage,BS_BITMAP)
                  EndIf
                  Hint = "Result"
            End Select
      End Select
      Print "Select2ndDoorForMyself loop. Hint = "; Hint ; " Client(Counter) = ";Client(Counter);" EventNumber = "; EventNumber
      If Hint ="Result" Then Exit Do
      If GadgetNo = EventNumber Then Exit Do
   Loop

End Sub

'***********************************************************

Sub ForStaySwitch()
   Hint = ""
   
   Print "ForStaySwitch"; "Client(Counter) = ";Client(Counter)
   
   Do While Client(Counter) = 0
      Select1stDoor()
   Loop

   Print "1 Hint = "; Hint; "  Monty = " ;Monty(Counter);"Client = ";Client(Counter)
   
   If Monty(Counter) <> Client(Counter) Then  'goat
      goat = 6 - Monty(Counter) - Client(Counter)
   Else                         'car
      Select Case Monty(Counter)
         Case 1
            goat = Counter Mod 2 + 2
         Case 2
            goat = Counter Mod 2 + 1
            If goat = 2 Then goat = 3
         Case 3
            goat = Counter Mod 2 + 1
      End Select
   EndIf
   
   Print "goat = " ;goat
   
   If strategy = "switch" Then
      Print "switch" ;Client(Counter)
      For i = 1 To 3
         If i <> goat And i <> Client(Counter) Then
            Client(Counter) = i
            Exit For
         EndIf
      Next
      Print "after switch" ;Client(Counter)
   End If
   
   Do While Hint = ""
      ClickHintForStaySwitch()
   Loop
   
   Print "2 Hint = "; Hint; "  Client(Counter) = ";Client(Counter); "  strategy = "; strategy

End Sub

'***********************************************************

Sub ForMyself()
   Hint = "" 
   
   Do While Client(Counter) = 0
      Select1stDoor()
   Loop
   
   'Print "Monty = " ;Monty(Counter),"Client = ";Client(Counter)
   
   If Monty(Counter) <> Client(Counter) Then  'goat
      For i = 1 To 3
         If Monty(Counter) <> i And Client(Counter) <>i Then
            goat = i
         EndIf
      Next i
   Else                         'car
      Select Case Monty(Counter)
         Case 1
            goat = Counter Mod 2 + 2
         Case 2
            goat = Counter Mod 2 + 1
            If goat = 2 Then goat = 3
         Case 3
            goat = Counter Mod 2 + 1
      End Select
   EndIf
   
   Print "goat = " ;goat
   GadgetNo = 50 + Monty(Counter)
   
   Do While Hint = "" And Client(Counter) > 0
      ClickHintForMyself()
   Loop

   If Hint ="finish" Then
      If counter < 10 Then
         SetGadgetText(21,"もう一度選択できます。同じ扉を選択しても、別の扉に変更してもかまいません。")
      Else
         SetGadgetText(21,"10回終わりました。右上の「終了」か「繰り返し」ボタンを押してください。")
      End If
      
      Do While Hint <> "Result"
         Select2ndDoorForMyself()
      Loop
   EndIf
   
End Sub

'***********************************************************

hwnd = OpenWindow("""Monty Hall"" Game",0,0,1000,600)
CenterWindow(hwnd)
SetGadgetFont(,LoadFont("Cambria",16)) 'Default font
TextGadget(10,10,10,750,150,MontyHall)

Start: '★★★★★★★★★★★★★★★★
Counter = 0
strategy = ""
strategyStart = ""
Acquisition = 0
ReDim Client(10)

TextGadget(11,10,150,750,30,"3 つの指定方法から、あなたの戦略を選択して、「スタート」を押して下さい。")
OptionGadget(1,10,180,640,30,"いつも自分で指定して選択します。",BS_AUTORADIOBUTTON)
OptionGadget(2,10,210,640,30,"最初に選んだ扉の選択を、そのまま維持します。(stay)",BS_AUTORADIOBUTTON)
OptionGadget(3,10,240,640,30,"最初に選んだ扉と別の扉に、必ず交換します。(switch)",BS_AUTORADIOBUTTON)
ButtonGadget(98,790,5,90,40,"繰返し")
ButtonGadget(99,890,5,90,40,"終了")

ButtonGadget(31,650,200,100,50,"スタート")
ButtonGadget(32,650,285,100,150,"ヒント")

TextGadget(21,20,500,950,30,"")
TextGadget(25,650,450,50,20,"") 'counter
TextGadget(26,670,465,100,24,"/10 回")

WindowStartDraw(hwnd)  'Start drawing
FillRectDraw(0,0,&hf0f0f0) ' Gray background
For i = 0 To 10
   For j = 0 To 3
      If i = 0 Then
         If j > 0 Then
            TextDraw(795+j*42,52+i*42,Str(j),&hffffff) ' Show No.
         EndIf
      Else
         If j = 0 Then
            TextDraw(795+j*42,45+i*42,Str(i),&hffffff) ' Show No.
         Else
            BoxDraw(780+j*42,35+i*42,40,40,0,&hffffff) ' Draw rectangles
         EndIf
      EndIf
   Next
Next
StopDraw 'Finish drawing

Do while strategyStart = ""
   ChooseStrategy()
Loop

Print "strategy = " ;strategy

For Counter = 1 To 10  
   
   SetGadgetText(25, Str(Counter)) 'counter
   SetGadgetFont(25,LoadFont("Cambria",16)) 'Title font
   SetGadgetColor(25, 0, &h0000ff, 2)
   SetGadgetText(21,"3 つの扉のどれかをマウスでクリップして下さい。")
   SetGadgetColor(21, 0, &h0000ff, 2)

   ButtonImageGadget(51,50,280,150,200,0,FB_BS_PUSHLIKE Or BS_BITMAP)
   ButtonImageGadget(52,250,280,150,200,0,FB_BS_PUSHLIKE Or BS_BITMAP)
   ButtonImageGadget(53,450,280,150,200,0,FB_BS_PUSHLIKE Or BS_BITMAP)
   'The image is displayed and becomes concavo-convex.
   'ButtonImageGadget(51,50,280,150,200,0,FB_BS_PUSHLIKE And BS_AUTORADIOBUTTON or BS_BITMAP)
   'ButtonImageGadget(52,250,280,150,200,0,FB_BS_PUSHLIKE And BS_AUTORADIOBUTTON or BS_BITMAP)
   'ButtonImageGadget(53,450,280,150,200,0,FB_BS_PUSHLIKE and BS_AUTORADIOBUTTON or BS_BITMAP)
   
   SetImageGadget(51,Load_image("DOOR1.jpg"))
   SetImageGadget(52,Load_image("DOOR2.png"))
   SetImageGadget(53,Load_image("DOOR3.jpg"))  

   Monty(Counter) = RndDice(3)
   'Print "Monty = " ;Monty(Counter),"Client = ";Client(Counter)
      
   If strategy = "myself" Then
      ForMyself()
   Else    '"stay" or "switch"
      ForStaySwitch()
   EndIf

   WindowStartDraw(hwnd,824,36+Counter*42,121,38) 
      FillRectDraw(0,0,&hf0f0f0) ' Gray background
      ImageDraw(carSImage, Monty(Counter)*42-40,1)
      If Monty(Counter) = Client(Counter) Then
         RoundDraw(Client(Counter)*42-40, 1, 35, 35, 255, -1,2) ' Draw an ellipse
      Else
         RoundDraw(Client(Counter)*42-40, 1, 35, 35, &hff0000, -1,2) ' Draw an ellipse
      End If   
   StopDraw
   Print "Client(Counter) = "; Client(Counter)

   If Monty(Counter) = Client(Counter) Then 
      Acquisition = Acquisition + 1
      MessBox("やったー!","あなたは車を手に入れました。取得した車の総数は " & Str(Acquisition))
   Else
      MessBox("残念","残念でしたね。また頑張ってください。")  
   EndIf   
      
   Print "Counter = " ;Counter ;" Acquisition = "; Acquisition; " Monty = " ;Monty(Counter);" Client = ";Client(Counter)
   Sleep (500)
Next

   Print "Counter = " ;Counter ;"For Next loop out"
   MessBox("結果","あなたは " & Str(Acquisition) & " 台の車を取得しました!!" & Chr(13) & Chr(10) _
   & "終了するには、右上の「終了」をクリックします。" & Chr(13) & Chr(10) _
   & "再挑戦するには、「繰返し」をクリックします。戦略を変更できます。")  

Do
   event9 = WaitEvent
   Select Case event9
    Case EventClose
      End
    Case EventGadget
      Select Case EventNumber
         Case 98 'Repeat
            GoTo Start
         Case 99
            End
      End Select
   End Select
Loop

End

 なぜ「交換」は「維持」の2倍の確率になるのでしょう。
下記のサイトの解説が分かりやすいです。
https://yougomywayyougomyway.com/monty-hall-problem
 最初に選択した扉に景品が入っている確率は 1/3 です。
それ以外の 2つの扉のいずれかに景品が入っている確率は、2/3になります。
これは誰でも理解できるはずです。
 ここで司会者が、2つの扉のうちハズレの方の扉を開けて除外します。
残りの扉は、2/3の確率を残しているので、こちらに「交換」すると、商品を受け取れる確率は、「維持」の 1/3 に対して 2 倍になるのです・・・・。

 【参考】 下は、Monty Hall の確率を、百万個の乱数を生成して集計検証するプログラムです。
http://rosettacode.org/wiki/Monty_Hall_problem#FreeBASIC
'Monty Hall problem

' version 19-01-2019
' compile with: fbc -s console
 
Const As Integer max = 1000000
Randomize Timer
 
Dim As UInteger i, car_door, chosen_door, montys_door, stay, switch
Dim As UInteger TotalStay = 0 , TotalSwitch = 0
Dim counter As Integer = 0

For i = 1 To max
   car_door = Fix(Rnd * 3) + 1
   chosen_door = Fix(Rnd * 3) + 1
   If car_door <> chosen_door Then
      ' 1 + 2 + 3 = 6
      'car_door <> chosen_door の場合、car_door と chosen_doorの組合せは次の3 種類のみ
      '1 + 2 = 3
      '1 + 3 = 4
      '2 + 3 = 5
      montys_door = 6 - car_door - chosen_door
   Else
      Do
         montys_door = Fix(Rnd * 3) + 1
      Loop Until montys_door <> car_door
   End If
   
   If i <= 10 Then
      Print "car_door = ";car_door," chosen_door = ";chosen_door," montys_door = ";montys_door;
      If car_door = chosen_door Then
         Print " stay"
      Else
         Print " switch"
      End If
   ElseIf i = 11 Then
      Print
      Print "counter" , "stay/100000" , "switch/100000"
   End If

   ' stay
   If car_door = chosen_door Then stay += 1
   ' switch
   If car_door = 6 - montys_door - chosen_door Then switch +=1
   
   If i Mod 100000 = 0 Then
      counter = counter + 1
      Print counter , stay ,switch
      TotalStay = TotalStay + stay
      TotalSwitch = TotalSwitch + switch
      stay = 0
      switch = 0
   EndIf
Next
 
Print 
Print Using "If you stay to your choice, you have a ##.## percent" _
                                         + " chance to win."; TotalStay / max * 100
Print Using "If you switched, you have a ##.## percent chance to win."; _
                                                           TotalSwitch / max * 100
 
' empty keyboard buffer
While InKey <> "" : Wend
Print "********** Hit any key to end program. **********"
Sleep
End

http://mneniya.ucoz.ru/

←リンク元に戻る Window9 トップに戻る FreeBASIC マニュアル トップに戻る
ロシア語オリジナル:https://users.freebasic-portal.de/freebasicru/window9lib/window9.html