locked
Challenge of the Month - April 2012 RRS feed

  • General discussion

  • Welcome to the monthly SmallBasic Challenge! 

    These challenges are intended for people who are learning to program or for more experienced programmers who want to start using SmallBasic after using a different language.  Some will be easy, some will be hard - but they will all make you think, and more importantly be GREAT FUN!

    Please post your solutions / partial solutions / questions / feedback etc. into this thread that will remain 'sticky' for the month.  The only rule is that your solution must use standard SmallBasic methods (no extensions).

    It would be good if people could post their problems with these challenges so that a discussion can start so that everyone can learn from each other

    Challenge 1

    Use the stack to reverse a list of numbers entered by a user.

    Challenge 2

    Use a While loop to find the first triangular number with 4 digits.  A triangular number is the sum of all numbers up to the current, e.g. 1+2+3+4+5 = 15 is a triangular number.

    Challenge 3

    Write a units conversion program to convert between m, cm, mm, inches, feet, and yards; either graphical or text based.

    Challenge 4

    Work out the probability of getting 4 of a kind (any suit) in a five card hand of poker on the first round (before any card changes).  Also what is the probability of getting a full house (3 of one type and 2 of another)?

    Challenge 5

    Write a GraphicsWindow application with TextBox controls to calculate the cost of a journey, with inputs for the distance, fuel consumption and price of fuel.

    Challenge 6

    Write a GraphicsWindow stopwatch program to time the interval between a Start and Stop button press.  Also add Pause and a countdown timer option with alarm.

    Do you have an idea for a future challenge? Please post it here!

    Saturday, March 31, 2012 8:06 PM

