[C] Kółko i krzyżyk + GTK

0

Jeżeli mam cały gotowy algorytm gry w kółko i krzyżyk w konsoli i chcę do tego dodać interfejs GTK to przy takim układzie kodu:

#include "funkcje.c"

int main(int argc, char *argv[])
{
    // Zmienne obliczeniowe
    int ruch = 1, poprzedni = 2, tmp;
    int wiersz;
    int ilosc_ruchow = 0;
    int wynik = 0;
    int comp_player = 1;
    char kolumna[1];

    // Wywołanie funkcji
    srand(time(0));
    ZerujTablice();
    RysujPole();

    while (ilosc_ruchow < F_SIZE*F_SIZE)
    {
        // Gra z jednym graczem
        // Gra przeciwko komputerowi
        // Generalnie wszystkie obliczenia etc.
    }

    // Wypisanie wyniku
    
    return 0;
}

Powinienem deklaracje okienka itd. zrobić poza ta pętlą czyli

 #include "funkcje.c"

int main(int argc, char *argv[])
{
    // Zmienne obliczeniowe
    int ruch = 1, poprzedni = 2, tmp;
    int wiersz;
    int ilosc_ruchow = 0;
    int wynik = 0;
    int comp_player = 1;
    char kolumna[1];

    // Wywołanie funkcji
    srand(time(0));
    ZerujTablice();
    RysujPole();
    
    GtkWidget *window;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Center");
    gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_widget_show(window);


    while (ilosc_ruchow < F_SIZE*F_SIZE)
    {
        // Gra z jednym graczem
        // Gra przeciwko komputerowi
        // Generalnie wszystkie obliczenia etc.
    }

    // Wypisanie wyniku
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_main();
    
    return 0;
}

Czy wewnątrz niej (co by w sumie wywoływało okienko przy każdym ruchu). Jak powinno wyglądać poprawne wywołanie okienka (połączenie gotowego algorytmu z interfejsem w GTK)

0

Programowanie pod okienka i programowanie takie w konsoli trochę różnią się od siebie.

Generalnie to biblioteka okienkowa zadba oto aby odpalić pętlę while w której wszystko będzie się działo np. wyświetlenie okna czy obsługa przycisków.

Teraz co musisz zrobić to zaprojektować wygląd aplikacji, dodać do okna np przyciski i je oprogramować.

0

Doszedłem do czegoś takiego

#include <gtk/gtk.h>



#define F_SIZE 3



GtkWidget *field_label[F_SIZE][F_SIZE];

int pole[F_SIZE][F_SIZE];

gint ruchy = 0;

int  ruch = 1, poprzedni = 2, *wsk_pole;



void ZerujTablice();

int WykonajRuch(GtkWidget *widget, gpointer label);



int main (int argc, char *argv[])

{

    int i, j;



    GtkWidget *field_[F_SIZE][F_SIZE];

    GtkWidget *window;

    GtkWidget *frame;

    GtkWidget *kolumny;



    gtk_init(&argc, &argv);

    ZerujTablice();



    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window), "Kolko i krzyzyk");

    gtk_window_set_default_size(GTK_WINDOW(window), 300, 300);

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);



    frame = gtk_fixed_new();

    gtk_container_add(GTK_CONTAINER(window), frame);



    kolumny = gtk_label_new("A");

    gtk_widget_set_size_request(kolumny, 100, 30);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 040, 0);

    kolumny = gtk_label_new("B");

    gtk_widget_set_size_request(kolumny, 100, 30);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 140, 0);

    kolumny = gtk_label_new("C");

    gtk_widget_set_size_request(kolumny, 100, 30);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 240, 0);

    kolumny = gtk_label_new("1");

    gtk_widget_set_size_request(kolumny, 40, 100);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 30);

    kolumny = gtk_label_new("2");

    gtk_widget_set_size_request(kolumny, 40, 100);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 130);

    kolumny = gtk_label_new("3");

    gtk_widget_set_size_request(kolumny, 40, 100);

    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 230);



    // Rysowanie pola

    for (i=0;i<F_SIZE;i++)

    {

        for(j=0;j<F_SIZE;j++)

        {

            field_[i][j] = gtk_button_new_with_label("");

            gtk_widget_set_size_request(field_[i][j], 100, 100);

            gtk_fixed_put(GTK_FIXED(frame), field_[i][j], 40+100*i, 30+100*j);



            switch(pole[i][j])

            {

                case 1:

                    field_label[i][j] = gtk_label_new("X");

                    break;

                case 2:

                    field_label[i][j] = gtk_label_new("O");

                    break;

                default:

                    field_label[i][j] = gtk_label_new("");

                    break;

            }

            gtk_fixed_put(GTK_FIXED(frame), field_label[i][j], 85+(100*i), 75+(100*j));

        }

    }





    gtk_widget_show_all(window);



    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);



    // Pobieranie ruchów od gracza

    for(i=0;i<F_SIZE;i++)

    {

        for(j=0;j<F_SIZE;j++)

        {

            if (!pole[i][j])

            {

                printf("%d %d\n", i, j);

                wsk_pole = &pole[i][j];

                pole[i][j] = 1;

                g_signal_connect(field_[i][j], "clicked", G_CALLBACK(WykonajRuch), field_label[i][j]);

            }

        }

    }



    gtk_main();



    return 0;

}



