Code covered by the BSD License

# GUI for Hybrid Sudoku Solver

### Chi-Hang Kwan (view profile)

A simple GUI to solve Sudoku puzzles. Uses both logical and bruteforce methods.

Sudoku_GUI2
```%%%%%%%%%%Programmed by: Chi-Hang Kwan%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%Creation Date: November 10, 2012%%%%%%%%%%%%%%%%%%%%
function Sudoku_GUI2
clear all
close all

WinWidth = 400; %window width
WinHeight = 500; %window height

%create the GUI window
'position',[0 0 WinWidth WinHeight],'name','Sudoku Solver ver. 1.1','visible','on');
movegui(window,'center')

%Calculations for cell entry positions
MarSide = 50;
MarTop = 50;
dC = (WinWidth - MarSide -10)/9;
CornerY = WinHeight-MarTop-dC;
CornerX = MarSide/2;

%Creating all 81 input boxes
for ii=1:9
for jj=1:9
XPos = CornerX + (jj-1)*dC + floor((jj-1)/3)*5;
YPos = CornerY - (ii-1)*dC - floor((ii-1)/3)*5;
tb.x(ii,jj) = uicontrol( 'Style','edit','unit','pixels','backgroundcolor','w',...
'string',[],'position', [XPos YPos dC dC],'KeyPressFcn', {@callback_entry,window,ii,jj},...
'fontsize',13, 'visible', 'on', 'fontWeight', 'normal','enable', 'on');
end
end

%The title textbox
tb.title = uicontrol('Style', 'text', 'unit', 'pixels', 'string', 'Hybrid Sudoku Solver',...
'Position',[0 WinHeight-45  WinWidth 30], 'Horizontalalignment', 'center',...
'FontSize',16, 'backgroundcolor', 0.8*[1 1 1], 'foregroundcolor', [0 0 1],...
'FontName', 'constantia', 'FontWeight', 'normal');

%The solve button
tb.solve = uicontrol('Style','pushbutton','unit','pixels','string','Solve',...
'position',[WinWidth-MarSide/2-100 55 100 30],'fontsize',10,...
'backgroundcolor',0.9*[1 1 1],'foregroundcolor',0.8*[0 1 0],...
'visible','on','callback',{@callback_update,window} );

%The clear button
tb.clear = uicontrol('Style','pushbutton','unit','pixels','string','Clear',...
'position',[WinWidth-MarSide/2-100 15 100 30],'fontsize',10,...
'backgroundcolor',0.9*[1 1 1],'foregroundcolor',0.8*[1 0 0],...
'visible','on', 'callback',{@callback_clear,window});

message = sprintf('Status:\nPress [Solve] to calculate solution.');
tb.status = uicontrol('Style', 'text', 'unit', 'pixels', 'string', message,...
'Position',[MarSide/2 35  250 50], 'Horizontalalignment', 'left',...
'FontSize',10, 'backgroundcolor', 0.8*[1 1 1]);

set(window,'UserData', tb); %save the completed tb structure back into the window handle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%The Input Function%%%%%%%%%%%%%%%%%%%%%%%%%%
function callback_entry(src,event, hAxes,ii,jj)
tb = get(hAxes,'UserData');
set(tb.x(ii,jj), 'FontWeight', 'bold'); % to differentiate between entered and calculated entries

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%The Solving Function%%%%%%%%%%%%%%%%%%%%%%%%%%
function callback_update(src, event, hAxes)

tb = get(hAxes,'UserData');

A=zeros(1,81);
for k=1:81
if isempty(get(tb.x(k), 'string'))
A(k) = 0;
else
A(k) = str2double(get(tb.x(k), 'string'));
end
end
A=reshape(A,9,9);

%Check for Invalid Entries%
for ii=1:9
for jj=1:9
if isnan(A(ii,jj)) || A(ii,jj)>9 || A(ii,jj)<0 || rem(A(ii,jj),1)~=0
message = sprintf('Status:\nError! The cell entries must be integers between 0 and 9.');
set(tb.status, 'string', message);
return
end
end
end

%Check for Conflicts*
for ii=1:9
for jj=1:9
if A(ii,jj)~=0
if NoConflict(A,ii,jj)==0
message = sprintf('Status:\nError! Conflicting cell entries.');
set(tb.status, 'string', message);
return
end
end
end
end

message = sprintf('Status:\nCalculating solution, please wait...');
set(tb.status, 'string', message);
pause(0.5)

%%%%%%%Here we call the SudokuSolver function*%%%%%%%%%%%%%%%%%%%%%%
%You may use your own solver if desired
%The input array A uses 0's to represent empty spots
tic
B = SudokuSolver(A');  %The transpose solution is usually faster!
B = B';
t=toc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

message = sprintf('Status:\nSolved! Solution time: %.3f sec.',t);
set(tb.status, 'string', message);

%Update cells
for k=1:81
if A(k)==0
set(tb.x(k), 'fontweight', 'normal');
set(tb.x(k),'string', num2str(B(k)));
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%The Clearing Function%%%%%%%%%%%%%%%%%%%%%%%%%%
function callback_clear(src, event, hAxes)
tb = get(hAxes,'UserData');

for k=1:81
set(tb.x(k),'string', []);
end

message = sprintf('Status:\nPress [Solve] to calculate solution.');
set(tb.status, 'string', message);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%Conflict Checking Function%%%%%%%%%%%%%%%%%%
function bool = NoConflict(C,Row,Col)

for ii=1:9
if ii~=Row
if C(ii,Col)==C(Row,Col)
bool=0;
return
end
end
end

for jj=1:9
if jj~=Col
if C(Row,jj)==C(Row,Col)
bool=0;
return
end
end
end

RemR = rem((Row-1),3);
RemC = rem((Col-1),3);

RowL = Row - RemR;
ColL = Col - RemC;

for ii=RowL:RowL+2
for jj=ColL:ColL+2
if (ii~=Row) ||(jj~=Col)
if C(ii,jj)==C(Row,Col)
bool=0;
return
end
end
end
end

bool=1;

```