Oon tekemässä korttipeliä joka arpoo 2 korttia ja katsoo kumpi on suurempi kortti. Toi onnistui, mutta sitten huomasin virheen: Joskus se arpo kaksi samaa korttia
Tietenkin näin on mahdollista tapahtua jos koodi on sellainen kun se on tällä hetkellä.
Eli mitä täytyisi tehdä että se korjaisi tuon virheen. Ja miten saisi tehtyä pakan (siis laittaisi kortit johonkin sattuman varaiseen järjestykseen ja jokaista korttia olisi vain yksi).
Koodi:
Private Sub Form_Click()
For i = 0 To 1 'korttien määrä
Randomize 'lisätään satunnaisuutta
kortti = Int(Rnd * 52) 'arvotaan kortti
X = cdtDraw(Me.hdc, i * 70, 0, kortti, 0, 0) 'piirretään kortti
Next
End Sub
Private Sub Form_Load()
'Aluksi on kutsuttava cdtInit-funktiota, joka palauttaa
'kortin leveyden ja korkeuden
X = cdtInit(leveys, korkeus)
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Lopuksi kutsutaan cdtTerm-käskyä, joka lopettaa cards.dll:n käytön.
cdtTerm
End Subja moduuliin
Declare Function cdtInit Lib "cards.dll" (dx As Long, dy As Long) As Long Declare Function cdtDrawExt Lib "cards.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy As Long, ByVal iCard As Long, ByVal iDraw As Long, ByVal clr As Long) As Long Declare Function cdtDraw Lib "cards.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal iCard As Long, ByVal iDraw As Long, ByVal clr As Long) As Long Declare Function cdtAnimate Lib "cards.dll" (ByVal hdc As Long, ByVal cd As Long, ByVal X As Long, ByVal Y As Long, ByVal ispr As Long) As Long Declare Function cdtTerm Lib "cards.dll" () As Long
Koodi on kopioitu Korttipeliohjelmointi-oppaasta.
Tee aluksi kaksi muuttujaa Kortti1 ja Kortti2.
Arvo ensimmäinen kortti ja laita sen arvo muuttujaan kortti1.
Arvo sen jälkeen se toinen kortti ja sijoita sen arvo muuttujaan Kortti2.
Sitten vertailet kortti1:n ja Kortti2:n arvoja näin:
If Kortti1 = Kortti2 Then 'arvo kortti2 uudestaan End If 'Kannattaa tehdä tuota vertailua varten vaikka uusi aliohjelma joka ajetaan joka kerta kun kortti on arvottu.
Näinhän se kannattaa tehdä!
Ei tullut mieleen kun lähetin viestiäni tänne.
Mutta miten korttipakan voisi rakentaa
Arvot siis ohjelmassa vain kaksi korttia 52:sta?
Tarkenna hieman vielä tuota "pakan rakentamista"
zigilii kirjoitti:
Ja miten saisi tehtyä pakan (siis laittaisi kortit johonkin sattuman varaiseen järjestykseen ja jokaista korttia olisi vain yksi).
kun on normaali korttipakka ja siittä nostaa kortteja -> samaa korttia ei tulisi uudestaan
Siis kun kortti on arvottu se siirretään pois pakasta ja sitä ei enää tule uudestaan?
Just silleen
No, tee vaikka taulukko jossa kortit ovat
Dim Kortit(1 To 52)
ja sitten teet aliohjelman jossa on silmukka joka laittaa
aina yhden kortin yhteen taulukon soluun.
Private Sub UusiPeli()
'käydään taulukko läpi
For i = 1 To 52
'käydään kortit läpi
For j = 1 To 52
Kortit(i) = kortti(j)
Next
Next
End SubSitten kun jokin kortti arvotaan se poistetaan taulukosta.
Muokkaa myös arvonta sellaiseksi että se arpoo kortteja taulukosta eikä jostain lukumäärästä.
Yritä vaikka itse ensin, ja jos ei onnistu niin pyydä apua uudelleen.
Ähh, en vaan osaa.
EI EI EI EI
Päässä pyörii kaikenlaista koodia mutta mikään ei toimi.
No autetaan hieman lisää...
tehdään toinen taulukko jossa on tieto siitä mitkä kortit ovat arvottu(arvo on taulukossa 0 jos ei ole arvottu ja 1 jos on arvottu):
Dim Arvotut(1 To 50)
Sitten lisää seuraava koodi Uusipeli subbariin:
For i = 1 To 52
Arvotut(i) = 0
NextSitten suoritetaan arvonta(tee tälle myös oma aliohjelma):
Kortti = Kortit(Int(rnd * 52)) If Arvotut(kortti) = 0 then 'näytetään kortti Arvotut(kortti) = 1 Else 'kortti on jo arvottu end if
En ole testannut koodia, mutta luulisin että se toimii.
Enpä ole ikinä korttipeliä yrittänyt väsätä, mutta kolmen ja puolen kokemuksella ohjelmoinnista sanoisin, että ei todellakaan tarvita mitään "Kortit", tai "Arvotut"-taulukoita, vaan sen sijaan tarvitaan taulukot niille paikoille, joissa kortteja voi olla, eli siis pelistä riippuen esimerkiksi "Pakka", "Käsi", jne.
Tämä on ensinnäkin oikea lähtökohta:
Type Kortit Maa As Integer Väri As Integer End Type Dim Pakka(1 To 52) As Kortit Dim Käsi(1 To 7) As Kortit 'jos 7 on vaikka maksimi määrä kortteja kädessä
Koska voin noin 95% varmuudella sanoa, että jollain toisella systeemillä tehdessä tulee myöhemmin huomattavia ongelmia. En siis ole koskaan korttipeliä koodannut, mutta kylläkin pelejä, joissa on tämäntyyppisiä systeemejä, ja voin sanoa, että itse olen havainnut tämän ainoaksi järkeväksi tavaksi.
Tuosta koodista voi sitten oman järjen mukaan jatkaa eteenpäin, tai jos ei onnistu, niin kysy lisää.
tuohan on paljon kätevämpi :)
No, itse en silti omista omituisista ohjelmointi tavoistani luovu.
Mutta zigilii, käytä tuota soodan tapaa.
tuomas kirjoitti:
Mutta zigilii, käytä tuota soodan tapaa.
Mitä tapaa oikein tarkoitat? Eihän sooda ole vastannut koko aiheeseen. :)
hups, sekosin nimissä :)
Elä suutu.
Pakassa olevat kortit kannattaa tosiaan tallentaa taulukkoon oman tietotyypin avulla. Jokaisesta kortista tallennetaan ainakin maa (= väri, 0 - 3), arvo (1 - 13) ja tila (pakassa, pelaajan kädessä, poispantuna...). Tämän jälkeen pakan voi sekoittaa esimerkiksi seuraavilla tavoilla:
Esimerkki molemmista sekoitustyyleistä:
Private Type KORTTI
maa As Integer 'kortin maa, 0 - 13
arvo As Integer 'kortin arvo, 1 - 13
tila As Integer 'kortin tila, aluksi esim. 0
End Type
Dim Pakka(51) As KORTTI
Sub Sekoitus1()
Dim i As Integer, v As KORTTI
Dim k1 As Integer, k2 As Integer
'laitetaan kortit järjestyksessä pakkaan
For i = 0 To 51
Pakka(i).maa = i Mod 4
Pakka(i).arvo = i \ 4 + 1
Pakka(i).tila = 0
Next
'vaihdetaan korttiparien paikat 5000 kertaa
For i = 1 To 5000
'arvotaan vaihdettavat kortit
k1 = Int(Rnd * 52)
k2 = Int(Rnd * 52)
'vaihto apumuuttujan avulla
v = Pakka(k2)
Pakka(k2) = Pakka(k1)
Pakka(k1) = v
Next
End Sub
Sub Sekoitus2()
Dim i As Integer, j As Integer
Dim ap(51) As KORTTI, a As Integer
'laitetaan kortit järjestyksessä apupakkaan
For i = 0 To 51
ap(i).maa = i Mod 4
ap(i).arvo = i \ 4 + 1
ap(i).tila = 0
Next
'arvotaan kaikki 51 korttia
For i = 51 To 0 Step -1
'arvotaan uusi kortti jäljelläolevista
a = Int(Rnd * (i + 1))
'lisätään kortti pakkaan
Pakka(i) = ap(a)
'poistetaan arvottu kortti apupakasta
For j = a To i - 1
ap(j) = ap(j + 1)
Next
Next
End Sub
Sub NaytaPakka()
Dim i As Integer, t As String, m As String
m = "parurihe"
'muodostetaan merkkijono kaikista pakan korteista
For i = 0 To 51
t = t & Mid(m, Pakka(i).maa * 2 + 1, 2) & Pakka(i).arvo & " "
Next
MsgBox t
End Sub
Private Sub Form_Load()
Randomize Timer
'sekoitustyyli 1
Sekoitus1
NaytaPakka
'sekoitustyyli 2
Sekoitus2
NaytaPakka
End SubAihe on jo aika vanha, joten et voi enää vastata siihen.