void ZerujTablice()

{

    int i = 0, j = 0;

    for (i = 0;i<F_SIZE;i++)

    {

        for (j=0;j<F_SIZE;j++)

        {

            pole[i][j] = 0;

        }

    }



}



int WykonajRuch(GtkWidget *widget, gpointer label)

{

    if (*wsk_pole == 0)

        ruchy++;



    if (ruchy > F_SIZE*F_SIZE)

        return 0;



    if (ruch == 1)

    {

        gtk_label_set_text( (GtkLabel*) label, "X" );

        ruch = 2;

        poprzedni = 1;

    }

    else

    {

        gtk_label_set_text( (GtkLabel*) label, "O" );

        ruch = 1;

        poprzedni = 2;

    }



    return 1;

}

Tylko, że to działa dość tragicznie ponieważ
a) można wykonywać ruchy w nieskończoność
b) można nadpisywać ruchy
Nie wiem jednak jak przechwycić, który konkretnie przycisk wcisnąłem i zależnie od tego sprawdzić czy można tam wsadzić coś czy nie.

0

Poprawiłem trochę tu i tam, jednak dalej można napisywać ruchy no i CzyWygral chce współpracować z programem tzn. zmienna wynik ciągle ma 0 niezależnie jakie ruchy się wykona

#include <gtk/gtk.h>

#define F_SIZE 3

GtkWidget *field_label[F_SIZE*F_SIZE];
GtkWidget *field_[F_SIZE*F_SIZE];
GtkWidget *frame;
int pole[F_SIZE*F_SIZE];
gint ruchy = 0;
int  ruch = 1, poprzedni = 2;
char buff[5];

void ZerujTablice();
void WykonajRuch(GtkWidget *widget, gpointer label);
void RysujPole();
int CzyWygral();

int main (int argc, char *argv[])
{
    int i= 0, j = 0, z = 0;

    GtkWidget *window;
    GtkWidget *kolumny;

    gtk_init(&argc, &argv);
    ZerujTablice();

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Kolko i krzyzyk");
    gtk_window_set_default_size(GTK_WINDOW(window), 150, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

    frame = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), frame);

    // Kosmetyczne wypisanie numeru wiersza i nazwy kolumny
    kolumny = gtk_label_new("A");
    gtk_widget_set_size_request(kolumny, 50, 15);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 020, 0);
    kolumny = gtk_label_new("B");
    gtk_widget_set_size_request(kolumny, 50, 15);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 70, 0);
    kolumny = gtk_label_new("C");
    gtk_widget_set_size_request(kolumny, 50, 15);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 120, 0);
    kolumny = gtk_label_new("1");
    gtk_widget_set_size_request(kolumny, 20, 50);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 15);
    kolumny = gtk_label_new("2");
    gtk_widget_set_size_request(kolumny, 20, 50);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 65);
    kolumny = gtk_label_new("3");
    gtk_widget_set_size_request(kolumny, 20, 50);
    gtk_fixed_put(GTK_FIXED(frame), kolumny, 0, 115);

    // Rysowanie pola
    for (i=0;i<F_SIZE*F_SIZE;i++)
    {
        field_[i] = gtk_button_new_with_label("");
        gtk_widget_set_size_request(field_[i], 50, 50);
		gtk_fixed_put(GTK_FIXED(frame), field_[i], 20+50*z, 15+50*j);
		switch(pole[i])
		{
			case 1:
				field_label[i] = gtk_label_new("X");
				break;
			case 2:
				field_label[i] = gtk_label_new("O");
				break;
			default:
				field_label[i] = gtk_label_new("");
				break;
		}
		gtk_fixed_put(GTK_FIXED(frame), field_label[i], 40+(50*z), 35+(50*j));
		if ((i+1)%3 == 0)
        {
			j++;
		}
		if (z == 2) z = 0;
		else z++;
    }

    gtk_widget_show_all(window);

    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // Pobieranie ruchów od gracza
    for(i=0;i<F_SIZE*F_SIZE;i++)
    {
        if (!pole[i])
        {
            g_signal_connect(field_[i], "clicked", G_CALLBACK(WykonajRuch), (gpointer) i);
            g_signal_connect(field_[i], "clicked", G_CALLBACK(RysujPole), field_label[i]);
        }
    }
	
    gtk_main();
   
    return 0;
}

