Solved

Memory Game algorithm in VB.Net 2010, help

Posted on 2010-11-08
22
1,818 Views
Last Modified: 2012-05-10
I'm starting with a memory match game, it is a 6x6 blocks (images). the thing is i need to populate the matrix but i dont know how:

I was trying to figure out this way:

first randomize from 1 to 36
assign an image to each number
assign each number a cell in the 6x6 matrix
compare clicked image1 with clicked image 2

That is how i can picture it by now. What i would need from you guys is a help to convert this poor algorithm into VB.Net 2010 code.

Thanks,

Oscar
0
Comment
Question by:José Perez
  • 7
  • 5
  • 5
  • +2
22 Comments
 
LVL 40

Expert Comment

by:Kyle Abrahams
ID: 34084684
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34085327
I think it would be even simpler than that. Just create your grid, randomly each image to two different cells, then, during the game, compare the references of each image to see if they point to the same image. This should be a start. Currently, it displays all the images--you'll need to develop the logic to only display them when they are selected. I left it this way so you can get a feel for what the code is doing.
Public Class Form1
    Private firstSelection As PictureBox

    Private Sub generateButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generateButton.Click
        Dim pb As PictureBox
        Dim cellCount As Integer = 12

        ' Clear existing
        Me.FlowLayoutPanel1.Controls.Clear()

        ' Create the cells
        For i As Integer = 0 To cellCount - 1
            pb = New PictureBox()

            pb.Margin = New Padding(5)
            pb.BackColor = Color.AliceBlue
            AddHandler pb.Click, AddressOf PictureBox_Click
            Me.FlowLayoutPanel1.Controls.Add(pb)
        Next

        ' Load the cells
        Dim rand As New Random(Now.Millisecond)
        Dim images() As Image = {New Bitmap("img1.bmp"), New Bitmap("img2.bmp"), New Bitmap("img3.bmp"), _
                                  New Bitmap("img4.bmp"), New Bitmap("img5.bmp"), New Bitmap("img6.bmp")}
        Dim populatedCount As Integer = 0
        Dim imgIndex As Integer

        ' Loop through available images
        For imgIndex = 0 To images.Length - 1
            ' Fill one image into two cells
            For loopTwice As Integer = 0 To 1
                Do
                    Dim randomInt As Integer = rand.Next(0, cellCount)

                    pb = DirectCast(Me.FlowLayoutPanel1.Controls(randomInt), PictureBox)
                Loop While pb.Image IsNot Nothing

                ' Set the image
                pb.Image = images(imgIndex)
            Next
        Next
    End Sub

    Private Sub PictureBox_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim clickedBox As PictureBox = DirectCast(sender, PictureBox)

        If Me.firstSelection Is Nothing Then
            clickedBox.BorderStyle = BorderStyle.Fixed3D
            Me.firstSelection = clickedBox
        Else
            If Me.firstSelection IsNot clickedBox AndAlso Me.firstSelection.Image Is clickedBox.Image Then
                Me.firstSelection.Image = Nothing
                clickedBox.Image = Nothing
                RemoveHandler Me.firstSelection.Click, AddressOf PictureBox_Click
                RemoveHandler clickedBox.Click, AddressOf PictureBox_Click

                MessageBox.Show("Match")
            End If

            Me.firstSelection.BorderStyle = BorderStyle.None
            Me.firstSelection = Nothing
        End If
    End Sub
End Class

Open in new window

0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34085363
I should have attached a screenshot of the code in action  :)
untitled.PNG
0
 
LVL 2

Author Comment

by:José Perez
ID: 34086513
ok, it is working, but what changes do i have to do to support 6x6 (36 images)?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34086561
Here's a quick Star Wars memory game I made for my son:
http://dl.dropbox.com/u/5131616/StarWarsMemory.zip

*The visual shuffle runs much smoother than in the screencast...the recorder isn't fast enough to capture it properly.
Public Class Form1



    Private Class Card

        Public Img As Image

        Public Name As String

        Public Sub New(ByVal img As Image, ByVal name As String)

            Me.Img = img

            Me.Name = name

        End Sub

    End Class



    Private R As New Random

    Private Cards As New List(Of Card)

    Private ClickCount As Integer = 0



    Private FirstCard, SecondCard As Card

    Private FirstPB, SecondPB As PictureBox



    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Cards.Clear()



        Cards.Add(New Card(My.Resources.Clone_Trooper_256x256, "CloneTrooper"))

        Cards.Add(New Card(My.Resources.Clone_Trooper_256x256, "CloneTrooper"))

        Cards.Add(New Card(My.Resources.Darth_Vader_256x256, "DarthVader"))

        Cards.Add(New Card(My.Resources.Darth_Vader_256x256, "DarthVader"))

        Cards.Add(New Card(My.Resources.Death_Star_256x256, "DeathStar"))

        Cards.Add(New Card(My.Resources.Death_Star_256x256, "DeathStar"))

        Cards.Add(New Card(My.Resources.Master_Joda_256x256, "Yoda"))

        Cards.Add(New Card(My.Resources.Master_Joda_256x256, "Yoda"))

        Cards.Add(New Card(My.Resources.R2D2_256x256, "R2D2"))

        Cards.Add(New Card(My.Resources.R2D2_256x256, "R2D2"))



        Cards.Add(New Card(My.Resources.Bicycle, "Bicycle"))

        Cards.Add(New Card(My.Resources.Bicycle, "Bicycle"))

        Cards.Add(New Card(My.Resources.BobbaFett, "BobbaFett"))

        Cards.Add(New Card(My.Resources.BobbaFett, "BobbaFett"))

        Cards.Add(New Card(My.Resources.Emblem1, "Emblem1"))

        Cards.Add(New Card(My.Resources.Emblem1, "Emblem1"))

        Cards.Add(New Card(My.Resources.Emblem2, "Emblem2"))

        Cards.Add(New Card(My.Resources.Emblem2, "Emblem2"))

        Cards.Add(New Card(My.Resources.RebelHelmet, "RebelHelmet"))

        Cards.Add(New Card(My.Resources.RebelHelmet, "RebelHelmet"))



        For Each pb As PictureBox In Me.Controls.OfType(Of PictureBox)()

            AddHandler pb.Click, AddressOf pb_Click

        Next

    End Sub



    Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown

        Shuffle()

    End Sub



    Private Sub Shuffle()

        If Not BackgroundWorker1.IsBusy Then

            My.Computer.Audio.Play(My.Resources.R2D2, AudioPlayMode.BackgroundLoop)

            BackgroundWorker1.RunWorkerAsync()

        End If

    End Sub



    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Dim C As Card

        Dim index As Integer



        ' shuffle them for awhile while R2D2 sounds play in the background

        Dim targetDT As DateTime = DateTime.Now.AddSeconds(3)

        While targetDT > Now

            For i As Integer = 0 To Cards.Count - 1

                index = R.Next(0, Cards.Count)

                C = Cards(i)

                Cards(i) = Cards(index)

                Cards(index) = C

            Next

            BackgroundWorker1.ReportProgress(0)

            System.Threading.Thread.Sleep(50) ' let them be visible for a split sec

        End While

    End Sub



    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        ' show shuffled cards

        For i As Integer = 0 To Cards.Count - 1

            CType(Me.Controls("PictureBox" & (i + 1)), PictureBox).Tag = True

            CType(Me.Controls("PictureBox" & (i + 1)), PictureBox).Visible = True

            CType(Me.Controls("PictureBox" & (i + 1)), PictureBox).Image = Cards(i).Img

        Next

    End Sub



    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

        ' cover them up

        For i As Integer = 1 To Cards.Count

            CType(Me.Controls("PictureBox" & i), PictureBox).Image = My.Resources.StarWarsLogo

            Me.Controls("PictureBox" & i).Tag = True

        Next

        My.Computer.Audio.Stop()

    End Sub



    Private Sub pb_Click(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim index As Integer

        Dim prefix As String = "PictureBox"

        Dim pb As PictureBox = CType(sender, PictureBox)

        If pb.Tag Then

            pb.Tag = False

            If Integer.TryParse(pb.Name.Substring(prefix.Length), index) Then

                pb.Image = Cards(index - 1).Img

                ClickCount = ClickCount + 1

                If ClickCount = 1 Then

                    FirstCard = Cards(index - 1)

                    FirstPB = pb

                ElseIf ClickCount = 2 Then

                    Application.DoEvents()

                    System.Threading.Thread.Sleep(750)



                    SecondCard = Cards(index - 1)

                    SecondPB = pb

                    If FirstCard.Name = SecondCard.Name Then

                        ' a match!

                        My.Computer.Audio.Play(My.Resources.LAZER_WAV, AudioPlayMode.Background)

                        FirstPB.Visible = False

                        FirstPB.Tag = True

                        SecondPB.Visible = False

                        SecondPB.Tag = True



                        Dim GameOver As Boolean = True

                        For Each ctl As Control In Me.Controls.OfType(Of PictureBox)()

                            If ctl.Visible Then

                                GameOver = False

                                Exit For

                            End If

                        Next

                        If GameOver Then

                            My.Computer.Audio.Play(My.Resources.Force, AudioPlayMode.WaitToComplete)

                            Shuffle()

                        End If

                    Else

                        ' not a match...

                        My.Computer.Audio.Play(My.Resources.chewy1, AudioPlayMode.Background)

                        FirstPB.Image = My.Resources.StarWarsLogo

                        FirstPB.Tag = True

                        SecondPB.Image = My.Resources.StarWarsLogo

                        SecondPB.Tag = True

                    End If



                    ClickCount = 0





                End If

            End If

        End If

    End Sub



End Class

Open in new window

Idle-Mind-367313.flv
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34086817
I'm glad you're able to get the screencasts to upload Idle. I have yet  to have one not error out during upload  :\

As far as my example and sizing it for 6 x 6, you would need to add some math to appropriately size the FlowLayoutPanel. As long as you set the width to max out at six cards, then the rest should "flow" into place automatically. You would want to fix the size of the panel (or maybe even the form) because any resizing of the panel will cause the PictureBoxes to re-flow, thereby messing up the layout.

"cellCount" and the image source ("images" in my example) would obviously change as well  :)
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34086829
I hope George Lucas doesn't come after you for that one  ;)
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34086852
Hehe...no money is being made from the game so I'd think it'd be ok.  =D

