16
Tags:
visual-basic
Skrevet af
Bruger #2353
@ 05.08.2004
Introduktion
I denne artikel vil jeg vise dig, hvorledes et klassisk kryds og bolle spil kan udformes. Visual Basic kan helt klart anvendes til disse meget konkrete og kreative udfoldelser, men det skal være helt klart, at noget grafisk krævende ikke er muligt på en simpel måde. Et kryds og bolle spil sætter ikke store krav til computerens processor, derfor er det ideelt at designe et sådant spil i netop VB. Jeg benytter VB 6.0, men koden vil angivelig strække sig helt ned til version 3.0.
I spillet er der nogle klare overordnede problemstillinger at have i bevidstheden:
- Det skal være muligt at spille to spillere mod hinanden
- Det skal være muligt at spille mod en kunstig intelligens
- Grafikken skal være overskuelig og funktionel
Det punkt der sætter de største krav til programmøren er naturligvis den kunstige intelligens, da den skal kunne forudsige nogle træk hos modstanderen og samtidig trække sig selv nærmere sejren. Jeg vil ikke fokusere, at intelligensen har en særlig intelligent indsigt i spillet, den bruger populært sagt udelukkelsesmetoden, og tillader ikke åbenlyse fejl. Den er derimod ikke i stand til at kunne sætte sig i sin modstanders sted og derudfra planlægge en strategi.
Lad os se på selve designet, eller brugergrænsefladen. (Du kan hente hele spillet ned med en detaljeret og overskuelig beskrivelse af hvert punkt, hvis du foretrækker det)
Placeringen:
http://udvikleren.dk/articlefiles/Kryds%20og%20Bolle.zipBrugerfladen
Vi skal bruge to forme, som jeg kalder Form1 og form2. Form1 er stedet, hvor selve spillets gang finder sted. Det skal indeholde følgende:
- Et vindue hvor krydserne og bollerne placeres i. (En picturebox med navnet: ”Skærm”) Størrelsen skal passe til 3x3 felter (Jeg bruger 6000x6000 twips).
- Tre knapper: Command1 = Start forfra – Command2 = Nye Indstillinger – Command3 = Luk
- En statusboks der viser hvis tur, det er. Kald den bare Label1
Form2 er startformen, altså stedet hvor indstillingerne vælges. (Vælg form2 som startform ved at højreklikke i projektvinduet i højre hjørne og vælge projekt1 properties. Efterfølgende vælger du Form2 som startup object.) Vi får brug for dette:
- To optionbuttons. De står for: ”To spillere” og ”Spil mod den kunstige intelligens”.
- To knapper: ”Luk” og ”start”
- Alle elementer bibeholder deres oprindelige navne.
Indholdet
Nu skal vi kigge på noget af indholdet i spillet. Lad os starte med det tørre – selve navigationen, du koder på form2. Kopier understående direkte ind i projektet. (Vælg form2’s generel procedure og vælg ”sæt ind” eller ”paste”) Der er ingen grund til at forklare de enkelte dele i detaljer her, se kommentarerne inde i selve projektet:
Private Sub Command1_Click()
' Angiver spillemåden
If Option1.Value = True Then
' Spiller to spillere
SpilleMåde = True
Else
' Spiller mod computeren
SpilleMåde = False
End If
' Viser spil-formen
Form1.Show
Unload Me
End Sub
Private Sub Command2_Click()
End
End Sub
Som det fremgår af koden, har jeg defineret en variabel der hedder ”SpilleMåde”. Denne variabel styrer spiller2s identitet. Hvis spillemåde indbefatter en sand værdi (True) spilles der to spillere. Opret nu et Modul ved navn ”Module1”. Det skal indeholde alle vores procedurer og variabler. Du kan ligeså godt kopiere hele indholdet ind i dit projekt med det samme, jeg refererer og forklarer i detaljer senere.
' Værdierne for hvert enkelt felt
Public Type VærdiFelt
' 0 betyder at feltet ikke er i brug endnu
' 1 = spiller 1
' 2 = spiller 2
Status As Integer
End Type
' Sætter variablen i funktion
Public Felt(3, 3) As VærdiFelt
' Spillerens tur
Public Tur As Integer
' Spillemåde (to spillere?)
Public SpilleMåde As Boolean
Public Sub BegyndSpillet()
' Nulstiller variablerne
For X = 1 To 3
For Y = 1 To 3
Felt(X, Y).Status = 0
Next Y
Next X
Tur = 1
' ========================
' Grafikken i pictureboxen
With Form1.Skærm
' Fjerner al grafik
.Cls
' Tegner gitter
For X = 1 To 2
For Y = 1 To 2
Form1.Skærm.Line (0, Y)-(3, Y), RGB(200, 200, 200)
Next Y
Form1.Skærm.Line (X, 0)-(X, 3), RGB(200, 200, 200)
Next X
End With
' =======================
' Spillerenes ture
Opdater
End Sub
Public Sub Opdater()
' * * * * * * * * * * * * *
' Se den kunstige intelligens i bunden
' * * * * * * * * * * * * *
With Form1
' Skriv spillerens navn
.Label1.Caption = "Spiller " & Tur & "'s tur"
' Tegn grafik
.Skærm.Cls
' Checker hvert felt seperat
For X = 1 To 3
For Y = 1 To 3
' Tegner et kryds for spiller 1
If Felt(X, Y).Status = 1 Then
.Skærm.Line (X - 1 + 0.2, Y - 1 + 0.2)-(X - 0.2, Y - 0.2), 0
.Skærm.Line (X - 0.2, Y - 1 + 0.2)-(X - 0.8, Y - 0.2), 0
End If
' Bolle for spiller 2
If Felt(X, Y).Status = 2 Then
.Skærm.Circle (X - 0.5, Y - 0.5), 0.4, 0
End If
Next Y
Next X
End With
' =========================
' Check om der er en vinder
'(Dette må desværre gøres "manuelt")
Dim VinderNummer As Integer
' (ingen vinder = 0)
VinderNummer = 0
' Vertikale placeringer
If Felt(1, 1).Status = Felt(1, 2).Status And Felt(1, 1).Status = Felt(1, 3).Status Then
VinderNummer = Felt(1, 1).Status
End If
If Felt(2, 1).Status = Felt(2, 2).Status And Felt(2, 1).Status = Felt(2, 3).Status Then
VinderNummer = Felt(2, 1).Status
End If
If Felt(3, 1).Status = Felt(3, 2).Status And Felt(3, 1).Status = Felt(3, 3).Status Then
VinderNummer = Felt(3, 1).Status
End If
' Horisontale placeringer
If Felt(1, 1).Status = Felt(2, 1).Status And Felt(1, 1).Status = Felt(3, 1).Status Then
VinderNummer = Felt(1, 1).Status
End If
If Felt(1, 2).Status = Felt(2, 2).Status And Felt(1, 2).Status = Felt(3, 2).Status Then
VinderNummer = Felt(1, 2).Status
End If
If Felt(1, 3).Status = Felt(2, 3).Status And Felt(1, 3).Status = Felt(3, 3).Status Then
VinderNummer = Felt(1, 3).Status
End If
' De to diagonale placeringer
If Felt(1, 1).Status = Felt(2, 2).Status And Felt(2, 2).Status = Felt(3, 3).Status Then
VinderNummer = Felt(1, 1).Status
End If
If Felt(1, 3).Status = Felt(2, 2).Status And Felt(1, 3).Status = Felt(3, 1).Status Then
VinderNummer = Felt(1, 3).Status
End If
' Er der en vinder?
If VinderNummer = 1 Then
MsgBox "Spiller 1 vandt!", vbInformation
BegyndSpillet
End If
If VinderNummer = 2 Then
If SpilleMåde = True Then
MsgBox "Spiller 2 vandt!", vbInformation
Else
MsgBox "Du må se dig slået af den kunstige intelligens, Tom! Tillykke til Tom!", vbInformation
End If
BegyndSpillet
End If
' Checker om alle felter er udfyldt
If VinderNummer = 0 Then
Dim Fyldt As Boolean
Fyldt = True
For X = 1 To 3
For Y = 1 To 3
If Felt(X, Y).Status = 0 Then
Fyldt = False
End If
Next Y
Next X
' Alle felter er fyldt
If Fyldt = True Then
MsgBox "Der var ingen vindere!", vbInformation
BegyndSpillet
Exit Sub
End If
End If
' == Tom rykker == '
' ==================
' Computeren rykker
If SpilleMåde = False And Tur = 2 Then
ComputerTænk
Opdater
End If
End Sub
Public Sub ComputerTænk()
' Disse ca. hundrede linjer repræsenterer:
' TOMS INTELLIGENS '
' Kodet af Rasmus Hedegård Sørensen '
' I princippet kunne der blot indtastes en masse
' informationer og strategier i denne procedure,
' men jeg forsøger at gøre det en lille smule mere
' kompliceret ved brug af løkker. Denne procedure
' afgør selvsagt kvaliteten af den kunstige intelligens
' og kan modificeres efter behov.
' (Jeg skriver ikke kommentarer til denne del,
' da det ikke er relevant, men blot et led i en
’ indtastningsproces. )
' *************************
' - - Forebygger sejr til spiller 1 - - '
' Vertikalt
For X = 1 To 3
If Felt(X, 1).Status = 1 And Felt(X, 2).Status = 1 And Felt(X, 3).Status = 0 Then
Felt(X, 3).Status = 2
GoTo rykket
End If
If Felt(X, 1).Status = 1 And Felt(X, 2).Status = 0 And Felt(X, 3).Status = 1 Then
Felt(X, 2).Status = 2
GoTo rykket
End If
If Felt(X, 1).Status = 0 And Felt(X, 2).Status = 1 And Felt(X, 3).Status = 1 Then
Felt(X, 1).Status = 2
GoTo rykket
End If
Next X
' Horisontalt
For Y = 1 To 3
If Felt(1, Y).Status = 1 And Felt(2, Y).Status = 1 And Felt(3, Y).Status = 0 Then
Felt(3, Y).Status = 2
GoTo rykket
End If
If Felt(1, Y).Status = 1 And Felt(2, Y).Status = 0 And Felt(3, Y).Status = 1 Then
Felt(2, Y).Status = 2
GoTo rykket
End If
If Felt(1, Y).Status = 0 And Felt(2, Y).Status = 1 And Felt(3, Y).Status = 1 Then
Felt(1, Y).Status = 2
GoTo rykket
End If
Next Y
' Diagonal1
If Felt(1, 1).Status = 0 And Felt(2, 2).Status = 1 And Felt(3, 3).Status = 1 Then
Felt(1, 1).Status = 2
GoTo rykket
End If
If Felt(1, 1).Status = 1 And Felt(2, 2).Status = 0 And Felt(3, 3).Status = 1 Then
Felt(2, 2).Status = 2
GoTo rykket
End If
If Felt(1, 1).Status = 1 And Felt(2, 2).Status = 1 And Felt(3, 3).Status = 0 Then
Felt(3, 3).Status = 2
GoTo rykket
End If
' Diagonal2
If Felt(1, 3).Status = 0 And Felt(2, 2).Status = 1 And Felt(3, 1).Status = 1 Then
Felt(1, 3).Status = 2
GoTo rykket
End If
If Felt(1, 3).Status = 1 And Felt(2, 2).Status = 0 And Felt(3, 1).Status = 1 Then
Felt(2, 2).Status = 2
GoTo rykket
End If
If Felt(1, 3).Status = 1 And Felt(2, 2).Status = 1 And Felt(3, 1).Status = 0 Then
Felt(3, 1).Status = 2
GoTo rykket
End If
' - - Rykker for at sejre - - '
' Hvis "Goto rykket" ikke er aktiveret
' vil denne del af proceduren automatisk
' blive aktuel.
' Det er i denne del, at den kunstige
' intelligens let kunne udvikles.
FindIgen:
Dim vX, vY As Integer
Randomize
vX = Int(Rnd * 3) + 1
vY = Int(Rnd * 3) + 1
If Felt(vX, vY).Status = 0 Then
' Der er fundet et tilfældigt
' ledigt felt.
Felt(vX, vY).Status = 2
Else
' Feltet er optaget - forsøg igen.
GoTo FindIgen
End If
rykket:
' **************************
' Skifter turen tilbage igen
Tur = 1
End Sub
Nu har vi i princippet allerede den kunstige intelligens, men lad os vente med at sætte fokus på den; lige nu skal vi se på selve spillets udformning, vi skal se på form1.
Det, der er helt afgørende for lige præcis dette spil, er, at jeg bruger en enkelt picturebox til at vise hele spillets gang. Men problemet er, at den skal vise 3x3 felter, altså de 9 felter spilleren kan benytte til at placere sit kryds eller sin bolle. Men det gøres meget enkelt, vi deler den simpelthen op ved at indstille følende variabler:
Skærm.scalewidth = 3
Skærm.scaleheight = 3
(Du kan enten gøre det i selve koden eller i projektet – når du klikker på pictureboxen. Sidste alternativ bliver brugt i programmet, der kan hentes.)
Nu består pictureboxen af 9 felter som sagt. Hvis vi skriver: ”skærm.line (0,0)-(1,1),0,bf” vil der komme en stor firkant til syne til forskel fra en picturebox med en standart scalewidth og –height.
For at have kontrol over de forskellige værdier, hvert felt indeholder, har jeg defineret et type-function i Module1. Kig i module1’s declarations procedure. Denne form for variabler kan bruges på en måde, så man fx kan skrive: Felt(2,3).status = 2. Det er altså en variabel der indeholder i alt 9 mulige, varierende værdier. (Idet der er 9 felter!)
Før vi går videre, skal du indsætte sidste del kode i dit projekt. Den skal indsættes i form1.
Private Sub Command1_Click()
BegyndSpillet
End Sub
Private Sub Command2_Click()
Form2.Show
Unload Me
End Sub
Private Sub Command3_Click()
End
End Sub
Private Sub Form_Load()
' Formens bredde
Me.Width = Skærm.Width + 380
' Nulstil
BegyndSpillet
End Sub
Private Sub Skærm_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim xPos, yPos As Integer
' Angiver den præcise x- og y-position
xPos = Int(X) + 1
yPos = Int(Y) + 1
' Checker om det er tilladt at placere en markering her
If Felt(xPos, yPos).Status = 0 Then
' Placer et ikon!
' Feltet er = tur = spillerens nummer
Felt(xPos, yPos).Status = Tur
' Næste spillers tur
Tur = Tur + 1
' Hov, hov - kun to spillere!
If Tur = 3 Then: Tur = 1
' * * * * * * * * * * * * * * * * * * '
' Den kunstige intelligens udregnes i '
' understående procedure '
' * * * * * * * * * * * * * * * * * * '
Opdater
' (Grafikken vises også i "opdater") '
Else
' Fejlmeddelelse
MsgBox "Det er ikke muligt at markere dette felt!", vbCritical
End If
End Sub
I proceduren hvor musen trykker ned på pictureboxen, ser vi følgende:
- Det ønskede felt lokaliseres gennem en undersøgelse af musens x- og y-position. Ved at anvende dette tal som et heltal, kan det direkte sættes i forbindelse med Felt-variablen i Module1.
Men lad os lige kaste et blik på ”Opdater”-proceduren der kan findes i Module1.
Umiddelbart virker den måske uoverskuelig, men i virkeligheden er der bare en stor del ”manuel” kode, som jeg kalder den. Med manuel kode mener jeg, at der er en række felter, der skal checkes i forhold til hinanden.
I delen der er markeret mellem ”With Form1” og ”End with” bliver grafikken udformet. For-next-løkken gennemgår alle 9 felter og tegner et ikon afhængig af værdien fra Felt.status. Hvis felt(x,y).status er 0, viser det, at feltet endnu ikke indeholder en værdi. 1 er spiller 1 og 2 er spiller 2 logisk nok.
Afrunding
Ved at bruge en ganske simpel kode, kan man skabe et kryds og bolle spil på bare ca. 300 linjer! Men hvis den kunstige intelligens (som jeg har gået meget let over) skulle være bedre, kunne man godt forberede sig på at tilføje endnu 300 linjer. Hvis man ønskede at opgradere spillet med mulighed for multiplayeropkobling, kunne man bruge Winsock-kontrollen. Det vil jeg imidlertid ikke komme mere ind på her, da det også er meget plads- og tidskrævende.
Jeg mener personligt, at det, der gør denne konstruktion af et kryds og bolle spil så unit, er måden hvorpå pictureboxen ”skærm” deles op på. Det sparer programmøren for mange linjer og meget besvær, set i mine øjne.
Nu kan der vidst ikke vrides mere ud af et simpelt kryds og bolle spil!? Jeg håber, at du kan bruge det.
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (14)
hmmm....hvordan kan det være at den ikke kan vinde over mig? også selvom jeg lader den vinde.
Men ellers en flot artikel
Hehe Mohamed, AI'er er jo bygget til at sørge for du ikke får tre på striber alt for let, og tænker altså slet ikke på sin egen sejr...
Ja det er nemlig korrekt. Den kunstige intelligens tager kun højde for at blokere dig fra at vinde. Jeg har ikke indprogrammeret en funktion der gør, at den selv forsøger at vinde. Det kunne må sagtens, men det ville som sagt tage tid, og jeg mener ikke, at det er relevant i denne sammenhæng.
hmm er det meningen er man skal hente spillet med en guide nu eller hva ?
Hvordan kan det være at mit felt øver ivenstre hjørne "blinker"??? det bliver sort en gang i mellem. det irreterer mig lidt.
hyggeligt nok er den vel
hvorfor kan jeg ikke hente koderne ned
hej rasmus
jeg spekulere over hvad du (præcist) mener når du skriver knapper. Så fortæl mig lige hvad for nogle knapper mener du ved: command1, 2, 3
og i øvrigt... virker det så til "visual basic 2005 express edition"?
hvordan laver man Module1 til Visual basic 2008 Express Edition?
har fundet ud af det men.. hvad med optionbuttons?..??
en okey artikkel, som jeg helt sikkert vil lege lidt med... 3-tal her fra
og sebastian du skal gå ind i Toolbox og vælge den lille runde grønne knap, som du også kan se hedder optionbutton når du holder musen over
Du skal være
logget ind for at skrive en kommentar.