├── README.md ├── graph.c ├── linkedlist.c ├── polynomial.c ├── quicksort.c ├── stack.c ├── tree.c ├── 作业文档 ├── 1143730113_王必聪_作业1.docx ├── 1143730113_王必聪_作业2.docx └── 1143730113_王必聪_作业3.docx ├── 实验报告 ├── 1143730113_王必聪_实验1_线性表及其应用.doc ├── 1143730113_王必聪_实验2_树及其应用.doc ├── 1143730113_王必聪_实验3_图及其应用.doc └── 1143730113_王必聪_实验4_查找与排序.doc └── 课程设计-扫雷 ├── 00.bmp ├── 01.bmp ├── 02.bmp ├── 03.bmp ├── 04.bmp ├── 05.bmp ├── 06.bmp ├── 07.bmp ├── 08.bmp ├── flag.bmp ├── game.py ├── gui.py ├── init.png ├── mine.bmp ├── mine.ico ├── theme.bmp ├── 第30组_王必聪_答辩.ppt └── 第30组_王必聪_课程设计报告.doc /README.md: -------------------------------------------------------------------------------- 1 | # Data-Structure-Algorithm 2 | 3 | > 本项目为哈工大《数据结构》课程的实验、作业以及课程设计相关的代码与文档。 4 | 5 | ## 项目说明 6 | 7 | - 代码基本为大二上学期上传,有很多不完善or设计不合理的部分,但是暂无修改计划。 8 | - 实验与作业相关的代码均使用C语言进行编写,课程设计为使用Python开发的扫雷小游戏。 9 | - 扫雷游戏在UI布局上存在Bug,在Windows10系统下测试可用,Ubuntu下存在UI布局问题。 10 | -------------------------------------------------------------------------------- /graph.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define INFINITY INT_MAX // assign infinity the max int. 5 | #define TRUE 1 6 | #define FALSE 0 // boolean 7 | 8 | typedef struct vertex 9 | { 10 | int identifier; 11 | int distance; 12 | struct vertex* next; 13 | } vertex; // create for every vertex. 14 | 15 | typedef struct MarkVertex 16 | { 17 | int identifier; 18 | int mark; 19 | int distance; 20 | int previous; 21 | } MarkVertex; // create for the mark array for dijkstra. 22 | 23 | int findMinIndex(MarkVertex* mark_vertex,int n); 24 | void freeTable(vertex* table,int n); 25 | void initial(MarkVertex* mark_vertex,int n); 26 | void printAllMinDistance(vertex* table,int n); 27 | void calculateMinDistance(vertex* table,MarkVertex* mark_vertex,int index,int n); 28 | void printTrace(MarkVertex* mark_vertex,int identifier); 29 | vertex* createTable(int* adj_matrix,int n); 30 | 31 | int main() 32 | { 33 | int n; 34 | int i,j; 35 | printf("How many vertexes in the graph?\n"); 36 | scanf("%d",&n); 37 | printf("Please input the adjacent matrix of the directed graph:\n"); 38 | int* adj_matrix = (int*)malloc(sizeof(int)*n*n); 39 | for(i=0; iidentifier = i + 1; 61 | (table+i)->distance = 0; 62 | (table+i)->next= NULL; 63 | } 64 | for(i=0; i 0) 70 | { 71 | p->next = (vertex*)malloc(sizeof(vertex)); 72 | p = p->next; 73 | p->identifier = j + 1; 74 | p->distance = adj_matrix[i*n+j]; 75 | } 76 | } 77 | p->next = NULL; 78 | } 79 | return table; 80 | } 81 | 82 | // initial the mark Array for dijkstra algorithm. 83 | void initial(MarkVertex* mark_vertex,int n) 84 | { 85 | int i; 86 | for(i=0; i "); 140 | printf("distance: %d\n",mark_vertex[j].distance); 141 | } 142 | } 143 | printf("\n"); 144 | } 145 | free(mark_vertex); 146 | } 147 | 148 | // calculate the min distance from a vertex to other vertexes. 149 | void calculateMinDistance(vertex* table,MarkVertex* mark_vertex,int index,int n) 150 | { 151 | mark_vertex[index].distance = 0; 152 | do 153 | { 154 | mark_vertex[index].mark = TRUE; 155 | vertex* p = table + index; 156 | while(p->next!=NULL) 157 | { 158 | p = p->next; 159 | int new_distance = mark_vertex[index].distance + p->distance; 160 | if(new_distance < mark_vertex[p->identifier-1].distance) 161 | { 162 | mark_vertex[p->identifier-1].distance = new_distance; 163 | mark_vertex[p->identifier-1].previous = mark_vertex[index].identifier; 164 | } 165 | } 166 | index = findMinIndex(mark_vertex,n); 167 | } 168 | while(index!=-1); 169 | } 170 | 171 | // print the trace from a vertex to other vertexes 172 | void printTrace(MarkVertex* mark_vertex,int identifier) 173 | { 174 | int previous = mark_vertex[identifier-1].previous; 175 | if(previous) 176 | { 177 | printTrace(mark_vertex,previous); 178 | } 179 | printf(" %d ",identifier); 180 | } 181 | 182 | // free table's memory 183 | void freeTable(vertex* table,int n) 184 | { 185 | int i; 186 | for(i=0; inext; 193 | free(delete_vertex); 194 | delete_vertex = p; 195 | } 196 | } 197 | free(table); 198 | } 199 | -------------------------------------------------------------------------------- /linkedlist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define TRUE 1 4 | #define FALSE 0 // 用幻数让boolean更直观 5 | 6 | typedef int ElementType; // 通用单位数据 7 | typedef struct LinkedNode{ 8 | ElementType element; 9 | struct LinkedNode* next; 10 | }LinkedNode; 11 | 12 | LinkedNode* create(); 13 | LinkedNode* addTwoList(LinkedNode* head1,LinkedNode* head2); 14 | int find(LinkedNode* head,ElementType x); 15 | int findIndex(LinkedNode* head,ElementType x); 16 | int length(LinkedNode* head); 17 | void insert(LinkedNode* head,ElementType x); 18 | void del(LinkedNode* head,ElementType x); 19 | void printList(LinkedNode* head); 20 | void reverse(LinkedNode* head); 21 | void copy(LinkedNode* head1,LinkedNode* head2); 22 | void makeCircle(LinkedNode* head); 23 | void oneToTwo(LinkedNode* head,LinkedNode* head1,LinkedNode* head2); 24 | ElementType* subEle(LinkedNode* head,int m,int n); 25 | 26 | int main() 27 | { 28 | FILE* fp = fopen("int.txt","r"); 29 | LinkedNode* head = create(); 30 | while(!feof(fp)){ // 从文件中读取 31 | int i; 32 | fscanf(fp,"%d ",&i); 33 | insert(head,i); 34 | } 35 | LinkedNode* head1 = create(); 36 | LinkedNode* head2 = create(); 37 | reverse(head); 38 | printList(head); // 基本测试 39 | oneToTwo(head,head1,head2); 40 | printList(head1); 41 | printList(head2); 42 | fclose(fp); 43 | return 0; 44 | } 45 | 46 | /* 47 | * 创建新的链表,返回头结点 48 | */ 49 | LinkedNode* create(){ 50 | LinkedNode* head = (LinkedNode*)malloc(sizeof(LinkedNode)); 51 | head->element = 0; 52 | head->next = NULL; 53 | return head; 54 | } 55 | 56 | /* 57 | * 在一个链表中查找数据x,返回boolean (支持环形链表) 58 | */ 59 | int find(LinkedNode* head,ElementType x){ 60 | LinkedNode* p = head; 61 | while(p->next!=NULL && p->next!= head){ 62 | p = p->next; 63 | if(p->element == x){ 64 | return TRUE; 65 | } 66 | } 67 | return FALSE; 68 | } 69 | 70 | /* 71 | * 向链表中添加数据 x ,并且让头结点的数据 + 1(表示链表长度) 72 | */ 73 | void insert(LinkedNode* head,ElementType x){ 74 | LinkedNode* p = head; 75 | LinkedNode* add_list = (LinkedNode*)malloc(sizeof(LinkedNode)); 76 | add_list->element = x; 77 | add_list->next = NULL; 78 | while(p->next!=NULL){ 79 | if(x < (p->next)->element){ 80 | break; 81 | } 82 | p = p->next; 83 | } 84 | add_list->next = p->next; 85 | p->next = add_list; 86 | head->element++; 87 | } 88 | 89 | /* 90 | * 删除链表中数据x ,可进行多次删除 91 | */ 92 | void del(LinkedNode* head,ElementType x){ 93 | LinkedNode* p = head; 94 | LinkedNode* delete_list = NULL; 95 | while(p->next!=NULL){ 96 | if(x == (p->next)->element){ 97 | delete_list = p->next; 98 | p->next = delete_list->next; 99 | free(delete_list); 100 | head->element--; 101 | continue; 102 | } 103 | p = p->next; 104 | } 105 | } 106 | 107 | /* 108 | * 头结点的数据表示链表长度,返回该数据 109 | */ 110 | int length(LinkedNode* head){ 111 | return head->element; 112 | } 113 | 114 | /* 115 | * 输出该链表(可输出循环链表) 116 | */ 117 | void printList(LinkedNode* head){ 118 | LinkedNode* p = head; 119 | while(p->next!=NULL && p->next!=head){ 120 | p = p->next; 121 | printf("%d ",p->element); 122 | } 123 | printf("\n"); 124 | } 125 | 126 | /* 127 | * 存储下一个节点和前一个节点,进行倒序 128 | */ 129 | void reverse(LinkedNode* head){ 130 | LinkedNode* p = head->next; 131 | LinkedNode* future_list = NULL; 132 | LinkedNode* past_list = NULL; 133 | if(p == NULL || p->next == NULL){ 134 | return; 135 | } 136 | while(p->next!=NULL){ 137 | future_list = p->next; 138 | p->next = past_list; 139 | past_list = p; 140 | p = future_list; 141 | } 142 | p->next = past_list; 143 | head->next = p; 144 | } 145 | 146 | /* 147 | * 实现两个链表的复制 148 | */ 149 | void copy(LinkedNode* head1,LinkedNode* head2){ 150 | LinkedNode* p = head1; 151 | while(p->next!=NULL){ 152 | p = p->next; 153 | insert(head2,p->element); 154 | } 155 | } 156 | 157 | /* 158 | * 实现合并两个已排序的链表,返回新的合并后的链表 159 | */ 160 | LinkedNode* addTwoList(LinkedNode* head1,LinkedNode* head2){ 161 | LinkedNode *head = create(); 162 | copy(head1,head); 163 | LinkedNode *p2 = head2; 164 | while((p2 = p2->next)!=NULL){ 165 | insert(head,p2->element); 166 | } 167 | return head; 168 | } 169 | 170 | /* 171 | * 令一个普通的单向链表变为循环链表 172 | */ 173 | void makeCircle(LinkedNode* head){ 174 | LinkedNode* p = head; 175 | while(p->next!=NULL){ 176 | p = p->next; 177 | } 178 | p->next = head; 179 | } 180 | /* 181 | * 在一个链表中查找数据x,返回index,若不存在返回-1,并添加该数据到尾部 182 | */ 183 | int findIndex(LinkedNode* head,ElementType x){ 184 | LinkedNode* p = head; 185 | int index = 0; 186 | while(p->next!=NULL){ 187 | p = p->next; 188 | index ++; 189 | if(p->element == x){ 190 | return index; 191 | } 192 | } 193 | LinkedNode* add_list = (LinkedNode*)malloc(sizeof(LinkedNode)); 194 | add_list->element = x; 195 | add_list->next = NULL; 196 | p->next = add_list; 197 | return -1; 198 | } 199 | 200 | /* 201 | * 将一个单向链表拆分为两个循环链表,第一个循环链表为原链表的奇数项,第二个循环链表为偶数项 202 | */ 203 | void oneToTwo(LinkedNode* head,LinkedNode* head1,LinkedNode* head2){ 204 | if(!head1) {head1 = create();} 205 | if(!head2) {head2 = create();} 206 | LinkedNode *p = head; 207 | int mark = 0; 208 | while((p = p->next)!=NULL){ 209 | if(++mark%2){ 210 | insert(head1,p->element); 211 | }else{ 212 | insert(head2,p->element); 213 | } 214 | } 215 | makeCircle(head1); 216 | head1->element = mark / 2 + 1; 217 | makeCircle(head2); 218 | head2->element = mark / 2; 219 | } 220 | 221 | /* 222 | * 实现类似substr()的功能 223 | */ 224 | ElementType* subEle(LinkedNode* head,int m,int n){ 225 | ElementType* pe = (ElementType* )malloc((n-m)*sizeof(ElementType)); 226 | LinkedNode* p = head; 227 | int i,j; 228 | for(i=0,j=0;p->next!=NULL;i++){ 229 | p = p->next; 230 | if(i >= m && i < n){ 231 | pe[j] = p->element; 232 | j++; 233 | } 234 | } 235 | return pe; 236 | } 237 | -------------------------------------------------------------------------------- /polynomial.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/polynomial.c -------------------------------------------------------------------------------- /quicksort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAX 250 4 | void quickSort(int a[],int start,int end); 5 | void printArray(int a[],int n); 6 | int* createRandomArray(int n); 7 | int main() 8 | { 9 | int *arr = createRandomArray(MAX); 10 | quickSort(arr,0,MAX-1); 11 | printArray(arr,MAX); 12 | free(arr); 13 | return 0; 14 | } 15 | void quickSort(int a[],int start,int end){ 16 | if(end - start<1){ // min of length is 2 17 | return; 18 | } 19 | int i = start; 20 | int j = end; 21 | int temp = a[start]; // middle number. 22 | while(i temp){ 32 | a[j--] = a[i]; 33 | break; 34 | } 35 | i++; 36 | } 37 | } 38 | a[i] = temp; 39 | quickSort(a,start,i-1); 40 | quickSort(a,i+1,end); 41 | } 42 | void printArray(int a[],int n){ // print the array. 43 | int i; 44 | for(i=0;i 2 | #include 3 | 4 | typedef char ElementType; // make the program more useful 5 | typedef struct LinkedNode{ 6 | ElementType element; 7 | struct LinkedNode* next; 8 | }LinkedNode; 9 | 10 | void* pop(LinkedNode** ptop); 11 | void* push(LinkedNode** ptop,ElementType element); 12 | 13 | int main() 14 | { 15 | char* old_str = "3*-y-a/y!2"; // ! instand of 16 | char* new_str = "3y-*ay2!/-"; 17 | LinkedNode* top = NULL; 18 | while(*new_str){ // push once,then check all the possible pop 19 | push(&top,*old_str); 20 | old_str++; 21 | printf("X"); 22 | while(top && top->element == *new_str){ 23 | pop(&top); 24 | new_str++; 25 | printf("S"); 26 | } 27 | } 28 | return 0; 29 | } 30 | 31 | /* 32 | * pop an element,return the last top's element 33 | */ 34 | void* pop(LinkedNode** ptop){ 35 | LinkedNode* top = *ptop; 36 | if(!top) return NULL; 37 | LinkedNode* last_top = top; 38 | top = top->next; 39 | free(last_top); 40 | return top; 41 | } 42 | 43 | /* 44 | * push a new element to the stack 45 | */ 46 | void* push(LinkedNode** ptop,ElementType element){ 47 | LinkedNode* top = *ptop; 48 | LinkedNode* new_top = (LinkedNode*)malloc(sizeof(LinkedNode)); 49 | new_top->element = element; 50 | new_top->next = top; 51 | return new_top; 52 | } 53 | -------------------------------------------------------------------------------- /tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef char ElementType; // make the program more useful 5 | typedef struct TreeNode{ // the struct for a tree node 6 | ElementType element; 7 | struct TreeNode* lc; 8 | struct TreeNode* rc; 9 | }TreeNode; 10 | typedef struct LinkedNode{ // the struct for a linkednode.In this program,it is used for a queue. 11 | TreeNode* element; 12 | struct LinkedNode* next; 13 | }LinkedNode; 14 | 15 | TreeNode* createTreeNode(ElementType element); 16 | TreeNode* find(TreeNode* root,ElementType element); 17 | LinkedNode* createLinkedNode(TreeNode* element); 18 | LinkedNode* enqueue(LinkedNode* back,TreeNode* element); 19 | LinkedNode* dequeue(LinkedNode* front); 20 | void preTraverse(TreeNode* root); 21 | void inTraverse(TreeNode* root); 22 | void postTraverse(TreeNode* root); 23 | void levelTraverse(TreeNode* root); 24 | void addTreeNode(ElementType element,TreeNode* parent,char mark); 25 | void addTreeNodeByUser(TreeNode* root,ElementType element,ElementType parent_element,char mark); 26 | void testTraverse(TreeNode* root); 27 | 28 | int main() 29 | { 30 | ElementType curr_ele,parent_ele; 31 | TreeNode* root = NULL; 32 | char mark; 33 | while(1){ 34 | scanf("%c%c%c",&curr_ele,&parent_ele,&mark); 35 | getchar(); 36 | // fflush(stdout); 37 | // printf("%c %c %c\n",curr_ele,parent_ele,mark); 38 | if(curr_ele == '#'){ // '#' is like a NULL or None. 39 | break; 40 | }else if(parent_ele == '#'){ 41 | root = createTreeNode(curr_ele); 42 | }else{ 43 | addTreeNodeByUser(root,curr_ele,parent_ele,mark); 44 | } 45 | } 46 | testTraverse(root); 47 | return 0; 48 | } 49 | 50 | // create a new tree node,usually used when creating a new root. 51 | TreeNode* createTreeNode(ElementType element){ 52 | TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); 53 | node->element = element; 54 | node->lc = NULL; 55 | node->rc = NULL; 56 | return node; 57 | } 58 | 59 | // create a new linked node. In this program,it is used for a queue. 60 | LinkedNode* createLinkedNode(TreeNode* element){ 61 | LinkedNode* p = (LinkedNode*)malloc(sizeof(LinkedNode)); 62 | p->element = element; 63 | p->next = NULL; 64 | return p; 65 | } 66 | 67 | // find a element in a tree. 68 | TreeNode* find(TreeNode* root,ElementType element){ 69 | if(!root){ 70 | return NULL; 71 | } 72 | TreeNode* find_node = NULL; 73 | if(root->element == element){ 74 | return root; 75 | }else if((find_node = find(root->lc,element))){ 76 | return find_node; 77 | }else if((find_node = find(root->rc,element))){ 78 | return find_node; 79 | }else{ 80 | return NULL; 81 | } 82 | } 83 | 84 | // use the current element,parent point and whether the current node is leftChild or rightChild to add a new node. 85 | void addTreeNode(ElementType element,TreeNode* parent,char mark){ 86 | TreeNode* child = createTreeNode(element); 87 | switch(mark){ 88 | case 'L': 89 | parent->lc = child; 90 | break; 91 | case 'R': 92 | parent->rc = child; 93 | break; 94 | } 95 | } 96 | 97 | // a simple method to add a new node. 98 | void addTreeNodeByUser(TreeNode* root,ElementType element,ElementType parent_element,char mark){ 99 | TreeNode* parent = find(root,parent_element); 100 | if(!parent){ 101 | return; 102 | } 103 | addTreeNode(element,parent,mark); 104 | } 105 | 106 | // data && leftTree && rightTree 107 | void preTraverse(TreeNode* root){ 108 | if(!root){ 109 | return; 110 | } 111 | printf("%c",root->element); 112 | preTraverse(root->lc); 113 | preTraverse(root->rc); 114 | } 115 | 116 | // leftTree && data && rightTree 117 | void inTraverse(TreeNode* root){ 118 | if(!root){ 119 | return; 120 | } 121 | inTraverse(root->lc); 122 | printf("%c",root->element); 123 | inTraverse(root->rc); 124 | } 125 | 126 | // leftTree && rightTree && data 127 | void postTraverse(TreeNode* root){ 128 | if(!root){ 129 | return; 130 | } 131 | postTraverse(root->lc); 132 | postTraverse(root->rc); 133 | printf("%c",root->element); 134 | } 135 | 136 | // traverse a tree by level. 137 | void levelTraverse(TreeNode* root){ 138 | if(!root){ 139 | return; 140 | } 141 | LinkedNode* front = NULL; 142 | LinkedNode* back = NULL; 143 | 144 | front = back = createLinkedNode(root); 145 | while(front){ 146 | TreeNode* node = front->element; 147 | if(node->lc){ 148 | back = enqueue(back,node->lc); 149 | } 150 | if(node->rc){ 151 | back = enqueue(back,node->rc); 152 | } 153 | printf("%c",node->element); 154 | front = dequeue(front); 155 | } 156 | } 157 | 158 | // test all the 4 traverses 159 | void testTraverse(TreeNode* root){ 160 | printf("Traverse data && leftTree && rightTree:\n"); 161 | preTraverse(root); 162 | printf("\nTraverse leftTree && data && rightTree:\n"); 163 | inTraverse(root); 164 | printf("\nTraverse leftTree && rightTree && data:\n"); 165 | postTraverse(root); 166 | printf("\nTraverse by level: \n"); 167 | levelTraverse(root); 168 | printf("\n"); 169 | } 170 | 171 | // make a data enter a queue 172 | LinkedNode* enqueue(LinkedNode* back,TreeNode* element){ 173 | LinkedNode* new_back = createLinkedNode(element); 174 | back->next = new_back; 175 | return new_back; 176 | } 177 | 178 | // make a data out 179 | LinkedNode* dequeue(LinkedNode* front){ 180 | LinkedNode* old_front = front; 181 | front = front->next; 182 | free(old_front); 183 | return front; 184 | } 185 | -------------------------------------------------------------------------------- /作业文档/1143730113_王必聪_作业1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/作业文档/1143730113_王必聪_作业1.docx -------------------------------------------------------------------------------- /作业文档/1143730113_王必聪_作业2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/作业文档/1143730113_王必聪_作业2.docx -------------------------------------------------------------------------------- /作业文档/1143730113_王必聪_作业3.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/作业文档/1143730113_王必聪_作业3.docx -------------------------------------------------------------------------------- /实验报告/1143730113_王必聪_实验1_线性表及其应用.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/实验报告/1143730113_王必聪_实验1_线性表及其应用.doc -------------------------------------------------------------------------------- /实验报告/1143730113_王必聪_实验2_树及其应用.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/实验报告/1143730113_王必聪_实验2_树及其应用.doc -------------------------------------------------------------------------------- /实验报告/1143730113_王必聪_实验3_图及其应用.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/实验报告/1143730113_王必聪_实验3_图及其应用.doc -------------------------------------------------------------------------------- /实验报告/1143730113_王必聪_实验4_查找与排序.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/实验报告/1143730113_王必聪_实验4_查找与排序.doc -------------------------------------------------------------------------------- /课程设计-扫雷/00.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/00.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/01.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/01.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/02.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/02.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/03.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/03.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/04.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/04.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/05.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/05.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/06.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/06.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/07.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/07.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/08.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/08.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/flag.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/flag.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/game.py: -------------------------------------------------------------------------------- 1 | # coding:utf8 2 | from random import randint 3 | 4 | class Game(object): 5 | 6 | def __init__(self, length=8, width=10, mineNum=10): 7 | self.length = length 8 | self.width = width 9 | self.mineNum = mineNum 10 | self.mapCoord = [] 11 | # 初始化Box二维列表 12 | for i in range(length+2): 13 | self.mapCoord.append([]) 14 | for j in range(width+2): 15 | self.mapCoord[i].append(Box()) 16 | self.createMap() 17 | 18 | def createMap(self): 19 | existMineCoords = [] 20 | i = 0 21 | while i < self.mineNum: 22 | x = randint(1, self.length) 23 | y = randint(1, self.width) 24 | if (x, y) not in existMineCoords: 25 | existMineCoords.append((x, y)) 26 | i += 1 27 | for (x, y) in existMineCoords: 28 | self.mapCoord[x][y].mineNum = -1 29 | # 布置地雷 30 | for i in range(1, self.length + 1): 31 | for j in range(1, self.width + 1): 32 | self.calculateMineNum(i, j) 33 | for i in range(0,self.length + 2): 34 | for j in range(0, self.width + 2): 35 | if i == 0 or j == 0 or i == self.length + 1 or j == self.width + 1: 36 | self.mapCoord[i][j].openMark = True 37 | # 令外圈为打开状态 38 | 39 | 40 | def calculateMineNum(self, x, y): 41 | if self.mapCoord[x][y].mineNum == -1: 42 | return 43 | count = 0 44 | if self.mapCoord[x+1][y].mineNum == -1: 45 | count += 1 46 | if self.mapCoord[x-1][y].mineNum == -1: 47 | count += 1 48 | if self.mapCoord[x][y+1].mineNum == -1: 49 | count += 1 50 | if self.mapCoord[x][y-1].mineNum == -1: 51 | count += 1 52 | if self.mapCoord[x+1][y+1].mineNum == -1: 53 | count += 1 54 | if self.mapCoord[x-1][y+1].mineNum == -1: 55 | count += 1 56 | if self.mapCoord[x+1][y-1].mineNum == -1: 57 | count += 1 58 | if self.mapCoord[x-1][y-1].mineNum == -1: 59 | count += 1 60 | self.mapCoord[x][y].mineNum = count 61 | 62 | # 代表每一个格子的状态 63 | class Box(object): 64 | 65 | def __init__(self, mineNum=0, flag=False, openMark = False): 66 | self.mineNum = mineNum 67 | self.flag = flag 68 | self.openMark = openMark 69 | 70 | # 测试该模板的运行情况 71 | if __name__ == '__main__': 72 | game = Game() 73 | mapCoord = game.mapCoord 74 | for i in range(len(mapCoord)): 75 | for j in range(len(mapCoord[0])): 76 | print mapCoord[i][j].mineNum, 77 | print 78 | print len(mapCoord), len(mapCoord[0]) -------------------------------------------------------------------------------- /课程设计-扫雷/gui.py: -------------------------------------------------------------------------------- 1 | # coding:utf8 2 | import wx 3 | from game import Game 4 | 5 | class App(wx.App): 6 | 7 | 8 | def OnInit(self): 9 | frame = Frame() 10 | frame.Show() 11 | self.SetTopWindow(frame) 12 | return True 13 | 14 | 15 | class Frame(wx.Frame): 16 | 17 | each = 28 # 每个格子所在矩阵的像素边长 18 | 19 | length = 8 20 | width = 10 21 | mineNum = 10 22 | time = 0 23 | 24 | existClosedNum = length * width - mineNum # 为了判断胜利条件 25 | existMineNum = mineNum 26 | 27 | def __init__(self): 28 | wx.Frame.__init__(self, parent=None, title=u'扫雷', pos=wx.DefaultPosition, 29 | size=(515, 580)) 30 | 31 | icon = wx.Icon('mine.ico', wx.BITMAP_TYPE_ICO) 32 | self.SetIcon(icon) 33 | 34 | self.statusBar = self.CreateStatusBar() 35 | self.statusBar.SetFieldsCount(2) 36 | self.statusBar.SetStatusWidths([-1, -1]) 37 | self.statusBar.SetStatusText(u"Mine Sweeping", 0) 38 | self.statusBar.SetStatusText(u"By wxPython", 1) 39 | 40 | self.panel = wx.Panel(self) 41 | theme = wx.Image('theme.bmp', wx.BITMAP_TYPE_BMP) 42 | wx.StaticBitmap(self.panel, wx.ID_ANY, wx.BitmapFromImage(theme)) 43 | self.SetMenu() 44 | 45 | # 定义所有本程序使用到的图像 46 | self.numBmp = [] 47 | for i in range(9): 48 | self.numBmp.append(wx.Bitmap('0'+str(i)+'.bmp', wx.BITMAP_TYPE_BMP)) 49 | self.initBmp = wx.Bitmap('init.png', wx.BITMAP_TYPE_PNG) 50 | self.flagBmp = wx.Bitmap('flag.bmp', wx.BITMAP_TYPE_BMP) 51 | self.mineBmp = wx.Bitmap('mine.bmp', wx.BITMAP_TYPE_BMP) 52 | 53 | 54 | def SetMenu(self): 55 | 56 | menuBar = wx.MenuBar() 57 | 58 | optionMenu = wx.Menu() 59 | resetMenuItem = optionMenu.Append(wx.ID_ANY, u'开始/重置') 60 | optionMenu.AppendSeparator() 61 | settingMenuItem = optionMenu.Append(wx.ID_ANY, u'设置') 62 | optionMenu.AppendSeparator() 63 | exitMenuItem = optionMenu.Append(wx.ID_ANY, u'退出') 64 | menuBar.Append(optionMenu, u'选项') 65 | 66 | helpMenu = wx.Menu() 67 | aboutMenuItem = helpMenu.Append(wx.ID_ANY, u'关于') 68 | menuBar.Append(helpMenu, u'帮助') 69 | 70 | self.SetMenuBar(menuBar) 71 | 72 | self.Bind(wx.EVT_MENU, self.OnSetting, settingMenuItem) 73 | self.Bind(wx.EVT_MENU, self.OnReset, resetMenuItem) 74 | self.Bind(wx.EVT_MENU, self.OnExit, exitMenuItem) 75 | 76 | self.Bind(wx.EVT_MENU, self.OnAbout, aboutMenuItem) 77 | 78 | def OnSetting(self, event): 79 | 80 | self.dialog = wx.Dialog(self, title=u'设置', pos=wx.DefaultPosition, size=(95, 160)) 81 | 82 | wx.StaticText(self.dialog, wx.ID_ANY, u'长度:', pos=(10, 15)) 83 | self.lenText = wx.TextCtrl(self.dialog, wx.ID_ANY, str(self.length), pos=(50, 10), size=(30, 25)) 84 | 85 | wx.StaticText(self.dialog, wx.ID_ANY, u'宽度:', pos=(10, 45)) 86 | self.widText = wx.TextCtrl(self.dialog, wx.ID_ANY, str(self.width), pos=(50, 40), size=(30, 25)) 87 | 88 | wx.StaticText(self.dialog, wx.ID_ANY, u'雷数:', pos=(10, 75)) 89 | self.mineNumText = wx.TextCtrl(self.dialog, wx.ID_ANY, str(self.mineNum), pos=(50, 70), size=(30, 25)) 90 | 91 | confirmButton = wx.Button(self.dialog, wx.ID_ANY, u'确认', pos=(10, 100), size=(70, 25)) 92 | confirmButton.Bind(wx.EVT_BUTTON, self.OnConfirmSetting) 93 | 94 | self.dialog.Show() 95 | 96 | # 放置所有的Button 97 | def OnReset(self, event): 98 | 99 | self.panel.Destroy() 100 | self.timer = wx.Timer(self) 101 | self.timer.Start(1000) 102 | self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 103 | self.existClosedNum = self.length * self.width - self.mineNum 104 | self.existMineNum = self.mineNum 105 | self.time = 0 106 | self.statusBar.SetStatusText(u"已用时间:" + str(self.time), 0) 107 | self.statusBar.SetStatusText(u"剩余雷数:" + str(self.existMineNum), 1) 108 | self.SetSize((self.length*self.each+17, self.width*self.each+84)) 109 | # self.SetMaxSize((self.length*self.each+17, self.width*self.each+84)) 110 | # self.SetMinSize((self.length*self.each+17, self.width*self.each+84)) 111 | self.panel = wx.Panel(self, size=(self.length*self.each, self.width*self.each)) 112 | self.mapList = [] 113 | sizeAll = wx.BoxSizer(wx.HORIZONTAL) 114 | for i in range(self.length): 115 | self.mapList.append([]) 116 | sizeEach = wx.BoxSizer(wx.VERTICAL) 117 | for j in range(self.width): 118 | button = wx.BitmapButton(self.panel, i*self.width+j, pos=(i*self.each, j*self.each), 119 | size=(self.each, self.each), style=wx.BU_AUTODRAW) 120 | button.Bind(wx.EVT_LEFT_DOWN, self.OnLeftClick) 121 | button.Bind(wx.EVT_RIGHT_DOWN, self.OnRightClick) 122 | self.mapList[i].append(button) 123 | sizeEach.Add(button) 124 | sizeAll.Add(sizeEach) 125 | self.panel.SetSizer(sizeAll) 126 | self.StartGame() 127 | 128 | def StartGame(self): 129 | game = Game(self.length, self.width, self.mineNum) 130 | self.mapCoord = game.mapCoord 131 | 132 | def OnTimer(self, event): 133 | self.time += 1 134 | self.statusBar.SetStatusText(u"已用时间:" + str(self.time), 0) 135 | 136 | def OnLeftClick(self, event): 137 | id = event.GetId() 138 | x = id / self.width + 1 139 | y = id % self.width + 1 140 | button = self.panel.FindWindowById(id) 141 | button.SetFocus() 142 | # 根据格子的属性进行不同的处理 143 | if not self.mapCoord[x][y].flag and not self.mapCoord[x][y].openMark: 144 | if self.mapCoord[x][y].mineNum == -1: 145 | self.gameLost() #游戏结束 146 | elif self.mapCoord[x][y].mineNum == 0: 147 | self.breathFirstSearch(x, y) #广度优先搜索 148 | else: 149 | self.mapCoord[x][y].openMark = True 150 | self.existClosedNum -= 1 151 | button.SetBitmap(self.numBmp[self.mapCoord[x][y].mineNum]) 152 | if not self.existClosedNum: 153 | self.gameWin() #游戏胜利 154 | 155 | def OnRightClick(self, event): 156 | id = event.GetId() 157 | x = id / self.width + 1 158 | y = id % self.width + 1 159 | button = self.panel.FindWindowById(id) 160 | button.SetFocus() 161 | # 改变标记状态 162 | if not self.mapCoord[x][y].openMark: 163 | if self.mapCoord[x][y].flag: 164 | button.SetBitmap(self.initBmp) 165 | self.existMineNum += 1 166 | self.statusBar.SetStatusText(u"剩余雷数:" + str(self.existMineNum), 1) 167 | self.mapCoord[x][y].flag = False 168 | else: 169 | button.SetBitmap(self.flagBmp) 170 | self.existMineNum -= 1 171 | self.statusBar.SetStatusText(u"剩余雷数:" + str(self.existMineNum), 1) 172 | self.mapCoord[x][y].flag = True 173 | 174 | 175 | def OnExit(self, event): 176 | self.Close() 177 | 178 | def OnAbout(self, event): 179 | wx.MessageBox(u'\n制作人:王必聪 宋源栋 谭学昱 刘鑫禹\n') 180 | 181 | def OnConfirmSetting(self, event): 182 | self.length = int(self.lenText.GetValue()) 183 | self.width = int(self.widText.GetValue()) 184 | self.mineNum = int(self.mineNumText.GetValue()) 185 | self.OnReset(event) 186 | self.dialog.Close() 187 | 188 | def gameLost(self): 189 | self.timer.Stop() 190 | self.showMap() 191 | wx.MessageBox(u'你失败了!') 192 | 193 | def gameWin(self): 194 | self.timer.Stop() 195 | self.showMap() 196 | wx.MessageBox(u'你胜利了!') 197 | 198 | # 显示所有格子 199 | def showMap(self): 200 | mapList = self.mapList 201 | mapCoord = self.mapCoord 202 | for i in range(1, self.length+1): 203 | for j in range(1, self.width+1): 204 | if not mapCoord[i][j].openMark: 205 | mapCoord[i][j].openMark = True 206 | if mapCoord[i][j].mineNum >= 0: 207 | mapList[i-1][j-1].SetBitmap(self.numBmp[mapCoord[i][j].mineNum]) 208 | else: 209 | mapList[i-1][j-1].SetBitmap(self.mineBmp) 210 | 211 | 212 | # 广度优先搜索,(实际中使用了深度优先搜索,效果一样,如果按照广度优先搜索进行,则需要利用到队列,将周围未开启的格子全部入队,出队时重复该操作) 213 | def breathFirstSearch(self, x, y): 214 | if not self.mapCoord[x][y].openMark: 215 | if self.mapCoord[x][y].flag: 216 | self.existMineNum += 1 217 | self.statusBar.SetStatusText(u"剩余雷数:" + str(self.existMineNum), 1) 218 | self.mapCoord[x][y].openMark = True 219 | self.existClosedNum -= 1 220 | self.mapList[x-1][y-1].SetBitmap(self.numBmp[self.mapCoord[x][y].mineNum]) 221 | if not self.mapCoord[x][y].mineNum: 222 | self.breathFirstSearch(x+1, y) 223 | self.breathFirstSearch(x-1, y) 224 | self.breathFirstSearch(x, y+1) 225 | self.breathFirstSearch(x, y-1) 226 | 227 | self.breathFirstSearch(x+1, y+1) 228 | self.breathFirstSearch(x-1, y+1) 229 | self.breathFirstSearch(x+1, y-1) 230 | self.breathFirstSearch(x-1, y-1) 231 | 232 | 233 | def main(): 234 | app = App() 235 | app.MainLoop() 236 | 237 | if __name__ == '__main__': 238 | main() -------------------------------------------------------------------------------- /课程设计-扫雷/init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/init.png -------------------------------------------------------------------------------- /课程设计-扫雷/mine.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/mine.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/mine.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/mine.ico -------------------------------------------------------------------------------- /课程设计-扫雷/theme.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/theme.bmp -------------------------------------------------------------------------------- /课程设计-扫雷/第30组_王必聪_答辩.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/第30组_王必聪_答辩.ppt -------------------------------------------------------------------------------- /课程设计-扫雷/第30组_王必聪_课程设计报告.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bicongwang/hit-data_structure_algorithm/b29994b605eb029886f0b622de328326bf766083/课程设计-扫雷/第30组_王必聪_课程设计报告.doc --------------------------------------------------------------------------------