Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: Random File

Sivun loppuun

Isopaha [19.08.2008 16:57:32]

#

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...

Grez [19.08.2008 17:29:21]

#

Toisessa ohjelmassa muuttujien tietotyyppiä ei ole määritelty. Sitä paitsi, tuo koko tiedostomuoto on kyllä suoraan sanoen järjenvastainen, varsinkin varianttien tallentaminen tuolla tavalla.

Isopaha [19.08.2008 17:36:10]

#

Toisessa ohjelmassa tietotyypit on esitelty erillisessä moduulissa, mutta kuinka nuo sitten pitäisi mielestänne esitellä kaikkein järkevimmin.

Grez [19.08.2008 17:40:37]

#

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.

Isopaha [19.08.2008 18:16:31]

#

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ä.

Grez [19.08.2008 20:15:58]

#

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.

Isopaha [19.08.2008 21:25:25]

#

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:

Grez [19.08.2008 21:39:38]

#

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.

Isopaha [19.08.2008 21:45:04]

#

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..

Grez [19.08.2008 21:49:51]

#

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.

Isopaha [19.08.2008 22:07:22]

#

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.

Grez [19.08.2008 22:34:20]

#

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.

Hycke [20.08.2008 09:36:04]

#

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

Isopaha [20.08.2008 15:25:20]

#

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ä.

sqwiik [20.08.2008 15:45:47]

#

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.

Grez [20.08.2008 20:34:24]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta