Możliwości w metodach.

0

Witam. Zaczynam uczyć się o metodach, żeby nie pakować wszystkiego do głównej metody main. Dzisiaj zrobiłem sobie małe ćwiczonko, w którym chciałbym, żeby program wypisał gwiazdki w każdym elemencie tablicy dwuwymiarowej(potrzebne do kółka i krzyżyk). Na początku zrobiłem wszystko w mainie(wtedy wszystko jeździło i wypisywało gwiazdeczki), ale potem wpadłem na pomysł, żeby całe wypisywanie gwiazdek zrobić w osobnej metodzie, a w mainie ją tylko wykonać. Czy można w metodzie używać Console.Writeline'ów? Domyślam się, że nie do końca rozumiem istoty metod, więc jak byście to napisali, żeby było poprawnie? Moje "dzieło":

 namespace Kolko_i_krzyzyk
{
    class Program
    {
        public void wyswietlenie()
        {
            string[,] tablica = new string[3, 3];
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    tablica[i, n] = "*";
                    Console.Write(tablica[i, n] + " ");
                }
                Console.WriteLine("\n");
            }
        }
        static void Main(string[] args)
        {
           //tutaj chciałbym jakoś wywołać tą metodę
            Console.ReadKey();


        }
    }
}
1
 namespace Kolko_i_krzyzyk
{
    class Program
    {
        public static void wyswietlenie() // metoda statyczna, innej nie bedziesz widzial w static Main
        {
            string[,] tablica = new string[3, 3];
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    tablica[i, n] = "*";
                    Console.Write(tablica[i, n] + " ");
                }
                Console.WriteLine("\n");
            }
        }
        static void Main(string[] args)
        {
            wyswietlenie(); // i wyswietlamy
            Console.ReadKey();


        }
    }
}
1

dodaj do tej funkcji słówko "static", tak aby było public static void...
i potem w main:

   wyswietlenie();
0

Wielkie dzięki za szybką odpowiedź! A ogólnie nie doszukaliście się żadnych błędów poza tym? I czym się różni metoda statyczna, od zwykłej?

0
bnbnowacki napisał(a):

czym się różni metoda statyczna, od zwykłej?

http://bit.ly/1nRDW9w leniuszku... :D

0

Metoda nie musi być statyczna. Zresztą robienie metod w klasie Program? Lepiej stworzyć osobną klasę.

using System;

public class TicTacToe
{
	public void DrawBoard()
	{
		string[,] board = new string[3, 3];
	    for (int i = 0; i < 3; i++)
	    {
	        for (int n = 0; n < 3; n++)
	        {
	            board[i, n] = "*";
	            Console.Write(board[i, n] + " ");
	        }
	        Console.Write(Environment.NewLine);
	    }
	}
}

public class Program
{
	public static void Main()
	{
		TicTacToe game = new TicTacToe();
		game.DrawBoard();
		
		Console.ReadKey();
	}
}
0

@fourfour, widzę, że poczucie humoru na forum na wysokim poziomie! :D Jestem początkującym i nie za bardzo rozumiem różnic między tworzeniem metody, a klasy w tym przypadku. Tworzenie tablicy bardziej mi brzmiało na metodę, a nie klasę. Mam teraz nowy problem. Chciałem spróbować wczytania jakiegoś znaku z klawiatury(w tym przypadku stringa) i też się pogubiłem. Program wyświetla błąd, że nie może skonwertować inta na string. Dziwne jest dla mnie to, że i metoda ReadLine i moja zmienna to stringi, więc po co tu coś konwertować?

namespace Kolko_i_krzyzyk
{
    class Program
    {
        static string kolej ="O";
        static int a, b;
        static string[,] tablica = new string[3, 3];
        public static void stworzenie()
        {
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    tablica[i, n] = "*";
                }
            }
        }
        public static void wyswietlenie()
        {
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    Console.Write(tablica[i, n]);
                }
                Console.WriteLine("\n");
            }
        }

        static void Main(string[] args)
        {
            stworzenie();
            wyswietlenie();
            Console.WriteLine("Witaj w grze kolko i krzyzyk!");
            Console.WriteLine("Teraz kolej " + kolej);
            kolej = Console.ReadLine(); << TUTAJ SIĘ WYŚWIETLA BŁĄD
            Console.WriteLine(kolej);
            Console.ReadKey();


        }
    }
}

 
0
bnbnowacki napisał(a):

@fourfour, widzę, że poczucie humoru na forum na wysokim poziomie! :D Jestem początkującym i nie za bardzo rozumiem różnic między tworzeniem metody, a klasy w tym przypadku.

O, i właśnie dlatego powinieneś zapoznać się, choćby pobieżnie, z czymś takim: http://4programmers.net/C_sharp lub podobnym, szukanym w sieci pod hasłem np. "kurs c#" ... :)

0

No już się zapoznałem, od tego w sumie zacząłem. Wiem co to klasa i czym się różni od metody klasy. Np. klasa to samochód, obiekty to ludzie w samochodzie, a metody klasy to otwieranie i zamykanie drzwi. Tylko nie wiem o co chodzi akurat w tym przykładzie. Dlaczego lepiej jest stworzyć nową klasę, a nie po prostu metodę. No i pozostaje problem tych całych konwersji w Read**(); Nie wiem za bardzo gdzie o tym poczytać. Czym się różni np. ReadKey od Read, albo Readline i kiedy konwertować i z czego na co.

0

Tak wracając do pytania to w tym kodzie co pokazałeś nie trzeba nic konwertować to powinno działać.
I zacznij jakiś kurs przerabiać lepiej.
BTW Wcześniej pisałeś jakieś programy w Windows Forms używając DataGridView, bindowania, itp a teraz się okazuje że nie wiesz jak używać metod?

0

@dam1an dokładnie tak! Na studiach na programowaniu od razu zaczęliśmy w okienkach, jeśli chodzi o c#, nic nie robiliśmy w konsoli, a wiadomo, w Windows Forms program praktycznie prawie wszystko robi za nas. Tworzysz button, zdarzenie kliknięcia itp, program sam wypisze cały szkielet. Dlatego stwierdziłem, że wracam do pisania prostych konsolowych apek i zrozumienia w 100% całej idei klas, metod itp. Czy mój tok myślenia jest dobry?

0

No raczej tak.
Ale to dziwne żeby bez hello worlda, wypisywania choinek na konsole itp. wprowadzili od razu do WF.

0

hello worda, choinki, kalkulatorki itp. były na pierwszym roku w c++. Potem zmienił się wykładowca, zaczął już działać na WF, a w pierwszym roku do klas nie doszliśmy.

Mam kolejny problem. Program nie zamienia mi stringa "kolej". Dodałem metodę, która ma co kolejkę zmieniać z O na X. I tak cały czas jest jako O. Ktoś wie, gdzie się rypnąłem? Poza tym program się wysypuje po 2 przejściach, jeśli dodać do tego rysowanie pola.

namespace Kolko_i_krzyzyk
{
    class Program
    {
        public static string kolej ="O";
        public static int k;
        public static string[,] tablica = new string[3, 3];
        public static void stworzenie()
        {
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    tablica[i, n] = "*";
                }
            }
        }
        public static void wyswietlenie()
        {
            for (int i = 0; i < 3; i++)
            {

                for (int n = 0; n < 3; n++)
                {
                    Console.Write(tablica[i, n]);
                }
                Console.WriteLine("\n");
            }
        }
        public static void zamiana()
        {
            if (k == 1) tablica[3, 1] = kolej;
            if (k == 2) tablica[3, 2] = kolej;
            if (k == 3) tablica[3, 3] = kolej;
            if (k == 4) tablica[2, 1] = kolej;
            if (k == 5) tablica[2, 2] = kolej;
            if (k == 6) tablica[2, 3] = kolej;
            if (k == 7) tablica[1, 1] = kolej;
            if (k == 8) tablica[1, 2] = kolej;
            if (k == 9) tablica[1, 3] = kolej;
        }
        public static void kolejka()
        {
            if (kolej == "O") kolej = "X";
            if (kolej == "X") kolej = "O";
        }

        static void Main(string[] args)
        {
            stworzenie();
            Console.WriteLine("Witaj w grze kolko i krzyzyk!");
            do
            {
                zamiana(); << wziąłem w komentarz, dla sprawdzenia samej zamiany
                wyswietlenie(); << -//-
                kolejka(); <<tutaj wywołuję metodę do zamiany kółka na krzyżyk
                Console.WriteLine("Teraz kolej " + kolej);
                k = int.Parse(Console.ReadLine());
                Console.Clear();
            } while (k < 10);
        }
    }
} 
1

nie wychodzisz z metody kolejka po zmianie

 if (kolej == "O") kolej = "X";
            if (kolej == "X") kolej = "O"; 

pierwsza linijka sprawdza czy jest O i jest wiec zmienia na X, a druga zaraz po niej sprawdza czy jest X i jest , bo linijke wczesniej to zmieniles i zamienia na O.

