-
Sep 16th, 2020, 06:29 PM
#1
Contest 14 - DnD Dice Roller (Delaney - VB.net)
Hello
Finally, I chose the console application, I never made one before and it reminds me my old days with DOS (when I was young )
Here is my contribution :
VB.NET (2017) Code:
Imports System Imports System.Collections.Generic Imports System.Linq Module RollTheDices Sub Main() Console.Title = "Roll the dices!!" Console.WriteLine("quit to exit, help for info how to write the command" & Environment.NewLine & "enter you roll command") While True Dim command As String = Console.ReadLine If command.ToLower = "quit" Then Exit While ElseIf command.ToLower = "help" Then Console.WriteLine("Enter your command under the template xdy with x the number of dices and y the number of faces of the dice") Console.WriteLine("You can roll several types of dice by simply separate the command with a comma or a space") Console.WriteLine("Dices allowed are 4-sided, 6-sided, 8-sided, 10-sided, 12-sided, 20-sided and percentage dice (you must use % instead of 100)") Console.WriteLine("Examples : 1d6,8d4 1d%") ElseIf command = "" Then 'deal with empty input Else Roll(command.ToLower) End If End While MsgBox("Thank you for playing",, "Good Bye") End Sub Public Class Dice Property dice_command As String Property Nb As Integer Property Max As Integer Property Result As Integer() End Class Public Function Getresult(a As Integer, b As Integer) As Integer() Dim RND As New Random Dim value(a) As Integer For i = 0 To a - 1 value(i) = RND.Next(1, b + 1) Next value(a) = value.Sum Return value End Function Private Sub Roll(commande As String) Dim game As New List(Of Dice) Try Dim dices() As String = commande.Split(New Char() {" "c, ","c}, StringSplitOptions.None) For Each ddice In dices Dim values() As String = ddice.Split(New Char() {"d"c}) If values(0) = Nothing Then values(0) = "1" ' in case you enter d6 instead of 1d6 If Not (values(1).Contains("4") Or values(1).Contains("6") Or values(1).Contains("8") Or values(1).Contains("10") Or values(1).Contains("12") Or values(1).Contains("20") Or values(1).Contains("%")) Then Console.WriteLine("This dice d{0} doesn't exist, try again", values(1)) Exit Sub End If If values(1) = "%" Then values(1) = "100" 'affect % Dim de As New Dice With {.dice_command = ddice, .Nb = CInt(values(0)), .Max = CInt(values(1)), .Result = Getresult(.Nb, .Max)} game.Add(de) Next Catch ex As Exception Console.WriteLine("You did something wrong ;) try again !") End Try For Each dice In game Dim texte As String = "" With dice texte += String.Format("{0} --> ", .dice_command) For i = 0 To dice.Nb - 1 texte += String.Format("{0}, ", .Result(i).ToString) Next texte += String.Format("Total = {0} ", .Result(.Nb).ToString) End With Console.WriteLine(texte) Next End Sub End Module
and the fiddle link : https://dotnetfiddle.net/BbF0Tw
Regards
Last edited by Delaney; Oct 27th, 2020 at 04:30 AM.
Reason: added the language in the title
The best friend of any programmer is a search engine
"Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
“They did not know it was impossible so they did it” (Mark Twain)
-
Oct 26th, 2020, 11:38 AM
#2
Re: Contest 14 - DnD Dice Roller (Delaney)
The program worked without issues.
In terms of length of code, this one is certainly the shortest.
There were a couple of areas of improvement that I could see. For example:
Code:
If command.ToLower = "quit" Then
Typically you'd want to use the String::Equals method and pass the StringComparison overload:
Code:
If command.Equals("quit", StringComparison.OrdinalIgnoreCase) Then
Also, the Random class should not be declared inside the GetResult function. Instead, it should declared as a ReadOnly variable at the module level:
Code:
Private ReadOnly _rnd As New Random()
There were some stylistic issues I had with the code, such as mixing the & and + operators to concatenate Strings. I also would loved to have seen delegates used to parse the incoming commands, but these don't actually go against you. They are more ramblings inside my mind.
-
Oct 27th, 2020, 04:26 AM
#3
Re: Contest 14 - DnD Dice Roller (Delaney)
Originally Posted by dday9
I also would loved to have seen delegates used to parse the incoming commands,
Hello Dday9,
I would need your help to understand how to do it because I don't know this way. Can you give me an example ?
regards
The best friend of any programmer is a search engine
"Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
“They did not know it was impossible so they did it” (Mark Twain)
-
Oct 27th, 2020, 10:15 AM
#4
Re: Contest 14 - DnD Dice Roller (Delaney - VB.net)
Take a look at this example:
Code:
Imports System
Imports System.Collections.Generic
Public Module Program
Private Delegate Function CommandDelegate() As Boolean
Private ReadOnly Commands As New Dictionary(Of String, CommandDelegate) From {
{ "quit", New CommandDelegate(AddressOf Quit) },
{ "help", New CommandDelegate(AddressOf Help) }
}
Public Sub Main()
Help()
Dim arguments() As String
Dim playing As Boolean = True
Do
Console.Write("> ")
arguments = Console.ReadLine().Split({" "c}, StringSplitOptions.RemoveEmptyEntries)
Try
playing = ParseInput(arguments)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Loop While playing
End Sub
Private Function ParseInput(arguments() As String) As Boolean
If (arguments.Length = 0) Then
' handle empty input
Return True
End If
Dim argument1 As String = arguments(0)
If (Not Commands.ContainsKey(argument1)) Then
' roll
Return True
End If
Return Commands(argument1).Invoke()
End Function
Private Function Help() As Boolean
Console.WriteLine("Enter ""help"" to bring up these instructions.")
Console.WriteLine("Enter ""quit"" to stop rolling.")
Console.WriteLine("Enter your command under the template xdy with x the number of dices and y the number of faces of the dice")
Console.WriteLine("You can roll several types of dice by simply separate the command with a comma or a space")
Console.WriteLine("Dices allowed are 4-sided, 6-sided, 8-sided, 10-sided, 12-sided, 20-sided and percentage dice (you must use % instead of 100)")
Console.WriteLine("Examples : 1d6,8d4 1d%")
Return True
End Function
Private Function Quit() As Boolean
Return False
End Function
Private Sub Roll(<[ParamArray]()> arguments() As String)
' logic here
End Sub
End Module
Fiddle: https://dotnetfiddle.net/tV0roK
The basic idea in this example is that a delegate function is setup which will return a boolean value that represents if the user wants to continue playing. The commands with their respective functions are defined in the Commands dictionary. Then in your main loop, you check for valid input which in turn invokes the respective command's delegate function.
Last edited by dday9; Oct 28th, 2020 at 08:47 AM.
-
Oct 28th, 2020, 04:56 PM
#5
Re: Contest 14 - DnD Dice Roller (Delaney - VB.net)
Thanks for the example. if i understand well, at some point you associate some words (string) to some functions so when you write the word, it call the function associated.
The best friend of any programmer is a search engine
"Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
“They did not know it was impossible so they did it” (Mark Twain)
-
Oct 29th, 2020, 07:52 PM
#6
Re: Contest 14 - DnD Dice Roller (Delaney - VB.net)
That's basically right.
The dictionary of String, Delegate in this case associates a word to the delegate function. In my opinion it is a more efficient means of code management because it allows you to easily add/remove commands.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|