NYCJUG/2011-02-08/MineSweeperConfigAndCode

From J Wiki
Jump to: navigation, search

Minesweeper.ijs

The “Launch” configuration is open to editing like this

EditConfigureLaunchEG.png

This line makes available the “Minesweeper” script which can be invoked like this (after re-starting the J-GTK session):

MinesweeperLaunchEG.png

(The duplication of "Minesweeper" and "minesweeper" is a known bug which has been slated for a fix.) This brings up the game like this:

MinesweeperEG.png

Following is the script invoked.

NB. Gtk user interface for Minesweeper game
NB. works with J7 gui/gtk addon (either from GtkIDE or console).

Note 'Example commands to run'
  MinesweeperGtk ''
  MinesweeperGtk 12 12
)

MinesweeperGtk_z_=: conew&'mineswpgtk'
require 'games/minesweeper/minefield'
require 'gui/gtk'
coclass 'mineswpgtk'
coinsert 'mineswp';'jgtk'

AddonPath=. jpath '~addons/games/minesweeper/'
Tiles=: ,((2 2 $ #) <;._3 ]) readimg AddonPath,'tiles26.png'

NB. Methods
NB. =========================================================
create=: 3 : 0
  if. -.IFGTK do. gtkinit'' end.
  newMinefield y
  IsEnd=: 0
  newwindow 'Minesweeper GTK'                  NB. create new window with Title
  consig window;'destroy';'window_destroy'     NB. assign event handler for event
  box1=. gtk_vbox_new 0 0           NB. create vertical box container for widgets
  gtk_container_add window, box1    NB. Add the container to the window
NB. tooltips group
  menutooltips=: gtk_tooltips_new''
NB. menu bar
  menu_init''
  mb=. edit_menu''
  gtk_box_pack_start box1, mb, 0 0 0         NB. pack menubar in the vertical box
NB. drawing area
  gtkda=: gtk_drawing_area_new''
  gtk_widget_set_size_request gtkda,((#>{.Tiles)*$Map)
  NB. GDK_LEAVE_NOTIFY_MASK,GDK_POINTER_MOTION_HINT_MASK
  events=. GDK_EXPOSURE_MASK,GDK_BUTTON_PRESS_MASK,GDK_BUTTON_RELEASE_MASK,GDK_POINTER_MOTION_MASK
  gtk_widget_add_events gtkda, OR events
  consig3 gtkda;'expose_event';'gtkda_minefld_expose_event'
  consig3 gtkda;'button_release_event';'gtkda_minefld_button_release_event'
  gtk_box_pack_start box1, gtkda, 1 1 0 NB. pack drawing area in the vertical box
NB. status bar
  GtkSbar=: gtk_statusbar_new ''
  SbarContxt=: gtk_statusbar_get_context_id GtkSbar;'msg'
  gtk_box_pack_start box1, GtkSbar, 0 0 0  NB. pack statusbar in the vertical box
  windowfinish''
  msgtk_update''
  if. -.IFGTK do. gtk_main'' end.
)

destroy=: 3 : 0
  cbfree''
  codestroy''
)

msgtk_startnew=: msgtk_update@newMinefield

msgtk_update=: 3 : 0
  'isend msg'=. eval ''
  IsEnd=: isend
  gtk_widget_queue_draw gtkda
  updateStatusbar msg
  if. isend do.
    mbinfo 'Game Over';msg
    msg=. ('K'={.msg) {:: 'won';'lost'
    updateStatusbar 'You ',msg,'! Try again?'
  end.
)

updateStatusbar=: 3 : 0
  gtk_statusbar_pop GtkSbar;SbarContxt   NB. clear last msg
  gtk_statusbar_push GtkSbar;SbarContxt;y
)

getTileIdx=: [: >:@:<. (#>{.Tiles) %~ 2 {. 0&".
gettext=: ]

NB. Event Handlers
NB. =========================================================
window_delete=: 0:

window_destroy=: 3 : 0
  g_object_ref_sink menutooltips
  if. -.IFGTK do. gtk_main_quit '' end.
  destroy ''
  0
)

NB. drawing area expose events
NB. ---------------------------------------------------------
NB. gtkwin      gtkda window
NB. gtkpx       offscreen pixmap
NB. gtkwh

gtkda_minefld_expose_event=: 3 : 0
  'widget event data'=. y
  NB. house keeping
  gtkwin=. getGtkWidgetWindow widget
  gtkdagc=. getdagc widget
  gtkwh=. 2 3{getGtkWidgetAllocation widget
  gtkpx=. gdk_pixmap_new gtkwin,gtkwh,_1
  gtkpx pixbuf_setpixels 0 0,gtkwh,(*/gtkwh)#0              NB. reset background
  imgpixels=. ; ,.&.>/"1 Tiles showField IsEnd             NB. get matrix of argb values to paint
  gtkpx pixbuf_setpixels 0 0,((#>{.Tiles)*$Map), , imgpixels NB. the real 'paint'
  gdk_draw_drawable gtkwin,gtkdagc,gtkpx,0 0 0 0 _1 _1     NB. render on drawable
  g_object_unref gtkpx                                     NB. clean up
)

NB. drawing area mouse events
NB. ---------------------------------------------------------

gtkda_minefld_button_release_event=: 3 : 0
  'widget event data'=. y
  'button type x1 y1 w h state'=. get_button_event_data event
  if. +./ IsEnd , ($Map)<idx=. getTileIdx ":x1,y1 do. return. end.
  select. button
    case. 1 do. msgtk_update@clearTiles idx
    case. 3 do. msgtk_update@markTiles idx
  end.
)

NB. menu events
NB. ---------------------------------------------------------

gamenew_activate=: 3 : 0
  msgtk_startnew $Map
)

gameoption_activate=: 0:

gamequit_activate=: 3 : 0
  gtk_widget_destroy window

)

helphelp_activate=: 3 : 0
  mbinfo ((gettext 'Minesweeper Instructions');Instructions)
)

