#!/usr/bin/scriba REM **************************************************************************** REM REM This is a port of my old ScriptBasic GTK demoprogram to the GTK-server. REM REM Originally published at july 20, 2002. REM Rewritten at december 26, 2005 - PvE. REM REM Tested with Scriptbasic 2.0 and the GTK-server module 2.0.7 for Scriptbasic REM REM **************************************************************************** IMPORT gtk.bas GLOBAL CONST nl = "\n" GLOBAL CONST FAKE = 12345 GLOBAL CONST EMPTY = 0 GLOBAL CONST WHITE = -1 GLOBAL CONST BLACK = 1 GLOBAL CONST GROUPIDSTART = 10 GLOBAL CONST CANVAS_WIDTH = 275 GLOBAL CONST CANVAS_HEIGHT = 246 REM ************************************************************** Main program CALL Initialize_Global CALL Create_Gopanel CALL Draw_Board REPEAT event = GUI("gtk_server_callback wait") IF event = newbutton THEN CALL New_Board IF event = "stone" THEN CALL Put_Stone IF event = buttoncapt THEN CALL Show_Prisoners UNTIL event = quitbutton OR event = gopanel GUI("gtk_exit 0") END REM ************************************************************** Concat arguments to GTK FUNCTION GUI(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9) LOCAL result$ result$ = STR(g0) & " " & STR(g1) & " " & STR(g2) & " " & STR(g3) & " " & STR(g4) & " " & STR(g5) & " " & STR(g6) & " " & STR(g7) & " " & STR(g8) & " " & STR(g9) GUI = GTK::gtk(result$) END FUNCTION REM ************************************************************** Initialize global parameters SUB Initialize_Global GUI("gtk_init NULL NULL") REM This array keeps the current go-board, wipe Go playing board FOR j = 1 TO 9 FOR i = 1 TO 9 board[i,j] = EMPTY NEXT i NEXT j REM These keep the coordinates of the last move played lastmovex = 0 lastmovey = 0 REM These keep the total amount of captured stones for each color capturedbywhite = 0 capturedbyblack = 0 END SUB REM ************************************************************** Create Go panel SUB Create_Gopanel gopanel = GUI("gtk_window_new 0") GUI("gtk_window_set_title", gopanel, "\"The Go panel Revived\"") GUI("gtk_widget_set_size_request", gopanel, 300, 350) gogrid = GUI("gtk_table_new", 55, 50, 1) GUI("gtk_container_add", gopanel, gogrid) frame = GUI("gtk_frame_new NULL") GUI("gtk_table_attach_defaults", gogrid, frame, 1, 49, 1, 43) GUI("gtk_frame_set_shadow_type", frame, 3) canvas = GUI("gtk_image_new") REM Create eventbox to catch mouseclick ebox = GUI("gtk_event_box_new") GUI("gtk_container_add", ebox, canvas) GUI("gtk_table_attach_defaults", gogrid, ebox, 2, 48, 2, 42) REM Connect mouse button signal to image GUI("gtk_server_connect", ebox, "button-press-event stone") radioblack = GUI("gtk_radio_button_new_with_label_from_widget NULL Black") GUI("gtk_table_attach_defaults", gogrid, radioblack, 20, 30, 44, 47) radiowhite = GUI("gtk_radio_button_new_with_label_from_widget", radioblack, "White") GUI("gtk_table_attach_defaults", gogrid, radiowhite, 20, 30, 48, 51) buttoncapt = GUI("gtk_button_new_with_label \"Show\nprison\"") GUI("gtk_table_attach_defaults", gogrid, buttoncapt, 10, 18, 44, 50) newbutton = GUI("gtk_button_new_with_label \"New\"") GUI("gtk_table_attach_defaults", gogrid, newbutton, 1, 9, 44, 50) quitbutton = GUI("gtk_button_new_with_label \"Quit\"") GUI("gtk_table_attach_defaults", gogrid, quitbutton, 41, 49, 44, 50) gostatus = GUI("gtk_statusbar_new") GUI("gtk_table_attach_defaults", gogrid, gostatus, 0, 50, 52, 55) cid = GUI("gtk_statusbar_get_context_id", gostatus, gopanel) GUI("gtk_statusbar_push", gostatus, cid, "\"New game started!\"") GUI("gtk_widget_show_all", gopanel) REM Create the pixmap gdkwin = GUI("gtk_widget_get_parent_window", canvas) pix = GUI("gdk_pixmap_new", gdkwin, CANVAS_WIDTH, CANVAS_HEIGHT, -1) gc = GUI("gdk_gc_new", pix) GUI("gtk_image_set_from_pixmap", canvas, pix, "NULL") REM Allocate memory for GdkColor with some random widget color = GUI("gtk_frame_new NULL") REM Now set foreground and backgroundcolors to WHITE GUI("gdk_color_parse #ffffff", color) GUI("gdk_gc_set_rgb_bg_color", gc, color) GUI("gdk_gc_set_rgb_fg_color", gc, color) REM Clear the complete pixmap with WHITE GUI("gdk_draw_rectangle", pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT) END SUB REM ************************************************************ Draw the Go board SUB Draw_Board LOCAL xfactor, yfactor REM Calculate square size xfactor = INT(CANVAS_WIDTH/9) yfactor = INT(CANVAS_HEIGHT/9) REM Draw vertical axes GUI("gdk_color_parse #000000", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) FOR i = xfactor/2 TO CANVAS_WIDTH - xfactor/2 STEP xfactor GUI("gdk_draw_line", pix, gc, INT(i), INT(yfactor/2), INT(i), INT(yfactor/2)+yfactor*8) NEXT i REM Draw horizontal axes FOR i = yfactor/2 TO CANVAS_HEIGHT - yfactor/2 STEP yfactor GUI("gdk_draw_line", pix, gc, INT(xfactor/2), INT(i), INT(xfactor/2)+xfactor*8, INT(i)) NEXT i REM Draw the positions of the stones FOR i = 1 TO 9 FOR j = 1 TO 9 IF board[i,j] = BLACK THEN GUI("gdk_color_parse #000000", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("gdk_draw_arc", pix, gc, 1, (i-1)*xfactor, (j-1)*yfactor, xfactor-1, yfactor-1, 0, 360*64) ELSE IF board[i,j] = WHITE THEN GUI("gdk_color_parse #ffffff", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("gdk_draw_arc", pix, gc, 1, (i-1)*xfactor, (j-1)*yfactor, xfactor-1, yfactor-1, 0, 360*64) GUI("gdk_color_parse #000000", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("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 GUI("gtk_widget_queue_draw", canvas) END SUB REM ************************************************************ Reset the board & draw SUB New_Board FOR j = 1 TO 9 FOR i = 1 TO 9 board[j,i] = EMPTY NEXT i NEXT j GUI("gdk_color_parse #ffffff", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("gdk_draw_rectangle", pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT) CALL Draw_Board lastmovex = 0 lastmovey = 0 capturedbywhite = 0 capturedbyblack = 0 GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"New game started!\"") END SUB REM ************************************************************ Show captured stones SUB Show_Prisoners GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"Captured by white: " & capturedbywhite & " - Captured by black: " & capturedbyblack & "\"") END SUB REM ************************************************************ Put a stone & draw SUB Put_Stone LOCAL mousex, mousey, xfactor, yfactor mousex = VAL(GUI("gtk_server_mouse 0")) mousey = VAL(GUI("gtk_server_mouse 1")) xfactor = INT(CANVAS_WIDTH/9) yfactor = INT(CANVAS_HEIGHT/9) FOR j = 1 TO 9 FOR i = 1 TO 9 IF (mousex>(j-1)*xfactor) AND (mousex<(j-1)*xfactor+xfactor) THEN IF (mousey>(i-1)*yfactor) AND (mousey<((i-1)*yfactor+yfactor)) THEN IF (GUI("gtk_toggle_button_get_active", radioblack) = "1") THEN IF board[j,i] = EMPTY THEN board[j,i] = BLACK GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"Black played.\"") lastmovex = j lastmovey = i ELSE GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"Cannot play here!\"") END IF ELSE IF board[j,i] = EMPTY THEN board[j,i] = WHITE GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"White played.\"") lastmovex = j lastmovey = i ELSE GUI("gtk_statusbar_pop", gostatus, cid) GUI("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 REM ************************************************************ Was last move suicide? SUB Determine_Suicide LOCAL i, j, group, freedoms, counter, current REM Wipe groups board with fake value FOR j = 0 TO 10 FOR i = 0 TO 10 groups[j,i] = FAKE NEXT i NEXT j REM Copy current playing board to groups board FOR j = 1 TO 9 FOR i = 1 TO 9 groups[j,i] = board[j,i] NEXT i NEXT j REM Clear temp array's keeping stone positions FOR i = 1 to 81 posx[i] = 0 posy[i] = 0 NEXT i REM Initialize local variables freedoms = 0 counter = 1 current = 1 posx[current] = lastmovex posy[current] = lastmovey group = groups[lastmovex,lastmovey] groups[lastmovex,lastmovey] = -1*group DO IF groups[posx[current]-1,posy[current]] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current]-1,posy[current]] = group THEN groups[posx[current]-1,posy[current]] = -1*group counter += 1 posx[counter] = posx[current]-1 posy[counter] = posy[current] END IF IF groups[posx[current]+1,posy[current]] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current]+1,posy[current]] = group THEN groups[posx[current]+1,posy[current]] = -1*group counter += 1 posx[counter] = posx[current]+1 posy[counter] = posy[current] END IF IF groups[posx[current],posy[current]-1] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current],posy[current]-1] = group THEN groups[posx[current],posy[current]-1] = -1*group counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]-1 END IF IF groups[posx[current],posy[current]+1] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current],posy[current]+1] = group THEN groups[posx[current],posy[current]+1] = -1*group counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]+1 END IF current += 1 LOOP UNTIL current > counter IF freedoms = 0 THEN board[lastmovex, lastmovey] = EMPTY GUI("gdk_color_parse #ffffff", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("gdk_draw_rectangle", pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT) CALL Draw_Board GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"This is an illegal move! Play again...\"") END IF END SUB REM ************************************************************ Find captured stones SUB Captured_Stones LOCAL i, j, group, freedoms, counter, current, total REM Wipe groups board FOR j = 0 TO 10 FOR i = 0 TO 10 groups[j,i] = FAKE NEXT i NEXT j REM Copy current playing board to groups board FOR j = 1 TO 9 FOR i = 1 TO 9 groups[j,i] = board[j,i] NEXT i NEXT j REM Clear temp array's keeping stone positions FOR i = 1 to 81 posx[i] = 0 posy[i] = 0 NEXT i REM Initialize used variables total = 0 FOR j = 1 TO 9 FOR i = 1 TO 9 REM Check: place is empty and is not the last color played IF (ABS(groups[j,i]) <> EMPTY) AND (groups[j,i]<>board[lastmovex,lastmovey]) THEN freedoms = 0 counter = 1 current = 1 posx[current] = j posy[current] = i group = groups[j,i] groups[j,i] = -5*group DO IF groups[posx[current]-1,posy[current]] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current]-1,posy[current]] = group THEN groups[posx[current]-1,posy[current]] = -5*group counter += 1 posx[counter] = posx[current]-1 posy[counter] = posy[current] END IF IF groups[posx[current]+1,posy[current]] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current]+1,posy[current]] = group THEN groups[posx[current]+1,posy[current]] = -5*group counter += 1 posx[counter] = posx[current]+1 posy[counter] = posy[current] END IF IF groups[posx[current],posy[current]-1] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current],posy[current]-1] = group THEN groups[posx[current],posy[current]-1] = -5*group counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]-1 END IF IF groups[posx[current],posy[current]+1] = EMPTY THEN freedoms += 1 ELSE IF groups[posx[current],posy[current]+1] = group THEN groups[posx[current],posy[current]+1] = -5*group counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]+1 END IF current += 1 LOOP UNTIL current > counter IF freedoms = 0 THEN counter = 1 current = 1 posx[current] = j posy[current] = i group = groups[j,i] groups[j,i] = EMPTY board[j,i] = EMPTY DO IF groups[posx[current]-1,posy[current]] = group THEN groups[posx[current]-1,posy[current]] = EMPTY board[posx[current]-1,posy[current]] = EMPTY counter += 1 posx[counter] = posx[current]-1 posy[counter] = posy[current] END IF IF groups[posx[current]+1,posy[current]] = group THEN groups[posx[current]+1,posy[current]] = EMPTY board[posx[current]+1,posy[current]] = EMPTY counter += 1 posx[counter] = posx[current]+1 posy[counter] = posy[current] END IF IF groups[posx[current],posy[current]-1] = group THEN groups[posx[current],posy[current]-1] = EMPTY board[posx[current],posy[current]-1] = EMPTY counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]-1 END IF IF groups[posx[current],posy[current]+1] = group THEN groups[posx[current],posy[current]+1] = EMPTY board[posx[current],posy[current]+1] = EMPTY counter += 1 posx[counter] = posx[current] posy[counter] = posy[current]+1 END IF current += 1 LOOP UNTIL current > counter GUI("gdk_color_parse #ffffff", color) GUI("gdk_gc_set_rgb_fg_color", gc, color) GUI("gdk_draw_rectangle", pix, gc, 1, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT) CALL Draw_Board total += counter END IF END IF NEXT i NEXT j IF total > 0 THEN GUI("gtk_statusbar_pop", gostatus, cid) GUI("gtk_statusbar_push", gostatus, cid, "\"" & total & " stones captured!\"") END IF IF board[lastmovex, lastmovey] = WHITE THEN capturedbywhite += total IF board[lastmovex, lastmovey] = BLACK THEN capturedbyblack += total END SUB