
5 Текст программы
Текст программы смотрите в приложении А
6 Примеры выполнения программы
Примеры выполнения программы приведены на рисунках 1, 2, 3, 4.
Рисунок 1 – Вид окна программе при запуске
Рисунок 2 – Победа игрока 1
Рисунок
2 – Победа игрока 2
Рисунок 3 – Выбор цвета крестиков/ноликов
Рисунок 4 - Палитра цветов
Приложение А
Файл ChildView.cpp:
//Модуль, содержащий основной алгоритм работы программы
#include "stdafx.h"
#define MAX_LOADSTRING 100
const int n = 20;
HINSTANCE hInst; // текущий экземпляр
TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка
TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
HINSTANCE hInstance, help;
int counter, x, y, x1, y1, win=-1;
int mas[n][n], stats[3];
int*p[n];
bool myTurn = true, newGame;
char stat[100];
COLORREF crossColor = RGB(0,255,0);//цвет крестиков
COLORREF nullColor = RGB(0,0,255);//цвет ноликов
// Отправить объявления функций, включенных в этот модуль кода:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK About1(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK SettingsDlgProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
for(int i=0; i<3; i++)
stats[i] = 0;
for(int i=0; i<n; i++)
p[i] = (int*)&mas[i];
newGame = false;
counter = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mas[i][j] = 0;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: разместите код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_NOUGHTS_AND_CROSSES, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Выполнить инициализацию приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_NOUGHTS_AND_CROSSES));
// Цикл основного сообщения:
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_NOUGHTS_AND_CROSSES));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_NOUGHTS_AND_CROSSES);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 100, 680, 600, 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;
static RECT rt, rect;
static HPEN hF,hOldF,hS,hOldS, hLine, hOldLine;
switch (message)
{
case WM_CREATE:
break;
case WM_SIZE:
x = LOWORD (lParam) / n;
y = HIWORD (lParam) / n;
break;
case WM_LBUTTONDOWN:
x1 = LOWORD (lParam) / x;
y1 = HIWORD (lParam) / y;
if(mas[x1][y1] == 0)
{
if(myTurn)
{
mas[x1][y1] = 1;
myTurn = false;
}
else
{
mas[x1][y1] = 2;
myTurn = true;
}
counter++;
}
win = fwinner(p, x1, y1, n);
rect.left = x1 * x;
rect.top = y1 * y;
rect.right = (x1 + 1) * x;
rect.bottom = (y1 + 1) * y;
InvalidateRect (hWnd, &rect, FALSE) ;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Разобрать выбор в меню:
switch (wmId)
{
case ID_STATS:
wsprintf(stat,"\nПобед 1го игрока - %d;\nПобед 2го игрока - %d;\nНичей - %d;",stats[0],stats[1],stats[2]);
MessageBox(hWnd,stat,"Статистика",NULL);
break;
case ID_NEWGAME:
if(newGame == false)
newGame = true;
else
{
newGame = false;
counter = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mas[i][j] = 0;
win = -1;
myTurn = true;
}
InvalidateRect (hWnd, NULL, TRUE);
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, About1);
break;
case ID_SETTINGS:
DialogBox(hInst, MAKEINTRESOURCE(IDD_SETTINGS),hWnd,SettingsDlgProc);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hF = CreatePen(PS_SOLID,2,crossColor);
hS = CreatePen(PS_SOLID,2,nullColor);
hLine = CreatePen(PS_SOLID,2,RGB(0,0,0));
hOldLine =(HPEN)SelectObject(hdc,hLine);
hOldF =(HPEN)SelectObject(hdc,hF);
hOldS =(HPEN)SelectObject(hdc,hS);
GetClientRect(hWnd, &rt);
TEXTMETRIC tm;
GetTextMetrics(hdc,&tm);
if(newGame)
{
SelectObject(hdc,hLine);
for(int i=1; i<=n; i++)
for(int j=1; j<n; j++)
Rectangle(hdc, rt.right/n*(i-1), (j-1)*rt.bottom/n, i*rt.right/n, j*rt.bottom/n);
wsprintf(stat,"Побед 1го игрока - %d; Побед 2го игрока - %d; Ничей - %d;",stats[0],stats[1],stats[2]);
TextOut(hdc, rt.right/n, (n-0.75)*rt.bottom/n, stat, strlen(stat));
for (x1 = 0 ; x1 < n ; x1++)
for (y1 = 0 ; y1 < n-1 ; y1++)
{
if( mas[x1][y1] == 1)
{
SelectObject(hdc,hF);
MoveToEx (hdc, x1*x, y1*y, NULL);
LineTo (hdc,(x1+1)*x,(y1+1)*y);
MoveToEx (hdc, x1 * x,(y1+1)*y, NULL);
LineTo (hdc,(x1+1) * x, y1 * y);
}
if(mas[x1][y1] == 2)
{
SelectObject(hdc,hS);
Ellipse(hdc, x1*x, y1*y,(x1+1)*x,(y1+1)*y);
}
}
if(win == 1)
{
MessageBox(hWnd,"Победил 1 игрок","Победа!",NULL);
newGame = false;
counter = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mas[i][j] = 0;
win = -1;
myTurn = true;
stats[0]++;
InvalidateRect (hWnd, NULL, TRUE);
}
else if(win == 0)
{
MessageBox(hWnd,"Победил 2 игрок","Победа!",NULL);
newGame = false;
counter = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mas[i][j] = 0;
win = -1;
myTurn = true;
stats[1]++;
InvalidateRect (hWnd, NULL, TRUE);
}
if(counter == n*n)
{
MessageBox(hWnd,"Боевая ничья, пожмите друг-другу руки!;)","Ничья!",NULL);
newGame = false;
counter = 0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mas[i][j] = 0;
win = -1;
myTurn = true;
stats[2]++;
InvalidateRect (hWnd, NULL, TRUE);
}
}
SelectObject(hdc,hOldF);
DeleteObject(hF);
SelectObject(hdc,hOldS);
DeleteObject(hS);
SelectObject(hdc,hOldLine);
DeleteObject(hLine);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//Нaстройки
BOOL CALLBACK CALLBACK SettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
HDC hdcSet;
PAINTSTRUCT ps;
COLORREF crFirst, crSecond;
static CHOOSECOLOR cc;//структура "выбора" цвета
static COLORREF CustClr[16];//массив структур
switch (uMsg)
{
case WM_INITDIALOG:
//инициализируем станд. окно выбора цвета
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hDlg;
cc.lpCustColors = (LPDWORD)CustClr;
cc.Flags = CC_FULLOPEN || CC_RGBINIT;
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_CHOOSE1:
if(ChooseColor(&cc))crossColor=cc.rgbResult;
break;
case IDC_CHOOSE2:
if(ChooseColor(&cc))nullColor=cc.rgbResult;
break;
case IDC_OK:
EndDialog(hDlg,0);
break;
}
InvalidateRect(hDlg,NULL,TRUE); //переисовываем модальное окно, чтоб квадратики были выбраного цвета
break;
case WM_PAINT://здесь выводяться 2 квадратика с соотв. цветами
crFirst = crossColor;
crSecond = nullColor;
hdcSet=BeginPaint(hDlg,&ps);
HBRUSH hBrushF,hOldBrush, hBrushS;
hBrushF=CreateSolidBrush(crFirst);
hBrushS=CreateSolidBrush(crSecond);
hOldBrush = (HBRUSH)SelectObject(hdcSet,hBrushF);
SelectObject(hdcSet,hBrushF);
Rectangle(hdcSet,140,50,160,70);
SelectObject(hdcSet,hBrushS);
Rectangle(hdcSet,140,87,160,107);
SelectObject(hdcSet,hOldBrush);
DeleteObject(hBrushF);
EndPaint(hDlg,&ps);
break;
}
return FALSE;
}
// Обработчик сообщений для окна "О создателе".
BOOL CALLBACK About1(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
EndDialog(hDlg, LOWORD(wParam));
break;
}
return FALSE;
}
#include "stdafx.h"
int fwinner(int**mas, int x1, int y1, int n)
{
int m, i;
//Победа по горизонтали
if(x1>4 && x1<n-4)
{
m = 5;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1] == 1 && mas[x1-i+1][y1] == 1 && mas[x1-i+2][y1] == 1 && mas[x1-i+3][y1] == 1 && mas[x1-i+4][y1] == 1)
return 1;
else if(mas[x1-i][y1] == 2 && mas[x1-i+1][y1] == 2 && mas[x1-i+2][y1] == 2 && mas[x1-i+3][y1] == 2 && mas[x1-i+4][y1] == 2)
return 0;
}
}
else
{
if(x1<5)
{
m = x1+1;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1] == 1 && mas[x1-i+1][y1] == 1 && mas[x1-i+2][y1] == 1 && mas[x1-i+3][y1] == 1 && mas[x1-i+4][y1] == 1)
return 1;
else if(mas[x1-i][y1] == 2 && mas[x1-i+1][y1] == 2 && mas[x1-i+2][y1] == 2 && mas[x1-i+3][y1] == 2 && mas[x1-i+4][y1] == 2)
return 0;
}
}
else
{
m = n-x1;
for(i=0; i<m; i++)
{
if(mas[x1+i][y1] == 1 && mas[x1+i-1][y1] == 1 && mas[x1+i-2][y1] == 1 && mas[x1+i-3][y1] == 1 && mas[x1+i-4][y1] == 1)
return 1;
else if(mas[x1+i][y1] == 2 && mas[x1+i-1][y1] == 2 && mas[x1+i-2][y1] == 2 && mas[x1+i-3][y1] == 2 && mas[x1+i-4][y1] == 2)
return 0;
}
}
}
//Победа по вертикали
if(y1>4 && y1<n-4)
{
m = 5;
for(i=0; i<m; i++)
{
if(mas[x1][y1-i] == 1 && mas[x1][y1-i+1] == 1 && mas[x1][y1-i+2] == 1 && mas[x1][y1-i+3] == 1 && mas[x1][y1-i+4] == 1)
return 1;
else if(mas[x1][y1-i] == 2 && mas[x1][y1-i+1] == 2 && mas[x1][y1-i+2] == 2 && mas[x1][y1-i+3] == 2 && mas[x1][y1-i+4] == 2)
return 0;
}
}
else
{
if(y1<5)
{
m = y1+1;
for(i=0; i<m; i++)
{
if(mas[x1][y1-i] == 1 && mas[x1][y1-i+1] == 1 && mas[x1][y1-i+2] == 1 && mas[x1][y1-i+3] == 1 && mas[x1][y1-i+4] == 1)
return 1;
else if(mas[x1][y1-i] == 2 && mas[x1][y1-i+1] == 2 && mas[x1][y1-i+2] == 2 && mas[x1][y1-i+3] == 2 && mas[x1][y1-i+4] == 2)
return 0;
}
}
else
{
m = n-x1;
for(i=0; i<m; i++)
{
if(mas[x1][y1+i] == 1 && mas[x1][y1-i+1] == 1 && mas[x1][y1+i-2] == 1 && mas[x1][y1+i-3] == 1 && mas[x1][y1+i-4] == 1)
return 1;
else if(mas[x1][y1+i] == 2 && mas[x1][y1-i+1] == 2 && mas[x1][y1+i-2] == 2 && mas[x1][y1+i-3] == 2 && mas[x1][y1+i-4] == 2)
return 0;
}
}
}
//Победа по главной диогонали
if(x1>4 && x1<n-4)
{
m = 5;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1-i] == 1 && mas[x1-i+1][y1-i+1] == 1 && mas[x1-i+2][y1-i+2] == 1 && mas[x1-i+3][y1-i+3] == 1 && mas[x1-i+4][y1-i+4] == 1)
return 1;
else if(mas[x1-i][y1-i] == 2 && mas[x1-i+1][y1-i+1] == 2 && mas[x1-i+2][y1-i+2] == 2 && mas[x1-i+3][y1-i+3] == 2 && mas[x1-i+4][y1-i+4] == 2)
return 0;
}
}
else
{
if(x1<5)
{
m = x1+1;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1-i] == 1 && mas[x1-i+1][y1-i+1] == 1 && mas[x1-i+2][y1-i+2] == 1 && mas[x1-i+3][y1-i+3] == 1 && mas[x1-i+4][y1-i+4] == 1)
return 1;
else if(mas[x1-i][y1-i] == 2 && mas[x1-i+1][y1-i+1] == 2 && mas[x1-i+2][y1-i+2] == 2 && mas[x1-i+3][y1-i+3] == 2 && mas[x1-i+4][y1-i+4] == 2)
return 0;
}
}
else
{
m = n-x1;
for(i=0; i<m; i++)
{
if(mas[x1+i][y1+i] == 1 && mas[x1+i-1][y1+i-1] == 1 && mas[x1+i-2][y1+i-2] == 1 && mas[x1+i-3][y1+i-3] == 1 && mas[x1+i-4][y1+i-4] == 1)
return 1;
else if(mas[x1+i][y1+i] == 2 && mas[x1+i-1][y1+i-1] == 2 && mas[x1+i-2][y1+i-2] == 2 && mas[x1+i-3][y1+i-3] == 2 && mas[x1+i-4][y1+i-4] == 2)
return 0;
}
}
}
//Победа по побочной диогонали
if(x1>4 && x1<n-4)
{
m = 5;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1+i] == 1 && mas[x1-i+1][y1+i-1] == 1 && mas[x1-i+2][y1+i-2] == 1 && mas[x1-i+3][y1+i-3] == 1 && mas[x1-i+4][y1+i-4] == 1)
return 1;
else if(mas[x1-i][y1+i] == 2 && mas[x1-i+1][y1+i-1] == 2 && mas[x1-i+2][y1+i-2] == 2 && mas[x1-i+3][y1+i-3] == 2 && mas[x1-i+4][y1+i-4] == 2)
return 0;
}
}
else
{
if(x1<5)
{
m = x1+1;
for(i=0; i<m; i++)
{
if(mas[x1-i][y1+i] == 1 && mas[x1-i+1][y1+i-1] == 1 && mas[x1-i+2][y1+i-2] == 1 && mas[x1-i+3][y1+i-3] == 1 && mas[x1-i+4][y1+i-4] == 1)
return 1;
else if(mas[x1-i][y1+i] == 2 && mas[x1-i+1][y1+i-1] == 2 && mas[x1-i+2][y1+i-2] == 2 && mas[x1-i+3][y1+i-3] == 2 && mas[x1-i+4][y1+i-4] == 2)
return 0;
}
}
else
{
m = n-x1;
for(i=0; i<m; i++)
{
if(mas[x1+i][y1-i] == 1 && mas[x1+i-1][y1-i+1] == 1 && mas[x1+i-2][y1-i+2] == 1 && mas[x1+i-3][y1-i+3] == 1 && mas[x1+i-4][y1-i+4] == 1)
return 1;
else if(mas[x1+i][y1-i] == 2 && mas[x1+i-1][y1-i+1] == 2 && mas[x1+i-2][y1-i+2] == 2 && mas[x1+i-3][y1-i+3] == 2 && mas[x1+i-4][y1-i+4] == 2)
return 0;
}
}
}
return 2;
}
ВЫВОДЫ
В ходе выполнения курсовой работы был разработан алгоритм действий компьютерного игрока при игре в крестики-нолики пять в ряд на бесконечном поле.
В ходе выполнения работы удалось добиться достаточно сильного уровня игры на сложности профессионал.
Разработанный алгоритм был реализован на языке C++ на платформе Microsoft Visual Studio 2008.
СПИСОК ЛИТЕРАТУРЫ
Арчер Т., Уайтчепел Э. Visual C++ .NET. Библия пользователя — Вильямс, 2007.
Либерти Д., Джонс Б. Освой самостоятельно C++ за 21 день. — Вильямс, 2007.
Материалы сайта http://www.firststeps.ru/mfc/steps.
Подбельский В.В. Язык C++. — М.:"Финансы и статистика", 2003.