*My son picked out all the images to use from a Google image search.
0
 
LVL 2

Author Comment

by:José Perez
ID: 34089276
idle_mind, your code is very good but too advance for me to understand it. the backgroundworker really confuses me so i cant understand your code (very integrated to the other staff in your code). do you have something more simplistic?

kaufmed, your code is very close to what i am looking for, if you could update to work with 6x6 i would really appreciate it :)

OscarG
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 150 total points
ID: 34093187
Here is an updated version. The blanks you see are because I only have 6 images--if the full 18 were provided, then these would have had images in them.
Public Class Form1
    Private firstSelection As PictureBox

    Private Sub generateButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles generateButton.Click
        Dim pb As PictureBox
        Dim cellCount As Integer
        Dim width As Integer
        Dim height As Integer
        Dim dummy As PictureBox = New PictureBox()

        If Not Integer.TryParse(Me.widthBox.Text, width) OrElse Not Integer.TryParse(Me.heightBox.Text, height) Then
            MessageBox.Show("Please enter a valid cell width and cell height!")
            Return
        End If

        cellCount = width * height

        ' Size the FlowLayoutPanel
        dummy.Margin = New Padding(5)
        Me.FlowLayoutPanel1.Width = (dummy.Width + dummy.Margin.Left + dummy.Margin.Right) * width
        dummy = Nothing

        ' Clear existing
        Me.FlowLayoutPanel1.Controls.Clear()

        ' Create the cells
        For i As Integer = 0 To cellCount - 1
            pb = New PictureBox()

            pb.Margin = New Padding(5)
            pb.BackColor = Color.AliceBlue
            AddHandler pb.Click, AddressOf PictureBox_Click
            Me.FlowLayoutPanel1.Controls.Add(pb)
        Next

        ' Load the cells
        Dim rand As New Random(Now.Millisecond)
        Dim images() As Image = {New Bitmap("img1.bmp"), New Bitmap("img2.bmp"), New Bitmap("img3.bmp"), _
                                  New Bitmap("img4.bmp"), New Bitmap("img5.bmp"), New Bitmap("img6.bmp")}
        Dim populatedCount As Integer = 0
        Dim imgIndex As Integer

        ' Loop through available images
        For imgIndex = 0 To images.Length - 1
            ' Fill one image into two cells
            For loopTwice As Integer = 0 To 1
                Do
                    Dim randomInt As Integer = rand.Next(0, cellCount)

                    pb = DirectCast(Me.FlowLayoutPanel1.Controls(randomInt), PictureBox)
                Loop While pb.Image IsNot Nothing

                ' Set the image
                pb.Image = images(imgIndex)
            Next
        Next
    End Sub

    Private Sub PictureBox_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim clickedBox As PictureBox = DirectCast(sender, PictureBox)

        If Me.firstSelection Is Nothing Then
            clickedBox.BorderStyle = BorderStyle.Fixed3D
            Me.firstSelection = clickedBox
        Else
            If Me.firstSelection IsNot clickedBox AndAlso Me.firstSelection.Image Is clickedBox.Image Then
                Me.firstSelection.Image = Nothing
                clickedBox.Image = Nothing
                RemoveHandler Me.firstSelection.Click, AddressOf PictureBox_Click
                RemoveHandler clickedBox.Click, AddressOf PictureBox_Click

                MessageBox.Show("Match")
            End If

            Me.firstSelection.BorderStyle = BorderStyle.None
            Me.firstSelection = Nothing
        End If
    End Sub
End Class

Open in new window

untitled.PNG
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 34094817
Hey these examples are pretty cool, ! It would be perfect to have a designer for these examples. If you think of it as pallete of images you can have one add images to the designer and create a single image pallete that you later could break into the dimensions. Would be flexible and only require maintaining one image the pallete per puzzle but allow the user to generate there own images for a puzzle by loading the pallete.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 2

Author Comment

by:José Perez
ID: 34095355
kaufmed, we're very closer!!! just 2 minor thing:

i have an error "not memeber of Form1" in the following:
'widthBox'
'hightBox'

what kind of controls are this?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34095505
Those are the two textboxes next to the button you see in my last screenshot. The left box is "widthBox" and the right box is "heightBox".
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 34095902
Here is a start for the basic idea for a designer (no GUI) using a single .TIFF image you have a basis for a easy to use pallete.
// usage:

Dim dlg As New OpenFileDialog
dlg.Multiselect = True
dlg.ShowDialog()
' Save the pallete
PuzzleDesigner.AddImage(dlg.FileNames)
PuzzleDesigner.Save("c:\users\medieval\documents\pallete.tiff", 64, 64)
 
' Load the saved pallete.
'Dim pallete As List(Of Image) = PuzzleDesigner.GetImages("c:\users\medieval\documents\pallete.tiff")
'For Each img As Image In pallete
' PictureBox1.Image = img
' Application.DoEvents()
' System.Threading.Thread.Sleep(200)
'Next

Imports System.IO

Imports System.Drawing.Imaging



Public Class PuzzleDesigner

    Private Sub New()

    End Sub



    Private Shared imageItems As New List(Of String)



    Public Shared Sub AddImage(ByVal imagePath As String)

        imageItems.Add(imagePath)

    End Sub

    Public Shared Sub AddImage(ByVal imagePaths() As String)

        imageItems.AddRange(imagePaths)

    End Sub

    Public Shared Sub Clear()

        imageItems.Clear()

    End Sub

    Public Shared Sub Save(ByVal fileName As String, _

                           ByVal w As Integer, _

                           ByVal h As Integer)

        Dim i As Integer

        Dim imageEncoder As Encoder = Encoder.SaveFlag

        Dim imageInfo As ImageCodecInfo = Nothing

        Dim imageCodec As ImageCodecInfo

        Dim ep As New EncoderParameters(1)

        For Each imageCodec In ImageCodecInfo.GetImageEncoders()

            If imageCodec.MimeType = "image/tiff" Then

                imageInfo = imageCodec

            End If

        Next imageCodec

        ep.Param(0) = New EncoderParameter(imageEncoder, EncoderValue.MultiFrame)

        Dim master As New Bitmap(imageItems(0))

        master = master.GetThumbnailImage(w, h, Nothing, IntPtr.Zero)

        master.Save(fileName, imageInfo, ep)

        ep.Param(0) = New EncoderParameter(imageEncoder, EncoderValue.FrameDimensionPage)

        For i = 1 To imageItems.Count - 1

            master.SaveAdd(New Bitmap(imageItems(i)).GetThumbnailImage(w, h, Nothing, IntPtr.Zero), ep)

        Next i

        ep.Param(0) = New EncoderParameter(imageEncoder, EncoderValue.Flush)

        master.SaveAdd(ep)

        master.Dispose()

    End Sub



    Public Shared Function GetImages(ByVal fileName As String) As List(Of Image)

        Dim i As Integer

        Dim imgItems As New List(Of Image)

        Dim fs As FileStream = File.Open(fileName, FileMode.Open, FileAccess.Read)

        Dim bm As Bitmap = Bitmap.FromStream(fs)

        For i = 0 To bm.GetFrameCount(FrameDimension.Page) - 1

            bm.SelectActiveFrame(FrameDimension.Page, i)

            Dim bmItem As New Bitmap(bm.Width, bm.Height)

            Dim g As Graphics = Graphics.FromImage(bmItem)

            g.DrawImageUnscaled(bm, 0, 0)

            g.Dispose()

            imgItems.Add(bmItem)

        Next i

        Return imgItems

    End Function



End Class

Open in new window

0
 
LVL 2

Author Comment

by:José Perez
ID: 34096179
received error "invalid parameter" on this part of the code:

Dim images() As Image = {New Bitmap("img1.bmp"), New Bitmap("img2.bmp"), New Bitmap("img3.bmp"), New Bitmap("img4.bmp"), New Bitmap("img5.bmp"), New Bitmap("img6.bmp"), _

                                 New Bitmap("img7.bmp"), New Bitmap("img8.bmp"), New Bitmap("img9.bmp"), New Bitmap("img10.bmp"), New Bitmap("img11.bmp"), New Bitmap("img12.bmp"), _

                                 New Bitmap("img13.bmp"), New Bitmap("img14.bmp"), New Bitmap("img15.bmp"), New Bitmap("img16.bmp"), New Bitmap("img17.bmp"), New Bitmap("img18.bmp"), _

                                 New Bitmap("img19.bmp"), New Bitmap("img20.bmp"), New Bitmap("img21.bmp"), New Bitmap("img22.bmp"), New Bitmap("img23.bmp"), New Bitmap("img24.bmp"), _

                                 New Bitmap("img25.bmp"), New Bitmap("img26.bmp"), New Bitmap("img27.bmp"), New Bitmap("img28.bmp"), New Bitmap("img29.bmp"), New Bitmap("img30.bmp"), _

                                 New Bitmap("img31.bmp"), New Bitmap("img32.bmp"), New Bitmap("img33.bmp"), New Bitmap("img34.bmp"), New Bitmap("img35.bmp"), New Bitmap("img36.bmp")}

Open in new window

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34096273
It probably can't find the files you're trying to use...

If you're running from the IDE they should be in the \bin folder.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34096316
You could load them this way as well:
    Dim images As New List(Of Image)



    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim imageName As String

        For i As Integer = 1 To 36

            imageName = "img" & i & ".bmp"

            Try

                images.Add(New Bitmap(imageName))

            Catch ex As Exception

                MessageBox.Show("File: " & imageName & vbCrLf & vbCrLf & ex.ToString, "Error Loading Image", MessageBoxButtons.OK, MessageBoxIcon.Error)

            End Try

        Next

    End Sub

Open in new window

0
 
LVL 2

Author Comment

by:José Perez
ID: 34096409
in fact, the 'bin' folder. thanks.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 34096445
IMHO It's a pain to deal with so many images individually this is why a pallete scheme could be very useful to implement you have 1 image per set of images. It will make it easier to to manage them and even be more user friendly if you wanted to add a designer for the user to add there own set of images. *The game may not get old so quick. Keep your kids busy while they make there own puzzle with images. This is the type of features users generally look for in applications it gives them a sense of being part of the game. You could even have a small website or people who build them and upload them as a single file expanding the game giving that extra edge.
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 34096495
LOL... Sometimes you need to talk to the wall
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34096526
I agree with you bud...but as he's learning still it's probably a bit much to wrap his head around.  ;)
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 34097370
>>  in fact, the 'bin' folder. thanks.

The solution was intended as a quick-and-dirty and I didn't make clear where the images were coming from; my apologies. Glad you got the answer.

I would suggest taking some time to study Idle_Mind's solution as well. His solution has a bit more coder-friendly re-usability in it (class Card and use of Resources for example). Don't be discouraged by his use of BackgroundWorker. It is there (to make the GUI more responsive during the shuffle). If you didn't spawn a separate thread from you GUI (which is what BW does internally), then you would get the infamous "[foo] (Not Responding)" until your shuffle logic completed. Besides, it's freakin' Star Wars  ;)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Red error squiggly on vb.net 7 27
Help with LINQ and XML 10 28
Variable Event ? 3 23
VB 2005 Tooltips on Form Load Event 15 16
What is RenderMan: RenderMan is a not any particular piece of software. RenderMan is an industry standard, defining set of rules that any rendering software should use, to be RenderMan-compliant. Pixar's RenderMan is a flagship implementation of …
As game developers, we quickly learn that Artificial Intelligence (AI) doesn’t need to be so tough.  To reference Space Ghost: “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer. (http://www.youtu…
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now