CATCH GOTO Handle_Error
CONST Gtk = "libgtk-x11-2.0.so.0"
CONST Gdk = "libgdk-x11-2.0.so.0"
CONST Gobject = "libgobject-2.0.so.0"
IMPORT "g_signal_connect_data" FROM Gobject TYPE void
IMPORT "gdk_color_parse" FROM Gdk TYPE void
IMPORT "gdk_draw_arc" FROM Gdk TYPE void
IMPORT "gdk_draw_line(long, long, int, int, int, int)" FROM Gdk TYPE void
IMPORT "gdk_draw_rectangle" FROM Gdk TYPE void
IMPORT "gdk_gc_new" FROM Gdk TYPE long
IMPORT "gdk_gc_set_rgb_bg_color" FROM Gdk TYPE void
IMPORT "gdk_gc_set_rgb_fg_color" FROM Gdk TYPE void
IMPORT "gdk_pixmap_new" FROM Gdk TYPE long
IMPORT "gdk_window_get_pointer" FROM Gdk TYPE long
IMPORT "gtk_button_new_with_label" FROM Gtk TYPE long
IMPORT "gtk_container_add" FROM Gtk TYPE void
IMPORT "gtk_event_box_new" FROM Gtk TYPE long
IMPORT "gtk_exit" FROM Gtk TYPE void
IMPORT "gtk_frame_new" FROM Gtk TYPE long
IMPORT "gtk_frame_set_shadow_type" FROM Gtk TYPE void
IMPORT "gtk_image_new" FROM Gtk TYPE long
IMPORT "gtk_image_set_from_pixmap" FROM Gtk TYPE void
IMPORT "gtk_init" FROM Gtk TYPE void
IMPORT "gtk_main" FROM Gtk TYPE void
IMPORT "gtk_radio_button_new_with_label_from_widget" FROM Gtk TYPE long
IMPORT "gtk_statusbar_get_context_id" FROM Gtk TYPE long
IMPORT "gtk_statusbar_new" FROM Gtk TYPE long
IMPORT "gtk_statusbar_pop" FROM Gtk TYPE void
IMPORT "gtk_statusbar_push" FROM Gtk TYPE void
IMPORT "gtk_table_attach_defaults" FROM Gtk TYPE void
IMPORT "gtk_table_new" FROM Gtk TYPE long
IMPORT "gtk_toggle_button_get_active" FROM Gtk TYPE long
IMPORT "gtk_widget_get_parent_window" FROM Gtk TYPE long
IMPORT "gtk_widget_queue_draw" FROM Gtk TYPE void
IMPORT "gtk_widget_set_size_request" FROM Gtk TYPE void
IMPORT "gtk_widget_show_all" FROM Gtk TYPE void
IMPORT "gtk_window_new" FROM Gtk TYPE long
IMPORT "gtk_window_set_position" FROM Gtk TYPE void
IMPORT "gtk_window_set_title" FROM Gtk TYPE void
SUB Draw_Board
LOCAL xfactor, yfactor, i, j TYPE int
xfactor = ROUND(CANVAS_WIDTH/9)
yfactor = ROUND(CANVAS_HEIGHT/9)
gdk_color_parse("#000000", col)
gdk_gc_set_rgb_fg_color(gc, col)
FOR i = xfactor/2 TO CANVAS_WIDTH - xfactor/2 STEP xfactor
gdk_draw_line(pix, gc, ROUND(i), ROUND(yfactor/2), ROUND(i), ROUND(yfactor/2)+yfactor*8)
NEXT i
FOR i = yfactor/2 TO CANVAS_HEIGHT - yfactor/2 STEP yfactor
gdk_draw_line(pix, gc, ROUND(xfactor/2), ROUND(i), ROUND(xfactor/2)+xfactor*8, ROUND(i))
NEXT i
FOR i = 1 TO 9
FOR j = 1 TO 9
IF board[i][j] EQ BLACK_STONE THEN
gdk_color_parse("#000000", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_arc(pix, gc, 1, (i-1)*xfactor, (j-1)*yfactor, xfactor-1, yfactor-1, 0, 360*64)
ELIF board[i][j] EQ WHITE_STONE THEN
gdk_color_parse("#ffffff", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_arc(pix, gc, 1, (i-1)*xfactor, (j-1)*yfactor, xfactor-1, yfactor-1, 0, 360*64)
gdk_color_parse("#000000", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_arc(pix, gc, 0, (i-1)*xfactor, (j-1)*yfactor, xfactor-1, yfactor-1, 0, 360*64)
END IF
NEXT j
NEXT i
gtk_widget_queue_draw (canvas)
END SUB
SUB New_Board
LOCAL i, j TYPE int
FOR j = 1 TO 9
FOR i = 1 TO 9
board[j][i] = EMPTY
NEXT i
NEXT j
gdk_color_parse("#ffffff", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_rectangle(pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
CALL Draw_Board
lastmovex = 0
lastmovey = 0
capturedbywhite = 0
capturedbyblack = 0
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "New game started!")
END SUB
SUB Captured_Stones
LOCAL i, j, group, freedoms, counter, curr, total TYPE int
LOCAL groups[11][11] TYPE int
LOCAL posx[82], posy[82] TYPE int
FOR j = 0 TO 10
FOR i = 0 TO 10
groups[j][i] = FAKE
NEXT i
NEXT j
FOR j = 1 TO 9
FOR i = 1 TO 9
groups[j][i] = board[j][i]
NEXT i
NEXT j
FOR i = 1 TO 81
posx[i] = 0
posy[i] = 0
NEXT i
total = 0
FOR j = 1 TO 9
FOR i = 1 TO 9
IF (ABS(groups[j][i]) NE EMPTY) AND (groups[j][i] NE board[lastmovex][lastmovey]) THEN
freedoms = 0
counter = 1
curr = 1
posx[curr] = j
posy[curr] = i
group = groups[j][i]
groups[j][i] = -5*group
REPEAT
IF groups[posx[curr]-1][posy[curr]] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]-1][posy[curr]] EQ group THEN
groups[posx[curr]-1][posy[curr]] = -5*group
counter = counter + 1
posx[counter] = posx[curr]-1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]+1][posy[curr]] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]+1][posy[curr]] EQ group THEN
groups[posx[curr]+1][posy[curr]] = -5*group
counter = counter + 1
posx[counter] = posx[curr]+1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]][posy[curr]-1] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]][posy[curr]-1] EQ group THEN
groups[posx[curr]][posy[curr]-1] = -5*group
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]-1
END IF
IF groups[posx[curr]][posy[curr]+1] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]][posy[curr]+1] EQ group THEN
groups[posx[curr]][posy[curr]+1] = -5*group
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]+1
END IF
curr = curr + 1
UNTIL curr > counter
IF freedoms EQ 0 THEN
counter = 1
curr = 1
posx[curr] = j
posy[curr] = i
group = groups[j][i]
groups[j][i] = EMPTY
board[j][i] = EMPTY
REPEAT
IF groups[posx[curr]-1][posy[curr]] EQ group THEN
groups[posx[curr]-1][posy[curr]] = EMPTY
board[posx[curr]-1][posy[curr]] = EMPTY
counter = counter + 1
posx[counter] = posx[curr]-1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]+1][posy[curr]] EQ group THEN
groups[posx[curr]+1][posy[curr]] = EMPTY
board[posx[curr]+1][posy[curr]] = EMPTY
counter = counter + 1
posx[counter] = posx[curr]+1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]][posy[curr]-1] EQ group THEN
groups[posx[curr]][posy[curr]-1] = EMPTY
board[posx[curr]][posy[curr]-1] = EMPTY
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]-1
END IF
IF groups[posx[curr]][posy[curr]+1] EQ group THEN
groups[posx[curr]][posy[curr]+1] = EMPTY
board[posx[curr]][posy[curr]+1] = EMPTY
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]+1
END IF
curr = curr + 1
UNTIL curr > counter
gdk_color_parse("#ffffff", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_rectangle( pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
CALL Draw_Board
total = total + counter
END IF
END IF
NEXT i
NEXT j
IF total > 0 THEN
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, CONCAT$(STR$(total), " stones captured!"))
END IF
IF board[lastmovex][lastmovey] EQ WHITE_STONE THEN
capturedbywhite = capturedbywhite + total
END IF
IF board[lastmovex][lastmovey] EQ BLACK_STONE THEN
capturedbyblack = capturedbyblack + total
END IF
END SUB
SUB Determine_Suicide
LOCAL i, j, group, freedoms, counter, curr TYPE int
LOCAL groups[11][11] TYPE int
LOCAL posx[82], posy[82] TYPE int
FOR j = 0 TO 10
FOR i = 0 TO 10
groups[j][i] = FAKE
NEXT i
NEXT j
FOR j = 1 TO 9
FOR i = 1 TO 9
groups[j][i] = board[j][i]
NEXT i
NEXT j
FOR i = 1 TO 81
posx[i] = 0
posy[i] = 0
NEXT i
freedoms = 0
counter = 1
curr = 1
posx[curr] = lastmovex
posy[curr] = lastmovey
group = groups[lastmovex][lastmovey]
groups[lastmovex][lastmovey] = -1*group
REPEAT
IF groups[posx[curr]-1][posy[curr]] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]-1][posy[curr]] EQ group THEN
groups[posx[curr]-1][posy[curr]] = -1*group
counter = counter + 1
posx[counter] = posx[curr]-1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]+1][posy[curr]] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]+1][posy[curr]] EQ group THEN
groups[posx[curr]+1][posy[curr]] = -1*group
counter = counter + 1
posx[counter] = posx[curr]+1
posy[counter] = posy[curr]
END IF
IF groups[posx[curr]][posy[curr]-1] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]][posy[curr]-1] EQ group THEN
groups[posx[curr]][posy[curr]-1] = -1*group
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]-1
END IF
IF groups[posx[curr]][posy[curr]+1] EQ EMPTY THEN
freedoms = freedoms + 1
ELIF groups[posx[curr]][posy[curr]+1] EQ group THEN
groups[posx[curr]][posy[curr]+1] = -1*group
counter = counter + 1
posx[counter] = posx[curr]
posy[counter] = posy[curr]+1
END IF
curr = curr + 1
UNTIL curr > counter
IF freedoms EQ 0 THEN
board[lastmovex][lastmovey] = EMPTY
gdk_color_parse("#ffffff", col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_rectangle(pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
CALL Draw_Board
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "This is an illegal move! Play again...")
END IF
END SUB
SUB Put_Stone(NUMBER widget, NUMBER gdkeventbutton, NUMBER userdata)
LOCAL mousex, mousey, xfactor, yfactor TYPE int
LOCAL i, j TYPE int
win = gtk_widget_get_parent_window(widget)
gdk_window_get_pointer(win, ADDRESS(mousex), ADDRESS(mousey), 0)
xfactor = ROUND(CANVAS_WIDTH/9)
yfactor = ROUND(CANVAS_HEIGHT/9)
FOR j = 1 TO 9
FOR i = 1 TO 9
IF (mousex > (j-1)*xfactor+xfactor*0.5) AND (mousex < (j-1)*xfactor+xfactor*1.5) THEN
IF (mousey > (i-1)*yfactor+yfactor*0.5) AND (mousey < (i-1)*yfactor+yfactor*1.5) THEN
IF gtk_toggle_button_get_active(radioblack) EQ 1 THEN
IF board[j][i] EQ EMPTY THEN
board[j][i] = BLACK_STONE
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "Black played.")
lastmovex = j
lastmovey = i
ELSE
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "Cannot play here!")
END IF
ELSE
IF board[j][i] EQ EMPTY THEN
board[j][i] = WHITE_STONE
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "White played.")
lastmovex = j
lastmovey = i
ELSE
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, "Cannot play here!")
END IF
END IF
END IF
END IF
NEXT i
NEXT j
CALL Draw_Board
CALL Captured_Stones
CALL Determine_Suicide
END SUB
SUB Exit_Prog
gtk_exit(0)
ENDSUB
SUB Initialize_Global
LOCAL i, j TYPE int
FOR j = 1 TO 9
FOR i = 1 TO 9
board[i][j] = EMPTY
NEXT i
NEXT j
lastmovex = 0
lastmovey = 0
capturedbywhite = 0
capturedbyblack = 0
END SUB
SUB Show_Prisoners
gtk_statusbar_pop(gostatus, cid)
gtk_statusbar_push(gostatus, cid, CONCAT$("Captured by white: ", STR$(capturedbywhite), " - Captured by black: ", STR$(capturedbyblack)))
END SUB
SUB Create_Gopanel
gtk_init(0, 0)
gopanel = gtk_window_new(0)
gtk_window_set_title(gopanel, "The Go panel Revived")
gtk_window_set_position(gopanel, 1)
gtk_widget_set_size_request(gopanel, 300, 350)
g_signal_connect_data(gopanel, "delete-event", Exit_Prog, 0, 0, 0)
gogrid = gtk_table_new(55, 50, 1)
gtk_container_add(gopanel, gogrid)
frame = gtk_frame_new(0)
gtk_table_attach_defaults(gogrid, frame, 1, 49, 1, 43)
gtk_frame_set_shadow_type(frame, 3)
canvas = gtk_image_new()
ebox = gtk_event_box_new()
gtk_container_add(ebox, canvas)
gtk_table_attach_defaults(gogrid, ebox, 2, 48, 2, 42)
g_signal_connect_data(ebox, "button-press-event", Put_Stone, 0, 0, 0)
radioblack = gtk_radio_button_new_with_label_from_widget(0, "Black")
gtk_table_attach_defaults(gogrid, radioblack, 24, 36, 44, 47)
radiowhite = gtk_radio_button_new_with_label_from_widget(radioblack, "White")
gtk_table_attach_defaults(gogrid, radiowhite, 24, 36, 48, 51)
buttoncapt = gtk_button_new_with_label("Show\nprison")
gtk_table_attach_defaults(gogrid, buttoncapt, 12, 22, 44, 50)
g_signal_connect_data(buttoncapt, "clicked", Show_Prisoners, 0, 0, 0)
newbutton = gtk_button_new_with_label("New")
gtk_table_attach_defaults(gogrid, newbutton, 1, 11, 44, 50)
g_signal_connect_data(newbutton, "clicked", New_Board, 0, 0, 0)
quitbutton = gtk_button_new_with_label("Quit")
gtk_table_attach_defaults(gogrid, quitbutton, 41, 49, 44, 50)
g_signal_connect_data(quitbutton, "clicked", Exit_Prog, 0, 0, 0)
gostatus = gtk_statusbar_new()
gtk_table_attach_defaults(gogrid, gostatus, 0, 50, 52, 55)
cid = gtk_statusbar_get_context_id(gostatus, gopanel)
gtk_statusbar_push(gostatus, cid, "New game started!")
gtk_widget_show_all(gopanel)
gdkwin = gtk_widget_get_parent_window(canvas)
pix = gdk_pixmap_new(gdkwin, CANVAS_WIDTH, CANVAS_HEIGHT, -1)
gc = gdk_gc_new(pix)
gtk_image_set_from_pixmap(canvas, pix, 0)
col = gtk_frame_new(0)
gdk_color_parse("#ffffff", col)
gdk_gc_set_rgb_bg_color(gc, col)
gdk_gc_set_rgb_fg_color(gc, col)
gdk_draw_rectangle(pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)
gtk_widget_show_all(gopanel)
END SUB
DECLARE board[10][10] TYPE int
CONST FAKE = 12345
CONST EMPTY = 0
CONST WHITE_STONE = -1
CONST BLACK_STONE = 1
CONST GROUPIDSTART = 10
CONST CANVAS_WIDTH = 275
CONST CANVAS_HEIGHT = 246
Create_Gopanel
Draw_Board
gtk_main
END
LABEL Handle_Error
PRINT ERR$(ERROR)
END