Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C#: Mistä ihmeestä ohjelma muistaa tämän?

kamppis [14.05.2014 06:56:36]

#

Tässä on miinaharavan alku jonka löysin alunperin C kielenä. Käänsin sitä C# kieleen harjoitusmielessä. Ohjelma toimii tähän asti jos antaa oikeita lukuja, mutta yksi asia on minulle mysteeri. Kun annan "process" metodille parametrit ja tämä merkkaa taulukkoon lasketun luvun niin miten ohjelma muistaa mitkä luvut taulukkoon on lisätty aiemmin? Joka kerta kun uusi taulukko tulostetaan siellä on siis ne vanhatkin kohdat merkittynä.

Käsittääkseni kaikki metodeille annetut parametrit ovat nimenomaan kopioita ja ne ei pitäisi siirtyä seuraavaan kierrokseen joten mielestäni taulukon tulostuksessa pitäisi näkyä vain viimeisin kohta, mutta näin ei ole. Onko tässä nyt joku jippo jota en vain hoksaa? Osaisitteko auttaa ja kertoa. Auttaisi tosi paljon taulukoiden ymmärtämisessä

Tässä koodi kokonaisuudessaan.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MineSweeper
{
    public class Program
    {
        static void Main(string[] args)
        {
            // alueen koko
            char[,] msweep = new char[12,12];

            // alueen koko joka näytetään käyttäjälle
            char[,] user_chart = new char[12, 12];

            // muuttujia
            int i,r,c;


            // kutsutaan metodia randomize_mines joka luo satunnaiset miinat ja annetaan parametriksi msweep taulukko
            randomize_mines(msweep);

            // kysytään koordinaatit joita kaivetaan
            Console.Write("Anna X-koordinaatti väliltä 1-10: ");
            r = int.Parse(Console.ReadLine());
            Console.Write("Anna Y-koordinaatti väliltä 1-11: ");
            c = int.Parse(Console.ReadLine());

            // tulostetaan miinakenttä annetuilla parametreillä
            printmatrix(user_chart);



            // prosessoidaan käyttäjän tekemä valinta
            i = process(msweep, r, c, user_chart);


            // mennään looppiin jossa prosessoidaan valintoja looppina
            while (i == 1)
            {
                Console.Write("Miinoja lähettyvillä {0}\n\n", msweep[r,c]);

                // Tulostetaan tämänhetkinen taulukko!
                printmatrix(user_chart);

                Console.Write("Anna X-koordinaatti väliltä 1-10: ");
                r = int.Parse(Console.ReadLine());
                Console.Write("Anna Y-koordinaatti väliltä 1-10: ");
                c = int.Parse(Console.ReadLine());
                i = 0;
                i = process(msweep, r, c, user_chart);
            }

            // jos astuttiin miinaan peli on ohi.
            if (i == 0)
            {
                Console.Write("Astuit miinaan\n");
                printmatrix(user_chart);
                Console.ReadLine();
            }
        }




        // Luodaan miinat, parametrina taulukko joka luotiin mainissa
        static void randomize_mines(char [,] msweep)
        {
            int r, c, m;

            // satunnainen muuttuja
            Random rnd = new Random();

            for (m = 0; m < 20; m++) // oletuksena 20 miinaa.
            {
                // miinat taulukoihin, reunojen ulkopuolelle.
                r = rnd.Next(1, 11);
                c = rnd.Next(1, 11);

                // 9 tarkoittaa, että siinä on miina johon verrataan myöhemmin
                msweep[r,c] = '9';

                //listataan paikat joissa on miina kokeilua varten (onko esim. reunoilla)
                Console.WriteLine("{0} {1} ", r, c);
            }
        }


            // tulostetaan matriksi
          static void printmatrix(char [,] user_chart)
        {
          int i,j;
          Console.WriteLine(".-.-.-.-.-.-.-.");
          for(i=1;i<11;i++)
    {
          Console.Write("./.");

          for(j=1;j<11;j++) // luvut 1-11 on miinoja varten
    {
          Console.Write(user_chart[i,j]); // näytetään nykyiset paikat joista miinoja on jo haravoitu
    }

          Console.Write(".\\.");
          Console.Write("\n");
  }
    Console.Write(".-.-.-.-.-.-.-.\n\n");
    }





        // tämä suoritetaan aina kun käyttäjä antaa kordinaatin.
   static int process(char[,] msweep, int r, int c, char[,] user_chart)
{

 int i=r,j=c,b=0;
 char C;

 if(msweep[r,c] == '9')
 {
   user_chart[r, c] = '*';
   return 0; // jos osutaan miinaan niin palautetaan 0
 }

     // lasketaan ympäröivät alueet ja jos siinä on miina niin lisätään miinalukuun aina 1.
 else
  {
   if(msweep[i-1,j-1] == '9')
    b++;
   if(msweep[i-1,j] == '9')
    b++;
   if(msweep[i-1,j+1] == '9')
    b++;
   if(msweep[i,j-1] == '9')
    b++;
   if(msweep[i,j+1] == '9')
    b++;
   if(msweep[i+1,j-1] == '9')
    b++;
   if(msweep[i+1,j] == '9')
    b++;
   if(msweep[i+1,j+1] == '9')
    b++;

     // miinojen yhteystulos muuttujaan C
  C = (char)(((int)'0')+b); // to covert int to char;


   // muokataan käyttäjälle näkyvään taulukkoon sama tulos
   user_chart[r,c] = C;
  }

 // palautetaan 1 joka kertoo, että ohjelma voi jatkua
 return 1;

}

 }
}

