Public Class Form1
Private Delegate Function BotAction(ByVal IsTest As Boolean) As Color
Private Q As ThreeDimensionsMatrix(Of Color, BotAction, Single)
Private Colors As Color() = New Color() {Color.Yellow, Color.Green, Color.Orange, Color.LightBlue}
Private Grid(15)() As Color
Private Position As Point
Private LastAction As BotAction
Private LastColor As Color
Private Function MoveUp(ByVal IsTest As Boolean) As Color
If IsTest = False Then
Position.Y -= 1
If Position.Y < 0 Then Position.Y = 0
Return Grid(Position.X)(Position.Y)
Else
Return Grid(Position.X)(If(Position.Y > 0, Position.Y - 1, Position.Y))
End If
End Function
Private Function MoveDown(ByVal IsTest As Boolean) As Color
If IsTest = False Then
Position.Y += 1
If Position.Y > 15 Then Position.Y = 15
Return Grid(Position.X)(Position.Y)
Else
Return Grid(Position.X)(If(Position.Y < 15, Position.Y + 1, Position.Y))
End If
End Function
Private Function MoveLeft(ByVal IsTest As Boolean) As Color
If IsTest = False Then
Position.X -= 1
If Position.X < 0 Then Position.X = 0
Return Grid(Position.X)(Position.Y)
Else
Return Grid(If(Position.X > 0, Position.X - 1, Position.X))(Position.Y)
End If
End Function
Private Function MoveRight(ByVal IsTest As Boolean) As Color
If IsTest = False Then
Position.X += 1
If Position.X > 15 Then Position.X = 15
Return Grid(Position.X)(Position.Y)
Else
Return Grid(If(Position.X < 15, Position.X + 1, Position.X))(Position.Y)
End If
End Function
Private Sub Learn(ByVal Alpha As Single, ByVal Gamma As Single, ByVal Reward As Single)
Dim Current As Color = Grid(Position.X)(Position.Y)
Dim Max As Single = -1
Dim NextBestAction As BotAction
For Each Action As BotAction In Q.Keys2
If Q(Current, Action) > Max Then
Max = Q(Current, Action)
NextBestAction = Action
End If
Next
'Alpha = coefficiente di apprendimento
' Se Alpha = 0, l'agente non apprende nulla;
' Se Alpha = 1, l'agente tiene conto solo delle esperienze più recenti.
'Gamma = coefficiente di sconto
' Se Gamma = 0, l'agente agisce per una ricompensa immediata
' Se Gamma = 1, l'agente tiene conto delle ricompense che potrà ricevere alla prossima mossa
Q(LastColor, LastAction) = Q(LastColor, LastAction) * (1 - Alpha) + Alpha * (Reward + Gamma * Max)
End Sub
Private Sub RefreshBestAction()
Dim Max As Single
Dim BestAction As BotAction
Dim Current As Color = Grid(Position.X)(Position.Y)
Max = -1
BestAction = Nothing
Current = Grid(Position.X)(Position.Y)
For Each Action As BotAction In Q.Keys2
If Q(Current, Action) > Max Then
Max = Q(Current, Action)
BestAction = Action
End If
Next
lblPrevision.Text = "Previsione" & vbCrLf & "La prossima volta il bot eseguirà questa azione: " & BestAction.Method.Name
End Sub
Private Sub tmrRefresh_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRefresh.Tick
Dim B As New Bitmap(400, 400)
Dim G As Graphics = Graphics.FromImage(B)
G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For I As Int16 = 0 To 15
For J As Int16 = 0 To 15
G.FillRectangle(New SolidBrush(Grid(I)(J)), I * 25, J * 25, 25, 25)
Next
Next
For N As Int16 = 0 To 16
G.DrawLine(Pens.Black, N * 25, 0, N * 25, B.Height)
G.DrawLine(Pens.Black, 0, N * 25, B.Width, N * 25)
Next
G.DrawImage(My.Resources.kopete, New Point(Position.X * 25 + 1, Position.Y * 25 + 1))
imgField.Image = B
G.Dispose()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Rnd As New Random()
For I As Int16 = 0 To 15
ReDim Grid(I)(15)
For J As Int16 = 0 To 15
Grid(I)(J) = Colors(Rnd.Next(Colors.Length))
Next
Next
Q = New ThreeDimensionsMatrix(Of Color, BotAction, Single)(0)
For Each C As Color In Colors
Q.AddKey1(C)
Next
Q.AddKey2(AddressOf MoveUp)
Q.AddKey2(AddressOf MoveDown)
Q.AddKey2(AddressOf MoveLeft)
Q.AddKey2(AddressOf MoveRight)
dgvSummary.DataSource = Q.InnerTable
tmrRefresh.Start()
End Sub
Private Sub btnDoAction_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDoAction.Click
Dim BestAction As BotAction
Dim Max As Single = -1
Dim Current As Color = Grid(Position.X)(Position.Y)
tmrRefresh.Stop()
For Each Action As BotAction In Q.Keys2
If Q(Current, Action) > Max Then
Max = Q(Current, Action)
BestAction = Action
End If
Next
BestAction.Invoke(False)
LastAction = BestAction
LastColor = Current
lblAction.Text = BestAction.Method.Name
lblColor.Text = Current.Name
tmrRefresh.Start()
btnReward.Enabled = True
btnPunish.Enabled = True
Me.RefreshBestAction()
End Sub
Private Sub btnReward_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReward.Click
Learn(nudAlpha.Value / 100, nudGamma.Value / 100, 5)
Me.RefreshBestAction()
End Sub
Private Sub btnPunish_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPunish.Click
Learn(nudAlpha.Value / 100, nudGamma.Value / 100, -5)
Me.RefreshBestAction()
End Sub
Private Sub dgvSummary_CellEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvSummary.CellEnter
lblSummary.Text = String.Format("({0}, {1}) = {2}", Q.Keys1(e.ColumnIndex).Name, Q.Keys2(e.RowIndex).Method.Name, Q.InnerTable.Rows(e.RowIndex).Item(e.ColumnIndex).ToString())
End Sub
Private Sub btnRefreshEverything_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefreshEverything.Click
tmrRefresh.Stop()
Q = Nothing
Form1_Load(Me, EventArgs.Empty)
End Sub
End Class