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 Sub
Yllä 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 Sub
Eli 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 '...jnejne
ja lukiessa:
Dim FileNum As Integer FileNum = FreeFile Open TaisteluVihollinenPolku For Random As FileNum Len = 1000 Get #FileNum, 1, VihollinenNimi Get #FileNum, 2, VihollinenHP '... jnejne
Joo, 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.