The Alchemist [14.05.2014 07:36:59]

#

Miksi et debuggaa itse? En näe koodissa riviäkään debug-koodia. Ongelmista oppisi parhaiten, jos edes vaivautuisi kokeilemaan niiden ratkaisua itse.

Grez [14.05.2014 07:45:34]

#

kamppis kirjoitti:

Käsittääkseni kaikki metodeille annetut parametrit ovat nimenomaan kopioita

Käytännössä objekteista (luokat, taulukot yms) välitetään viittauksen kopio. Viittauksen kopio viittaa kuitenkin alkuperäiseen objektiin.

void Demo(int luku, List<int> lista)
{
    //Muutos ei näy kutsujalle
    luku = 38;

    //Muutos näkyy kutsujalle
    lista.Add(38);

    //Muutos ei näy kutsujalle
    lista = new List<int>();

    //Tämäkään ei näy kutsujalle koska lista ei viittaa enää alkuperäiseen
    lista.Add(38);
}

The Alchemist kirjoitti:

Miksi et debuggaa itse? En näe koodissa riviäkään debug-koodia. Ongelmista oppisi parhaiten, jos edes vaivautuisi kokeilemaan niiden ratkaisua itse.

Tarvitseeko debuggaamista varten laittaa jotain koodia jonnekin? :o

feenix [14.05.2014 12:50:58]

#

C# tosiaan välittää taulukoista viittaukset eikä kopioi niitä, kuten C/C++ tekisi ilman referenssimerkintää. Täten kaikki muutokset mitä kutsuttu funktio tekee tietysti palaavat takaisin. Sinun pitää itse tehdä kopio taulukosta, jos et halua muutosten säilyvän. Tähän käy esimerkiksi Clone()-metodi.

Jos taas taulukossa olisi olioita, pitää huomata, että Clone() kopioi vain osoittimet, ei luo uusia olioita, eli kaikki muutokset näihin olioihin näkyvät sekä alkuperäisessä että kopioidussa taulukossa.

Lisäys:

The Alchemist kirjoitti:

Miksi et debuggaa itse? En näe koodissa riviäkään debug-koodia. Ongelmista oppisi parhaiten, jos edes vaivautuisi kokeilemaan niiden ratkaisua itse.

a) kaikki debuggaus ei vaadi mitään lisäkoodia
b) jos minulla olisi ongelma, en sotkisi koodia debuggitulosteilla tai muilla, vaan säästäisin muiden vaivaa ja laittaisin mahdollisimman kompaktin esimerkin ongelmasta
c) tässä tilanteessa oli selvästi kyse niin perustavan tason erosta totuttuun, että ei debuggaus olisi selittänyt miksi näin tapahtuu, ainoastaan näkee, että näin tapahtuu.

Vastaus

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

Tietoa sivustosta