//
// Copyright (c) 2005,2006 Frlo
//
#include <gtk/gtk.h>
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#define rozmer 8
#define pixlov 40
#define OKRAJ 20
#define PRAZDNE 0
#define BIELY 4
#define CIERNY 2
// musi byt 4 a 2 aby som mohol vypocitat zakazny pohyb dozadu 4-3=1 pre bieleho
//a 2-3=-1 pre cierneho
#define OZNACENY 1
#define SKOK 8
GtkWidget *window;
GtkWidget *drawarea;
GtkWidget *vpane, *button;
GtkWidget *hwindow;
GtkWidget *text;
GtkWidget *view;
GtkTextBuffer *buffer;
GdkGC *gc;
GdkColor colbg_biela = { 0, 50000, 50000, 50000 };
GdkColor colfig_biela = { 0, 65000, 65000, 65000 };
GdkColor colbg_cierna = { 0, 25000, 25000, 25000 };
GdkColor colfig_cierna = { 0, 15000, 15000, 15000 };
GdkColor col_skok = { 0, 25000, 25000, 65000 };
GdkColor col_oznaceny = { 0, 65000, 25000, 25000 };
gint8 polohy[rozmer][rozmer];
gint8 *posledny_oznaceny;
gint8 natahu;
gint8 winner;
gint
delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
{
g_print ("Ukoncene krizikom.\n");
return (FALSE);
}
void
destroy (GtkWidget * widget, gpointer data)
{
g_print ("Ukoncenie aplikacie.\n");
gtk_exit (1);
}
void
draw_sachovnica (GtkWidget * widget)
{
int x, y;
if (natahu == CIERNY)
gdk_gc_set_foreground (gc, &colfig_cierna);
else
gdk_gc_set_foreground (gc, &colfig_biela);
gdk_draw_rectangle (widget->window, gc, TRUE, 0, 0,
widget->allocation.width, OKRAJ);
gdk_draw_rectangle (widget->window, gc, TRUE,
widget->allocation.width - OKRAJ, 0, OKRAJ,
widget->allocation.height);
gdk_draw_rectangle (widget->window, gc, TRUE, 0,
widget->allocation.height - OKRAJ,
widget->allocation.width, widget->allocation.height);
gdk_draw_rectangle (widget->window, gc, TRUE, 0, 0, OKRAJ,
widget->allocation.height);
for (x = 0; x < rozmer; x++)
for (y = 0; y < rozmer; y++)
{
if (((x + y) % 2) == 0)
gdk_gc_set_foreground (gc, &colbg_cierna);
else
gdk_gc_set_foreground (gc, &colbg_biela);
gdk_draw_rectangle (widget->window, gc, TRUE, x * pixlov + OKRAJ,
y * pixlov + OKRAJ, pixlov, pixlov);
if (polohy[x][y] & CIERNY)
{
gdk_gc_set_foreground (gc, &colfig_cierna);
gdk_draw_arc
(widget->window, gc, TRUE, x * pixlov + OKRAJ,
y * pixlov + OKRAJ, pixlov, pixlov, 0, 64 * 360);
}
else if (polohy[x][y] & BIELY)
{
gdk_gc_set_foreground (gc, &colfig_biela);
gdk_draw_arc
(widget->window, gc, TRUE, x * pixlov + OKRAJ,
y * pixlov + OKRAJ, pixlov, pixlov, 0, 64 * 360);
}
if (polohy[x][y] & OZNACENY)
{
gdk_gc_set_foreground (gc, &col_oznaceny);
gdk_draw_rectangle (widget->window, gc, FALSE, x * pixlov + OKRAJ,
y * pixlov + OKRAJ, pixlov - 1, pixlov - 1);
}
else if (polohy[x][y] & SKOK)
{
gdk_gc_set_foreground (gc, &col_skok);
gdk_draw_rectangle (widget->window, gc, FALSE, x * pixlov + OKRAJ,
y * pixlov + OKRAJ, pixlov - 1, pixlov - 1);
}
}
}
gint
drawarea_expose (GtkWidget * widget, GdkEventExpose * event,
gpointer callback_data)
{
g_print ("Prekreslenie grafickej plochy.\n");
g_print ("Oblast: od x=%d, y=%d rozmery sirka=%d, vyska=%d\n",
event->area.x, event->area.y, event->area.width,
event->area.height);
draw_sachovnica (widget);
return FALSE;
}
bool
skontroluj_vytaza ()
{
int x, y;
bool win_cierny = true;
bool win_biely = true;
for (x = 0; x < 4; x++)
for (y = 0; y < 4 - x; y++)
{
if (not (polohy[x][y] & BIELY))
win_biely = false;
if (not (polohy[rozmer - x - 1][rozmer - y - 1] & CIERNY))
win_cierny = false;
}
if (win_biely)
{
winner = BIELY;
g_print ("Vyhral BIELY hrac !!!.\n");
}
if (win_cierny)
{
winner = CIERNY;
g_print ("Vyhral CIERNY hrac !!!.\n");
}
}
void
vypocitaj_skoky (int in_x, int in_y, int step)
{
int x, y, ix, iy;
for (ix = -1; ix < 2; ix++)
{
for (iy = -1; iy < 2; iy++)
{
x = in_x + ix;
y = in_y + iy;
if ((x >= 0) and (x < rozmer) and (y >= 0) and (y <
rozmer) and not ((ix
==
0)
and
(iy
==
0))
and not (polohy[x][y] & SKOK)
// podmienka aby som sa mohol hybat iba dopredu
// and ( (natahu-3)*(ix+iy) <= 0 )) nemohol hybat dozadu
and ((natahu - 3) * (ix + iy) < 0))
{
if ((step == 0) and not (polohy[x][y] & (CIERNY | BIELY)))
polohy[x][y] = polohy[x][y] | SKOK;
else if ((polohy[x][y] & (CIERNY | BIELY))
and (x + ix >= 0) and (x + ix < rozmer)
and (y + iy >= 0) and (y + iy <
rozmer) and (polohy[x + ix][y +
iy]
== PRAZDNE))
{
polohy[x + ix][y + iy] = SKOK;
vypocitaj_skoky (x + ix, y + iy, step + 1);
}
}
}
}
}
void
odznac_skoky ()
{
int x, y;
for (x = 0; x < rozmer; x++)
for (y = 0; y < rozmer; y++)
{
polohy[x][y] = polohy[x][y] & (255 - SKOK);
}
}
void
game_init ()
{
int x, y;
for (x = 0; x < rozmer; x++)
for (y = 0; y < rozmer; y++)
{
polohy[x][y] = PRAZDNE;
}
for (x = 0; x < 4; x++)
for (y = 0; y < 4 - x; y++)
{
polohy[x][y] = CIERNY;
polohy[rozmer - x - 1][rozmer - y - 1] = BIELY;
}
posledny_oznaceny = NULL;
natahu = BIELY;
winner = PRAZDNE;
odznac_skoky ();
draw_sachovnica (drawarea);
}
gint
button_clicked (GtkWidget * widget, GdkEventButton * event)
{
game_init ();
/* hwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (hwindow), "delete_event", G_CALLBACK (delete_event), NULL);
gtk_container_set_border_width (GTK_CONTAINER (hwindow), 0);
gtk_window_set_default_size(GTK_WINDOW(hwindow), 300, 600);
gtk_window_set_resizable (GTK_WINDOW (hwindow), FALSE);
gtk_window_set_title (GTK_WINDOW (hwindow), "Pravidla");
gtk_window_set_icon (GTK_WINDOW (hwindow), gdk_pixbuf_new_from_file ("iconka.png", NULL));
view = gtk_text_view_new ();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer,
"Pravidla hry :\nK tejto stolovej hre potrebujete sachovnicu 8x8 a dvadsat damovych kamenov (10 ciernych a 10 bielych). Rozostavite ich na sachovnici ako ukazuje obrazok cislo 1.\nZacina biely. Posunie jeden zo svojich kamenov do susedneho pola. Potom je na tahu cierny a dalej sa pravidelne striedaju. Kamene postupuju dopredu alebo dostrany, mozu prejst len na susedne policko, s ktorym sa ich policko dotyka bud celou stranou alebo aj rohom.\nKamene spolu nebojuju, maju sa co najrychlejsie presunut do opacneho kuta, odkial vychadza na zaciatku partie super. Postup kamenov sa da urychlit skokom cez jeden alebo viaceroi kamenov, cudzich i vlastnych (ako pri dame). Medzi preskakovanymi kamenmi vsak musi byt vzdy jedno pole volne. Pri viacnasobnom skoku je povolene po kazdom dopade zmenit smer.\nKto ma skorej svojich desat kamenov v povodnom rozostaveni v opacnom rohu sachovnice, vyhrava.\n"
, -1);
gtk_container_add (GTK_CONTAINER (hwindow), view);
gtk_widget_show (view);
gtk_widget_show (hwindow);*/
return TRUE;
}
gint
button_press_event (GtkWidget * widget, GdkEventButton * event)
{
if (winner != PRAZDNE)
return FALSE;
guint x, y;
x = (int) event->x - OKRAJ;
y = (int) event->y - OKRAJ;
x = x / pixlov;
y = y / pixlov;
g_print ("Klik: x=%d, y=%d \n", x, y);
// klikol som na svoj kamen
if (natahu & polohy[x][y])
{
// oznacujem pole
if (posledny_oznaceny != NULL)
*posledny_oznaceny = *posledny_oznaceny & (255 - OZNACENY);
polohy[x][y] = polohy[x][y] | OZNACENY;
posledny_oznaceny = &polohy[x][y];
odznac_skoky ();
vypocitaj_skoky (x, y, 0);
}
else if (SKOK & polohy[x][y])
{
polohy[x][y] = natahu;
odznac_skoky ();
*posledny_oznaceny =
*posledny_oznaceny & (255 - OZNACENY - CIERNY - BIELY);
skontroluj_vytaza ();
if (winner == PRAZDNE)
natahu = abs (natahu - 6);
}
draw_sachovnica (widget);
return FALSE;
}
int
main (int argc, char **argv)
{
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_title (GTK_WINDOW (window),
"Rohac, just another chessboard game");
gtk_window_set_icon (GTK_WINDOW (window),
gdk_pixbuf_new_from_file ("iconka.png", NULL));
drawarea = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (drawarea),
pixlov * rozmer + 2 * OKRAJ,
pixlov * rozmer + 2 * OKRAJ);
vpane = gtk_vpaned_new ();
button = gtk_button_new_with_label ("Nova hra");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (button_clicked), NULL);
gtk_container_add (GTK_CONTAINER (window), vpane);
gtk_container_add (GTK_CONTAINER (vpane), drawarea);
gtk_container_add (GTK_CONTAINER (vpane), button);
gtk_widget_set_events (drawarea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
gtk_widget_show (drawarea);
gtk_widget_show (vpane);
gtk_widget_show (button);
gtk_widget_show (window);
gc = gdk_gc_new (drawarea->window);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &colbg_biela,
TRUE, TRUE);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &colbg_cierna,
TRUE, TRUE);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &colfig_biela,
TRUE, TRUE);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &colfig_cierna,
TRUE, TRUE);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &col_skok, TRUE,
TRUE);
gdk_colormap_alloc_color (gtk_widget_get_colormap (window), &col_oznaceny,
TRUE, TRUE);
g_signal_connect (G_OBJECT (drawarea), "expose_event",
G_CALLBACK (drawarea_expose), NULL);
g_signal_connect (G_OBJECT (drawarea), "button_press_event",
G_CALLBACK (button_press_event), NULL);
game_init ();
gtk_main ();
return (0);
}
Platon Group <platon@platon.sk> http://platon.sk/
|