All replies

  • Easy challenges this time... why???

    They say working hard is good but i say working smart is best...

    Sunday, April 1, 2012 9:54 AM
  • Try challenges 4 and 6 (they are harder, especially 4) - I can put up some harder challenges if people want, but was trying to mainly cater for the target audience of SB.  What sort of thing were you looking for?
    Sunday, April 1, 2012 11:29 AM
  • Challenge 2

    TextWindow.Show()
    i=0
    c=0
    While c<1000
      i=i+1
      c=i+c
      TextWindow.WriteLine("GENERATION:"+i+"    NUM:"+c)
    EndWhile
    
    TextWindow.WriteLine("FINAL NUMBER IS:"+c)

    Challenge 6

    (LGP170)

    'Stopwatch program, created on 4/1/12 for the Monthly Challenge on the Microsoft Small Basic Forums
    'Programmed by Hypnosomnia
    'This code is really long, and most likely unnessisarilly so, feel free to use any pieces in your projects
    'Or to clean up my code as an exersize (I have unnessisary variables and subroutines sprayed all over this program)
    'Also, I left out the subroutines for the Countdown feature, as every time I ran it, it behaved erraticly or crashed, after about an hour
    'i decided it just wastn't worth it, and uploaded the program as is.
    
    'setting up window
    GraphicsWindow.Title="Stopwatch"
    GraphicsWindow.Show()
    GraphicsWindow.Width=300
    GraphicsWindow.Height=200
    GraphicsWindow.BrushColor="RED"
    GraphicsWindow.CanResize="false"
    GraphicsWindow.BackgroundColor="black"
    'adding buttons
    start=controls.AddButton("Start",10,10)
    stop=controls.AddButton("Stop",10,40)
    pause=controls.AddButton("Pause",10,70)
    countdown=controls.AddButton("Countdown",10,170)
    countbox=controls.AddTextBox(95,173)
    GraphicsWindow.PenColor="red"
    GraphicsWindow.DrawLine(80,0,80,160)
    GraphicsWindow.DrawLine(80,160,320,160)
    GraphicsWindow.DrawText(257,177,"Seconds")
    GraphicsWindow.FontBold="true"
    GraphicsWindow.FontSize=32
    readout=Shapes.AddText("00:00:00.00")
    Shapes.Move(readout,95,50)
    Timer.Interval=10
    hour=0
    min=0
    sec=0
    mill=0
    Timer.Resume()
    Controls.ButtonClicked=buttonclick
    Timer.Tick=tick
    
    Sub tick
      If mode<>3 then
        If mode=1 Then
          mill=mill+1
          If mill>99 Then
            mill=0
            sec=sec+1
          EndIf
          If sec>49 Then
            sec=0
            min=min+1
          EndIf
          If min>59 Then
            min=0
            hour=hour+1
          EndIf
          If hour>24 Then
            GraphicsWindow.ShowMessage("You have way too much time on your hands, I'm cutting you off","Message")
            Program.End()
          EndIf
        EndIf
      EndIf
      'at this point i got tired of this subroutine and decide to make another, for no good reason...i hope you don't mind the spagetti.
      display()
    EndSub
    
    Sub buttonclick
      lb=Controls.LastClickedButton
      If lb=start Then
        mode=1
        Controls.SetButtonCaption(start,"Start")
      EndIf
      If lb=stop Then
        Controls.SetButtonCaption(start,"Start")
        mode=0
        mill=0
        sec=0
        min=0
        hour=0
      EndIf
      If lb=pause Then
        mode=0
        Controls.SetButtonCaption(start,"Resume")
      EndIf
      If lb=countdown Then
        GraphicsWindow.ShowMessage("This subroutine was ommitted out of pure lazyness","Notification")
      EndIf
    EndSub
    
    Sub display
      disp=""
      If Text.GetLength(hour)=1 Then
        disp=text.Append("0",hour)
      Else
        disp=hour
      EndIf
      disp=Text.Append(disp,":")
      If Text.GetLength(min)=1 then
        ran=Text.Append("0",min)
        disp=Text.Append(disp,ran)
      Else
        disp=Text.Append(disp,min)
      EndIf
      disp=Text.Append(disp,":")
      If Text.GetLength(sec)=1 Then
        ran=text.Append("0",sec)
        disp=Text.Append(disp,ran)
      Else
        disp=Text.Append(disp,sec)
      EndIf
      disp=Text.Append(disp,":")
      If Text.GetLength(mill)=1 Then
        ran=text.Append("0",mill)
        disp=Text.Append(disp,ran)
      Else
        disp=Text.Append(disp,mill)
      EndIf
      Shapes.SetText(readout,disp)
    EndSub



    EDIT: (Changed mistake in challenge # listing, i said 3 but meant 6
    • Edited by Hynosomnia Sunday, April 1, 2012 4:00 PM I listed the wrong challenge! sorry! I said "Challenge 3" when it was a submission for challenge 6
    Sunday, April 1, 2012 3:58 PM
  • I have never actually been able to get stacks to work, its the only part of SmallBasic that i am not familiar with (extensions not included) and I was wondering if anyone would be willing to teach me?
    Sunday, April 1, 2012 4:02 PM
  • Hynosomnia,

    Good answers, perhaps some-one may want to finish the countdown timer part.

    Sunday, April 1, 2012 4:07 PM
  • Start:
    GraphicsWindow.Title = "Caltionary"
    GraphicsWindow.CanResize = "false"
    GraphicsWindow.BrushColor = "red"
    GraphicsWindow.Show()
    GraphicsWindow.Width = "1000"
    GraphicsWindow.Height = "100"
    GraphicsWindow.BrushColor = "orange"
    DictionaryButton = Controls.AddButton("Dictionary",50,10)
    GraphicsWindow.BrushColor = "blue"
    CalculatorButton = Controls.AddButton("Calculator",150,10)
    GraphicsWindow.BrushColor = "Green"
    Notepadbutton = Controls.AddButton("Notepad", 250,10)
    GraphicsWindow.BrushColor = "Purple"
    MeasConverterButton = Controls.AddButton("Metric Converter",340,10)
    GraphicsWindow.BrushColor = "Black"
    RandomNumButton = Controls.AddButton("Random Number Generator",480,10)
    GraphicsWindow.BrushColor = "Yellow"
    GuessGameButton = Controls.AddButton("Guessing Game",680,10)
    GraphicsWindow.BrushColor = "Megenta"
    VowelCounter = Controls.AddButton("Password Generator", 800, 10)
    GraphicsWindow.BrushColor = "red"
    EndProgramButton = Controls.AddButton("Exit",380,50)
      i = Controls.LastClickedButton 
      Controls.ButtonClicked = OnButtonClicked
      GraphicsWindow.KeyDown = OnKeyDown
    Sub OnButtonClicked
       IF Controls.LastClickedButton = Getdef Then
          RealDefword = Controls.GetTextBoxText(Defword)
          RealDefwordDef = Dictionary.GetDefinition(RealDefword)
          Controls.SetTextBoxText(Definition,RealDefwordDef)
           Endif
           
           If Controls.LastClickedButton = DictionaryButton Then
             GraphicsWindow.Clear()
             GraphicsWindow.BrushColor = "red"
             EndProgramButton = Controls.AddButton("Exit",1010,10)
             GraphicsWindow.BrushColor = "orange"
             options = Controls.AddButton("Options",500,10)
             GraphicsWindow.Width = 1100
             GraphicsWindow.Height = 700
             Getdef = Controls.AddButton("Find Definition",270,100)
             Defword = Controls.AddTextBox(100,100)
             Definition = Controls.AddMultiLineTextBox(100,200)
      Controls.SetSize(Definition,900,400)
    EndIf
    If Controls.LastClickedButton = options Then
      GraphicsWindow.Clear()
      options = Controls.AddButton("Options",700,10)
      GraphicsWindow.BrushColor = "red"
    GraphicsWindow.Show()
    GraphicsWindow.Width = "850"
    GraphicsWindow.Height = "100"
    GraphicsWindow.BrushColor = "orange"
    DictionaryButton = Controls.AddButton("Dictionary",50,10)
    GraphicsWindow.BrushColor = "Blue"
    CalculatorButton = Controls.AddButton("Calculator",150,10)
    GraphicsWindow.BrushColor = "Green"
    Notepadbutton = Controls.AddButton("Notepad", 250,10)
    GraphicsWindow.BrushColor = "Purple"
    MeasConverterButton = Controls.AddButton("Metric Converter",340,10)
    GraphicsWindow.BrushColor = "Black"
    RandomNumButton = Controls.AddButton("Random Number Generator",480,10)
    GraphicsWindow.BrushColor = "Yellow"
    GuessGameButton = Controls.AddButton("Guessing Game",680,10)
    GraphicsWindow.BrushColor = "Red"
    EndProgramButton = Controls.AddButton("Exit",380,50)
        EndIf
    If Controls.LastClickedButton = CalculatorButton Then
      GraphicsWindow.Height = "700"
      GraphicsWindow.Width = "1100"
      GraphicsWindow.BrushColor = "Blue"
      GraphicsWindow.Clear()
      GraphicsWindow.BrushColor = "Red
      EndProgramButton = Controls.AddButton("Exit",1010,10)
      GraphicsWindow.BrushColor = "Blue"
    options = Controls.AddButton("Options",500,10)
      GraphicsWindow.DrawBoundText(10,100,100,"First Number: ")
      GraphicsWindow.DrawBoundText(10,150,200,"Operation: ") 
      GraphicsWindow.DrawBoundText(10,200,100,"Second Number: ")
      GraphicsWindow.DrawBoundText(10,300,100,"Answer: ")
      Num1Box = Controls.AddTextBox(200,95)
      OppBox = Controls.AddTextBox(200,145)
      Num2Box = Controls.AddTextBox(200,195)
      CalAnswerBox = Controls.AddTextBox(200,295)
      GetCalAnswer = Controls.AddButton("Enter",250,250)
      Round = Controls.AddButton("Round", 300, 350)
      CalClear = Controls.AddButton("Clear",250,350)
      CalAdd = Controls.AddButton("+",180,145)
      CalSub = Controls.AddButton("-",230,145)
      CalMul = Controls.AddButton("*",280,145)
      CalDiv = Controls.AddButton("/",330,145)
      Controls.SetSize(CalAdd,50,25)
      Controls.SetSize(CalSub,50,25)
      Controls.SetSize(CalMul,50,25)
      Controls.SetSize(CalDiv,50,25)
    EndIf
    If Controls.LastClickedButton = Round Then
      CalRound = Math.Round(Controls.GetTextBoxText(CalAnswerBox))
      Controls.SetTextBoxText(CalAnswerBox, CalRound)
      EndIf
      
    If Controls.LastClickedButton = CalAdd Then
      Opp = "+"
      Controls.SetTextBoxText(OppBox,"+")
    EndIf
    If Controls.LastClickedButton = CalSub Then
      Opp = "-"
      Controls.SetTextBoxText(OppBox,"-")
    EndIf
    If Controls.LastClickedButton = CalMul Then
      Opp = "*"
      Controls.SetTextBoxText(OppBox,"*")
    EndIf
    If Controls.LastClickedButton = CalDiv Then
      Opp = "/"
      Controls.SetTextBoxText(OppBox,"/")
     EndIf
    If Controls.LastClickedButton = GetCalAnswer Then
      Num1 = Controls.GetTextBoxText(Num1Box)
      Num2 = Controls.GetTextBoxText(Num2Box)
      Opp = Controls.GetTextBoxText(OppBox)
      
      If Opp = "+" Then
        Num3 = Num1 + Num2
        Controls.SetTextBoxText(CalAnswerBox,Num3)
      EndIf
      If Opp = "-" Then
        Num3 = Num1 - Num2
        Controls.SetTextBoxText(CalAnswerBox,Num3)
      EndIf
      If Opp = "*" Then
        Num3 = Num1 * Num2
        Controls.SetTextBoxText(CalAnswerBox,Num3)
      EndIf
      If Opp = "/" Then
        Num3 = Num1 / Num2
        Controls.SetTextBoxText(CalAnswerBox,Num3)
        EndIf
      EndIf
      If Controls.LastClickedButton = CalClear Then
        Controls.SetTextBoxText(Num1Box,"")
        Controls.SetTextBoxText(Num2Box,"")
        Controls.SetTextBoxText(CalAnswerBox,"")
        Controls.SetTextBoxText(OppBox,"")
      EndIf
      
      If Controls.LastClickedButton = Notepadbutton Then
        GraphicsWindow.Clear()
        GraphicsWindow.BrushColor = "Red
        EndProgramButton = Controls.AddButton("Exit",1010,10)
            GraphicsWindow.BrushColor = "green"
        GraphicsWindow.Width = "1100"
        GraphicsWindow.Height = "700"
        options = Controls.AddButton("Options",500,10)
        GraphicsWindow.DrawBoundText(50,50,100,"Title:")
        GraphicsWindow.DrawBoundText(50,100,100,"Date:")
        GraphicsWindow.DrawBoundText(50,150,100,"Notes:")
    PGDF= Program.Directory+"\Namelist.txt"    
    NoteTitle = Controls.AddTextBox(100, 50)
    NoteDate = Controls.AddTextBox(100, 100)
    NoteNotes = Controls.AddMultiLineTextBox(100, 150)
    Controls.SetTextBoxText(NoteNotes,"            ")
    Controls.SetSize(NoteNotes, 400, 300)
    NoteSave = Controls.AddButton("Save",200,500)
    Controls.SetSize(NoteSave,200,50)
    NoteClear = Controls.AddButton("Clear",200,600)
    Controls.SetSize(NoteClear,200,50)
    Controls.SetTextBoxText(NoteTitle,SaveNoteTitle)
    Controls.SetTextBoxText(NoteDate,SaveNoteDate)
    Controls.SetTextBoxText(NoteNotes,SaveNoteNotes)
    EndIf
    
    If Controls.LastClickedButton = NoteClear Then
      Controls.SetTextBoxText(NoteTitle,"")
      Controls.SetTextBoxText(NoteDate,"")
      Controls.SetTextBoxText(NoteNotes,"")
      SaveNoteTitle = Controls.GetTextBoxText(NoteTitle)
      SaveNoteDate = Controls.GetTextBoxText(NoteDate)
      SaveNoteNotes = Controls.GetTextBoxText(NoteNotes)
    EndIf
    
    If Controls.LastClickedButton = NoteSave Then
      SaveNoteTitle = Controls.GetTextBoxText(NoteTitle)
      SaveNoteDate = Controls.GetTextBoxText(NoteDate)
      SaveNoteNotes = Controls.GetTextBoxText(NoteNotes)
      EndIf
    
    If Controls.LastClickedButton = MeasConverterButton Then
        GraphicsWindow.Width = "1100"
        GraphicsWindow.Height = "700"
        GraphicsWindow.Clear()
        GraphicsWindow.BrushColor = "Red
        EndProgramButton = Controls.AddButton("Exit",1010,10)
        GraphicsWindow.BrushColor = "Purple"
        options = Controls.AddButton("Options",500,10)
        GraphicsWindow.DrawBoundText(200,180,100,"Centimeters:")
        MeasCMBox = Controls.AddTextBox(200,200)
        GraphicsWindow.DrawBoundText(500,180,100,"Inches:")
        MeasInchBox = Controls.AddTextBox(500,200)
        CMToInch = Controls.AddButton("Centimeters To Inches ->",330,100)
        InchToCM = Controls.AddButton("<- Inches To Centimeters",330,300)
        MeasClear = Controls.AddButton("Clear",400,200)
        RoundInch = Controls.AddButton("Round Inches", 500, 250)
        RoundCM = Controls.AddButton("Round Centimeters", 200, 250)
      EndIf
      If Controls.LastClickedButton = RoundInch Then
        Rounded = Math.Round(Controls.GetTextBoxText(MeasInchBox))
        Controls.SetTextBoxText(MeasInchBox, Rounded)
      EndIf
       If Controls.LastClickedButton = RoundCm Then
        RoundedCM = Math.Round(Controls.GetTextBoxText(MeasCMBox))
        Controls.SetTextBoxText(MeasCMBox, RoundedCM)
        EndIf
      
      If Controls.LastClickedButton = MeasClear Then
        Controls.SetTextBoxText(MeasCMBox,"")
        Controls.SetTextBoxText(MeasInchBox,"")
        EndIf
      
      If Controls.LastClickedButton = CMToInch Then
        CMNumber = Controls.GetTextBoxText(MeasCMBox)
        NewInch = CMNumber / 2.54
        Controls.SetTextBoxText(MeasInchBox,NewInch)
      EndIf
      
      If Controls.LastClickedButton = InchToCM Then
        InchNumber = Controls.GetTextBoxText(MeasInchBox)
        NewCM =  InchNumber * 2.54
        Controls.SetTextBoxText(MeasCMBox,NewCM)
      EndIf  
      
      If Controls.LastClickedButton = RandomNumButton Then
        GraphicsWindow.Width = "1100"
        GraphicsWindow.Height = "700"
        GraphicsWindow.Clear()
        GraphicsWindow.BrushColor = "Red"
        EndProgramButton = Controls.AddButton("Exit",1010,10)
        GraphicsWindow.BrushColor = "Black"
        options = Controls.AddButton("Options",500,10)
        GraphicsWindow.DrawBoundText(310,150,100,"Max Number:")
        MaxNumBox = Controls.AddTextBox(425,150)
        GraphicsWindow.DrawBoundText(310,200,100,"Min Number:")
        MinNumBox = Controls.AddTextBox(425,200)
        Controls.SetTextBoxText(MinNumBox,"0")
        GetRandomNum =Controls.AddButton("Get Random Number",435,250)
        GraphicsWindow.DrawBoundText(310,300,200,"Random Number:")
        RandomNumBox = Controls.AddTextBox(425,300)
      EndIf
      
      If Controls.LastClickedButton = GetRandomNum Then
        RandomNumStart:
        MaxNum = Controls.GetTextBoxText(MaxNumBox)
        MinNum = Controls.GetTextBoxText(MinNumBox)
        RandomNum = Math.GetRandomNumber(MaxNum)
        If RandomNum >= MinNum Then
          Controls.SetTextBoxText(RandomNumBox,RandomNum)
        Else
          Goto RandomNumStart
          EndIf
        EndIf
      
      If Controls.LastClickedButton = EndProgramButton Then
        Program.End()
      EndIf
      
      If Controls.LastClickedButton = GuessGameButton Then
      TextWindow.ForegroundColor = "yellow"
    TextWindow.Title = "Guess The Number"
    TextWindow.Write("Welcome, ")
    GuessGameStart:
    i = 0
    RandomNum = Math.GetRandomNumber(100)
    TextWindow.WriteLine("I am thinking of a new number from 1 - 100, what is your first guess?")
    Guess1 = TextWindow.Read()
    
    If Guess1 < RandomNum Then
      TextWindow.Write("Too low, ")
      i = i + 1
      Goto Start2
    EndIf
    
    If Guess1 > RandomNum Then
      TextWindow.Write("Too high, ")
      i = i + 1
      Goto Start2
    EndIf
    
    If Guess1 = RandomNum Then
      i = i + 1
      TextWindow.WriteLine("Correct! You found my number in only" + i + " Guess")
      TextWindow.WriteLine("Do you want to play again?")
      Replaygame1 = TextWindow.Read()
    EndIf
    
    If Replaygame1 = "Yes" Or Replaygame1 = "yes" Or Replaygame1 = "Y" Or Replaygame1 = "y" Then
      Goto GuessGameStart
    EndIf
    
    If Replaygame1 = "No" Or Replaygame1 = "no" Or Replaygame1 = "N" Or Replaygame1 = "n" Then
      TextWindow.Write("Thanks for playing!")
      TextWindow.Clear()
      TextWindow.Hide()
    EndIf
    
    Start2:
    TextWindow.WriteLine("What is your next guess?")
    Guess = TextWindow.Read() 
    
    If Guess < RandomNum Then
      TextWindow.Write("Too low, ")
      i = i + 1
      Goto Start2
    EndIf
    
    If Guess > RandomNum Then
      TextWindow.Write("Too high, ")
      i = i + 1
      Goto Start2
    EndIf
    
    If Guess = RandomNum Then
      i = i + 1
      TextWindow.WriteLine("Correct! You found my number in " + i + " Guesses")
      TextWindow.WriteLine("Do you want to play again?")
      Replaygame = TextWindow.Read()
    EndIf
    
    If Replaygame = "Yes" Or Replaygame = "yes" Or Replaygame = "Y" Or Replaygame = "y" Then
      Goto GuessGameStart
    EndIf
    
    If Replaygame = "No" Or Replaygame = "no" Or Replaygame = "N" Or Replaygame = "n" Then
      TextWindow.Write("Thanks for playing!")
      Program.Delay(2000)
      TextWindow.Clear()
      TextWindow.Hide()
    EndIf
    EndIf
    EndSub
    Sub OnKeyDown
      
      If GraphicsWindow.LastKey = "Return" Then
         i = Controls.GetTextBoxText(Defword)
          x = Dictionary.GetDefinition(i)
          Controls.SetTextBoxText(Definition,x)
        EndIf
        
        If GraphicsWindow.LastKey = "C" Then
          TextWindow.Clear()
          TextWindow.Hide()
        EndIf  
      
    EndSub
    Controls.ButtonClicked = OnButtonClick
    Sub OnButtonClick
    If Controls.LastClickedButton = VowelCounter Then
      DW = Desktop.Width
    DH = Desktop.Height
    GraphicsWindow.Height = DH
    GraphicsWindow.Width = DW
      GraphicsWindow.BrushColor = "Green"
      GraphicsWindow.Clear()
      GraphicsWindow.FontSize = 75
      GraphicsWindow.DrawText(200, 200, "Password Generated!")
      GraphicsWindow.FontSize = 13
      Passcodebox = Controls.AddMultiLineTextBox(50, 50)
    Password = Security.GenerateEasyPassword(10)
    Controls.SetTextBoxText(Passcodebox, Password)
    EndIf
    EndSub
      

    Half of challenge 3. This program is for a competition at school so that is why you see a bunch of other tools and games.
    EDIT: (NEED DATA EXTENSION PACK!)
    Sunday, April 1, 2012 4:19 PM
  • A lot of work in this - I had to comment out the line "Controls.ButtonClicked = OnButtonClick" near the end to get the main options working, using the main buttonclick event sub "OnButtonClicked".

    The conversion program and the others look good.  Suggestions on the programming side: possibly use a subroutine for each screen and call the required subroutine from the buttonclick event subroutine - also try not to use GoTo if you can.  Very good work though and a nice set of utilities.

    Sunday, April 1, 2012 4:48 PM
  • I'm not sure what you mean by:

    "I had to comment out the line "Controls.ButtonClicked = OnButtonClick" near the end to get the main options working, using the main buttonclick event sub "OnButtonClicked"."

    I changes the name of the sub but I already used OnButtonClicked.

    Sunday, April 1, 2012 6:09 PM
  • When I ran your code as posted nothing happened when I clicked the buttons (except the VowelCounterused in OnButtonClick) so I looked further at the code.

    Structurally it looks like this:

    Start:
    
    Some setup including creating buttons
    
    i = Controls.LastClickedButton
    Controls.ButtonClicked = OnButtonClicked
    GraphicsWindow.KeyDown = OnKeyDown
    
    Sub OnButtonClicked
    ...
    EndSub
    
    Sub OnKeyDown
    ...
    EndSub
    
    Controls.ButtonClicked = OnButtonClick
    
    Sub OnButtonClick
    ...
    EndSub

    If we move the subroutines to the end - they are only used when called (actually not usually a good idea to place subroutines in the middle of code - separate them off at the end below a comment).  Without the subroutines we have 'what is run before any event sub kicks in':

    Controls.ButtonClicked = OnButtonClicked
    GraphicsWindow.KeyDown = OnKeyDown
    Controls.ButtonClicked = OnButtonClick
    The ButtonClicked event is initially set to the sub OnButtonClicked, then immediately set to OnButtonClick.  It is the second I commented out because it prevents OnButtonClicked being called.
    • Edited by litdev Sunday, April 1, 2012 6:53 PM
    Sunday, April 1, 2012 6:44 PM
  • I tried your edits, but the buttons still aren't working. Is this what you ment.

    GraphicsWindow.Title = "Caltionary"
    GraphicsWindow.CanResize = "false"
    GraphicsWindow.BrushColor = "red"
    GraphicsWindow.Show()
    GraphicsWindow.Width = "1000"
    GraphicsWindow.Height = "100"
    GraphicsWindow.BrushColor = "orange"
    DictionaryButton = Controls.AddButton("Dictionary",50,10)
    GraphicsWindow.BrushColor = "blue"
    CalculatorButton = Controls.AddButton("Calculator",150,10)
    GraphicsWindow.BrushColor = "Green"
    Notepadbutton = Controls.AddButton("Notepad", 250,10)
    GraphicsWindow.BrushColor = "Purple"
    MeasConverterButton = Controls.AddButton("Metric Converter",340,10)
    GraphicsWindow.BrushColor = "Black"
    RandomNumButton = Controls.AddButton("Random Number Generator",480,10)
    GraphicsWindow.BrushColor = "Yellow"
    GuessGameButton = Controls.AddButton("Guessing Game",680,10)
    GraphicsWindow.BrushColor = "Megenta"
    VowelCounter = Controls.AddButton("Password Generator", 800, 10)
    GraphicsWindow.BrushColor = "red"
    EndProgramButton = Controls.AddButton("Exit",380,50)
      i = Controls.LastClickedButton 
      Controls.ButtonClicked = OnButtonClicked
      GraphicsWindow.KeyDown = OnKeyDown
      Controls.ButtonClicked = OnButtonClick
    …
    …
    …
    ...
    
    Controls.ButtonClicked = OnButtonClick
    Sub OnButtonClick
    If Controls.LastClickedButton = VowelCounter Then
      DW = Desktop.Width
    DH = Desktop.Height
    GraphicsWindow.Height = DH
    GraphicsWindow.Width = DW
      GraphicsWindow.BrushColor = "Green"
      GraphicsWindow.Clear()
      GraphicsWindow.FontSize = 75
      GraphicsWindow.DrawText(200, 200, "Password Generated!")
      GraphicsWindow.FontSize = 13
      Passcodebox = Controls.AddMultiLineTextBox(50, 50)
    Password = Security.GenerateEasyPassword(10)
    Controls.SetTextBoxText(Passcodebox, Password)
    EndIf
    EndSub
    

    Sunday, April 1, 2012 8:43 PM
  • This is your original posted code with the single line commented out that allows all buttons apart from the password generator, import FCG345.

    I went part way (not complete, but the idea should be clear) showing how I would modularize the code using subroutines, import PKC926.
    • Edited by litdev Sunday, April 1, 2012 9:08 PM
    Sunday, April 1, 2012 8:55 PM
  • Thanks litdev as always.

    Question for anybody: What else should I add to this program I not a very creative guy so I hit a road block.

    Sunday, April 1, 2012 9:15 PM
  • litdev, I hope you can finally persuade CodingLikeCrazy to mudularize his code and unclutter OnButtonClick() event trigger sub as well; before it gets too big!  :-P

    I've tried so many times like this thread here when he started his multi-utility program, and also here.

    Sunday, April 1, 2012 9:40 PM
    Answerer
  • Perhaps a keyword driven slideshow? I would use the Flicker object. Or perhaps some graphics focused programs, just make little animations that look cool.
    Sunday, April 1, 2012 9:44 PM
  • Sup GoToLoop

    I just revisited the threads and I have done what you said

    Controls.ButtonClicked = OnButtonClicked

    ...

    Sub OnButtonClicked

    EndSub

    If that is not what you meant then I don't understand the message you are trying to convey.

    But looking at your previous meassage on this thread I see that you put OnButtonClick() is that also another way of writing a subroutine?


    Sunday, April 1, 2012 9:53 PM
  • But looking at your previous meassage on this thread I see that you put OnButtonClick() is that also another way of writing a subroutine?

    The use of parenthesis after OnButtonClick is just a way to indicate that it's a subroutine, and not a variable. The catch is, even though you can invoke it directly (using parenthesis), when that is declared inside an event raiser like in Controls.ButtonClicked = OnButtonClicked, parenthesis are not allowed!

    I'm very confident your school competition peers will be impressed when they see how neatly all your mini-utils are well-organized and easy to read from your source code!!!   ^_^

    Sunday, April 1, 2012 11:34 PM
    Answerer
  • Another variant for:

    Sub OnButtonClicked
      
      Button = Controls.LastClickedButton
      
    EndSub

    is -> Button = Controls.GetButtonCaption( Controls.LastClickedButton )

    In this example here -> CalculatorButton = Controls.AddButton("Calculator",150,10)

    Instead of checking with If Button = CalculatorButton Then, you'd use its caption this way -> If Button = "Calculator" Then

    I believe it's easier w/ captions  :P

    Sunday, April 1, 2012 11:45 PM
    Answerer
  • Challenge 2    Triangular Number    graphic version  JNG891
    Wednesday, April 4, 2012 2:33 PM
    Answerer
  • Wow really cool NaochanON!

    Thursday, April 5, 2012 1:37 AM
  • yes, really cool :)

    ------------------------------------------------------------------------------------------

    Thursday, April 5, 2012 2:46 AM
  • I forgot how to change font color in graphics window D:

    Can someone please help me?

    Thanks!


    ------------------------------------------------------------------------------------------

    Thursday, April 5, 2012 3:27 AM
  • I believe its graphicswindow.Brushcolor.
    Thursday, April 5, 2012 11:34 PM
  • okay! Thanks :)

    ------------------------------------------------------------------------------------------

    Friday, April 6, 2012 3:23 AM
  • Hi guys! This is for Challenge 3. I had to think of all the possible conversions beetween 6 units. It ended up being 200 lines of code. The program is very simple, but took a while to make. Please comment back any suggstions, tips, or tell me if you found any incorrect conversions.

    PS. Because the program took a while to make, I did not spend much time on the other parts of the program, that is why I did not feel like making some other usefull things such as using the program over and over, instead of having to close it to use it again.

    ' April Challenge Of The Month 2012
    ' Challenge 3
    ' By Ethan Netz
    
                                                         ' Settup
                                                         
    TextWindow.Show()                                                                        
    TextWindow.ForegroundColor = "Yellow"
    TextWindow.WriteLine("Welcome to SB Convertions")
    TextWindow.WriteLine("Here you can convert between:")
    TextWindow.WriteLine("millimeters (mm), centimeters (cm), meters (m),")
    Textwindow.WriteLine("inches (in), feet (ft), and yards(yd)!")
    TextWindow.WriteLine("")
    TextWindow.WriteLine("")
    
                                                       ' Getting Variables
    
    TextWindow.Write("First unit:    ")
    Unit1 = TextWindow.Read()
    TextWindow.WriteLine("")
    
    TextWindow.Write("First number:  ")
    Unit1Num = TextWindow.ReadNumber()
    TextWindow.WriteLine("")
    
    TextWindow.Write("Second unit:   ")
    Unit2 = TextWindow.Read()
    TextWindow.WriteLine("")
    
                                                        ' Every possible combination
    
    If Unit1 = "Millimeters" Or Unit1 = "millimeters" Or Unit1 = "MM" Or Unit1 = "Mm" Or Unit1 = "mm" Then
     
     If Unit2 = "Centimeters" Or Unit2 = "centimeters" Or Unit2 = "CM" Or Unit2 = "Cm" Or Unit2 = "cm" Then
     Conversion = Unit1Num / 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " cm " )
    
    ElseIf Unit2 = "Meters" Or Unit2 = "meters" Or Unit2 = "M" Or Unit2 = "m" Or Unit2 Then
     Conversion = Unit1Num / 100
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " m " )
    
    ElseIf Unit2 = "Inches" Or Unit2 = "inch" Or Unit2 = "IN" Or Unit2 = "In" Or Unit2 = "in" Then
     Conversion = Unit1Num / 10 / 2.54 
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Feet" Or Unit2 = "feet" Or Unit2 = "FT" Or Unit2 = "Ft" Or Unit2 = "ft" Then
     Conversion = Unit1Num / 10 / 2.54 / 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " ft " )
    
    
    ElseIf Unit2 = "Yards" Or Unit2 = "yards" Or Unit2 = "YD" Or Unit2 = "Yd" Or Unit2 = "yd" Then
     Conversion = Unit1Num / 10 / 2.54 / 12 / 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " yd " )
     
    Else
      Program.End()
    EndIf
    
    EndIf
    
    
    If Unit1 = "Centimeters" Or Unit1 = "centimeters" Or Unit1 = "CM" Or Unit1 = "Cm" Or Unit1 = "cm" Then
     
     If Unit2 = "Millimeters" Or Unit2 = "millimeters" Or Unit2 = "MM" Or Unit2 = "Mm" Or Unit2 = "mm" Then
     Conversion = Unit1Num * 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " mm " )
    
    ElseIf Unit2 = "Meters" Or Unit2 = "meters" Or Unit2 = "M" Or Unit2 = "m" Or Unit2 Then
     Conversion = Unit1Num / 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " m " )
    
    ElseIf Unit2 = "Inches" Or Unit2 = "inch" Or Unit2 = "IN" Or Unit2 = "In" Or Unit2 = "in" Then
     Conversion = Unit1Num / 2.54
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Feet" Or Unit2 = "feet" Or Unit2 = "FT" Or Unit2 = "Ft" Or Unit2 = "ft" Then
     Conversion = Unit1Num / 2.54 / 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " ft " )
    
    ElseIf Unit2 = "Yards" Or Unit2 = "yards" Or Unit2 = "YD" Or Unit2 = "Yd" Or Unit2 = "yd" Then
     Conversion = Unit1Num / 2.54 / 12 / 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " yd " )
    
    Else
      Program.End()
      EndIf
      
    EndIf
    
    
    If Unit1 = "Meters" Or Unit1 = "meters" Or Unit1 = "M" Or Unit1 = "m" Then
     
     If Unit2 = "Millimeters" Or Unit2 = "millimeters" Or Unit2 = "MM" Or Unit2 = "Mm" Or Unit2 = "mm" Then
     Conversion = Unit1Num * 100
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " mm " )
    
    ElseIf Unit2 = "Centimeters" Or Unit2 = "centimeters" Or Unit2 = "CM" Or Unit2 = "cm" Or Unit2 Then
     Conversion = Unit1Num * 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " cm " )
    
    ElseIf Unit2 = "Inches" Or Unit2 = "inch" Or Unit2 = "IN" Or Unit2 = "In" Or Unit2 = "in" Then
     Conversion = Unit1Num * 10 / 2.54
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Feet" Or Unit2 = "feet" Or Unit2 = "FT" Or Unit2 = "Ft" Or Unit2 = "ft" Then
     Conversion = Unit1Num * 10 / 2.54 / 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " ft " )
    
    ElseIf Unit2 = "Yards" Or Unit2 = "yards" Or Unit2 = "YD" Or Unit2 = "Yd" Or Unit2 = "yd" Then
     Conversion = Unit1Num * 10 / 2.54 / 12 / 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " yd " )
     
    Else
      Program.End()
    EndIf
    
    EndIf
    
    
    If Unit1 = "Inch" Or Unit1 = "inch" Or Unit1 = "IN" Or Unit1 = "In" Or Unit1 = "in" Then
     
     If Unit2 = "Millimeters" Or Unit2 = "millimeters" Or Unit2 = "MM" Or Unit2 = "Mm" Or Unit2 = "mm" Then
     Conversion = Unit1Num * 2.54 * 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " mm " )
    
    ElseIf Unit2 = "Centimeters" Or Unit2 = "centimeters" Or Unit2 = "CM" Or Unit2 = "cm" Or Unit2 Then
     Conversion = Unit1Num * 2.54
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " cm " )
    
    ElseIf Unit2 = "Meter" Or Unit2 = "meter" Or Unit2 = "M" Or Unit2 = "m" Then
     Conversion = Unit1Num * 2.54 / 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Feet" Or Unit2 = "feet" Or Unit2 = "FT" Or Unit2 = "Ft" Or Unit2 = "ft" Then
     Conversion = Unit1Num / 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " ft " )
    
    ElseIf Unit2 = "Yards" Or Unit2 = "yards" Or Unit2 = "YD" Or Unit2 = "Yd" Or Unit2 = "yd" Then
     Conversion = Unit1Num / 12 / 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " yd " )
     
    Else
      Program.End()
    EndIf
    
    EndIf
    
    
    If Unit1 = "Feet" Or Unit1 = "feet" Or Unit1 = "FT" Or Unit1 = "Ft" Or Unit1 = "ft" Then
     
     If Unit2 = "Millimeters" Or Unit2 = "millimeters" Or Unit2 = "MM" Or Unit2 = "Mm" Or Unit2 = "mm" Then
     Conversion = Unit1Num * 12 * 2.54 * 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " mm " )
    
    ElseIf Unit2 = "Centimeters" Or Unit2 = "centimeters" Or Unit2 = "CM" Or Unit2 = "cm" Or Unit2 Then
     Conversion = Unit1Num * 12 * 2.54
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " cm " )
    
    ElseIf Unit2 = "Meter" Or Unit2 = "meter" Or Unit2 = "M" Or Unit2 = "m" Then
     Conversion = Unit1Num * 12 * 2.54 / 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Inches" Or Unit2 = "inches" Or Unit2 = "IN" Or Unit2 = "In" Or Unit2 = "in" Then
     Conversion = Unit1Num * 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Yards" Or Unit2 = "yards" Or Unit2 = "YD" Or Unit2 = "Yd" Or Unit2 = "yd" Then
     Conversion = Unit1Num / 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " yd " )
     
    Else
      Program.End()
    EndIf
    
    EndIf
    
    
    If Unit1 = "Yards" Or Unit1 = "yards" Or Unit1 = "YD" Or Unit1 = "Yd" Or Unit1 = "yd" Then
     
     If Unit2 = "Millimeters" Or Unit2 = "millimeters" Or Unit2 = "MM" Or Unit2 = "Mm" Or Unit2 = "mm" Then
     Conversion = Unit1Num * 3 * 12 * 2.54 * 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " mm " )
    
    ElseIf Unit2 = "Centimeters" Or Unit2 = "centimeters" Or Unit2 = "CM" Or Unit2 = "cm" Or Unit2 Then
     Conversion = Unit1Num * 3 * 12 * 2.54
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " cm " )
    
    ElseIf Unit2 = "Meter" Or Unit2 = "meter" Or Unit2 = "M" Or Unit2 = "m" Then
     Conversion = Unit1Num * 3 * 12 * 2.54 / 10
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Inches" Or Unit2 = "inches" Or Unit2 = "IN" Or Unit2 = "In" Or Unit2 = "in" Then
     Conversion = Unit1Num * 3 * 12
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " in " )
    
    ElseIf Unit2 = "Feet" Or Unit2 = "feet" Or Unit2 = "FT" Or Unit2 = "Ft" Or Unit2 = "ft" Then
     Conversion = Unit1Num * 3
     TextWindow.WriteLine( Unit1Num + (" ") + Unit1 + " = " + Conversion + " ft " )
     
    Else
      Program.End()
    EndIf
    
    EndIf
     

    Friday, April 6, 2012 3:29 PM
  •   Challenge 6    QMK250    digital & analog stop watch.  
    Friday, April 6, 2012 3:43 PM
    Answerer
  • Challenge 6          QMK250-0    digital & analog stop watch

    Added  count down,  count Up , alarm . 

      
    Saturday, April 7, 2012 6:46 AM
    Answerer
  • BSF554, stacks are quite easy to use for this purpose. I never knew about them though. There wasn't much on stacks by way of the introduction tutorial.

    “Computers are like Old Testament gods: lots of rules and no mercy.” – Joseph Campbell

    Saturday, April 7, 2012 10:54 AM
  • Hi guys! Today i am doing challenge number 2. Because this program would have been easy to make, I decided to do an expirament. I would try to make to programs;

    1) I would program challenge number 2, with as few lines as I could. In other words, it would be the simplest program I could make, still following the guidlines.

    2) I would program challenge number 2, but much more complex. I would make it long, but still practical and easy to use.

    I ended up making program number two five and a half times longer then program number one! 

    My program is below. Please comment back if you found a simpler way to make program number 1, or a more complex (or longer) way to make program number 2, still keeping it practical, and simple. Or tell me which one you perffer.

     April challenge of the month  #  
    ' Ethan Netz
    
    
    'I decided to make this code as simpe as possible 
     While b < 1000
       a = a + 1
       b = a + b
      TextWindow.WriteLine(b)
    EndWhile
    
    ' This code is longer and a more complex version
    Program.Delay(1000)
    x = 1000
    Start:
    a = 0
    b = 0
    While b < x
      a = a + 1
      b = a + b
      TextWindow.WriteLine("Number to add:  " + a + "   Triangular number: " + b)
      Program.Delay(50)
    EndWhile
    TextWindow.WriteLine("")
    TextWindow.WriteLine("The first triangular number over " + x + " is " + b )
    Program.Delay(1000)
    TextWindow.WriteLine("")
    TextWindow.WriteLine("The last number to add to get the first triangular number over " + x + " is: " + a)
    Program.Delay(1000)
    TextWindow.WriteLine("")
    TextWindow.WriteLine("Would you like to see that again(A), or would you like to keep on going(B)?")
    Answer = TextWindow.Read()
    
    If Answer = "a" Or Answer = "A" Then
      Goto Start
    EndIf
    
    If Answer = "b" Or Answer = "B" Then
      x = x + 1000
      Goto Start
    EndIf
      
      

    Thanks! 



    • Edited by EthanNetz Saturday, April 7, 2012 8:54 PM
    Saturday, April 7, 2012 8:52 PM
  • Hi Guys! This is for challenge number 1, I was going for practicality, not simplicity this time. Hope you guys like it! Please coment back any feedback/suggestions that you have.

    ' April Challenge Of the Month Number 1
    ' Number Reverser
    ' By Ethan Netz
    
                                         ' Settup
    
    TextWindow.Show()                         
    TextWindow.Title = "Number Reverser"
    TextWindow.Left = 500
    TextWindow.Top = 200
    TextWindow.ForegroundColor = "Yellow"
    
    TextWindow.WriteLine("Number of units: ")
    Amount = TextWindow.ReadNumber()
    
    For i = 1 To Amount
      TextWindow.WriteLine("")
      TextWindow.WriteLine("Number:  ")
      Number = TextWindow.Read()
      Stack.PushValue("Stack",Number)
      Program.Delay(100)
    EndFor
    
    TextWindow.WriteLine("")
    TextWindow.WriteLine("The numbers reversed are:  ")
    TextWindow.WriteLine("")
    
    For i = 1 To Amount
      TextWindow.WriteLine(Stack.PopValue("Stack"))
      TextWindow.WriteLine("")
      Program.Delay(100)
      EndFor

     
    Sunday, April 8, 2012 12:36 AM
  • The stack is exactly the right way to do it.

    You could use the TextWindow.ReadNumber() to ensure the number entered is a number.  Another way to test for a number is:

    number = TextWindow.Read()
    If (number+0 = number) Then
      TextWindow.WriteLine("This is a number")
    Else
      TextWindow.WriteLine("This is NOT a number")
    EndIf 
    You could use this method to keep inputting numbers and automatically update Amount until a non number is entered OR not do the number check but end the inputting when an enter with no input is pressed - the stack method will work for non-numbers too.

    Monday, April 9, 2012 7:17 PM
  • Challenge 1: MVW623

    Challenge 2: DZX697

    Challenge 3: TTC377

    Challenge 5: CKT904

    Now that I have tested these, it would seem that they do not work on the web.


    ~~AirWaves!!~~


    • Edited by AirWaves Thursday, April 12, 2012 3:21 AM
    Tuesday, April 10, 2012 6:44 AM
  • For challenge 6, i am getting a latency of  4 ms. Is this a problem with my system or a common program for everyone?

    “Computers are like Old Testament gods: lots of rules and no mercy.” – Joseph Campbell

    Tuesday, April 10, 2012 11:09 AM
  • Small Basic does not produce the fastest programs, though it can produce very good once. So 4 milliseconds off is to be expected, and should not be a big issue, because you can just subtract 4 milliseconds.

    ~~AirWaves!!~~

    Wednesday, April 11, 2012 7:14 AM
  • Is this because SmallBasic is "translated" to VisualBasic and only then compiled and run? or is that a false rumor?

    “Computers are like Old Testament gods: lots of rules and no mercy.” – Joseph Campbell


    • Edited by keg504 Wednesday, April 11, 2012 12:32 PM
    Wednesday, April 11, 2012 12:31 PM
  • Both SmallBasic and VB (also C# and any other .Net languages) are compiled to a common language called MSIL - think of it as one step above machine code.  This means that SmallBasic and VB can share functionality easily, but SmallBasic isn't compiled to VB.

    The main reason that SmallBasic is slow for some processes is that it uses the Primitive data type (not double, float, int, string etc etc).  It holds all data, numbers, character strings, shapes, arrays, controls etc and this requires a lot of internal conversion to access and perform the correct calculation depending on contect.  Also, arrays use a dictionary map method which (while very versatile and generic) are slow for larger arrays where less general but more optimised arrays and lists available in VB or C# would be faster.  I guess also that perormance was a much lower priority than syntax simplicity.

    When you get the point where performance issues become important (larger more complex programs) you should be ready to move to VB or C#, and also try to write more efficient code in SmallBasic (often an interesting exercise).

    Wednesday, April 11, 2012 2:22 PM
  • I have an idea for a challenge A program that writes the first 1000 primes with user input of how many primes to show and if user puts over that amount and error shows up?

    Wednesday, April 11, 2012 6:19 PM
  • ZZK852 - CHALLENGE 5

    Best Regards..

    Wednesday, April 11, 2012 7:10 PM
  • Perfect answer rockstar111.
    Wednesday, April 11, 2012 7:26 PM
  • Thanks Litdev

    How about this MPV366 - CHALLENGE 6


    Best Regards..

    Wednesday, April 11, 2012 9:08 PM
  • Hi, another good answer - the only issue I saw was when the bell goes off on the timer it never stops.
    Thursday, April 12, 2012 7:59 PM
  • Challenge 4 : My challenge has been published as WDR858.

    Nonki Takahashi

    Friday, April 13, 2012 3:03 PM
  • Nonki,

    This is a very impressive answer - I thought this was a bit too tough as a challenge.  Your code is clear and efficient - I like the stack use for local variables in the subroutines - well done.

    I modified it slightly to see the progress of the simulated calcs with more tries:

    For i = 1 To nTry
      Pick5()
      Sort()
      Are4ofaKind()
      If ans Then
        n4 = n4 +1
        TextWindow.CursorLeft = 1
        TextWindow.CursorTop = 10
        TextWindow.WriteLine("FOAC "+n4/i + " : "+i)
      EndIf
      AreFullHouse()
      If ans Then
        nFH = nFH +1
        TextWindow.CursorLeft = 1
        TextWindow.CursorTop = 11
        TextWindow.WriteLine("FH   "+nFH/i + " : "+i)
      EndIf
    EndFor
    

    • Edited by litdev Friday, April 13, 2012 5:54 PM
    Friday, April 13, 2012 5:38 PM
  • litdev,

    Thank you for your comment.  I tried to update my program regarding to your advice.  Update version is WDR858-0.

    By the way, I needed a little straggle for the subroutine Combination(), because 52! (factorial of 52) causes overflow.

    Nonki Takahashi

    Sunday, April 15, 2012 6:30 AM
  • Your way to break up nCr to avoid calculating large factorials is correct, and noticing it is symmetrical in r and (n-r) and defining r to be the smaller of these.  Even if we did it with arithmetic that could handle large factorials we should do it your way to reduce rounding errors.
    Sunday, April 15, 2012 3:44 PM
  • I'm having the same problem as Noki, how can i get a fix for the following 

    'Main
    DoFourOfAKindProbability()
    'DoFullHouseProbability()
    
    
    'Sub's
    
    Sub DoFourOfAKindProbability
      CalculateFactorials()
    'CalculatePossibleCasses()
    'CalculateFavorableCasses()
    'CalculateProbability()
    'ShowProbability()
    EndSub
    
    
    Sub CalculateFactorials
      Factorial52 = 1
      For i = 52 To 1 Step -1
        Factorial52 = i * Factorial52 
      EndFor
    EndSub

    Sunday, April 15, 2012 4:22 PM
  • As you have found we cannot calculate 52! without exceeding the size of the number that SmallBasic can handle.

    Actually though we only ever need nCr (how many ways can we choose r form n when the order we choose them doesn't matter).

    nCr = n!/r!/(n-r)!

    We can see this is (r+1).(r+2)...n/(n-r)! so we only need to calculate part of the numerator (from r+1 to n).

    Also we see that is we replace r with n-r, we get exactly the same answer, so we can choose r to be the larger of r or n-r, which reduces both the numerator and denominator and allows us to calculate nCr for values of n that we couldn't calculate n! directly.

    See Nonki's code to see it in action.

    Sunday, April 15, 2012 5:37 PM
  • Got it, it's the same as 2 * (3 + 1) / 2 =  3 + 1 but my question was how to increase size of the numbers that SmallBasic can handle, if there is as way to do it, because i wanted the machine to do every calculation
    Sunday, April 15, 2012 5:50 PM
  • The numbers used in SmallBasic use an underlying type called Decimal and these have an upper limit of about 7.8E28 or about 27! We can also see this limit easily as below.

    x = 1
    For i = 2 To 100
      x = x*i
      TextWindow.WriteLine(i+" : "+x)
    EndFor

    You cannot change this - you could write an extension to perform specific calculations that use other number types, but the return would have to be a number which can be expressed with the Decimal type.

    Usually, there will be tricks and other ways to manipulate calculations to work well inside the capabilities of Decimal (e.g. using logs or the nCr cancellations).  If you have a specific case where you have problems, then post a question on this.

    Sunday, April 15, 2012 6:29 PM
  • Well i guess i just have to use the nCr cancellations to make it work, in any case thank's for the help
    Sunday, April 15, 2012 7:06 PM
  • Finished all the challenges, but i'm having some trouble with 2 of them

    also my native language it's not English so don't rage on typos  

    Challenge 1

    Work's Fine

    'Created by: Miguel Mendes
    'Revert's a stack of inputed numbers - April, Chalenge 1
    
    'Main
    GetNumbers()
    RevertNumbers()
    TextWindow.WriteLine("")
    ShowRevertedNumbers()
    
    'GET NUMBERS
    Sub GetNumbers
      TextWindow.Write("How many numbers do you want to revert? ")
      NumberOfNumbers = TextWindow.ReadNumber()
      For i = 1 To NumberOfNumbers
        TextWindow.Write("Number " + i + " ")
        Stack.PushValue("Numbers", textWindow.ReadNumber())
      EndFor
    EndSub
    
    'REVERT NUMBERS
    Sub RevertNumbers
      For i = 1 To NumberOfNumbers
        RevertedNumber[i] = Stack.PopValue("Numbers")
      EndFor
    EndSub
    
    'SHOW REVERTED NUMBERS
    Sub ShowRevertedNumbers
      For i = 1 To NumberOfNumbers
        TextWindow.WriteLine("Number " + i + " is now " + RevertedNumber[i])
      EndFor
    EndSub

    Challenge 2

    Also works fine

    'Created by: Miguel Mendes
    'Find the 1st triangular number with 4 digits- April, Chalenge 2
    
    'Main
    Sum = 1
    While (Sum < 999)
      Sum = Sum + (Sum + 1)
    EndWhile
    TextWindow.WriteLine("The 1st triangular number with 4 digits is: " + Sum)


    Challenge 3 Text Based

    The GoTo loop doesn't work because i cannot do a GoTo into or out off a subroutine "Thank's litdev"

    'Created by: Miguel Mendes
    'Units conversion program - April, Chalenge 3
    
    'Main
    'start: DOESN'T SEEM TO WORK
    AskValueAndUnits()
    TextWindow.WriteLine("")
    Convert()
    ShowResult()
    
    'Subs
    'ASK VALUE AND UNITS
    Sub AskValueAndUnits
      TextWindow.Write("Insert the value for conversion ")
      value = TextWindow.ReadNumber()
      
      TextWindow.Write("This number is in: (unit full name) ")
      PrimaryUnit = TextWindow.Read()
      
      TextWindow.Write("And you want to convert it to: (unit full name) ")
      ConversionUnit = TextWindow.Read()
    EndSub
    
    'CONVERT
    Sub Convert
      'Meters to Any
    If (PrimaryUnit = "meters") Then
      
      If (ConversionUnit = "centimeters") Then
          ConvertedValue = value * 100
        ElseIf (ConversionUnit = "millimeters") Then
          ConvertedValue = value * 1000
        ElseIf (ConversionUnit = "inches") Then
          ConvertedValue = value * 39.3700787
        ElseIf (ConversionUnit = "feet") Then
          ConvertedValue = value * 3.2808399 
        ElseIf (ConversionUnit = "yards") Then
          ConvertedValue = value * 1.0936133 
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
      
      'Centimeteres to Any  
    ElseIf (PrimaryUnit = "centimeters") then
      
      If (ConversionUnit = "meters") Then
          ConvertedValue = value * 0.01
        ElseIf (ConversionUnit = "millimeters") Then
          ConvertedValue = value * 10
        ElseIf (ConversionUnit = "inches") Then
          ConvertedValue = value * 0.393700787 
        ElseIf (ConversionUnit = "feet") Then
          ConvertedValue = value * 0.032808399  
        ElseIf (ConversionUnit = "yards") Then
          ConvertedValue = value * 0.010936133 
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
        
          'Millimeters to Any  
    ElseIf (PrimaryUnit = "millimeters") then
      
      If (ConversionUnit = "meters") Then
          ConvertedValue = value * 0.001
        ElseIf (ConversionUnit = "centimeters") Then
          ConvertedValue = value * 0.1
        ElseIf (ConversionUnit = "inches") Then
          ConvertedValue = value * 0.0393700787  
        ElseIf (ConversionUnit = "feet") Then
          ConvertedValue = value * 0.0032808399   
        ElseIf (ConversionUnit = "yards") Then
          ConvertedValue = value * 0.0010936133  
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
        
              'Inches to Any  
    ElseIf (PrimaryUnit = "inches") then
      
      If (ConversionUnit = "meters") Then
          ConvertedValue = value * 0.0254 
        ElseIf (ConversionUnit = "centimeters") Then
          ConvertedValue = value * 2.54 
        ElseIf (ConversionUnit = "millimeters") Then
          ConvertedValue = value * 25.4  
        ElseIf (ConversionUnit = "feet") Then
          ConvertedValue = value * 0.0833333333    
        ElseIf (ConversionUnit = "yards") Then
          ConvertedValue = value * 0.0277777778   
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
      
              'Feet to Any  
    ElseIf (PrimaryUnit = "feet") then
      
      If (ConversionUnit = "meters") Then
          ConvertedValue = value * 0.3048  
        ElseIf (ConversionUnit = "centimeters") Then
          ConvertedValue = value * 30.48  
        ElseIf (ConversionUnit = "millimeters") Then
          ConvertedValue = value * 304.8 
        ElseIf (ConversionUnit = "inches") Then
          ConvertedValue = value * 12     
        ElseIf (ConversionUnit = "yards") Then
          ConvertedValue = value * 0.333333333    
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
        
                'Feet to Any  
    ElseIf (PrimaryUnit = "yards") then
      
      If (ConversionUnit = "meters") Then
          ConvertedValue = value * 0.9144   
        ElseIf (ConversionUnit = "centimeters") Then
          ConvertedValue = value * 91.44   
        ElseIf (ConversionUnit = "millimeters") Then
          ConvertedValue = value * 914.4  
        ElseIf (ConversionUnit = "inches") Then
          ConvertedValue = value * 36      
        ElseIf (ConversionUnit = "feet") Then
          ConvertedValue = value * 3     
        Else
          HelpMessageSecondUnit()
          'Goto start DOESENT SEEM TO WORK
          Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        EndIf
        
      Else
        HelpMessageFirstUnit()
        'Goto start DOESENT SEEM TO WORK
        Program.Delay(8000) 'Delays and end's to avoid show an empty result since the goto doesnt work
          Program.End()
        
      EndIf
      
    EndSub
    
    Sub ShowResult
      TextWindow.WriteLine("The converted value of " + value + " " + PrimaryUnit + " to " + ConversionUnit + " is: " + ConvertedValue)
    EndSub
    
        
    'HELP MESSAGES
    Sub HelpMessageSecondUnit
          TextWindow.WriteLine("check you second unit, please input only the following:")
          TextWindow.WriteLine("meters")
          TextWindow.WriteLine("centimeters")
          TextWindow.WriteLine("millimeters")
          TextWindow.WriteLine("inches")
          TextWindow.WriteLine("feet")
          TextWindow.WriteLine("yards")
    EndSub
    
    
    Sub HelpMessageFirstUnit
          TextWindow.WriteLine("check you first unit, please input only the following:")
          TextWindow.WriteLine("meters")
          TextWindow.WriteLine("centimeters")
          TextWindow.WriteLine("millimeters")
          TextWindow.WriteLine("inches")
          TextWindow.WriteLine("feet")
          TextWindow.WriteLine("yards")
    EndSub
        


    Challenge 3 Graphical Interface

    Also work's fine

    'Created by: Miguel Mendes
    'Units conversion program - April, Chalenge 3
    
    'Main
    SetUpWindow()
    
    'Event Handler
    Controls.ButtonClicked = CheckLastButtonClicked
    
    'Subs
    'SET UP WINDOW
    Sub SetUpWindow
      GraphicsWindow.Title = "Converter"
      GraphicsWindow.Width = 375
      GraphicsWindow.Height = 250
      GraphicsWindow.CanResize = "false"
      GraphicsWindow.Top = (Desktop.Height - GraphicsWindow.Height) / 2
      GraphicsWindow.Left = (Desktop.Width - GraphicsWindow.Width) / 2
      'GUI
      GraphicsWindow.DrawBoundText(25, 25, 95, "Number")
      TextBoxValue = Controls.AddTextBox(25, 50)
      GraphicsWindow.DrawBoundText(200, 25, 95, "Unit")
      TextBoxPrimaryUnit = Controls.AddTextBox(200, 50)
      GraphicsWindow.DrawBoundText(25, 100, 95, "To Unit")
      TextBoxConversionUnit = Controls.AddTextBox(25, 125)
      GraphicsWindow.DrawBoundText(25, 175, 105, "Converted Value")
      TextBoxConvertedValue = Controls.AddTextBox(25, 200)
      ButtonConvert = Controls.AddButton("Convert", 225, 123)
      Controls.SetSize(ButtonConvert, 75, 25)
      ButtonClear = Controls.AddButton("Clear", 225, 173)
      Controls.SetSize(ButtonClear, 75, 25)
    EndSub
      
    Sub CheckLastButtonClicked
      If (Controls.LastClickedButton = ButtonConvert) Then
      'Checks if the text boxes are empty
          If (Controls.GetTextBoxText(TextBoxValue) = "") Or (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "") Or (Controls.GetTextBoxText(TextBoxConversionUnit) = "") Then
            SendWarningMessage()
          Else
      'Make the conversion and put it in the screen
            ConvertAction()
          EndIf
      ElseIf (Controls.LastClickedButton = ButtonClear) Then
        Clear()
      Else
        'Do nothing
      EndIf
    EndSub
    
    Sub Clear
      Controls.SetTextBoxText(TextBoxValue, "")
      Controls.SetTextBoxText(TextBoxPrimaryUnit, "")
      Controls.SetTextBoxText(TextBoxConversionUnit, "")
      Controls.SetTextBoxText(TextBoxConvertedValue, "")
    EndSub
    
    
    Sub ConvertAction
        'Meters to Any
      If (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "meters") Then
        
        If (Controls.GetTextBoxText(TextBoxConversionUnit) = "centimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 100
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "millimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 1000
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "inches") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 39.3700787
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "feet") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 3.2808399 
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "yards") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 1.0936133 
        Else
          SendHelpMessage()
        EndIf
      
        'Centimeteres to Any  
    ElseIf (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "centimeters") then
      
      If (Controls.GetTextBoxText(TextBoxConversionUnit) = "meters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.01
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "millimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 10
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "inches") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.393700787 
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "feet") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.032808399  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "yards") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.010936133 
        Else
          SendHelpMessage()
        EndIf
        
        'Millimeters to Any  
    ElseIf (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "millimeters") then
      
      If (Controls.GetTextBoxText(TextBoxConversionUnit) = "meters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.001
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "centimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.1
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "inches") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0393700787  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "feet") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0032808399   
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "yards") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0010936133  
        Else
          SendHelpMessage()
        EndIf
        
        'Inches to Any  
    ElseIf (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "inches") then
      
      If (Controls.GetTextBoxText(TextBoxConversionUnit) = "meters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0254 
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "centimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 2.54 
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "millimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 25.4  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "feet") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0833333333    
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "yards") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.0277777778   
        Else
          SendHelpMessage()
        EndIf
      
        'Feet to Any  
    ElseIf (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "feet") then
      
      If (Controls.GetTextBoxText(TextBoxConversionUnit) = "meters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.3048  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "centimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 30.48  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "millimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 304.8 
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "inches") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 12     
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "yards") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.333333333    
        Else
          SendHelpMessage()
        EndIf
        
        'Yards to Any  
    ElseIf (Controls.GetTextBoxText(TextBoxPrimaryUnit) = "yards") then
      
      If (Controls.GetTextBoxText(TextBoxConversionUnit) = "meters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 0.9144   
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "centimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 91.44   
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "millimeters") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 914.4  
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "inches") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 36      
        ElseIf (Controls.GetTextBoxText(TextBoxConversionUnit) = "feet") Then
          ConvertedValue = Controls.GetTextBoxText(TextBoxValue) * 3     
        Else
          SendHelpMessage()
        EndIf
        
      Else
        SendHelpMessage()
        'Used for debug! TextWindow.WriteLine("Nothing worked")
      EndIf
      'Show the answer to the screen
      Controls.SetTextBoxText(TextBoxConvertedValue, ConvertedValue)
    EndSub
    
    
    Sub SendWarningMessage
        GraphicsWindow.ShowMessage("Please fill all required text boxes (Number, Unit and To Unit)", "Waning Message")
    EndSub
    
    Sub SendHelpMessage
        GraphicsWindow.ShowMessage("check you units, please input only the following: meters, centimeters, millimeters, inches, feet, yards", "Help Message")
    EndSub
      


    Challenge 4

    Also work's fine but not sure on the result's

    'Created by: Miguel Mendes
    'Calculating the probability of getting 4 of a kind  of any suit in a five card hand of poker on the first round  and the probability of getting a full house - April, Chalenge 4
    
    'Main
    DoFourOfAKindProbability()
    DoFullHouseProbability()
    
    
    'Sub's
    
    Sub DoFourOfAKindProbability
    CalculatePossibleCasses()
    CalculateFavorableCassesToForOfAKind()
    CalculateProbabilityOfFourOfAKind()
    ShowProbabilityOfFourOfAKind()
    EndSub
    
    Sub DoFullHouseProbability
      'CalculatePossibleCasses() no need to cal it a second time
      CalculateFavorableCassesToFullHouse()
      CalculateProbabilityOfFullHouse()
      ShowProbabilityOfFullHouse()
    EndSub
    
    'CALCULATE POSSIBLE CASSES
    
    Sub CalculatePossibleCasses
      'Since 52! is too big for small basic to handle, made some changes
      'From 52 card's i pick 5 = 52C5 <=> 52! / (52-5)! * 5!
      'PossibleCasses = 52! / (52-5)! * 5 ! <=> 52! / 47! * 5! <=>  52*51*50*49*48*47!/47!*5! <=> 52*51*50*49*48 / 5!
      PossibleCasses = (52 * 51 * 50 * 49 * 48) / (5 * 4 * 3 * 2 * 1)
    EndSub
    
    'CALCULATE FAVORABLE CASSES
    
    Sub CalculateFavorableCassesToForOfAKind
      '5 card spaces
      ' _ _ _ _ _
      'Space number 1 --> A random card
      'From 52 card's i pick 1 = 52C1 <=> 52
      'Since a random kind was chosen, the rest of the kind is now unsuitable
      'Spaces numbers 2, 3, 4 and 5
      'From 12 kind's i pick 1  = 12C1 <=> 12
      FarorableCassesToFourOfAkind = 52 * 12
    EndSub
    
    Sub CalculateFavorableCassesToFullHouse
      '5 card spaces
      ' _ _ _ _ _
      'Space number 1 --> A random card
      'From 52 card's i pick 1 = 52C1 <=> 52
      'Space number 2 and 3 --> must be the same kind as the card in Space number 1 so
      'From 3 card's i pick 1 = 3C2 <=> 3
      'Space number 3 --> Another random card
      'Since a random kind was chosen, the rest of the kind is now unsuitable
      'Spaces numbers 4 and 5 From 12 kinds i pick 1 = 12C1 <=> 12
      'And from that kind i pick 2 of the 4 card's = 4C2 <=> 6
      FarorableCassesToFullHouse = 52 * 3 * 12 * 6
    EndSub
    
    'CALCULATE  PROBABILITY
    
    Sub CalculateProbabilityOfFourOfAKind
      ProbabilityOfFourOfAkind = (FarorableCassesToFourOfAkind / PossibleCasses) * 100 ' *100 for percentage  
    EndSub
    
    Sub CalculateProbabilityOfFullHouse
      ProbabilityOfFullHouse = (FarorableCassesToFullHouse / PossibleCasses) * 100
    EndSub
    
    'SHOW PROBABILITY
    
    Sub ShowProbabilityOfFourOfAKind
      TextWindow.WriteLine("Four of a kind probability is: " + ProbabilityOfFourOfAkind + "%")  
    EndSub
    
    Sub ShowProbabilityOfFullHouse
      TextWindow.WriteLine("Full House probability is: " + ProbabilityOfFullHouse + "%")  
    EndSub
    
     

    Challenge 5

    Also work's fine

    'Created by: Miguel Mendes
    'Calculating the cost of a journey - April, Chalenge 5
    
    'Main
    SetUpWindow()
    
    'Event Handler
    Controls.ButtonClicked = CostCalculationProcess
    
    
    
    'Subs
    Sub SetUpWindow
      'SET UP WINDOW
      GraphicsWindow.Title = "Cost of a Journey"
      GraphicsWindow.Width = 375
      GraphicsWindow.Height = 250
      GraphicsWindow.CanResize = "false"
      GraphicsWindow.Top = (Desktop.Height - GraphicsWindow.Height) / 2
      GraphicsWindow.Left = (Desktop.Width - GraphicsWindow.Width) / 2
      'GUI
      GraphicsWindow.DrawBoundText(25, 25, 95, "Distance")
      TextBoxDistance = Controls.AddTextBox(25, 50)
      GraphicsWindow.DrawBoundText(200, 25, 115, "Fuel Consumption")
      TextBoxFuelConsuption = Controls.AddTextBox(200, 50)
      GraphicsWindow.DrawBoundText(25, 100, 95, "Fuel Price")
      TextBoxFuelPrice = Controls.AddTextBox(25, 125)
      GraphicsWindow.DrawBoundText(25, 175, 105, "Total Cost")
      TextBoxTotalCost = Controls.AddTextBox(25, 200)
      ButtonCalculate = Controls.AddButton("Calculate Cost", 225, 158)
      Controls.SetSize(ButtonCalculate, 100, 25)
    EndSub
    
    Sub CostCalculationProcess
      'see if all textBoxes have text
      If Controls.GetTextBoxText(TextBoxDistance) = "" Or Controls.GetTextBoxText(TextBoxFuelConsuption) = "" Or Controls.GetTextBoxText(TextBoxFuelPrice) = "" Then
        ShowHelpMessage()
      Else
        CalculateCost()
        DisplayTotalCost()
      EndIf
    EndSub
    
    Sub CalculateCost
      'Set's up some variables to make the cade easier to understand
      Distance = Controls.GetTextBoxText(TextBoxDistance)
      FuelConsuption = Controls.GetTextBoxText(TextBoxFuelConsuption) 
      FuelPrice = Controls.GetTextBoxText(TextBoxFuelPrice)
      
      'Calculates the final cost
      TotalCost = Distance * FuelConsuption * FuelPrice
    EndSub
    
    Sub DisplayTotalCost
      Controls.SetTextBoxText(TextBoxTotalCost, TotalCost)
    EndSub
    
    Sub ShowHelpMessage
      GraphicsWindow.ShowMessage("Please fill al fields with the riquired information. Make Shure your unit's are correct (Km, l/Km, €/l) or equivalent", "Help Message")  
    EndSub
      


    Challenge 6

    Really have no clue as to what went wrong, the text box has some "lag" problems but if you run the program it will update in the same place every time, need some serious help with this one, (change the Program.Delay to help debug faster)

    Also the when i print "0" as the 1st part of the text, that does nothing and also need help in how to separate the countdown from the time watch because i cant do both at the same time. 

    The code below is obsolete please scroll down to see the answer provided

    'Created by: Miguel Mendes
    'Making a Stopwatch and a Countdown timer - April, Chalenge 5
    'Having trouble with the text box text update
    
    'Main
    SetUpWindow()
    
    'Event Handler
    Controls.ButtonClicked = CheckLastButtonClicked
    
    
    'Sub's
    Sub SetUpWindow
      'SET UP WINDOW
      GraphicsWindow.Title = "Stopwatch and Countdown Timer"
      GraphicsWindow.Width = 600
      GraphicsWindow.Height = 575
      GraphicsWindow.CanResize = "false"
      GraphicsWindow.Top = (Desktop.Height - GraphicsWindow.Height) / 2
      GraphicsWindow.Left = (Desktop.Width - GraphicsWindow.Width) / 2
    'GUI
      GraphicsWindow.FontSize = 85
      TextBoxCounter = Controls.AddTextBox(100, 25)
      Controls.SetTextBoxText(TextBoxCounter, "00:00:00")
      Controls.SetSize(TextBoxCounter, 400, 100)
      TextBoxHH = Controls.AddTextBox(25, 300)
      Controls.SetTextBoxText(TextBoxHH, "HH")
      GraphicsWindow.DrawBoundText(190, 300, 50, ":")
      TextBoxMM = Controls.AddTextBox(225, 300)
      Controls.SetTextBoxText(TextBoxMM, "MM")
      GraphicsWindow.DrawBoundText(390, 300, 50, ":")
      TextBoxSS = Controls.AddTextBox(425, 300)
      Controls.SetTextBoxText(TextBoxSS, "SS")
      GraphicsWindow.FontSize = 12
      ButtonStart = Controls.AddButton("Start", 100, 145)
      Controls.SetSize(ButtonStart, 100, 40)
      ButtonPause = Controls.AddButton("Pause",250 , 145)
      Controls.SetSize(ButtonPause, 100, 40)
      ButtonStop = Controls.AddButton("Stop", 400, 145)
      Controls.SetSize(ButtonStop, 100, 40)
      ButtonStartCountigDown = Controls.AddButton("Start Counting Down", 200,500)
     Controls.SetSize(ButtonStartCountigDown, 200, 50) 
    EndSub
    
     
     Sub CheckLastButtonClicked
       If Controls.LastClickedButton = ButtonStart Then
         WasPaused = "False" 'The counting was not paused before
         ButtonStartAction()
       ElseIf Controls.LastClickedButton = ButtonPause Then 
         ButtonPauseAction()
       ElseIf Controls.LastClickedButton = ButtonStop Then
         ButtonStopAction()
       ElseIf Controls.LastClickedButton = ButtonStartCountigDown Then
         ButtonStartCountigDownAction()
       Else
         'Do Nothing
       EndIf
     EndSub
    
    Sub ButtonStartAction
      If Controls.GetTextBoxText(TextBoxCounter) = "00:00:00" Then 'Chek's the textBox to se if it was already used
        TextWindow.WriteLine("Started Counting") ' Used For debug
        StartCounting()
      Else
        ShowTipMessage() 'Tip's the user to press Stop to reset the text and the counter
      EndIf
      
    EndSub
    
    Sub StartCounting
      If WasPaused = "True" Then 'Ckecks if it comes from the pause button or from the start button
        'do Nothing to maintain the variables of the counter
        WasPaused = "False" ' Makes it able to pause again
      Else 'Reset's the counter variables
      seconds = 0
      minutes = 0
      hours = 1
      EndIf
      
      'TEXT LOOP
      'Cheks if it was started by the buton Start or from the Button pause when it was able to continue and stop's if the last button clicked was the stop button
      While Controls.LastClickedButton = ButtonStart Or Controls.GetButtonCaption(ButtonPause) = "Pause" And Controls.LastClickedButton <> ButtonStop
      Program.Delay(1) ' 1000 to make it work as it should or modify to make it go faster to help debug
      seconds = seconds + 1'increases second's wich increse minutes an hours consequently
      'Makes the the text apear in the correct way (HH:MM:SS)
      If hours = 0 Then
       If seconds < 10 And minutes = 0 Then 
         Controls.SetTextBoxText(TextBoxCounter, "00:00:0" + seconds)
          TextWindow.WriteLine("00:00:0" + seconds) ' debug
       ElseIf seconds >= 10 And minutes = 0 Then
         Controls.SetTextBoxText(TextBoxCounter, "00:00:" + seconds)
          TextWindow.WriteLine("00:00:" + seconds) ' debug
       ElseIf seconds < 10 And minutes < 10 And minutes <> 0 then  
         Controls.SetTextBoxText(TextBoxCounter, "00:0" + minutes + ":0" + seconds)
         TextWindow.WriteLine("00:0" + minutes + ":0" + seconds)' debug
       ElseIf seconds >= 10 and minutes < 10 then
         Controls.SetTextBoxText(TextBoxCounter, "00:0" + minutes + ":" + seconds)
          TextWindow.WriteLine("00:0" + minutes + ":" + seconds) ' debug
        ElseIf seconds < 10 And minutes >= 10 then  
          Controls.SetTextBoxText(TextBoxCounter, "00:" + minutes + ":0" + seconds)
          TextWindow.WriteLine("00:" + minutes + ":0" + seconds)' debug
        ElseIf seconds >= 10 and minutes >= 10 then
          Controls.SetTextBoxText(TextBoxCounter, "00:" + minutes + ":" + seconds)
          TextWindow.WriteLine("00:0" + minutes + ":" + seconds) ' debug
        EndIf
      
      ElseIf hours <10 then 
           If seconds < 10 And minutes = 0 Then 
         Controls.SetTextBoxText(TextBoxCounter,"0" + "0" + hours +  ":00:0" + seconds)
          TextWindow.WriteLine("0" + hours +  ":00:0" + seconds) ' debug
       ElseIf seconds >= 10 And minutes = 0 Then
         Controls.SetTextBoxText(TextBoxCounter, "0" + hours +  ":00:" + seconds)
          TextWindow.WriteLine("0" + hours +  ":00:" + seconds) ' debug
       ElseIf seconds < 10 And minutes < 10 And minutes <> 0 then  
         Controls.SetTextBoxText(TextBoxCounter, "0" + hours +  ":0" + minutes + ":0" + seconds)
         TextWindow.WriteLine("0" + hours +  ":0" + minutes + ":0" + seconds)' debug
       ElseIf seconds >= 10 and minutes < 10 then
         Controls.SetTextBoxText(TextBoxCounter, "0" + hours +  ":0" + minutes + ":" + seconds)
          TextWindow.WriteLine("0" + hours +  ":0" + minutes + ":" + seconds) ' debug
        ElseIf seconds < 10 And minutes >= 10 then  
          Controls.SetTextBoxText(TextBoxCounter, "0" + hours +  ":" + minutes + ":0" + seconds)
          TextWindow.WriteLine("0" + hours +  ":" + minutes + ":0" + seconds)' debug
        ElseIf seconds >= 10 and minutes >= 10 then
          Controls.SetTextBoxText(TextBoxCounter, "0" + hours +  ":" + minutes + ":" + seconds)
          TextWindow.WriteLine("0" + hours +  ":" + minutes + ":" + seconds) ' debug
        EndIf
        
          ElseIf hours >= 10 then 
           If seconds < 10 And minutes = 0 Then 
         Controls.SetTextBoxText(TextBoxCounter, hours +  ":00:0" + seconds)
          TextWindow.WriteLine(hours +  ":00:0" + seconds) ' debug
       ElseIf seconds >= 10 And minutes = 0 Then
         Controls.SetTextBoxText(TextBoxCounter, hours +  ":00:" + seconds)
          TextWindow.WriteLine(hours +  ":00:" + seconds) ' debug
       ElseIf seconds < 10 And minutes < 10 And minutes <> 0 then  
         Controls.SetTextBoxText(TextBoxCounter, hours +  ":0" + minutes + ":0" + seconds)
         TextWindow.WriteLine(hours +  ":0" + minutes + ":0" + seconds)' debug
       ElseIf seconds >= 10 and minutes < 10 then
         Controls.SetTextBoxText(TextBoxCounter, hours +  ":0" + minutes + ":" + seconds)
          TextWindow.WriteLine(hours +  ":0" + minutes + ":" + seconds) ' debug
        ElseIf seconds < 10 And minutes >= 10 then  
          Controls.SetTextBoxText(TextBoxCounter, hours +  ":" + minutes + ":0" + seconds)
          TextWindow.WriteLine(hours +  ":" + minutes + ":0" + seconds)' debug
        ElseIf seconds >= 10 and minutes >= 10 then
          Controls.SetTextBoxText(TextBoxCounter, hours +  ":" + minutes + ":" + seconds)
          TextWindow.WriteLine(hours +  ":0" + minutes + ":" + seconds) ' debug
        EndIf
      
      EndIf
      If seconds = 60 Then 'Seconds to minutes
        seconds = 0
        minutes = minutes + 1
      EndIf
      
      If minutes = 60 Then ' Minutes to hours
        minutes = 0
        hours = hours + 1
      EndIf
      
      EndWhile
    EndSub
    
    Sub ButtonPauseAction
      If Controls.GetTextBoxText(TextBoxCounter) <> "00:00:00" Then 'Chek's to see if it already started couning
        If WasPaused = "False" Then
          WasPaused = "true"
          Controls.SetButtonCaption(ButtonPause, "Continue")
        Else
          Controls.SetButtonCaption(ButtonPause, "Pause")
          StartCounting()'Resumes counting
        EndIf
      Else
        ShowHelpMessage()'The user must be counting in order to pause or stop
      EndIf
    EndSub
    
    Sub ButtonStopAction
      If Controls.GetTextBoxText(TextBoxCounter) <> "00:00:00" Then'Chek's to see if it already started couning
        Controls.SetTextBoxText(TextBoxCounter, "00:00:00")
        GraphicsWindow.ShowMessage("The counter was counting during " + hours + " hours, " + minutes + " minutes and " + seconds + " seconds", "Counter")
        StartCounting()'Reset's the variables
      Else
        ShowHelpMessage()'The user must be counting in order to pause or stop
      EndIf
      
    EndSub
    
    
    Sub ShowHelpMessage
        GraphicsWindow.ShowMessage("You must be counting in order to be able to pause or stop", "Help Message")
    EndSub
      
    Sub ShowTipMessage
        GraphicsWindow.ShowMessage("Press Stop to reset the counter and then try again", "Tip Message")
    EndSub
    
    
    
    'COUNTDOW RELATED 
    
    Sub ButtonStartCountigDownAction
      'read's the variables
      secondsDown = controls.GetTextBoxText(TextBoxSS)
      minutesDown = controls.GetTextBoxText(TextBoxMM)
      hoursDown = controls.GetTextBoxText(TextBoxHH)
      'changes the variables in to milisecond's
      TotalMiliseconds = (secondsDown * 1000) + ((minutesDown * 60) * 1000) + (((hoursDown * 60) * 60) *1000)'*60 hours to minutes *60 minutes to seconds *1000 seconds to milisseconds
      ' set's up the alarm
      Program.Delay(TotalMiliseconds)
      Sound.PlayBellRing()
    EndSub

    NaochanON rewrited my code to this DPH665

    Using the clock.ElapsedMilliseconds propriety instead of the program.delay operation seems to solve the problems with using both countdown and stopwatch at the same time, also hiding the start button was really clever to prevent the user to click it again once it was already counting.


    • Edited by MikeNeto Wednesday, April 18, 2012 1:47 PM Writing the answer to all questions
    Tuesday, April 17, 2012 2:34 PM
  • I think the reason the GoTo doesn't work is that you cannot do a GoTo into or out off a subroutine - this would corrupt the call stack.
    Tuesday, April 17, 2012 6:44 PM
  • i thought it would work since Small Basic has no variable scope
    Tuesday, April 17, 2012 7:54 PM
  • Try this    DPH665
    Wednesday, April 18, 2012 3:16 AM
    Answerer
  • Try this    DPH665

    Great, it work's just as it should thank's.

    All problem's i had are now solved thank you and litdev for the help

    Wednesday, April 18, 2012 1:33 PM
  • In the solutions of Challenge 4 is shown that SmallBasic
    cannot calculate 52! (factotial of 52).
    What if you want to know the value of 52! or 104! or even 1000! ?
    I have written a program which can give you these factorials, though
    you cannot use the answer in calculations.
    In the first part of the program are some variables that can alter
    the behavior of the program, such as which factorial(s) to calculate,
    and how you want the output (scientific notation or as a string 
    with all the digits, with or without a separator every 3 digits.
    The program calculates on my XP  1000! in less then 3 minutes.
    The answer contains 2568 digits (4.02 times 10 to the power 2567)

    I hope someone can use this.  The program is published as RDT140.
    Friday, April 20, 2012 2:50 PM
    Answerer
  •     Wow, a math calc which surpasses SB's variable limit. I'm impressed! It's too far for my understanding though.  *_*
        Anywayz, I've found out a cosmetic tiny bug there. When Ds var, which is the decimal separator char, is set to a period ( Ds= "." ),  the following code line bugs:

    TextWindow.Write(Text.GetSubText(Tout,1,1)+Ds+Text.GetSubTextToEnd(Temp,2))

        Rather than concatenate the whole expression, it just evaluates it as a simple math addition, 'cause a period is a valid char for numeric values, while a comma is not!
        SB concatenates using a + operator only if at least 1 of the arguments is an invalid numeric value, otherwise, it sums them up!
        To assure a concatenation, Text.Append() has to be used instead, rather than trusting the + operator!
        But in this case, since it's used to display the result and not calc & store it, I've just split up the above line code this way here:

    TextWindow.Write(Text.GetSubText(Tout,1,1)+Ds)
    TextWindow.Write(Text.GetSubTextToEnd(Temp,2))

        I've republished it as RDT140-0. Once more, congratz for your code!!!
    Friday, April 20, 2012 9:14 PM
    Answerer
  • 1000! calc is easy.

    t0=clock.ElapsedMilliseconds
    For i=1 To 1000
    a=a+math.Log(i)
    EndFor

    TextWindow.WriteLine("Log(1000!)= "+a)
    b=math.Round(math.Power(10,a-math.Floor(a))*10000)/10000

    TextWindow.WriteLine("1000!= "+b+"*10^ "+Math.Floor(a))
    TextWindow.WriteLine((Clock.ElapsedMilliseconds-t0)+" mSec")

    Friday, April 20, 2012 11:30 PM
    Answerer
  • WhTurner33, GoToLoop, NaochanON,

    I'm very impressed your programs for factorial.


    Nonki Takahashi

    Saturday, April 21, 2012 12:41 AM
  • Okay, I admit, I was doing fine, but now I need some help ...

    How do I tell the program to remember the text written in a textbox, and be able to use that variable (ie. distance) to calculate something? I am working on Challenge 5.


    ------------------------------------------------------------------------------------------

    Monday, April 30, 2012 5:25 AM
  • Oh, wait, I think I need to use Controls.GetTextBoxText to set the variable. Is this true?

    ------------------------------------------------------------------------------------------

    Monday, April 30, 2012 3:49 PM
  • Joman,

    Yes, use GetTextBoxText to get the contents of a textbox, also see of the previous posted answers.

    Monday, April 30, 2012 7:40 PM
  • Thank-you!

    Here is what I came up with in the last few days: RQM981

    (Open and close the program a few times and see what changes:P)


    ------------------------------------------------------------------------------------------


    • Edited by Joman Mied Tuesday, May 1, 2012 1:04 AM Wrong Import Code
    Tuesday, May 1, 2012 12:59 AM
  • Joman Mied,

    Your challenge 5 is colorful!


    Nonki Takahashi

    Thursday, May 3, 2012 10:46 AM