// Wykonanie ruchu, zapisanie go do tablicy ze postawionymi znakami i sprawdzenie kto wygral
void WykonajRuch(GtkWidget *widget, gpointer label)
{
	
	int id = (int) label;
	int wynik = 0;
	
	printf("Stan: ");
	switch (wynik)
	{
		case 1:
			printf("Wygral X");
			break;
		case 2:
			printf("Wygral O");
			break;
		case 0:
			printf("Remis!");
			break;
		default:
			printf("System Failture");
			break;
	}
	printf("\n");
	
    if (pole[id] == 0 && ruchy < F_SIZE*F_SIZE)
    {
        ruchy++;
        pole[id] = ruch;
        printf("Gracz %d wykonuje ruch na pole %d\n", ruch, id);
        wynik = CzyWygral();

    }
    
    if (ruch == 1)
    {
        ruch = 2;
        poprzedni = 1;
    }
    else
    {
        ruch = 1;
        poprzedni = 2;
    }
}

// Funkcja odswiezajaca dane pole
void RysujPole(GtkWidget *widget, gpointer label)
{	
	if (ruch == 2)
		gtk_label_set_text( (GtkLabel*) label, "X" );
					
	else
		gtk_label_set_text( (GtkLabel*) label, "O" );	 
}

// Funkcja sprawdzajaca czy gracz wygral
int CzyWygral()
{
    int i = 0, j = 0, suma = 0, z = 0;
    //Sprawdzanie przekatnych
    if (pole[0] || pole[F_SIZE-1])
    {
        // Lewa przekatna
        for(i = 0;i<F_SIZE;i++)
        {
			if (i%4 == 0) 
			{
				if(pole[i] != pole[0])
					break;
				else
					suma++;
			}

            if (suma == F_SIZE)
                return pole[0];
        }

        // Prawa przekatna
        suma = 0;
        for(i=0;i<F_SIZE*2;i++)
        {
			if (i%2 == 0)
			{
				if(pole[i] != pole[F_SIZE-1])
					break;
				else
					suma++;
			}

            if (suma == F_SIZE)
                return pole[F_SIZE-1];
        }
    }
    // Sprawdzanie linii poziomych
    for (i = 0;i<F_SIZE;i++)
    {
        suma = 0;
        for (j = 0;j<F_SIZE;j++) 
        {
			if (pole[(F_SIZE*i)])
			{
				if (pole[j+(3*i)] != pole[(F_SIZE*i)])
					break;
				else
					suma++;
			}

			if (suma == F_SIZE)
				 return pole[j+(3*i)];
		}
    }

    // Sprawdzanie linii pionowych
    for (j = 0;j<F_SIZE;j++)
    {
		suma = 0;
		for (i = 0;i<F_SIZE;i++)
		{
			if (pole[j])
			{
				z = j + (F_SIZE*i);
				if (pole[z] != pole[j])
					break;
				else
					suma++;
				
				if (suma == F_SIZE)
					return pole[j];
			}
		}
	}

    return 0;
}
 

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