function sudokue(varargin)
% SUDOKUE play sudoku with MATLAB (aids for solving included)
%
% A guide on how sudoku works can be found e.g. on
% http://en.wikipedia.org/wiki/Sudoku
%
% This program has a history-function, i.e. you can undo and redo each
% single step. You can also save and load a score including all settings
% (execpt for the branching solver).
%
% New games can be imported either as ASCII-string or from sdm- or
% sdk-files resprectively. Puzzles in ASCII-Format or as sdm- or sdk-file
% respectively can be found e.g. on http://www.sudocue.net/
%
% Aids for solving the puzzle can be found on the menu entry "solver": If
% you enable tooltips, then all possible numbers for each fields are
% shown as tooltip when mouse cursor is placed over the corresponding
% field. There is a semiautomatic, which shows all fields whose solution
% is unique regarding the logical constraints, but in opposite to the
% automatic solver, the values are just taken if one clicks on it. In
% addition to the automatik solver, which just evaluates the logical
% constraints, there is an additional branching algorithm implemented,
% who solves any arbitrary sudoku. This algorithm will not check, whether
% this solution is unique, but it is guaranteed, that the solution is
% valid.
% (c) Matthias Schwaiger, 2007
% <
[email protected]>
sudoku_version='$Revision: 1.1 $';
sudoku_datum='$Date: 2007/01/15 07:19:00 $';
userdata.version=sudoku_version(12:length(sudoku_version)-2);
userdata.datum=sudoku_datum(8:length(sudoku_datum)-2);
if nargin > 0 && ~isempty(findobj('tag',mfilename))
sudoku_cb(varargin{1});
return
end
if ~isempty(findobj('tag',mfilename))
figure(findobj('tag',mfilename));
return
end
sudoku_scr=get(0,'screensize');
sudoku_fig_width=360;
sudoku_fig_height=300;
sudoku_fig=figure('menubar','none', 'numbertitle','off', ...
'position',[(sudoku_scr(3)-sudoku_fig_width)/2 (sudoku_scr(4)-sudoku_fig_height)/2 sudoku_fig_width sudoku_fig_height],...
'resize','off', ...
'tag',mfilename,'CloseRequestFcn',[mfilename '(103);']);
eval('set(sudoku_fig,''DockControl'',''off'')','');
feldanteil=0.9;
statusleistenhoehe=0.07;
for k=1:9
for m=1:9
sudoku_feld((k-1)*9+m)=uicontrol('parent', sudoku_fig, 'units', 'normalized', 'style','edit',...
'fontsize',12,'fontweight','bold','Horizontalalignment','center','Backgroundcolor',[0.7 0.7 0.7],...
'position',[(1-feldanteil)/10+(m-1)*((feldanteil/9)+(1-feldanteil)/10) ...
1-(feldanteil/9)*(1-statusleistenhoehe)-((1-feldanteil)/10+(k-1)*((feldanteil/9)*(1-statusleistenhoehe)+(1-feldanteil)/10)) ...
(feldanteil/9) (feldanteil/9)*(1-statusleistenhoehe)]);%#ok
if floor(((floor((k-1)/3)+1)+(floor((m-1)/3)+1))/2)==((floor((k-1)/3)+1)+(floor((m-1)/3)+1))/2
set (sudoku_feld((k-1)*9+m),'Backgroundcolor',[0.8 0.8 0.8]);
end
end
end
sudoku_feld(99)=uicontrol('parent', sudoku_fig, 'units', 'normalized', 'style','text',...
'Horizontalalignment','left', ...
'fontsize',8,'position',[(1-feldanteil)/10 0 1-2*(1-feldanteil)/10 statusleistenhoehe-(1-feldanteil)/10]);
menu_datei=uimenu('label','&File');
sudoku_feld(104)=uimenu(menu_datei,'label','&New','accelerator','n');
sudoku_feld(105)=uimenu(menu_datei,'label','New from &Keyboard','accelerator','k');
sudoku_feld(106)=uimenu(menu_datei,'label','New from &file','accelerator','f');
sudoku_feld(100)=uimenu(menu_datei,'label','&Open','separator','on','accelerator','o');
sudoku_feld(101)=uimenu(menu_datei,'label','&Save','accelerator','s');
sudoku_feld(102)=uimenu(menu_datei,'label','Save &as...');
sudoku_feld(103)=uimenu(menu_datei,'label','Quit','separator','on');
menu_bearbeiten=uimenu('label','&Edit');
sudoku_feld(110)=uimenu(menu_bearbeiten,'label','&Undo','accelerator','z');
sudoku_feld(111)=uimenu(menu_bearbeiten,'label','&Redo','accelerator','y');
menu_loeser=uimenu('label','&Solver');
sudoku_feld(120)=uimenu(menu_loeser,'label','&Tooltips','accelerator','t');
sudoku_feld(121)=uimenu(menu_loeser,'label','&Semiautomatic','separator','on','accelerator','m');
sudoku_feld(122)=uimenu(menu_loeser,'label','&Automatic','accelerator','a');
sudoku_feld(123)=uimenu(menu_loeser,'label','Autom. w. &branching','accelerator','b');
menu_hilfe=uimenu('label','&Help');
sudoku_feld(130)=uimenu(menu_hilfe,'label','&Help');
sudoku_feld(131)=uimenu(menu_hilfe,'label','&About SUDOKU','separator','on');
for k=1:length(sudoku_feld)
if sudoku_feld(k)~=0
set(sudoku_feld(k),'callback',[mfilename '(' num2str(k) ')']);
end
end
userdata.sudoku_feld=sudoku_feld;
set(sudoku_fig,'userdata',userdata);
sudoku_cb(0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function sudoku_cb(choice)
sudoku_fig=findobj('tag',mfilename);
userdata=get(sudoku_fig,'userdata');
sudoku_feld=userdata.sudoku_feld;
set(sudoku_feld(99),'string',[char(169) ' Matthias Schwaiger, 2007'],'horizontalalignment','right','Foregroundcolor',[0 0 0],'enable','off');
if choice == 0
userdata.datei='';
userdata.gespeichert=1;
userdata.tooltips=0;
userdata.automatik=0;
userdata.halbautomatik=0;
userdata.baumsuche=0;
userdata.suchfelder=[];
userdata.schrittzaehler=1;
userdata.maxschritt=1;
userdata.sudokudaten=zeros(81,82);
userdata.sudokubounds=ones(81,82)*(2^9-1);
end
if any(choice == 1:81)
nummer=get(sudoku_feld(choice),'string');
set(sudoku_feld(choice),'style','edit');
if isempty(nummer) || userdata.sudokudaten(choice,userdata.schrittzaehler) ~= 0
return
end
nummer=max(1,min(9,round(str2num(nummer(1)))));%#ok
% ?erpr?ung, ob Zahl ?erhaupt gesetzt werden darf
if ~bitget(userdata.sudokubounds(choice,userdata.schrittzaehler),nummer)
set(sudoku_feld(choice),'foregroundcolor',[1 0 0]);
set(sudoku_feld(99),'string','Clash: Number must not be set!', ...
'foregroundcolor',[1 0 0],'horizontalalignment','left','enable','on');
return
end
userdata.schrittzaehler=userdata.schrittzaehler+1;
userdata.maxschritt=userdata.schrittzaehler;
userdata.sudokudaten(:,userdata.schrittzaehler)=userdata.sudokudaten(:,userdata.schrittzaehler-1);
userdata.sudokudaten(choice,userdata.schrittzaehler)=nummer;
userdata.sudokubounds(:,userdata.schrittzaehler)=userdata.sudokubounds(:,userdata.schrittzaehler-1);
zeile=floor((choice-1)/9)+1;
spalte=choice-(floor((choice-1)/9)*9);
for k=1:9
% Ziffern in der Zeile d?fen nicht mehr gesetzt werden
userdata.sudokubounds((zeile-1)*9+k,userdata.schrittzaehler)= ...
bitset(userdata.sudokubounds((zeile-1)*9+k,userdata.schrittzaehler),nummer,0);
% Ziffern in der Spalte d?fen nicht mehr gesetzt werden
userdata.sudokubounds((k-1)*9+spalte,userdata.schrittzaehler)= ...
bitset(userdata.sudokubounds((k-1)*9+spalte,userdata.schrittzaehler),nummer,0);
end
zeileblock=floor((zeile-1)/3)+1;
spalteblock=floor((spalte-1)/3)+1;
for k=1:3
for m=1:3
userdata.sudokubounds((((zeileblock-1)*3+(k-1))*9+((spalteblock-1)*3+m)),userdata.schrittzaehler)= ...
bitset(userdata.sudokubounds((((zeileblock-1)*3+(k-1))*9+((spalteblock-1)*3+m)),userdata.schrittzaehler),nummer,0);
end
end
end
if choice==100 %Laden
if ~userdata.gespeichert
ButtonName = questdlg('Do you want to save the game?', ...
'Quit Sudoku', ...
'Yes', 'No', 'Cancel', 'Cancel');
switch ButtonName,
case 'Yes',
eval([mfilename '(102);'],'');
case 'Cancel',
return;
end
end
[filename, pathname] = uigetfile({'*.mat','MATLAB mat-files (*.ma