ogolnie uzyj lepiej wartosci bool np.

public static bool kolejX = false;
...

public static void kolejka()
        {
           kolejX = !kolejX;
        }
 
0

Hah, faktycznie. Trochę matoł ze mnie, no ale cóż, nie poddaję się. :) Poczytałem o zmiennych logicznych, zrobiłem po swojemu i.... działa! Zmienia mi z X na O, tylko teraz pozostaje problem wysypywania się programu po dwóch przejściach.. :/

1

to raczej nie o dwa przejscia chodzi a o skrajne pola (ktore akurat kilkales w drugim przebiegu:))

W miedzyczasie taki kawal:
Ile palcow ma programista???

9, bo liczy od ZERA.

Popelniles podstawowy blad, wiec zapamietaj go na dlugo. PROGRAMISTA LICZY OD ZERA, wiec twoja tablica dwuwymiarowa o wymiarach 3 na 3, ma elementy:

 
            tablica[2, 0] 
            itablica[2, 1] 
            tablica[2, 2] 
            tablica[1, 0]
            tablica[1, 1]
            tablica[1, 2] 
            tablica[0, 0]
            tablica[0, 1]
            tablica[0, 2]

Juz jasniej???

0

Tak! Dzięki ;) Dobrze, że jest takie forum, bo bym rozkminiał nad tym jeszcze długo ;)

3

@bnbnowacki - a w ramach podziękowania za pomoc, dostaniesz ćwiczenie - skróć te instrukcje:

if (k == 1) tablica[3, 1] = kolej;
if (k == 2) tablica[3, 2] = kolej;
if (k == 3) tablica[3, 3] = kolej;
if (k == 4) tablica[2, 1] = kolej;
if (k == 5) tablica[2, 2] = kolej;
if (k == 6) tablica[2, 3] = kolej;
if (k == 7) tablica[1, 1] = kolej;
if (k == 8) tablica[1, 2] = kolej;
if (k == 9) tablica[1, 3] = kolej;

do jednej, wykorzystując prostą arytmetykę; Używanie warunków tylko tam, gdzie to konieczne to dobra praktyka optymalizacyjna; Tylko zastosuj takie idenksowanie tablicy, jakie podał Ci (słusznie) @szalonyfacet :]

Poza tym masz mały problem z warunkami, bo nie stosujesz else, stąd wszystkie Twoje warunki zawsze zostaną sprawdzone, bez względu na wynik poprzedniego warunku; Wcześniej miałeś z tym problem przy zmianie kolejki, teraz wykonujesz sprawdzenie każdej wartości zmiennej k, a to niepotrzebne; Dlatego sugeruję zamianę tych warunków na modyfikację tylko jednego pola tablicy; Dzięki temu raz - uprościsz kod, dwa - kod będzie działał prawidłowo.

0

Ok, jak na razie zamieniłem wszystkie warunki na switch'a.(Nie mam pojęcia jak można zrobić to na jednej instrukcji warunkowej, chyba, że chodziło właśnie o coś takiego) Czy tak jest lepiej? No i dzięki temu ćwiczeniu widzę już, że różnica między dwona warunkami, a jednym z else jest ogromna. Wcześniej używałem samych ifów, bo wydawało mi się to bardziej czytelne. Jakie ćwiczenie byście mi poradzili jako kolejne?

        public static void zamiana()
        {
            switch (k)
            {
                case 1:
                    tablica[2, 0] = kolej;
                    break;
                case 2:
                    tablica[2, 1] = kolej;
                    break;
                case 3:
                    tablica[2, 2] = kolej;
                    break;
                case 4:
                    tablica[1, 0] = kolej;
                    break;
                case 5:
                    tablica[1, 1] = kolej;
                    break;
                case 6:
                    tablica[1, 2] = kolej;
                    break;
                case 7:
                    tablica[0, 0] = kolej;
                    break;
                case 8:
                    tablica[0, 1] = kolej;
                    break;
                case 9:
                    tablica[0, 2] = kolej;
                    break;
                default:
                    Console.WriteLine("użyto innego znaku");
                    break;

            } 
3

Myślę, że chodziło raczej o coś takiego:

tablica[2-(k-1)/3,(k-1)%3] = kolej;
0

Ooo.. No na takie coś bym nie wpadł.. Wychodzą same liczby ułamkowe, chodzi o to, że int i tak zaokrągli i to będzie działało? Nie sprawdzę u siebie, bo już zmieniłem k na string, żeby było odporne na wpisywanie znaków w switchu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1