# Would like feedback...

• ### 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

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 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 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 2 For i = 1 To 8 3 Array.SetValue("deck",i,"Blue") 4 EndFor 5 For i = 9 To 15 6 Array.SetValue("deck",i,"Orange") 7 EndFor 8 For i = 16 To 21 9 Array.SetValue("deck",i,"Red") 10 EndFor 11 For i = 22 To 26 12 Array.SetValue("deck",i,"Green") 13 EndFor 14 15 'Shuffle the deck 16 For 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) 21 endfor 22 23 'read out first 3 cards 24 For i = 1 To 3 25 TextWindow.WriteLine(Array.GetValue("deck",i)) 26 EndFor 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