Đồ án Giải thuật lập trình Sudoku 9x9 (Có code)Sudoku là một trò chơi câu đố sắp xếp chữ số dựa trên logic theo tổ hợp. Mục tiêu của trò chơi là điền các chữ số vào một lưới 9×9 sao cho mỗi cột, mỗi hàng, và mỗi phần trong số chín lưới con 3×3 cấu tạo nên lưới chính đều chứa tất cả các chữ số từ 1 tới 9
Trang 1KHOA CÔNG NGHỆ THÔNG TIN
ĐỒ ÁN GIẢI THUẬT VÀ LẬP TRÌNH
Đề tài: GIẢI SUDOKU 9x9
SINH VIÊN THỰC HIỆN:
Đà Nẵng, 11/2018
Trang 2MỤC LỤC
MỤC LỤC 1
LỜI MỞ ĐẦU 2
DANH MỤC HÌNH VẼ 3
1 GIỚI THIỆU ĐỀ TÀI 4
2 CƠ SỞ LÝ THUYẾT 5
2.1 Ý tưởng 5
2.2 Cơ sở lý thuyết 6
3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN 6
3.1 Phát biểu bài toán 6
3.2 Cấu trúc dữ liệu 6
3.3 Thuật toán Quay lui (Backtracking) 9
4 CHƯƠNG TRÌNH VÀ KẾT QUẢ 9
4.1 Tổ chức chương trình 10
4.2 Ngôn ngữ cài đặt 17
4.3 Kết quả 17
4.3.1 Giao diện chính của chương trình 17
4.3.2 Kết quả thực thi của chương trình 18
4.3.3 Nhận xét 20
5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 21
5.1 Kết luận 21
5.2 Hướng phát triển 21
TÀI LIỆU THAM KHẢO 22
Trang 3Tuy nhiên, do kiến thức còn hạn hẹp, mặc dù đã nỗ lực hết sức mình, nhưng chắc rằng đồ
án khó tránh khỏi thiếu sót Chúng em rất mong nhận được sự thông cảmvà chỉ bảo tận tìnhcủa quý Thầy cô và các bạn
Xin chân thành cảm ơn
Trang 4Hình 5 Giao diện chương trình chính.
Hình 6 Đầu vào input.txt
Hình 7 Lựa chọn 1: Giải từng bước – Xem tiến trình bước 1 – Đáp án 1
Hình 8 Lựa chọn 1: Giải từng bước - Xem tiến trình bước 2 – Đáp án 2
Hình 9 Lựa chọn 2: Xem đáp án 1
Hình 10 Lựa chọn 2: Xem đáp án 2
Hình 11 So sánh kết quả và đầu ra output.
Trang 51 GIỚI THIỆU ĐỀ TÀI
Sudoku là một từ Nhật, có thể dịch tạm là con số độc nhất, (Thật ra nó có nguồn gốc
từ Mỹ với tên gọi là "đặt con số vào vị trí đúng") Đây là một trò chơi trí tuệ nổi tiếng,thu hút nhiều người tham gia thuộc nhiều tầng lớp, độ tuổi khác nhau
Sudoku có nhiều biến thể khác nhau: 3x3, 4x4, 6x6, 8x8, 9x9, 12x12, 16x16,… Đốivới đề tài này, chúng em áp dụng cho sudoku dạng chuẩn 9x9
Bảng câu đố hình vuông, mỗi chiều có 9 ô nhỏ, hợp thành 9 cột, 9 hàng và đượcchia thành 9 ô lớn 3x3 Một vài ô nhỏ được đánh số, đó là những manh mối duy nhất đểbạn tìm lời giải Tuỳ theo mức độ nhiều hay ít của các manh mối, các câu đố được xếploại dễ, trung bình, khó hay cực khó
Hình 1 Ví dụ một đề bài Sudoku 9x9
Cách chơi Sudoku là điền các số từ 1 đến 9 vào các ô trống theo quy luật đơn giản:
- Các ô ở mỗi hàng (ngang) phải có đủ các con số từ 1 đến 9 không cần theo thứtự
- Các ô ở mỗi hàng (dọc) phải có đủ các con số từ 1 đến 9 không cần theo thứ tự
- Mỗi miền 3x3 được viền đậm phải có đủ các số từ 1 đến 9
Trang 6Hình 2 Đáp án câu đố
2 CƠ SỞ LÝ THUYẾT
2.1 Ý tưởng
Chương trình giải dựa trên thuật toán quay lui Bằng việc liệt kê các tình huống,
thử các khả năng có thể cho đến khi tìm thấy một lời giải đúng, thuật toán quay lui chianhỏ bài toán, lời giải của bài toán lớn sẽ là kết quả của việc tìm kiếm theo chiều sâu củatập hợp các bài toán phần tử Trong suốt quá trình tìm kiếm nếu gặp phải một hướng nào
đó mà biết chắc không thể tìm thấy đáp án thì quay lại bước trước đó và tìm hướng khác
kế tiếp hướng vừa tìm kiếm đó Trong trường hợp không còn một hướng nào khác nữa thìthuật toán kết thúc
2.2 Cơ sở lý thuyết
2.2.1 Thuật toán Quay lui (Backtracking)
Quay lui là một chiến lược tìm kiếm lời giải cho các bài toán thỏa mãn ràng buộc.Các bài toán thỏa mãn ràng buộc là các bài toán có một lời giải đầy đủ, trong đó thứ
tự các phần tử không quan trọng Các bài toán này bao gồm một tập các biến mà mỗibiếncần được gán một giá trị tùy theo các ràng buộc cụ thể của bài toán Việc quay lui làthửtất cả các tổ hợp để tìm một lời giải Thế mạnh của phương pháp này là nhiều cài đặttránh được việc phải thử nhiều tổ hợp chưa hoàn chỉnh, và nhờ đó giảm thời gian chạy,tìm được nhiều đáp án cho những bài toán có nhiều cách giải
Trang 7Đó là một quá trình tìm kiếm độ sâu trong một tập hợp các lời giải Trong quá trìnhtìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, ta quay lui về điểm lựa chọnnơi có các hướng khác và thử hướng lựa chọ tiếp theo Khi đã thử hết các lựa chọn xuấtphát từ điểm lựa chọn đó, ta quay lại điểm lựa chọn trước đó và thử hướng lựa chọn tiếptheotại đó Quá trình tìm kiếm thất bại khi không còn điểm lựa chọn nào nữa
Quy trình đó thường được cài đặt bằng một hàm đệ quy mà trong đó mỗi thể hiệncủa hàm lấy thêm một biến và lần lượt gán tất cả các giá trị có thể cho biến đó, với mỗilầngán giá trị lại gọi chuỗi đệ quy tiếp theo để thử các biến tiếp theo Chiến lược quay luitương tự với tìm kiếm theo độ sâu nhưng sử dụng ít không gian bộ nhớ hơn, nó chỉ lưutrữ trạng thái của một lười giải hiện tại và cập nhật nó
Hình 3 Cây tìm kiếm quay lui
- Ở một bài toán hiện tại (mỗi nốt), ta đi tìm lời giả cho bài toán đó Ứng với lờigiải,ta đi giải bài toán kế tiếp cho đến khi bài toán gốc trở nên đầy đủ
- Lời giải của bài toán gốc thường là một lối đi từ gốc đến nốt cuối cùng
3 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN
3.1 Phát biểu bài toán
- Đầu vào : Đề Sudoku đọc bảng từ file , hoặc do người dùng nhập
- Đầu ra (Kết quả): Đáp án có thể là các bước giải Sudoku của chương trình hoặc đáp
án toàn bộ chương trình (có thể ra nhiều đáp án nếu đầu vào có nhiều đáp án)
Trang 83.2 Cấu trúc dữ liệu
1 Biến
Sử dụng biến kiểu mảng hai chiều để thể hiện vị trí của các phần tử đang xét.Mảng hai chiều là một mảng mà các phần tử của nó là mảng một chiều, giống nhưmột bảng gồm có dòng và cột, được đánh dấu vị trí là các chỉ số bao gồm chỉ số dòng vàchỉ số cột trong đó
Trong ngôn ngữ C, mảng hai chiều được khai báo theo cú pháp:
data_type array_name[num1][num2];
- với data_type là kiểu dữ liệu của các phần tử trong mảng
- num1 số mảng một chiều có trong mảng
- num2 số phần tử có trong mỗi mảng một chiều
Ví dụ mảng hai chiều S trong bài được khai báo như sau:
int S[9][9];
Khi đó mảng S giống như một bảng có 9 hàng và 9 cột (mỗi hàng có 9 phần tử), và mỗi
phần tử trong mảng là một số kiểu int
0 1 2 3 4 5 6 7 8
Hình 4 Mảng S
Muốn truy cập đến một phần tử trong mảng ta dùng cú pháp S[i][j] Khi đó S[i][j] chứa giá trị của ô ở vị trí hàng i cột j
2 Hàm
Trang 9Trong mảng hai chiều đưa vào chương trình, các phần tử trong mảng tương ứngvới các ô trong đề Sudoku Trong mảng này, các ô chưa được điền nhận giá trị bằng 0,các ô đã được điền mang giá trị đã được điền vào Với mỗi ô chưa được điền, giá trị của ô
đó bằng 0
Khi đó để kiểm tra khả năng điền giá trị của ô đó ta dùng hàm check() như sau:
- Kiểm tra hàng: Kiểm tra giá trị k (với k có thể nhận giá trị từ 1-9) có thể điền vào
ô trên hay không Kiểm tra xem trên hàng đó đã có ô nào có giá trị bằng k haychưa bằng cách duyệt hết tất cả các phần tử trên hàng đó, nếu đã có thì loại bỏ khảnăng ô đó nhận giá trị k
- Kiểm tra cột: Kiểm tra giá trị k (với k có thể nhận giá trị từ 1-9) có thể điền vào ô
đó không Kiểm tra xem trên cột đó đã có ô nào mang giá trị k chưa bằng cáchduyệt hết tất cả các phần tử có trong cột, nếu đã có thì loại bỏ khả năng ô đó nhậngiá trị k
- Kiểm tra trong vùng 9 ô: với giá trị k có thể có giá trị từ 1 đến 9 Kiểm tra xemtrong vùng 9 ô có ô nào chứa giá trị k chưa, nếu có thì loại trừ khả năng nhận giátrị k của ô đó
- Nếu với một số k sau khi kiểm tra đạt cả 3 khả năng trên thì có thể gán giá trị kcho ô đó
Trong đó các tham số truyền vào là:
+ Mảng S[][] là mảng chúng ta đang xét
+ Số nguyên x chứa vị trí dòng của ô đang xét trong mảng
+ Số nguyên y chứa vị trí cột của ô đang xét
+ k là giá trị muốn kiểm tra xem có thể điền vào ô đang xét hay không Hàm trên sẽ trả về giá trị 1 nếu k được điền vào ô đang xét và trả về 0 nếukhông được điền vào ô đang xét
Hàm sovle() thực hiện thuật toán quay lui Hàm có 3 tham số đầu vào: mảng dữ liệu
S, biến vị trí x,y Chương trình sẽ duyệt trên từng ô của mảng hai chiều, trên từng ôchương trình sẽ kiểm tra xem ô đó đã được điền hay chưa, nếu chưa được điền thìchương trình sẽ duyệt hết tất cả các giá trị k chạy từ 1- 9 xem những giá trị nào có thểđiền vào ô đang xét Tại đây ứng với mỗi giá trị có thể điền vào ô đang xét chương trình
sẽ gọi đệ quy đến ô tiếp theo trong hàng Nếu trường hợp do giá trị điền ô trước đó mà ôtiếp theo không thể điền giá trị thì chương trình sẽ quay lui lại và thử với giá trị khác Cứ
Trang 10như thế cho đến khi xét xong ô cuối cùng trong mảng (ô thứ 81) Tại đây chương trình sẽxuất ra kết quả và kết thúc chương trình.
3.3 Thuật toán
3.3.1 Thuật toán quay lui
Thuật toán quay lui (backtracking) như tên gọi của nó, là một quá trình tìm kiếm
mà trong quá trình tìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, ta quay lui
về điểm lựa chọn nơi có các hướng khác và thừ hướng lựa chọn tiếp theo Quá trình tìmkiếm thất bại khi không còn điểm lựa chọn nào nữa
Trang 11int S[9][9];
void show( int S [][9]);
void gotoxy( int x , int y );
void setcolor( int color );
void tientrinh( int , int , int k , int color );
int readFile(FILE * f );
void getData( int S [][9]);
void option1_solve_sudoku( int S [9][9], int x , int y );
void option2_solve_sudoku( int S [9][9], int x , int y );
int check( int S [][9], int x , int y , int k );
void Output( int S [][9]);
void resuilt( int S [][9]);
void main( void ){
printf( " -SUDOKU -\n" );
printf( "1 Xem tien trinh : \n" );
printf( "2 Xem dap an : \n" );
Trang 12// ham thiet lap mau chu
void setcolor( int color )
// ham tien trinh
void tientrinh( int , int , int k , int color )
Trang 13// ham chuyen du lieu file qua mang S
void getData( int S [][9])
S [i][j] = A[t];
t++;
} }
fclose(f);
}
// lua chon tien trinh giai sudoku
void option1_solve_sudoku( int S [9][9], int x , int y ){
Sleep(400);
if ( y == 9){
if ( x == 8){
Trang 14} else {
option1_solve_sudoku( S , x , y +1);
}
}
// lua chon xuat tat ca dap an ra man hinh
void option2_solve_sudoku( int S [9][9], int x , int y ){
Trang 15} else {
option2_solve_sudoku( S , x , y +1);
}
}
// ham kiem tra so k co dien duoc vao vi tri x y hay ko
int check( int S [][9], int x , int y , int k ){
Trang 16return 1;
}
// ham xuat mang
void show( int S [][9]){
//ham xuat dap an ra man hinh
void resuilt( int S [][9]){
Trang 17void Output( int S [][9]){
FILE *p = fopen( "Output.TXT" , "w+" );
int i, j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++) {
int a = S [i][j];
fprintf(p, "%2d" , [i][j]);
} fprintf(p, "\n" );
4.3.1 Giao diện chính của chương trình
Đây là màn hình hiển thị các lựa chọn khi chạy chương trình sudoku 9x9
1 Lựa chọn 1: Xem các bước giải sudoku
2 Lựa chọn 2: Xem đáp án
Trang 18Hình 5 Giao diện chương trình chính
4.3.2.
Kết quả thực thi của chương trình
Hình 6 Đầu vào Input.txt
Trang 19Hình 7 Lựa chọn 1: Giải từng bước – Xem tiến trình bước 1 – Đáp án 1
Hình 8 Lựa chọn 1: Giải từng bước - Xem tiến trình bước 2 – Đáp án 2
Trang 20Hình 9 Lựa chọn 2: Xem đáp án 1
Hình 10 Lựa chọn 2: Xem đáp án 2
Trang 21Hình 11 So sánh kết quả và đầu ra output
4.3.3 Nhận xét
Chương trình giải được ô số sudoku có kích thước 9x9 có mức độ từ dễ đến khó Hạnchế của chương trình là chỉ đưa ra được một đáp án và nếu dữ liệu đầu vào quá ít thìchương trình có thề không đưa ra được kết quả Bài toán sudoku là bài toán phức tạp nênnhóm chỉ thao tác với chế độ văn bản
5 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
5.1 Kết luận
- Ưu điểm:
+ Cài đặt được thuật toán quay lui để giải bài toán
+ Chương trình đạt được yêu cầu đề ra (giải bài toán sudoku 9x9)
Trang 22TÀI LIỆU THAM KHẢO