⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sudokon.m

📁 数独的程序
💻 M
📖 第 1 页 / 共 4 页
字号:
                  % yet selected.
      if hc(85,4)>1  % if this is the second request for hints, finish all
                % selections.
         kk = find(~hc(1:81,4)); dd = kk; hc(kk,4) = 1; lkk = numel(kk);
         for j=1:lkk
            dd(j) = find(p(kk(j),:)); 
            set(hc(kk(j),1),'Visible','on','Fontsize',30,'Fontweight','bold',...
            'String',dd(j))
         end
         hst = [hst; ones(lkk,1),kk,dd];
         set(hc(85,1),'Visible','on', 'String','Congratulations!')
      else
         hc(85,4) = 0; update(hc,p), hc(85,4) = 2;
         set(hc(85,1),'Visible','on', 'String',get(hc(84,2),'Userdata'))
      end
      
   else

      if hc(85,4)<0
         hc(85,4) = 0; update(hc,p)
         set(hc(85,1),'Visible','on','String',get(hc(84,2),'Userdata'))
         if isequal(get(p(82,1),'Visible'),'on')
            set([p(82,:), hc(82,4)],'Visible','off');
         end

      else
         strings = get(hc(85,1),'String');
         if iscell(strings), strings = strings{1}; end
         if (strings(1)=='E'||strings(1)=='N')
            update(hc,p)
            set(hc(~hc(1:81,4),1),'String',''), hc(85,4) = -1;
            set(hc(85,1),'Visible','on','String',get(hc(83,3),'Userdata'))
         else
            hc(85,2) = 0;
            if isequal(get(gcf,'SelectionType'),'alt')
               hc(85,2) = 1;
            end
            switch checkit(dg,p,gr,hc,action)
            case 0
               messge = get(hc(85,1),'Userdata');
            case 2
                   messge = {'Every circle indicates';'a removable choice'};
            case 1
               messge = 'Every star indicates a correct choice';
            case -1
               messge = 'No obvious correct choices';
            end
            set(hc(85,1),'String',messge,'Visible','on')
         end
      end
   end