helpabout_activate=: 3 : 0
  mbinfo ((gettext 'About Minesweeper');About)
)

NB. Text Nouns
NB. =========================================================
Instructions=: 0 : 0
Object:
   Uncover (clear) all the tiles that are not mines.

How to play:
 - click on a tile to clear it
 - right-click on a tile to mark it as a suspected mine
 - if you uncover a number, that is the number of mines adjacent
    to the tile
 - if you uncover a mine the game ends (you lose)
 - if you uncover all tiles that are not mines the game ends (you win).
)

About=: 0 : 0
Minesweeper Game
Authors: Ric Sherlock, Bill Lam

Uses J7 graphics/gtk for GUI
)

NB. Menu bar
NB. =========================================================
NB. replace nb. by NB.
fixNB=: 3 : 0
  x=. I. 'nb.' E. y
  'NB' (0 1 +/~ x) } y
)

getmenu=: 3 : 0
  ndx=. MENUIDS i. <y
  if. ndx=#MENUIDS do.
    ((gettext 'menu not found: '),y) assert 0
  end.
  ndx pick MENUDEF
)

menu_init=: 3 : 0
  f=. < @ (<;._1) @ (','&,)
  j=. f;._2 Menus
  MENUIDS=: {.&> j
  MENUDEF=: }.each j
  0
)

Menus=: fixNB 0 : 0
gamenew,gtk-new,_New Game,,Start a new game,gamenew_activate
gameoption,gtk-preferences,_Options,,Not implemented,gameoption_activate
gamequit,gtk-quit,_Quit,cQ,Quit the program,gamequit_activate
helphelp,gtk-help,_Instructions,,,helphelp_activate
helpabout,gtk-about,_About,,,helpabout_activate
)

edit_menu=: 3 : 0
  mb=. gtk_menu_bar_new''
  game_menu mb
  help_menu mb
  gtk_widget_show_all mb
  mb
)

game_menu=: 3 : 0
  pop=. create_menu_popup y;gettext '_Game'
  con=. create_menu_container pop
  con ccmenu 'gamenew'
  con ccmenu 'gameoption'
  create_menu_sep con
  con ccmenu 'gamequit'
)

help_menu=: 3 : 0
  pop=. create_menu_popup y;gettext '_Help'
  con=. create_menu_container pop
  con ccmenu 'helphelp'
  con ccmenu 'helpabout'
)

NB. Auto-run UI
NB. =========================================================
cocurrent 'base'
MinesweeperGtk ''