Задача: создать игру Сапер; Я думаю, все из вас сталкивались с такой игрой, как сапер. В данной программе дано поле 20х20, количество мин вы можете выбрать на свой вкус от 10 до 99. Мины распределяются случайно по полю, затем, производится проход по всему полю. Что мы делаем: Так же имеется меню: Индикатор смерти показан в правом вернем углу. Основная трудность в данной задаче, это произвести открытие всех соседних пустых клеточек, при нажатии на пустую клетку. Я предложу вам 2 варианта решения этой проблемы: 1. BFS: /*Необходимые объявления*/ int dx[8]={0,0,1,-1,1,1,-1,-1}; int dy[8]={1,-1,1,1,0,-1,-1,0}; struct NODE // элемент очереди { int x,y; NODE* next; }node; struct QUEUE // очередь { NODE *begin,*end; }queue; QUEUE zq; // создаем очередь NODE *tmp,*n; // создаем ссылки на два элемента очереди. /*Вызов функции*/ zq.begin = zq.end = NULL; // наша очередь пуста if(zq.begin == zq.end && zq.begin == NULL) // если очередь пустая { zq.begin = zq.end = (NODE*)malloc(sizeof(node)); // выделяем память для первого элемента tmp = zq.end; tmp->x = y_m; tmp->y = x_m; // помещаем в x,y координаты элемента в матрице tmp->next = NULL; // у нас только 1 элемент, дальше ничего нет. } tmp = zq.begin; // начинаем сначала. gdk_draw_zeropoint(zq.begin->x,zq.begin->y); // вызываем BFS для открытия пустых ячеек. /* -BFS- */ gboolean gdk_draw_zeropoint(int i,int j) { while(tmp!=NULL) // пока не дойдем до конца списка { for(int s=0; s<8; s++) // пробегаем окрестность элемента (в общем случае с ним граничит ровно 8 элементов) { // если такой элемент в матрице существует, и клеточка еще не открыта if((i+dx[s] >= 0) && (i+dx[s] < N) && (j+dy[s] >= 0) && (j+dy[s] < N) && (a[i+dx[s]][j+dy[s]].plstrue)) { if(a[i+dx[s]][j+dy[s]].point == 0) // если количество мин в окрестности равно 0. { n = (NODE*)malloc(sizeof(node)); // выделяем память для нового элемента. n->next = NULL; // следующий за последним, пустой. // записываем координаты точки. n->x = i+dx[s]; n->y = j+dy[s]; zq.end->next = n; // следующий элемент в очереди за последним, это этот элемент. zq.end = n; // передвигаем конец очереди. gdk_draw_picture(pl,(j+dy[s])*HH,MH + (i+dx[s])*HH,HH,HH); // рисуем на экране картинку (открытой ячейки) a[i+dx[s]][j+dy[s]].plstrue = 0; // этот элемент мы уже открыли и обработали } else { gdk_draw_picture(pl,(j+dy[s])*HH,MH + (i+dx[s])*HH,HH,HH); // рисуем картинку (открытой ячейки) gettext(txt,a[i+dx[s]][j+dy[s]].point); // преобразовываем число мин в строку символов draw_text_in_center(txt,(j+dy[s])*HH+HH/2,(i+dx[s])*HH+HH/2+MH); // выводим число мин на экран a[i+dx[s]][j+dy[s]].plstrue = 0; // этот элемент мы уже открыли и обработали } } } zq.begin = zq.begin->next; // передвигаем начало очереди, начальный элемент мы уже обработали if(tmp == zq.end) break; // если достигли конца списка, конец. tmp = zq.begin; // tmp - начальный элемент списка. // записываем в i,j координаты элемента в матрице. i = tmp->x; j = tmp->y; } return TRUE; } 2. DFS: int dx[8]={0,0,1,-1,1,1,-1,-1}; int dy[8]={1,-1,1,1,0,-1,-1,0}; void dfs(int x,int y) // x,y - координаты данной точки в массиве. { if(open[x][y]) return; // если клетка уже открыта, просто возвращаемся. open[x][y]; // открыть клетку (т.е. вывести её содержимое на экран) if(point[x][y]==0) // если количество мин в окрестности равно 0. { for(int k=0;k<8;k++) // пробегая по массивам dx,dy мы сможем поочередно пройти всех соседей данной клетки. { if(good(x+dx[k],y+dy[k])) // если координаты x+dx[k],y+dy[k] хорошие, т.е. 0<=x+dx[k]<N && 0<=y+dy[k]<N. dfs(x+dx[k],y+dy[k]); // вызываемся рекурсивно в данной точке. } } } В архиве так же содержится, доработанная и улучшенная версия данной игры. Но код улучшенной версии не предоставляется, а предоставляется готовая игра, в ознакомительных целях. Приятной игры.
Ключевые слова:
Сапер, игра
|
|||||||