locked
Would like feedback... RRS feed

  • General discussion

  • Hi, my son and I have been playing around with SmallBasic and we absolutely love it.  Recently, my son bought a used game that did not have a deck of cards required to play.  We found out online what kinds of cards were in this deck, and we've written a program that will let us replicate the mechanic that the card gives in the game.  The basic idea is that there are 4 kinds of cards.  One kind of card has 8 cards, the next has 7, the next 6, and the last 5.  They are four different colors, and there are 26 cards total.  You flip three cards, and based on the pattern, you get points.  Kind of like a slot machine.  Anyway, this is the code we wrote, and I was wondering if there was a more efficient way to do it.  We've pared it down substantially, but we're both new, and I'm sure there is a more efficent and elegant way to write it. 

    Thanks in advance for any feedback, and thank you for making SmallBasic available.
     
    num = 0 
    start: 
    num = (num + 1) 
    a = Math.GetRandomNumber(100) 
     
    While (num < 4
     
        If (a <32) Then 
            TextWindow.WriteLine("Blue") 
            Goto start 
        EndIf 
     
        If (a < 59) Then 
            TextWindow.WriteLine("Orange") 
            Goto start 
        EndIf 
     
        If (a < 81) Then 
                TextWindow.WriteLine("red")            
            Goto start 
            Else 
                TextWindow.WriteLine("green")            
            Goto start 
        EndIf 
     
    EndWhile 

    Tuesday, November 11, 2008 4:04 PM

All replies

  • That's a pretty cool use of Small Basic, Marion.  I'll rewrite your program as below, using the For Loop.

    For num = 1 to 3  
        a = Math.GetRandomNumber(100)  
     
        If (a <32) Then    
            TextWindow.WriteLine("Blue")    
        EndIf    
        If (a < 59) Then    
            TextWindow.WriteLine("Orange")    
        EndIf    
        If (a < 81) Then    
            TextWindow.WriteLine("red")               
        EndIf  
        TextWindow.WriteLine("green")               
    EndFor  
     

    We're considering adding an ElseIf keyword, for the next release.  If that goes through, the inner piece of code would become:

    If (a < 32) Then 
      TextWindow.WriteLine("Blue")  
    ElseIf (a < 59) Then 
      TextWindow.WriteLine("Orange")  
    ElseIf (a < 81) Then 
      TextWindow.WriteLine("Red")  
    Else 
      TextWindow.WriteLine("Green")  
    EndIf  
     

    But until then, you can work with the first version.
    Tuesday, November 11, 2008 5:29 PM
  • How about this?

    Array.SetValue("color",0,"red")
    Array.SetValue("color",1,"orange")
    Array.SetValue("color",2,"blue")
    Array.SetValue("color",3,"green")

    For i = 1 To 3
        a = Math.GetRandomNumber(4) 
        TextWindow.WriteLine(Array.GetValue("color",a))
    EndFor

    I was not quite sure that GetRandomNumber was generating integers or what and if 0 was in the generator but it appears to be integers from 0 to max - 1.  If I see lots of If's I usually figure there is a better way.  Goto's can really make things ugly.

    Tuesday, November 11, 2008 5:57 PM
  • I believe the reason for the GetRandomNumber(100) and then the 32, 59, 81 split was to represent the probability based on the number of cards available for each color set. 

    Although, one could say

    GetRandomNumber(26) and then use 8, 15, 21 as the splits - this would match 1:1 with the number of cards.
    Tuesday, November 11, 2008 6:16 PM
  • Opps.  I did not even look at the probabilities.  And I teach probability!  I shall beat myself profusely about the head and shoulders for being as dumb as a box of rocks.  And my little program looked so cute.
    Tuesday, November 11, 2008 7:17 PM
  • How about a graphics version
     
    'Color Card Game  
    GraphicsWindow.KeyDown = DrawCards 
     
    GraphicsWindow.Show()  
     
    GraphicsWindow.BrushColor = "Black" 
    GraphicsWindow.DrawText(10, 140, "Press any key to deal, 'Q' to quit")  
     
    Sub DrawCards  
     
        K = GraphicsWindow.LastKey  
        K = Text.ConvertToUpperCase(K)  
        If (K = "Q") Then  
            Program.End()  
        EndIf  
          
        For num = 1 To 3  
            'Get a random number  
            a = Math.GetRandomNumber(100)  
              
            'Get correct Color  
            If (a < 32  ) Then    
                CardColor = "Blue" 
            EndIf  
            If (a >= 32 And a < 59 ) Then   
                CardColor = "Orange" 
            EndIf  
            If (a >= 59 And a < 81) Then   
                CardColor = "Red" 
            EndIf  
            If (a >= 81) Then    
                CardColor = "Green" 
            EndIf  
              
            'set the brush to draw the correct color  
            GraphicsWindow.BrushColor = CardColor 
              
            'draw the "cards"  
            If (num = 1) Then  
                GraphicsWindow.FillRectangle(10,10,80,120)  
            EndIf  
            If (num = 2) Then  
                GraphicsWindow.FillRectangle(110,10,80,120)  
            EndIf  
            If (num = 3) Then  
                GraphicsWindow.FillRectangle(210,10,80,120)  
            EndIf  
              
        EndFor  
    EndSub  
     
     
     
     

    • Edited by Rushworks Tuesday, November 11, 2008 8:05 PM
    Tuesday, November 11, 2008 8:04 PM
  • Thank you all for the suggestions.  I knew there had to be a cleaner way of writing it. And thanks for the graphic version, we didn't get that far in the manual, but that is a great idea. 

    Again, thanks for making SmallBasic available, my son really enjoys it, as do I.  It seems like a fantastic way to introduce kids to programming.
    Tuesday, November 11, 2008 10:01 PM
  • Can't quit now.  Here is version 6 (or so).  This just a mod on the graphic version.  I do not like repeated ifs.  I will waste a couple of hours thinking of some way to get rid of or reduce the number of the other ifs.

    'Color Card Game     
    GraphicsWindow.KeyDown = DrawCards    
        
    GraphicsWindow.Show()     
        
    GraphicsWindow.BrushColor = "Black"    
    GraphicsWindow.DrawText(10, 140, "Press any key to deal, 'Q' to quit")     
     
    Sub DrawCards     
          
        K = GraphicsWindow.LastKey     
        K = Text.ConvertToUpperCase(K)     
        If (K = "Q") Then     
            Program.End()     
        EndIf     
             
        For num = 1 To 3     
            'Get a random number     
            a = Math.GetRandomNumber(100)     
                 
            'Get correct Color     
            If (a < 32  ) Then       
                CardColor = "Blue"    
            EndIf     
            If (a >= 32 And a < 59 ) Then      
                CardColor = "Orange"    
            EndIf     
            If (a >= 59 And a < 81) Then      
                CardColor = "Red"    
            EndIf     
            If (a >= 81) Then       
                CardColor = "Green"    
            EndIf     
                 
            'set the brush to draw the correct color     
            GraphicsWindow.BrushColor = CardColor    
                 
            'draw the "cards"     
            'compute the location of the card on the screen  
            coor = (num - 1) * 100 + 10  
            GraphicsWindow.FillRectangle(coor,10,80,120)        
        EndFor     
    EndSub     
     
     
    Tuesday, November 11, 2008 10:10 PM
  • I've tried to think of away to reduce the number of ifs as well, but to no success. I have about 60 if() statements in something I'm writing, just for one section. I figure I have about 70-75 if() statements total. If you find a way, definitely post it! :). I will do likewise.
    • Edited by Pacolaco Wednesday, November 12, 2008 12:50 AM
    Wednesday, November 12, 2008 12:49 AM
  • The problem with all of these solutions is that as cards are 'played' they are not removed from the deck.
    This leads to the possibility of statistically improbable sets such as Green-Green-Green occurring more than they should.  A solution to this is to enumerate the entire deck, shuffle the deck then read out however many cards you want.  Doing it this way also has the effect of removing all of the IF statements and de-spaghetti-ising your code.

    1'initialise deck 
    2For i = 1 To 8 
    3    Array.SetValue("deck",i,"Blue") 
    4EndFor 
    5For i = 9 To 15 
    6    Array.SetValue("deck",i,"Orange") 
    7EndFor 
    8For i = 16 To 21 
    9    Array.SetValue("deck",i,"Red") 
    10EndFor 
    11For i = 22 To 26 
    12    Array.SetValue("deck",i,"Green") 
    13EndFor 
    14 
    15'Shuffle the deck 
    16For i = 1 To 26 
    17    j = Math.GetRandomNumber(26) +1 
    18    temp = Array.GetValue("deck",i) 
    19    Array.SetValue("deck",i,array.GetValue("deck",j))  
    20    Array.SetValue("deck",j,temp) 
    21endfor 
    22 
    23'read out first 3 cards 
    24For i = 1 To 3 
    25    TextWindow.WriteLine(Array.GetValue("deck",i)) 
    26EndFor 
    27 

    This can be cleaned up a little by implementing functions and making it more user friendly but it should give a better idea of how to do it.

    Another thing to point out is the use of Math.GetRandomNumber(x) this will return {0 <= value < x}.  If one uses 1 as the start of any index and setx x to 26, then you run into the possibility of this function returning 0 (below the start of your count), also it will never return 26 which is the last card.
    In order to get intended use out of this, simply add one to the return value to convert the {0 <= value < x} to {1 <= value <= x}



    Wednesday, November 12, 2008 5:32 AM
  • Very nice, Tekgno!
    Wednesday, November 12, 2008 6:06 AM
  • Some people are just too damn smart.  Tekgno's solution is sweet and real.  I will have to wait for the next seemingly trivial problem to spend too much time on.
    Wednesday, November 12, 2008 6:49 PM