Guest User

hotseat Squava (a tiny LablGtk2 demo)

a guest
Apr 6th, 2026
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 6.31 KB | None | 0 0
  1.  
  2. (* GEANY lablgtk2+vanilla project *)
  3. (* F8 : ocamlopt.opt -o "%e" -w s -I +lablgtk2 lablgtk.cmxa "%f" *)
  4. (* F5 : "./%e" *)
  5.  
  6. let window =
  7.     GMain.init ();
  8.     let wnd = GWindow.window ~resizable:true ~title:"Squava board game" ()
  9.     in  wnd#connect#destroy GMain.quit; wnd
  10.  
  11. let vbox1 =
  12.     GPack.vbox ~packing:window#add ()
  13.  
  14. let button id tooltip =
  15.     let but = GButton.tool_button ~stock:id () in
  16.     but#misc#set_tooltip_markup tooltip;
  17.     but
  18.    
  19. let restart =
  20.     button `NEW "<b>Start</b> a new game"
  21.  
  22. let about =
  23.     button `ABOUT "<b>About</b> Squava"
  24.  
  25. let quit =
  26.     button `QUIT "<b>Quit</b> the application"
  27.    
  28. let toolbar =
  29.     let bar = GButton.toolbar
  30.         ~orientation:`HORIZONTAL ~style:`ICONS ~packing:vbox1#pack ()
  31.     in
  32.     bar#set_icon_size `LARGE_TOOLBAR;
  33.     bar#insert restart;
  34.     bar#insert (GButton.separator_tool_item ());
  35.     bar#insert about;  
  36.     bar#insert (GButton.separator_tool_item ());
  37.     bar#insert quit;   
  38.     bar
  39.  
  40. let center =
  41.     GBin.alignment ~xalign:0.5 ~yalign:0.5 ~xscale:0. ~yscale:0. ~packing:vbox1#add ()
  42.  
  43. let pixbuf =
  44.     GdkPixbuf.from_file "./squava.png"
  45. let pixmap,_ =
  46.     GdkPixbuf.create_pixmap pixbuf
  47. let sqr_size1 = GdkPixbuf.get_width pixbuf / 5
  48. let sqr_size = sqr_size1 - 1
  49. let asize = sqr_size1 * 5
  50. let asize1 = asize + 1
  51.  
  52. let area =
  53.     GMisc.drawing_area ~width:asize1 ~height:asize1 ~packing:center#add ()
  54. let drawing =
  55.     new GDraw.drawable (area#misc#realize (); area#misc#window)
  56.  
  57. let statusbar =
  58.     GMisc.statusbar ~has_resize_grip:true ~packing:vbox1#pack ()
  59.  
  60. let dialog = GWindow.about_dialog
  61.     ~authors:
  62.     ["Game design by Cameron Browne & N\xC3\xA9stor Romeral Andr\xC3\xA9s";
  63.     "GTK2 application by SpiceGuid (<[email protected]>)"]
  64.     ~copyright:"Copyright \xC2\xA9 2026 SpiceGuid"
  65.     ~license:"LGPL-2.1-or-later\nWITH OCaml-LGPL-linking-exception"
  66.     ~version:"1.1"
  67.     ~website:"https://boardgamegeek.com/boardgame/112745/squava"
  68.     ~website_label:"Board Game Geek : Squava"
  69.     ~parent:window
  70.     ~destroy_with_parent:true ()
  71.  
  72. let put_pixmap i src =
  73.     if src >= 0 then
  74.     let x = (i mod 5) * sqr_size1 + 1
  75.     and y = (i / 5) * sqr_size1 + 1
  76.     and xsrc = (src mod 5) * sqr_size1 + 1
  77.     and ysrc = (src / 5) * sqr_size1 + 1
  78.     in drawing#put_pixmap ~x ~y ~xsrc ~ysrc ~width:sqr_size ~height:sqr_size pixmap
  79.  
  80. let str_restart = "Click Start to begin a new game."
  81. let str_free_position = "Please click a free position."
  82. let str_white_turn = "It's White player turn."
  83. let str_red_turn = "It's Red player turn."
  84. let str_white_winner = "White player is the winner."
  85. let str_red_winner = "Red player is the winner."
  86. let str_white_loser = "White player is the loser."
  87. let str_red_loser = "Red player is the loser."
  88.  
  89. let status_context = statusbar#new_context ~name:""
  90.  
  91. let winner_moves =
  92.     [|
  93.     31457280; 15728640; 983040; 491520; 30720; 15360; 960; 480; 30; 15;
  94.     17318400; 541200; 8659200; 270600; 4329600; 135300; 2164800; 67650;
  95.     1082400; 33825; 17043520; 266305; 1118464; 69904; 8521760; 532610; 2236928;
  96.     34952 |]
  97.    
  98. let loser_moves =
  99.     [|
  100.     29360128; 14680064; 7340032; 917504; 458752; 229376; 28672; 14336; 7168;
  101.     896; 448; 224; 28; 14; 7; 17317888; 541184; 16912; 8658944; 270592; 8456;
  102.     4329472; 135296; 4228; 2164736; 67648; 2114; 1082368; 33824; 1057; 4472832;
  103.     4260864; 1092; 16644; 2236416; 139776; 8521728; 133152; 2184; 34944;
  104.     532608; 8322; 17043456; 266304; 4161; 1118208; 69888; 4368 |]
  105.  
  106. let has_mask mask n =
  107.     mask land n = n
  108.  
  109. let mouse m =
  110.     let mx = int_of_float (GdkEvent.Button.x m)
  111.     and my = int_of_float (GdkEvent.Button.y m)
  112.     in  (mx - 1) / sqr_size1 + ((my - 1) / sqr_size1) * 5
  113.    
  114. let main =
  115.     let ctrl =
  116.         object (self)
  117.             val mutable pressed = (-1)
  118.             val mutable released = (-1)
  119.             val mutable white_mask = 0
  120.             val mutable red_mask = 0
  121.             val mutable moves = 0
  122.             val board = Array.make 25 (-1)
  123.             method clicked =
  124.                 board.(pressed) <- moves;
  125.                 status_context#pop ();
  126.                 if moves land 1 = 1 then begin
  127.                     red_mask <- 1 lsl pressed + red_mask;
  128.                     if Array.exists (has_mask red_mask) winner_moves then
  129.                         (status_context#push str_red_winner; moves <- 24)
  130.                     else if Array.exists (has_mask red_mask) loser_moves then
  131.                         (status_context#push str_red_loser; moves <- 24)
  132.                     else begin
  133.                         status_context#push str_white_turn; ()
  134.                     end
  135.                 end else begin
  136.                     white_mask <- 1 lsl pressed + white_mask;
  137.                     if Array.exists (has_mask white_mask) winner_moves then
  138.                         (status_context#push str_white_winner; moves <- 24)
  139.                     else if Array.exists (has_mask white_mask) loser_moves then
  140.                         (status_context#push str_white_loser; moves <- 24)
  141.                     else begin
  142.                         status_context#push str_red_turn; ()
  143.                     end
  144.                 end;
  145.                 area#misc#draw None;
  146.                 pressed <- (-1); released <- (-1);
  147.                 moves <- moves + 1;
  148.             method restart () =
  149.                 pressed <- (-1); released <- (-1);
  150.                 white_mask <- 0; red_mask <- 0;
  151.                 moves <- 0; Array.fill board 0 25 (-1);
  152.                 area#misc#draw None;
  153.                 status_context#pop ();
  154.                 status_context#push str_white_turn;
  155.                 ()
  156.             method button_press m =
  157.                 if GdkEvent.Button.button m = 1 then begin
  158.                     pressed <- mouse m;
  159.                     if moves = 25 then status_context#flash str_restart;
  160.                 end;
  161.                 false
  162.             method button_release m =
  163.                 if GdkEvent.Button.button m = 1 then begin
  164.                     released <- mouse m;
  165.                     if pressed >=0 && released = pressed && moves < 25 then
  166.                         if board.(pressed) >= 0 then
  167.                             status_context#flash str_free_position
  168.                         else
  169.                             self#clicked;
  170.                 end;
  171.                 false
  172.             method expose _ =
  173.                 drawing#set_foreground `WHITE;
  174.                 drawing#rectangle ~x:0 ~y:0 ~width:asize1 ~height:asize1 ~filled:true ();
  175.                 drawing#set_foreground `BLACK;
  176.                 let y = ref 0 in
  177.                 while !y <= asize do
  178.                     drawing#line ~x:0 ~y:!y ~x:asize1 ~y:!y;
  179.                     y := !y + sqr_size1;
  180.                 done;
  181.                 let x = ref 0 in
  182.                 while !x <= asize do
  183.                     drawing#line ~x:!x ~y:0 ~x:!x ~y:asize1;
  184.                     x := !x + sqr_size1;
  185.                 done;
  186.                 Array.iteri put_pixmap board;
  187.                 false
  188.         end
  189.     in 
  190.     about#connect#clicked (fun () -> dialog#run (); dialog#misc#hide ());
  191.     area#event#connect#expose ~callback:ctrl#expose;
  192.     area#event#add [`BUTTON_PRESS;`BUTTON_RELEASE];
  193.     area#event#connect#button_press ~callback:ctrl#button_press;
  194.     area#event#connect#button_release ~callback:ctrl#button_release;
  195.     restart#connect#clicked ~callback:ctrl#restart;
  196.     quit#connect#clicked GMain.Main.quit;
  197.     status_context#push str_restart;
  198.     window#show ();
  199.     GMain.main ()
  200.  
Add Comment
Please, Sign In to add comment