case 'prints'
   button = questdlg('Where should the board be sent to?','Send to ...',...
           'Printer','File','Command Window','Printer');
   if isempty(button), button = 'N'; end
   switch button(1)
   case {'P','F'}
      set(hc(83,4),'Visible','on')
      set([reshape(hc(83:84,1:3),1,6),hc(85,1)],'Visible','off')
      if button(1)=='F'
         curbd = get(hc(84,1),'Userdata');
         [pn,mfname,coru] = getfilename('.eps',curbd);
         if ~isempty(mfname)
            eval(['print -deps ',pn,mfname,'.eps'])
            set(hc(84,1),'Userdata',curbd+1);
            fprintf(['sudokon ',coru,'ated the eps-file  ',mfname,...
                      '  in the directory ',strrep(pn(1:end-1),'\','\\'),'\n']);
         end
      else
         print
      end
      set(hc(83,4),'Visible','off')
      set([reshape(hc(83:84,1:3),1,6),hc(85,1)],'Visible','on')

   case 'C'
      border = ' +-------+-------+-------+';
      tline   = repmat(' | . . . | . . . | . . . |',3,1);
      printg = [border;repmat([tline;border],3,1)]; dotsp = find(printg=='.');
      numbers = find(dg); strdg = num2str(dg); dotsd = find(strdg~=' ');
      printg(dotsp(numbers)) = strdg(dotsd(numbers));
      disp(printg)
   
   end

case 'save'   % saves the current history in the current directory
              % for later recall via the command load
   curbd = get(hc(84,1),'Userdata');
   [pn,mfname,coru] = getfilename('.mat',curbd);
   if isempty(mfname), return, end

   save([pn mfname],'hst')
   set(hc(84,1),'Userdata',curbd+1);
   fprintf(['sudokon ',coru,'ated the MAT-file  ',mfname,...
                '  in the directory ',strrep(pn(1:end-1),'\','\\'),'\n']);

case 'load'   % restores the board to the end of the history brought
              % back from 

      % get a file name

   curbd = get(hc(84,1),'Userdata'); % used in serializing exported data
   mfname = ['board',num2str(curbd),'.mat']; curdir = pwd;
   if ~(curdir(end)==filesep), curdir = [curdir filesep]; end
   getfiletitle = 'Which saved board would you like to load?';
   [mfname,pn] = uigetfile([curdir mfname], getfiletitle);
   if isequal(mfname,0)||isequal(pn,0)
        % the user hit Cancel, so give up on this
      return
   end
   load([pn mfname])

         % check out that this is actually a workable history
   accepted = 0;    
   q = unique(hst(:,3));
   q(q==0|q==1|q==2|q==3|q==4|q==5|q==6|q==7|q==8|q==9)=[];
   if isempty(q)
      q = unique(hst(:,1));
      q(q==0|q==1|q==2)=[];
      if isempty(q)
         q = unique(hst(:,2));
         if ~any(q-fix(q))&&q(1)>0&&q(end)<82
            accepted = 1;
            [dg,p,hc] = bringback(hst,p,gr,hc);
            mfname(end-3:end) = [];
            set(hc(85,1),'Visible','on','String',['back to ',mfname])
         end
      end
   end

   if ~accepted
      set(hc(85,1),'Visible','on','String',['the file ''',...
               mfname,''' does not appear to be generated by sudokon.'])
   end

case 'prefer'  % makes choices for what exactly check? does
               % Userdata          action
               %    1         check correctness
               %    2         check correctness and print detail
               %    3         check number of solutions
               %    4         print all solutions (if any)
   temp = get(hc(84,3),'Userdata') + 1; if temp>4, temp = 1; end
   hc(85,3) = 0;
   switch temp
   case 1
      set(hc(83,3),'Tooltipstring','checks consistency of choices made so far')
      set(hc(84,3),'String','...choices made')
   case 2
      set(hc(84,3),'String','...choices; print')
      set(hc(83,3),'Tooltipstring', ...
      'checks consistency of choices made so far and prints details')
      hc(85,3) = 1;
   case 3
      set(hc(84,3),'String','...# solutions')
      set(hc(83,3),'Tooltipstring','checks number of solutions')
   case 4
      set(hc(84,3),'String','...all solutions')
      set(hc(83,3),'Tooltipstring','prints out all solutions (if any)')
   end
   set(hc(84,3),'Userdata',temp)

case 'works'  % act on the selected cell

   answer = get(gcf,{'CurrentPoint','SelectionType'});
   k = get(gco,'Userdata');
   
   if hc(k,4) % the cell has been settled, so, show the undo button
      setdonot(hc(82,4),hc(k,2:3))
      set(hc(82,3),'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],...
               'Visible','on','Userdata',k)
      set(hc(85,1),'visible','off')
   else
      switch hc(85,4)
         % hc(85,4) gives the 5 modes: clueless (-1), some help (0),
         % no help but only singletons (1), help with singletons (2), done (3).

      case {0,2}  % some help, hence this is a click on digit or else undo wish

         set(hc(85,1),'String',get(hc(84,2),'Userdata'))

         d = find(p(k,:)); 
         if length(d)==1
                % we are in the help mode and are looking at a singleton cell
                % that has not yet been settled.
            if isequal(answer{2},'normal') 
               hst(end+1,:) = [1,k,d];
               set(hc(82,3:4),'Visible','off')
               [dg,p,hc] = rm(k,d,dg,p,gr,hc);
            else   % anything other than a left click brings up the undo button
               setdonot(hc(82,4),hc(k,2:3))
               set(hc(82,3),'Visible','on',...
                     'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
               set(hc(85,1),'Visible','off')
            end
         else
          % check which digit was clicked
            dc = ...
           find(histc(answer{1}(1), [-inf, hc(k,2)+[-w(1)/6,w(2)/6], inf]))+...
           3*(3-...
             find(histc(answer{1}(2), [-inf, hc(k,3)+[-w(1)/6,w(2)/6], inf])));
               % ... and act accordingly
            if p(k,dc) % the digit is one of the possible choices
               switch answer{2}  % which should be 'normal' or 'alt'
               case 'normal'     % a left click, hence select this digit
                  hst(end+1,:) = [1,k,dc];
                  [dg,p,hc] = rm(k,dc,dg,p,gr,hc);
               case 'alt'        % a right click, hence delete this digit
                  p(k,dc) = 0; hst(end+1,:) = [2,k,dc];
                  text = get(hc(k,1),'string');
                  temp = [1 7 13 2 8 14 3 9 15]; text(temp(dc))=' ';
                  set(hc(k,1),'string',text,...
                              'Fontweight','normal','Foregroundcolor','k')
               otherwise % put up the undo button
                  setdonot(hc(82,4),hc(k,2:3))
                  set(hc(82,3),'Visible','on',...
                          'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
                  set(hc(85,1),'Visible','off')
               end

            else       % an empty space was clicked, hence put up undo button
               setdonot(hc(82,4),hc(k,2:3))
               set(hc(82,3),'Visible','on','Position',...
                  [hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
               set(hc(85,1),'Visible','off')
            end
         end


      case {-1,1} % no help, hence show the keyboard
         setdonot(hc(82,4),hc(k,2:3))
         keyboard(k,hc,p,w); 
         set(hc(85,1),'String','click digit to select','Visible','on')
         set(p(82,:),'Tooltipstring','click to select',...
               'Callback','sudokon ''finis''');
      otherwise
         error('something wrong in sudokon')
      end
   end

case 'finis'  % make the selected digit the choice for this cell

   stored = get(gco,'Userdata');
   k = stored(1); d = stored(2);
   if ~p(k,d) % we are in the clueless state
               % but will refuse any inconsistent choice
      set(hc(85,1),'Visible','on', ...
         'String',['your choice of ',num2str(d),' is inconsistent'])
   else
      set([p(82,:),hc(82,3:4)],'Visible','off')
      hst(end+1,:) = [1,k,d];
      [dg,p,hc] = rm(k,d,dg,p,gr,hc);
      set(hc(85,1),'String',get(hc(83,3),'Userdata'))
   end


case 'undo' % return to the stage before the last change made to this cell

   set(hc(82,3:4),'Visible','off')
   k = get(gco,'Userdata'); 
   last = find(hst(:,2)==k,1,'last');
   if ~hst(last,1) % this is one of the original givens, hence merely start
                   % from scratch
      last = find(hst(:,1),1);
   end
   hst(last:end,:) = [];

   [dg,p,hc] = bringback(hst,p,gr,hc);

case 'donot' % do nothing

   set([p(82,:),hc(82,3:4)],'Visible','off')
   set(hc(85,1),'Visible','on')
case 'closefigure'
   delete(findobj('Tag','sudokon Message Box'))
   return

end

if hc(85,4)<3&&all(hc(1:81,4)) % we just finished
   hc(85,4) = 3;
   set(hc(85,1),'Visible','on', 'String','Congratulations!')
   for j=1:6
      set(hc(85,1),'Visible','off'), pause(.1)
      set(hc(85,1),'Visible','on'), pause(.1)
   end
end

set(hf,'Userdata',{hf,p,dg,gr,hc,hst})

function [ok,dg,p] = checkit(dg,p,gr,hc,action)
%CHECKIT check for inconsistencies and/or new singletons

switch action(1)
case 'h'
    ok = -1; ntries = 3; nrep = 4; pstart = p;
case {'c','a'}
   ntries = numel(find(dg==0)); nrep = 1; hc(85,2) = 0;
        % made sure that an earlier right click on hints doesn't generate
        % detailed printout now
end

if hc(85,3)
   if action(1)=='h', fprintf('\n detailed hints\n')
   else counts = zeros(1,6);
   fprintf(['\n',action,'\n rcb, bc, br, two, three   ',...
   'count occurrences of the following:\n rare digit ',...
   'removed from box(rcb), column(bc), row(br);\n all other choices removed',...
    ' from only pair(two)/triple(three)\n',...
    ' that can contain a certain pair/triple of digits.\n']);
   end
end
for tries=1:ntries

   for rep=1:nrep
    for r=1:27
       tt = sum(p(gr(:,r),:));
       if ~all(tt), ok = 0; return, end %inconcistency: some digit is excluded
                  
       sd = find(tt==1); %These are the digits that occur exactly once in this
                      % group, hence the corresponding k should be a singleton.
        for d = sd
          k = gr(p(gr(:,r),d)==1,r);
          if ~dg(k) % this should be a singleton
             if hc(85,3)&&action(1)=='h'
                dd = 1:9; dd(d) = [];
                if any(p(k,dd))||r<10
                   fprintf(' ** select cell %g|%g for digit %g\n',cellid(k),d)
                end
             end
             p(k,:) = 0;
             % also remove this digit from all the other cells in the two

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -