Разработка программы на языке С++ с использованием функций WinAPI: < Игра Сима >

Автор: Пользователь скрыл имя, 21 Февраля 2013 в 05:55, курсовая работа

Краткое описание

Целью данной курсовой работы является реализовать данную игру («Сима», при победной комбинации сбора треугольника противником его же цветом) с помощью использования процедур и функций операционной системы. А также цель данного проекта систематизация, углубление и активное применение знаний по системному программированию, закрепление полученных знаний.

Оглавление

Введение ……………………………………………………....………
5
Основная часть…..………………........................................................
6
1 Анализ предметной области и постановка задач …………………
6
2 Разработка структуры программы и алгоритмов …………………
10
3 Разработка программы ………………………………….………….
14
4 Тестирование программы и инструкция пользователя …………..
23
4.1 Тестирование программы……………………………………..
23
4.2 Инструкция пользователя ………..…………………………..
23
Выводы……………………………………………………..……….…
27
Перечень ссылок………………………………………………………
28

Файлы: 1 файл

Записка.doc

— 431.00 Кб (Скачать)

Затем необходимо проверить, нет ли выигрышной комбинации. Данное действие определяется с помощью «карты точек». Суть состоит в проверке каждой строки «карты точек» на наличие одинаковых значений, а также проверки на одинаковость соответствующих одинаковых значений индексов столбцов.

В случае если такая комбинация существует у игрока, то считается, что он проиграл. В противном случае игра продолжается.

После того, как игра сыграна, игрокам  предоставляется возможность повторить  состязание, начав все заново с  установки количества точек на поле или выйти из игры.

 

Структурная схема алгоритма  программы:

 

 

 

 

 

 

 

 

 

3 РАЗРАБОТКА ПРОГРАММЫ

 

Данная программа состоит из двух модулей: основной (Sima_08.cpp) и модуль функций (funcs.cpp). Основные фрагменты кода этих модулей представлены ниже.

 

/*funcs.cpp*/

 

#include "stdafx.h"

#include "funcs.h"

 

struct Pointers

{

public:

bool marked;

POINT point;

};

 

struct Manager

{

int pointCount;

HWND pHWnd;

int **map;

Pointers *points;

};

 

struct Line

{

int x1;

int x2;

int y1;

int y2;

};

 

 

void crossLine(Manager& tm, Line& line1, Line& line2, bool& isFail, int* mas1, int* mas2, LPARAM lParam)

{

////////////////////

//mas[0] = A;

//mas[1] = B;

//mas[2] = C;

 

int x,y,z;

isFail = false;

line1.x2 = LOWORD(lParam);

line1.y2 = HIWORD(lParam);

 

mas1[0] = line1.y2 - line1.y1;

mas1[1] = line1.x1 - line1.x2;

mas1[2] = (line1.x2 - line1.x1)*line1.y1 - (line1.y2 - line1.y1)*line1.x1;

 

for(int i=0; i<tm.pointCount; i++)

for(int j=0; j<tm.pointCount; j++)

{

if(tm.map[i][j])

{

line2.x1 = tm.points[i].point.x;

line2.y1 = tm.points[i].point.y;

line2.x2 = tm.points[j].point.x;

line2.y2 = tm.points[j].point.y;

 

mas2[0] = line2.y2 - line2.y1;

mas2[1] = -1*(line2.x2 - line2.x1);

mas2[2] = (line2.x2 - line2.x1)*line2.y1 - (line2.y2 - line2.y1)*line2.x1;

 

x = (mas2[2]*mas1[1] - mas1[2]*mas2[1])/(mas1[0]*mas2[1] - mas2[0]*mas1[1]);

y = (mas2[2]*mas1[0] - mas1[2]*mas2[0])/(mas1[1]*mas2[0] - mas2[1]*mas1[0]);

 

if (line1.x2 < line1.x1)

{

z = line1.x1;

line1.x1 = line1.x2;

line1.x2 = z;

}

 

if (line2.x2 < line2.x1)

{

z = line2.x1;

line2.x1 = line2.x2;

line2.x2 = z;

}

 

 

if((x > line1.x1) && (x < line1.x2) &&

(x > line2.x1) && (x < line2.x2))

{

isFail = true;

return;

}

else

{

continue;

}

}

}

}

 

void RandomInit(Pointers* mas, Manager* tm)

{

srand(time(NULL));

for(int i = 0; i < tm->pointCount; i++){

mas[i].point.x = 25 + rand() % 425;

mas[i].point.y = 25 + rand() % 425;

 

}

 

}

 

void MapInit(Manager &tm)

{

int count = tm.pointCount;

tm.map = new int*[count];

 

for(int i = 0; i < count; i++)

tm.map[i] = new int[count];

 

 

for(int i = 0; i < count; i++ )

for(int j=0; j < count; j++)

tm.map[i][j] = 0;

}

/*Sima_08.cpp */

 

#include "stdafx.h"

#include "Sima_08.h"

#include "funcs.h"

 

#define MAX_LOADSTRING 100

#define BLUE false

#define RED true

#define FIRST 1000

#define SECOND 2000

 

struct Pointers

{

public:

bool marked;

POINT point;

};

 

struct Manager

{

int pointCount;

HWND pHWnd;

int **map;

Pointers *points;

};

 

struct Line

{

int x1;

int x2;

int y1;

int y2;

};

 

static int trans;

 

 

// Global Variables:

HINSTANCE hInst;        // current instance

TCHAR szTitle[MAX_LOADSTRING];     // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name

INT_PTR CALLBACK InputParam(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACK AgainDialog(HWND, UINT, WPARAM, LPARAM);

void    crossLine(Manager& tm, Line& line1, Line& line2, bool& isFail, int* mas1, int* mas2, LPARAM);

void    RandomInit(Pointers *, Manager*);

void    MapInit(Manager&);

 

// Forward declarations of functions included in this code module:

ATOM    MyRegisterClass(HINSTANCE hInstance);

BOOL    InitInstance(HINSTANCE, int);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

 

int APIENTRY _tWinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPTSTR    lpCmdLine,

                     int       nCmdShow)

{

UNREFERENCED_PARAMETER(hPrevInstance);

UNREFERENCED_PARAMETER(lpCmdLine);

 

  // TODO: Place code here.

MSG msg;

HACCEL hAccelTable;

 

// Initialize global strings

LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

LoadString(hInstance, IDC_SIMA_08, szWindowClass, MAX_LOADSTRING);

MyRegisterClass(hInstance);

 

// Perform application initialization:

if (!InitInstance (hInstance, nCmdShow))

{

return FALSE;

}

 

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SIMA_08));

 

// Main message loop:

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

 

return (int) msg.wParam;

}

 

ATOM MyRegisterClass(HINSTANCE hInstance)

{

WNDCLASSEX wcex;

 

wcex.cbSize = sizeof(WNDCLASSEX);

 

wcex.style   = CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc = WndProc;

wcex.cbClsExtra  = 0;

wcex.cbWndExtra  = 0;

wcex.hInstance  = hInstance;

wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SIMA_08));

wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SIMA_08);

wcex.lpszClassName = szWindowClass;

wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 

return RegisterClassEx(&wcex);

}

 

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

   HWND hWnd;

 

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, 100, 100, 500, 500, NULL, NULL, hInstance, NULL);

 

   if (!hWnd)

   {

      return FALSE;

   }

 

   ShowWindow(hWnd, nCmdShow);

   UpdateWindow(hWnd);

 

   return TRUE;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc, temphdc;

static Manager tm;

static char text[20];

static bool temp = false;

static HBRUSH redBrush, blueBrush;

static HPEN redPen, bluePen, hLinePen, hOldPen, hElPen;

static POINT startPoint, endPoint;

static int index, rad = 5, changePlayer;;

static int mas1[3], mas2[3];

static int x1, x2, y1, y2;

static Line line1, line2;

static bool isFail;

 

 

switch (message)

{

case WM_COMMAND:

wmId    = LOWORD(wParam);

wmEvent = HIWORD(wParam);

// Parse the menu selections:

switch (wmId)

{

case IDM_ABOUT:

DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

break;

 

case ID_FILE_START:

xxx:

////////////////////////////////// params inputing

DialogBox(hInst, MAKEINTRESOURCE(IDD_INPUTPARAM), hWnd, InputParam);

tm.pointCount = ::trans;

 

////////////////////////////////// points initializating

tm.points = new Pointers[tm.pointCount];

RandomInit(tm.points, &tm);

InvalidateRect(hWnd, NULL, true);

 

////////////////////////////////// map creating

MapInit(tm);

changePlayer = FIRST;

EnableMenuItem(GetMenu(hWnd), ID_FILE_START, true);

break;

 

case IDM_EXIT:

DestroyWindow(hWnd);

break;

 

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

break;

 

 

case WM_CREATE:

tm.pHWnd = hWnd;

redPen = (HPEN)CreatePen(PS_SOLID, 3, RGB(255,0,0));

bluePen = (HPEN)CreatePen(PS_SOLID, 3, RGB(0,0,255));

hElPen = (HPEN)CreatePen(PS_SOLID, 4, RGB(0,255,0));

 

break;

 

 

case WM_LBUTTONDOWN:

 

for(int i=0; i<::trans; i++)

{

if((abs(tm.points[i].point.x - LOWORD(lParam)) <= rad) &&

(abs(tm.points[i].point.y - HIWORD(lParam))) <= rad &&

!temp)

{

temp = !temp;

index = i;

line1.x1 = LOWORD(lParam);

line1.y1 = HIWORD(lParam);

 

// selection (green Ellipse)

temphdc = GetDC(hWnd);

SelectObject(temphdc, hElPen);

Ellipse(temphdc, LOWORD(lParam)-rad, HIWORD(lParam)-rad, LOWORD(lParam)+rad, HIWORD(lParam)+rad);

ReleaseDC(hWnd, temphdc);

 

}

 

else if((abs(tm.points[index].point.x - rad) <= LOWORD(lParam)) &&

(abs(tm.points[index].point.x + rad) >= LOWORD(lParam)) &&

(abs(tm.points[index].point.y - rad)) <= HIWORD(lParam) &&

(abs(tm.points[index].point.y + rad)) >= HIWORD(lParam) &&

temp)

{

temp = !temp;

//MessageBox(NULL, NULL, NULL, NULL);

InvalidateRect(hWnd, NULL, true);   

break;

}

 

else if((abs(tm.points[i].point.x - LOWORD(lParam)) <= rad) &&

(abs(tm.points[i].point.y - HIWORD(lParam))) <= rad &&

temp)

{

 

crossLine(tm, line1, line2, isFail, mas1, mas2, lParam);

 

if(!isFail && tm.map[index][i] != 0)

isFail = true;

 

 

if(!isFail){

temp = !temp;

 

////////////////// map recording

if(changePlayer == FIRST){

tm.map[index][i] = FIRST;

tm.map[i][index] = FIRST;

}

else if(changePlayer == SECOND)

{

tm.map[index][i] = SECOND;

tm.map[i][index] = SECOND;

}

 

for(int i=0; i<::trans; i++)

if(tm.map[index][i] == changePlayer)

for(int j=i; j<::trans; j++)

if((tm.map[index][i] == tm.map[index][j]) && tm.map[i][j] == changePlayer){

changePlayer == FIRST ? (wsprintf(text, "Blue Player is winner!")) :

wsprintf(text, "Red Player is winner!");

MessageBox(hWnd, text, "Winner!", MB_OK);

DialogBox(hInst, MAKEINTRESOURCE(IDD_AGAIN), hWnd, AgainDialog);

if(!trans)

DestroyWindow(hWnd);

if(trans)

goto xxx;

}

 

/////////////////// changePlayer

if(changePlayer == FIRST)

changePlayer = SECOND;

else

changePlayer = FIRST;

 

InvalidateRect(hWnd, NULL, true);

}

}

}  

break;

 

case WM_MOUSEMOVE:

break;

 

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

if(changePlayer == FIRST)

hOldPen = (HPEN)SelectObject(hdc, redPen);

else if(changePlayer == SECOND)

hOldPen = (HPEN)SelectObject(hdc, bluePen);   

 

if(temp)

{

MoveToEx(hdc, startPoint.x, startPoint.y, NULL);

LineTo(hdc, endPoint.x, endPoint.y);

}

 

SelectObject(hdc, hOldPen);

 

///////////////////////////////// PointDraw

for(int i = 0; i < tm.pointCount; i++)

{

Ellipse(hdc, tm.points[i].point.x - rad, tm.points[i].point.y - rad,

tm.points[i].point.x + rad, tm.points[i].point.y + rad);

SetPixel(hdc, tm.points[i].point.x, tm.points[i].point.y, NULL);

}

 

///////////////////////////////// LineDraw

for(int i=0; i<::trans; i++)

for(int j=0; j<::trans; j++)

{

if(tm.map[i][j]){

 

if(tm.map[i][j] == FIRST)

{

hLinePen = (HPEN)CreatePen(PS_SOLID, 3, RGB(255,0,0));

}

else

{

if(tm.map[i][j] == SECOND)

hLinePen = (HPEN)CreatePen(PS_SOLID, 3, RGB(0,0,255));

}

 

SelectObject(hdc, (HPEN)hLinePen);

MoveToEx(hdc, tm.points[i].point.x, tm.points[i].point.y, NULL);

LineTo(hdc, tm.points[j].point.x, tm.points[j].point.y);

 

}

}

 

 

// TODO: Add any drawing code here...

EndPaint(hWnd, &ps);

break;

 

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

 

INT_PTR CALLBACK InputParam(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

char EditText[10] = "";

 

switch (message)

{

case WM_INITDIALOG:

return (INT_PTR)TRUE;

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK)

{

GetDlgItemText(hDlg, IDC_PARAM, EditText, sizeof(EditText));

::trans = atoi(EditText);

EndDialog(hDlg, LOWORD(wParam));

return (INT_PTR)TRUE;

}

break;

}

return (INT_PTR)FALSE;

}

 

INT_PTR CALLBACK AgainDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

switch (message)

{

case WM_INITDIALOG:

return (INT_PTR)TRUE;

 

case WM_COMMAND:

if (LOWORD(wParam) == IDC_BYES)

{

::trans = 1;

EndDialog(hDlg, LOWORD(wParam));

return (INT_PTR)TRUE;

}

else if (LOWORD(wParam) == IDC_BNO)

{

::trans = 0;

EndDialog(hDlg, LOWORD(wParam));

return (INT_PTR)TRUE;

}

break;

}

 

return (INT_PTR)FALSE;

}

 

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

UNREFERENCED_PARAMETER(lParam);

switch (message)

{

case WM_INITDIALOG:

return (INT_PTR)TRUE;

 

case WM_COMMAND:

if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, LOWORD(wParam));

return (INT_PTR)TRUE;

}

break;

}

return (INT_PTR)FALSE;

}

 

 

 

 

 

 

4 ТЕСТИРОВАНИЕ ПРОГРАММЫ И ИНСТРУКЦИЯ ПОЛЬЗОВАТЕЛЯ

 

4.1 Тестирование программы

Функциональное тестирование данного  программного обеспечения показало соответствие его пользовательским требованиям, так как набор изначально поставленных пользовательских задач выполняется на необходимом уровне. Модульное тестирование показало что отдельные функции, модули полностью работоспособны и не приводят к регрессии программы.

Разработанная в рамках курсовой работы программа не чувствительна к техническим характеристикам современных ПК, т.к. для её работы требуется 300 Кб свободной памяти на жестком диске и минимальный размер оперативной памяти 4 Мб. Требование к операционной системе:  Windows XP, Windows Vista, Windows 7.

 

4.2 Инструкция пользователя

После запуска приложения вы увидите  перед собой следующие окно:

Рис. 4.1 – Начальное окно

Для того чтобы начать игру, следует  в меню выбрать пункт «File -> Start» . После этого вы увидите диалоговое окно, которое попросит вас ввести количество точек в игре:

Рис. 4.2 – Ввод количества точек

 

После этого вы увидите хаотично расположенные точки внутри поля:

Рис. 4.3 – Начальное положение  точек в игре

 

После нажатия на какую-либо точку, она становится активной:

Рис. 4.4 – Активация точки

 

После этого игрок должен соединить  данную точку с какой-либо другой:

Рис. 4.5 – Соединение

 

Игрок проигрывает тогда, когда  он соберет треугольник из своих  цветов:

 

Рис. 4.6 – Победа красного игрока

После этого предлагается продолжить игру или покинуть:

Рис. 4.7 – Снова?

 

ВЫВОД

 

В процессе выполнения курсовой работы была разработана программа, реализующая игру Сима с безграничным числом точек. Программа была написана при помощи интегрированной среды разработки Visual C++. Программа соответствует всем функциональным требованиям, заданным на курсовое проектирование.

Тестирование программы показало соответствие её пользовательским требованиям, т.к. набор изначально поставленных пользовательских задач выполняется на необходимом уровне. Модульное тестирование показало что отдельные функции, модули полностью работоспособны и не приводят к регрессии программы.

Проект не содержит недоработок  и полностью отвечает требованиям, заданным на курсовое проектирование. Но, несмотря на это, всегда есть место для усовершенствования. В дальнейшем можно будет разработать алгоритм игры против ИИ,  создать звуковое сопровождение во время игры.

Исходя из выше сказанного, можно  сделать вывод, что задание на курсовое проектирование было полностью выполнено.

 

СПИСОК ИСПОЛЬЗОВАНЫХ  ИСТОЧНИКОВ

 

1. Келецкий Я. Энциклопедия языка  Си/ Пер. с англ. - М.: Мир, 1992. - 687с.

2. Керниган Б., Ричи Д., Фьюер А. Язык программирования Си. Задачи по языку С / Пер. с англ. - М.: Финансы и статистика, 1985. - 279с.

3. Петзольд Ч. Программирование  под Windows 95. В двух книгах: BHV - Санкт - Петербург, 1997, silt.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ПРИЛОЖЕНИЕ


Информация о работе Разработка программы на языке С++ с использованием функций WinAPI: < Игра Сима >