Ihmettelen kyllä joskus miksei mikään suju niinkuin pitäisi..
Aloittelin uutta projektia Visual Basic 6:lla, mutta törmäsin jälleen erääseen ongelmaan Random Openin kanssa.
Jostain syystä toisella ohjelmalla tallennettu Random tiedosto ei aukea oikein toisessa ohjelmassa (VihollinenHVMin, VihollinenHVMax ja VihollinenReaktio eivät näytä oikeita tuloksia.), vaikka kaiken logiikan mukaan sen pitäisi toimia.
** Ohjelma, jolla Random-tiedosto tallennetaan
Public OtteluNimi As String
Public VihollinenNimi As String
Public VihollinenHP As Variant
Public VihollinenHVMin As Integer
Public VihollinenHVMax As Integer
Public VihollinenReaktio As Integer
Public VihollinenRahat As Variant
Private Sub Command1_Click()
If Text1.Text = "" Or Text2.Text = "" Or Text3.Text = "" Or Text4.Text = "" Or Text5.Text = "" Or Text6.Text = "" Then
MsgBox "Ei tyhjiä kenttiä"
Else
On Error GoTo Ongelma
OtteluNimi = Text1.Text
TaisteluVihollinenPolku = App.Path & "\Tietokanta\Viholliset\" + OtteluNimi + ".enemy"
VihollinenNimi = Text2.Text
VihollinenHP = Text3.Text
VihollinenHVMin = Text4.Text
VihollinenReaktio = Text5.Text
VihollinenRahat = Text6.Text
VihollinenHVMax = Text7.Text
Dim FileNum As Integer
FileNum = FreeFile
Open TaisteluVihollinenPolku For Random As #1 Len = 1000
Put #1, 1, VihollinenNimi
Put #1, 2, VihollinenHP
Put #1, 3, VihollinenHVMin
Put #1, 4, VihollinenHVMax
Put #1, 5, VihollinenReaktio
Put #1, 6, VihollinenRahat
Close #1
MsgBox "Tallennus onnistui"
Exit Sub
Ongelma:
MsgBox "Ongelmia tallennuksessa!"
End If
End SubYllä oleva ohjelma ottaa tiedot TextBoxeista, laittaa ne muuttujiin ja tallentaa Random Accessillä tiedostoon, jonka nimi on Text1.Text laatikossa.
**Ohjelma, jossa Random-tiedosto avataan
Private Sub Form_Load()
'Testauksen vuoksi myös pelaajalle on annettu valmiiksi arvot
OtteluNimi = "B" 'Kutsuu taistelun
PelaajaHP = 25
PelaajaAseMin = 1
PelaajaAseMax = 15
PelaajaReaktio = 1
PelaajaSuoja = 1
'Arvojen anto päättyy
If OtteluNimi = "" Then
MsgBox "Ongelmia pelissä!"
Unload Taistelu
Else
TaisteluVihollinenPolku = App.Path & "\Tietokanta\Viholliset\" + OtteluNimi + ".enemy"
Dim FileNum As Integer
FileNum = FreeFile
Open TaisteluVihollinenPolku For Random As #1 Len = 1000
Get #1, 1, VihollinenNimi
Get #1, 2, VihollinenHP
Get #1, 3, VihollinenHVMin
Get #1, 4, VihollinenHVMax
Get #1, 5, VihollinenReaktio
Get #1, 6, VihollinenRahat
Close #1
Text1.Text = VihollinenHP
Text2.Text = VihollinenNimi
Text3.Text = VihollinenHVMin
Text4.Text = VihollinenHVMax
Text5.Text = VihollinenReaktio
Text6.Text = VihollinenRahat
If VihollinenReaktio > PelaajaReaktio Then
MsgBox (VihollinenNimi & "reagoi nopeammin kuin sinä ja onnistuu vahingoittamaan sinua ennen kuin ehdit suojaan!")
Randomize
ReaktioMiinus = Rand(1, 10)
PelaajaHP = PelaajaHP - ReaktioMiinus
Exit Sub
Else
MsgBox ("Reagoit tilanteeseen nopeasti ja ehdit vahingoittaa vihollista ennen kuin hän ehtii suojaan!")
Randomize
ReaktioMiinus = Rand(1, 10)
VihollinenHP = VihollinenHP - ReaktioMiinus
Exit Sub
End If
End If
End SubEli lyhykäisyydessään tämän Form Loadin pitäisi avata tuo Random-tiedosto, ottaa sieltä tiedot muuttujiin ja näyttää ne TextBoxeissa.
Toivottavasti osaatte auttaa, tuntuu niin turhautuneelta kun mikään ei onnistu ja aina on tultava tänne kysymään apua...
Toisessa ohjelmassa muuttujien tietotyyppiä ei ole määritelty. Sitä paitsi, tuo koko tiedostomuoto on kyllä suoraan sanoen järjenvastainen, varsinkin varianttien tallentaminen tuolla tavalla.
Toisessa ohjelmassa tietotyypit on esitelty erillisessä moduulissa, mutta kuinka nuo sitten pitäisi mielestänne esitellä kaikkein järkevimmin.
No jos välttämättä haluaa käyttää tuollaista binääritiedostoa, niin itse ainakin tekisin tyypin, jossa eri muuttujat on perustietotyyppeinä ja mahdollisille merkkijonoille määritelty kiinteä pituus. Sitten ko. tyypin pituuden voisi antaa myös random access tiedoston tietuepituudeksi. Nythän tuossa kaikki tiedot (mm. 2-tavuiset integerit) vie 1000 tavua tilaa kiintolevyltä.
Sanoit, että tuossa toisessa tietotyypit on määritelty erillisessä moduulissa, eli nuo ovat sitten ilmeisesti globaaleja muuttujia. Aika WTF ratkaisu sekin.
En mielestäni pyytänyt missään vaiheessa arvostelemaan koodaustapaani...
Mutta kuitenkin, on kummallista että olen tehnyt toisen ohjelman täysin identtisellä koodilla ja se toimi moitteettomasti..
Eli voisiko joku antaa konkreettisen esimerkin mitä ihmettä minun pitäisi tehdä.
Isopaha kirjoitti:
En mielestäni pyytänyt missään vaiheessa arvostelemaan koodaustapaani...
Älä huoli, tein sen ilmaiseksi. Ei kestä kiittää.
Isopaha kirjoitti:
Eli voisiko joku antaa konkreettisen esimerkin mitä ihmettä minun pitäisi tehdä.
Laittaa koko roska (eli myös se moduuli) näkyville. Virheitä on paha etsiä sellaisesta osasta koodia, jota et laita meille näkyville.
Anyways, löydän 3 mahdollista syytä ongelmaan:
1) Ohjelman 2 (erillisessä moduulissa olevat) muuttujien määrittelyt poikkeavat ohjelman 1 muuttujien määrittelyistä
tai
2) talletetun ottelun nimi oli joku muu kuin "B" (sehän asetetaan kiinteästi ohjelmassa 2)
tai
3) Ohjelmat sijaitsivat eri hakemistoissa ("tietokannan" polku määräytyy ohjelman hakemiston mukaan)
Kun nuo kaikki 3 oli kunnossa, niin ohjelma 2 latasi ohjelman 1 tallentamat tiedot.
Kylläpäs nyt vitsiä pukkaa...
Mutta asiaan,
1) Tuossa kohti oli virhe ohjelmassani; kaikkia muuttujia ei määritelty ensimmäisessä ohjelmassa --> Korjasin
2) Tallennetun ottelun nimi on "B"
3) Mikäli polku olisi väärin, ohjelmassa ei aukaisisi mitään. Nyt ohjelma 1 kuitenkin avaa muutamia tietoja, mutta vääristää VihollinenHVMin, VihollinenHVMax ja VihollinenReaktio -muuttujien sisällöt.
EDIT: En kyllä nyt rehellisesti enään ymmärrä. Kopioin ensimmäisen ohjelman koodin uuteen projektiin täysin muuttamattomana ja siellä koodi toimii moitteettomasti! Testasin myös tämän uudeen formin siirtämistä Ohjelma Number kakkoseen ja siellä se taas lakkasi toimimasta.. Aika turhauttavaa eikös..
EDIT 2: Tein muutamia käytännön testejä ja niistä selvisi, että ohjelma toimii oikein käännettynä, mutta testitilassa väärin. Mikähän tässä oikein on D:
Isopaha kirjoitti:
Kylläpäs nyt vitsiä pukkaa...
Ei se ollut mikään vitsi.
Järjelliset koodauskäytännöt vähentävät turhautumista...
Isopaha kirjoitti:
Aika turhauttavaa eikös..
Tosin tee miten tykkäät, itsehän siitä eniten kärsit.
Isopaha kirjoitti:
3) Mikäli polku olisi väärin, ohjelmassa ei aukaisisi mitään. Nyt ohjelma 1 kuitenkin avaa muutamia tietoja, mutta vääristää VihollinenHVMin, VihollinenHVMax ja VihollinenReaktio -muuttujien sisällöt.
No en edelleenkään voi ottaa tarkemmin kantaa näihin, kun koodissasi on vain osatotuus. Virhe on jossain muualla kuin noissa mainitsemissasi pätkissä, koska täydennettynä sillä, mitä olet kertonut niiden ulkopuolella olevan, ne toimivat.
Suosittelen ainakin että laitat jokaisen eksplisiittiset muuttujamäärittelyt käyttöön (eli jokaisen kooditiedoston alkuun tulee Option Explicit) niin näet jos käytät määrittämätöntä muuttujaa. Tällä hetkellä nimenomaan nuo 16-bit kokonaisluvuiksi (Integer) määritellyt muuttuvat, joten viittaisi siihen, että lukeva ohjelma ei lue niitä Integereinä, vaan esim. Varianteina.
lainaus:
Ei se ollut mikään vitsi.
Näin sen tulkitsin. Koodaan itselleni, en muille.
Itse epäilen myös, että ohjelma luulee tuon Integerin olevan jotain aivan muuta. Mutta kaiken järjen mukaan näin ei pitäisi käydä, koska myös tuo VihollinenHP on Integer.
Katso edellisestä viestistä EDIT 1 ja 2, siinä on jotain mielenkiintoista..
Isopaha kirjoitti:
Näin sen tulkitsin. Koodaan itselleni, en muille.
No, jos olet masokisti, niin ei kai siinä mitään. Olet kuitenkin laittanut koodiasi julkisesti nähtäville, joten väitteesi ei pidä paikkaansa.
Edit 1:n luinkin jo (jopa quotesin sitä viestiin) ja 2:n osalta voin sanoa vain että lue neuvoni ja opettele debuggaamaan*, niin kyllä se siitä.
* Jos olisin koneellasi niin pystyisin sanomaan minuutissa mistä ongelma johtuu, koska VB:ssä on helppo debugata. Antamillasi puutteellisilla tiedoilla sen sijaan on mahdotonta antaa muuta kuin arvauksia.
Koodaan lähinnä itselleni, mutta kun tälläisiä ongelmia esiintyy niin pakkohan se on kysyä. En pyytänyt kuitenkaan missään vaiheessa itse koodin kommentointia, joten lopetetaan tämä turha keskustelu tähän.
Olen ruvennut pohtimaan voisiko tuo vika johtua ihan omasta Visual Basic 6 versiostani, koska käytän erästä Portable versiota.
Isopaha kirjoitti:
Koodaan lähinnä itselleni, mutta kun tälläisiä ongelmia esiintyy niin pakkohan se on kysyä. En pyytänyt kuitenkaan missään vaiheessa itse koodin kommentointia
Joo, saahan sitä kysyä, vaikka ei haluaisikaan vastausta.
Vähän kuin hakkaisi päätä seinään kerran minuutissa ja menisi lääkärille pyytämään apua päänsärkyyn. Sitten kun lääkäri sanoisi että päänsärky aiheutuu pään hakkaamisesta seinään ja korjaantuu lopettamalla se, niin potilas suuttuisi että "en tullut tänne pyytämään elämänohjeita vaan saamaan helpotusta särkyyn".
Sori nyt vaan, mutta olen antanut jo kaikki "buranat" mitä voin tuohon "päänsärkyysi", sen lisäksi että ehdotin myös sen pään seinään hakkaamisen lopettamista. Jos et niitä "buranoitakaan" halua ottaa, niin sitten en voi auttaa.
Voisiko ongelma johtua siitä että kirjoitat ja luet aina #1 tiedostoa. Koodissa otat kuitenkin FreeFilen talteen muttet käytä sitä?
kokeile oheista kirjoituksessa:
Dim FileNum As Integer
FileNum = FreeFile
Open TaisteluVihollinenPolku For Random As FileNum Len = 1000
Put #FileNum , 1, VihollinenNimi
Put #FileNum , 2, VihollinenHP
'...jnejneja lukiessa:
Dim FileNum As Integer
FileNum = FreeFile
Open TaisteluVihollinenPolku For Random As FileNum Len = 1000
Get #FileNum, 1, VihollinenNimi
Get #FileNum, 2, VihollinenHP
'... jnejneJoo, huomasin tuon itsekkin eilen, mutta vaikka muutin sitä, ei se muuttanut tulosta :(
Luultavasti johtuu siitä, että FreeFile palauttaa myös tuon #1, jolloin mitään ongelmaa ei pitäisikään syntyä.
Pikakysymys: muuttuuko tulos, jos määrittelet string-muuttujat vakiopituisiksi?
Dim ... As String * 30
Tällöin tosin tulee stringiin epäesteettisiä tyhjiä, mutta ne saa kikkailtua pois.
Sqwiik: Kuten jo mainitsinkin, niin nuo toimivat ihan hyvin jos katsoo nuo kolme mainitsemaani asiaa kuntoon (ja lisäksi tuon tiedostonumeron).
Ongelma ei siis ole näytetyssä koodissa (vaikka se onkin ongelmallista) vaan jossakin sellaisessa, mitä ei kerrota tai joka on tehty eri lailla kuin kerrottu.
Tietysti koodissa olisi hyvä huolehtia ettei merkkijonot ole yli 1000 merkin pituisia, koska tiedostosta varataan niille vain sen verran tilaa. Mutta en usko että se olisi tällä kertaa ongelman aiheuttaja.
Aihe on jo aika vanha, joten et voi enää vastata siihen.