一、功能:
(1)输出排名
从文件中读出数据,保存在单链表中,并利用选择排序对数据进行排序后输出。
(2)开始游戏
进入该游戏系统后,系统先随机创建一个唯一解的数独,并解出该数独答案。
(3)选择难度
根据玩家选择的难度,挖空系统已经解出的数独,比如选择简单(给出40个数),则把系统已经解出的答案随机挖空41格,挖空处用数字0代替。
(4)给出数独并开始作答
玩家得到题目后进行解答(解答需将数独完整写一遍,以空格分割每列,以回车分割每行),最后系统根据答案判断玩家解答是否正确,正确则输出所用时间,如果该玩家是新纪录,则还要记录到文件,如果玩家解答错误,则失败并给出正确答案。
功能结构图:
二、涉及数据结构:
十字双向循环链表
三、涉及算法:
DLX算法
如何将数独转化为精准覆盖问题,并用DLX算法去解
数据结构体设计:
①玩家游戏记录信息
②存储数独结点信息
四、实验环境:
使用语言:C
使用软件:Microsoft Visual C++ 6.0
五、功能截图:
六、具体代码:
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<math.h>
#include<time.h>
#include <windows.h>
#include<string.h>
#define MAX 999
struct Node{
Node *up,*down,*left,*right,*colPtr,*rowPtr;//指向row,col对应的行对象和列对象
int row_num;//记录行数,行专属(从1开始)
int col_elemCount;//记录该列元素个数,列专属
};
struct player{
//玩家信息结点
int m ;
int s ;
char name[20];
int level ;
player* next;
};
int row_size=593;//行数
int col_size = 324;//列数
int result[81];//存放结果行的栈
int index = 0;//栈指针
int sudoku[81] = {
0};//存放数独
int time_start = 0;
int time_end = 0;//起始时间
void init(Node* head){
head->left = head;
head->right = head;
head->up = head;
head->down = head;
for(int k = 0;k < row_size;k++){
//创建行对象(头插)
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->up = head;
newNode->down = head->down;
newNode->left = newNode;
newNode->right = newNode;
newNode->down->up = newNode;
head->down = newNode;
newNode->row_num = row_size-k;
newNode->col_elemCount = 0;//借用,作为标志
}
}
void init_col(Node* head){
/************初始化行列对象*******************/
for(int j = 0;j < col_size;j++){
//创建列对象(头插)
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->right = head->right;
newNode->left = head;
newNode->down = newNode;
newNode->up = newNode;
newNode->right->left = newNode;
head->right = newNode;
newNode->col_elemCount = 0;//列元素个数初始为0
}
}
void link(Node* head,int** matrix){
/***********插入结点*************/
Node *current_row, *current_col, *current;//当前行对象,当前列对象,当前节点
current_row = head;
for(int row = 0;row<row_size;row++){
current_row = current_row->down;
current_col = head;
for(int col = 0;col<col_size;col++){
current_col = current_col->right;
if(matrix[row][col] == 0)
continue;
/*****插入结点,结点的行和列都用尾插法来与行列对象链接*****/
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->colPtr = current_col;//设置节点对应的行和列
newNode->rowPtr = current_row;
/**********列尾插************/
newNode->down = current_col;
newNode->up = current_col->up;
newNode->up->down = newNode;
current_col->up = newNode;//链接当前节点到列双向链尾端
if(current_row->col_elemCount == 0){
//行的这个为0,说明该行还没有元素,行双向链表不把行对象包含进来(便于后面覆盖)
current_row->right = newNode;
newNode->left = newNode;
newNode->right = newNode;
current_row->col_elemCount++;//此为标志,为了不把行对象包含进来
}
current = current_row->right;
newNode->left = current->left;
/**********行尾插************/
newNode->right = current;
newNode->left->right = newNode;
current->left = newNode;//链接当前节点到行双向链尾端
current_col->col_elemCount++;//该列元素加1
}
}
}
int** create_matrix()//将数独转换为01矩阵
{
int** matrix = (int**)malloc(row_size*sizeof(int*));//申请二维数组空间
for(int m=0;m<row_size;m++)
matrix[m] = (int*)malloc(col_size*sizeof(int));
for(int r=0;r<row_size;r++)
for(int c=0;c<col_size;c++)
matrix[r][c] = 0;//初始化
int i = 0;
for (int x = 0; x < 81; x++){
int val = sudoku[x];
if (val != 0){
//有值则插入一行
matrix[i][x] = 1;
matrix[i][81 + x/9*9 + val -1] = 1;
matrix[i][162 + x%9*9 + val -1] = 1;
matrix[i][243 + (x/9/3*3+x%9/3)*9 &