在表单

时间:2015-06-27 09:20:38

标签: vb.net winforms

我试图用VB Express 2013模拟'赛马',这让我对线程如何与windows窗体一起工作的理解存在差距。我们的想法是,当按下表单上的按钮时,蓝色正方形和红色正方形(马匹)从一个表格(具有白色背景)从左到右竞赛。每个运动增量应该是(伪)随机生成的,因此胜利者应该是不可预测的。

这是我用过的代码。方块的运动确实是随机的,但它们一起移动,而不是独立移动,所以比赛总是一个平局。如果我只在一个线程程序中包含Randomize,它的行为更像是一场比赛,但胜利者通常是可以预测的。有人可以告诉我我错过了什么吗?感谢您的期待。

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim t1 As System.Threading.Thread
        Dim t2 As System.Threading.Thread

        t1 = New System.Threading.Thread(AddressOf RedHorse)
        t2 = New System.Threading.Thread(AddressOf BlueHorse)

        t1.Start()
        t2.Start()

    End Sub

    Public Sub RedHorse()
        Randomize()
        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bRed As Brush
        bRed = New SolidBrush(Color.Red)
        Dim bWhite As Brush
        bWhite = New SolidBrush(Color.White)

        Dim x1 As Integer
        x1 = 100

        G.FillRectangle(bWhite, x1, 100, 50, 50)

        Do Until x1 >= 800
            x1 = x1 + Rnd()
            G.FillRectangle(bRed, x1, 100, 50, 50)
            Threading.Thread.Sleep(1)
            G.FillRectangle(bWhite, x1, 100, 50, 50)
        Loop
    End Sub

    Public Sub BlueHorse()
        Randomize()
        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bBlue As Brush
        bBlue = New SolidBrush(Color.Blue)
        Dim bWhite As Brush
        bWhite = New SolidBrush(Color.White)

        Dim x2 As Integer
        x2 = 100

        G.FillRectangle(bWhite, x2, 200, 50, 50)

        Do Until x2 >= 800
            x2 = x2 + Rnd()
            G.FillRectangle(bBlue, x2, 200, 50, 50)
            Threading.Thread.Sleep(1)
            G.FillRectangle(bWhite, x2, 200, 50, 50)
        Loop

    End Sub

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

        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bRed As Brush
        bRed = New SolidBrush(Color.Red)
        Dim bBlue As Brush
        bBlue = New SolidBrush(Color.Blue)

        G.FillRectangle(bRed, 100, 100, 50, 50)
        G.FillRectangle(bBlue, 100, 200, 50, 50)

    End Sub
End Class

1 个答案:

答案 0 :(得分:0)

首先不要使用Randomize,使用Random类,阅读本文。基本问题是线程同时启动,然后在循环之间同时睡眠。这是您的代码,但有一些更改。

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        'Me.Width = 1000 'testing
        isWinner = -1

        Dim t1 As System.Threading.Thread
        Dim t2 As System.Threading.Thread

        t1 = New System.Threading.Thread(AddressOf RedHorse)
        t2 = New System.Threading.Thread(AddressOf BlueHorse)

        t1.Start()
        t2.Start()

    End Sub

    Dim prng As New Random
    Const maxMove As Integer = 21
    Const maxSleep As Integer = 51
    Dim isWinner As Integer = -1

    Public Sub RedHorse()
        Threading.Thread.Sleep(prng.Next(maxSleep))
        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bRed As Brush
        bRed = New SolidBrush(Color.Red)
        Dim bWhite As Brush
        bWhite = New SolidBrush(Color.White)

        Dim x1 As Integer
        x1 = 100

        G.FillRectangle(bWhite, x1, 100, 50, 50)

        Do While x1 < 800 AndAlso isWinner < 0
            x1 = x1 + prng.Next(maxMove)
            G.FillRectangle(bRed, x1, 100, 50, 50)
            Threading.Thread.Sleep(prng.Next(maxSleep))
            G.FillRectangle(bWhite, x1, 100, 50, 50)
        Loop
        'G.FillRectangle(bRed, x1, 100, 50, 50)
        If isWinner < 0 Then
            isWinner = 1
        End If
    End Sub

    Public Sub BlueHorse()
        Threading.Thread.Sleep(prng.Next(maxSleep))
        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bBlue As Brush
        bBlue = New SolidBrush(Color.Blue)
        Dim bWhite As Brush
        bWhite = New SolidBrush(Color.White)

        Dim x2 As Integer
        x2 = 100

        G.FillRectangle(bWhite, x2, 200, 50, 50)

        Do While x2 < 800 AndAlso isWinner < 0
            x2 = x2 + prng.Next(maxMove)
            G.FillRectangle(bBlue, x2, 200, 50, 50)
            Threading.Thread.Sleep(prng.Next(maxSleep))
            G.FillRectangle(bWhite, x2, 200, 50, 50)
        Loop
        'G.FillRectangle(bBlue, x2, 200, 50, 50)
        If isWinner < 0 Then
            isWinner = 2
        End If
    End Sub

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

        Dim G As Graphics
        G = Me.CreateGraphics
        Dim bRed As Brush
        bRed = New SolidBrush(Color.Red)
        Dim bBlue As Brush
        bBlue = New SolidBrush(Color.Blue)

        G.FillRectangle(bRed, 100, 100, 50, 50)
        G.FillRectangle(bBlue, 100, 200, 50, 50)
    End Sub
End Class