Реализовать консольное игровое приложения "Пятнашки" (с чего начать, какую литературу и какие темы изучать?) - C (СИ)
Формулировка задачи:
День добрый. Я - первокурсник, не так давно начал изучать язык С. И вот выдали мне тему курсового проекта: реализация игрового приложения "Пятнашки" в консоли на языке С. Квадратные глаза и n-ное кол-во кирпичей - вот так можно описать мое состояние. Срок сдачи приближается и я решился обратиться за помощью.
Посоветуйте, с чего вообще начинать, какую литературу и какие темы изучать? И, может быть, у кого-нибудь завалялась готовая программа? =) Заранее спасибо.
Решение задачи: «Реализовать консольное игровое приложения "Пятнашки" (с чего начать, какую литературу и какие темы изучать?)»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define SIZE 4
#define NUMBS SIZE*SIZE
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
int board[SIZE][SIZE];
void FillBoard ( void );
//ведь в си нет bool?
int HaveSolution( void );
int EndOfGame ( void );
void PrintBoard ( void );
void Move ( int );
int main( void )
{
HANDLE cInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD dr;
INPUT_RECORD rec;
//init
system("title 15 P U ZZ L E");
FillBoard();
PrintBoard();
//
while( !EndOfGame() )
{
//Sleep(50);
ReadConsoleInput(cInput, &rec, sizeof(INPUT_RECORD), &dr);
FlushConsoleInputBuffer(cInput);
if(rec.EventType == KEY_EVENT && rec.Event.KeyEvent.bKeyDown)
{
switch(rec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_LEFT:
Move(LEFT);
break;
case VK_RIGHT:
Move(RIGHT);
break;
case VK_UP:
Move(UP);
break;
case VK_DOWN:
Move(DOWN);
break;
}
PrintBoard();
}
}
return 0;
}
void FillBoard( void )
{
do
{
srand( time( NULL ));
int numbers[NUMBS] = {0};
int i;
int nextNum;
for(i = 0; i < NUMBS-1; i++)
while(1)
{
nextNum = rand()%(NUMBS-1)+1;
if(numbers[nextNum] == 0)
{
numbers[nextNum] = 1;
board[ i/SIZE ][ i%SIZE ] = nextNum;
break;
}
}
} while( !HaveSolution() );
}
int HaveSolution( void )
{
int i, j;
int inv = 0;
for(i = 0; i < NUMBS; i++)
{
if(board[ i/SIZE ][ i%SIZE ] == 0)
inv += i+1;
for(j = 0; j < i; j++)
if(board[ j/SIZE ][ j%SIZE ] > board[ i/SIZE ][ i%SIZE ])
inv++;
}
return (inv%2 ? 0 : 1);
}
int EndOfGame( void )
{
int i;
for(i = 0; i < NUMBS-1; i++)
if(board[ i/SIZE ][ i%SIZE ] != i+1)
return 0;
return 1;
}
void PrintBoard( void )
{
system("cls");
system("color 0F");
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
COORD cPos;
unsigned char BL = 219;
SetConsoleTextAttribute(hCon, BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
printf("15 P U ZZ L E");
SetConsoleTextAttribute(hCon, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE);
int i, j;
for(i = 0; i < SIZE; i++)
{
for(j = 0; j < SIZE; j++)
{
cPos.X = j*3;
cPos.Y = i*2+1;
//maybe at five or maybe at six
SetConsoleCursorPosition(hCon, cPos);
printf("%c%c%c%c", BL, BL, BL, BL);
cPos.Y = i*2+2;
cPos.X = j*3;
SetConsoleCursorPosition(hCon, cPos);
if(board[i][j])
printf("%c%2i%c", BL, board[i][j], BL);
else
printf("%c %c", BL, BL);
cPos.Y = i*2+3;
cPos.X = j*3;
SetConsoleCursorPosition(hCon, cPos);
printf("%c%c%c%c", BL, BL, BL, BL);
}
}
SetConsoleTextAttribute(hCon, BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
printf("\nM A Y O N E Z\n");
}
void Move( int direction )
{
int dy[] = {1,-1, 0, 0};
int dx[] = {0, 0, 1,-1};
int i, j;
for(i = 0; i < SIZE; i++)
for(j = 0; j < SIZE; j++)
if(board[i][j] == 0)
{
int newy = i + dy[direction];
int newx = j + dx[direction];
if( newy >= 0 && newy < SIZE &&
newx >= 0 && newx < SIZE)
{
board[i][j] = board[newy][newx];
board[newy][newx] = 0;
}
return;
}
}
Объяснение кода листинга программы
- В коде реализована игра
Пятнашки. - Игра реализована на языке C.
- Для работы с консолью используются библиотеки
, , и . - Игра состоит из основной функции main() и дополнительных функций FillBoard(), HaveSolution(), EndOfGame() и PrintBoard().
- Функция FillBoard() заполняет игровое поле случайными числами от 1 до 15.
- Функция HaveSolution() проверяет, есть ли в игре решение (набор чисел от 1 до 15 без пропусков).
- Функция EndOfGame() проверяет, достигнута ли конечная позиция (когда все числа от 1 до 15 расставлены).
- Функция PrintBoard() выводит игровое поле на экран.
- В основной функции main() происходит инициализация игрового поля, вывод его на экран, а затем начинается цикл игры, в котором пользователь управляет перемещением чисел с помощью клавиш со стрелками.
- Для управления курсором в консоли используется функция SetConsoleCursorPosition().
- Для перемещения чисел по игровому полю используется функция Move().
- В игре используется алгоритм поиска в глубину (DFS) для проверки наличия решения.
- Код содержит макросы и константы для удобства работы с игровым полем: SIZE (размер поля), NUMBS (общее количество ячеек), UP, DOWN, LEFT, RIGHT (коды направлений движения).
- В игре используется ASCII-кодировка для представления чисел и символов на игровом поле.
- Для генерации случайных чисел используется функция rand() из библиотеки
.