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

2010-12-19 16:46

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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)

edytowany 1x, ostatnio: Deith, 2010-12-19 16:47

Pozostało 580 znaków

alehaandro
2010-12-19 22:13
alehaandro
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ć.

Pozostało 580 znaków

2010-12-20 23:46

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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.

Pozostało 580 znaków

2010-12-21 21:28

Rejestracja: 9 lat temu

Ostatnio: 8 lat temu

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 :hmm:

#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;
}

Pozostało 580 znaków

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