Реферат по предмету "Информатика, программирование"


Аркадна гра "гольф" з елементами трьохвимірної поверхні

Міністерство освіти інауки УкраїниФАКУЛЬТЕТ ІНФОРМАТИКИ
КАФЕДРАРеєстраційний №________
Дата ___________________КУРСОВА РОБОТА
Тема:
аркаднагра“гольф” з елементами трьох-вимірноїповерхніРекомендована до захисту
“____” __________ 2007р.
Робота захищена
“____” __________ 2007р.
з оцінкою
_____________________
Підписи членів комісії

ЗмістВступТеоріяПрактична частинаВисновкиЛітература

Вступ
Поставлена задача написати просту аркадну гру “гольф” зелементами трьох-вимірної поверхні. Для створення актуального програмногопродукту на цю тематику був обраний шлях написання універсальної програми – якаб могла запускатись з мінімальними потребами до пам”яті та інших ресурсів. Томув якості засобу розробки був обраний старий компілятор BORLAND C++ 3.0 і прийняте рішення невикористовувати графічні функції Windows.

ТеоріяЗасоби організації збереження іобробки даних для графічних програм/> Методи організації і збереження лінійних списків
Лінійний список — це кінцевапослідовність однотипних елементів (вузлів), можливо, з повтореннями. Кількістьелементів у послідовності називається довжиною списку, причому довжина впроцесі роботи програми може змінюватися.
Лінійний список F, що складається зелементів D1,D2,...,Dn, записують у виді послідовностізначень укладеної вкутові дужки F=, або представляють графічно.
Наприклад,F1=,F2=, F3=. Довжина списків F1, F2,F3 дорівнює відповідно 3,6,0.
При роботі зі списками на практицінайчастіше приходиться виконувати наступні операції:
— знайти елемент із заданою властивістю;
— визначити перший елемент у лінійномусписку;
— уставити додатковий елемент до абопісля зазначеного вузла;
— виключити визначений елемент зісписку;
— упорядкувати вузли лінійного списку увизначеному порядку.
У реальних мовах програмування немаєякої-небудь структури даних для представлення лінійного списку так, щоб усізазначені операції над ним виконувалися в однаковому ступені ефективно. Томупри роботі з лінійними списками важливим є представлення використовуваних упрограмі лінійних списків таким чином, щоб була забезпечена максимальнаефективність і за часом виконання програми, і по обсязі необхідної пам'яті.
Методи збереження лінійних списківрозділяються на методи послідовного і зв'язаного збереження. Розглянемонайпростіші варіанти цих методів для списку з цілими значеннями F=.
При послідовному збереженні елементилінійного списку розміщаються в масиві d фіксованих розмірів, наприклад, 100, ідовжина списку вказується в перемінної l, тобто в програмі необхідно матиоголошення виду
float d[100]; int l;
Розмір масиву 100 обмежує максимальнірозміри лінійного списку. Список F у масиві d формується так:
d[0]=7; d[1]=10; l=2;
При зв'язаному збереженні як елементизбереження використовуються структури, зв'язані по одній з компонентів уланцюжок, на початок якої (першу структуру) указує покажчик dl. Структураутворюючий елемент збереження, повинна крім відповідного елемента спискумістити і покажчик на сусідній елемент збереження.
Опис структури і покажчика в цьомувипадку може мати вид:
typedef struct snd /* структура елемента збереження */
{ float val; /* елемент списку */
struct snd *n; /* покажчик на елемент збереження */
} DL;
DL *p; /* покажчик поточного елемента */
DL *dl; /* покажчик на початок списку */
Для виділення пам'яті під елементизбереження необхідно користуватися функцією malloc(sizeof(DL)) абоcalloc(l,sizeof(DL)). Формування списку в зв'язаному збереженні можездійснюється операторами:
p=malloc(sizeof(DL));
p->val=10; p->n=NULL;
dl=malloc(sizeof(DL));
dl->val=7; dl->n=p;
В останньому елементі збереження (кінецьсписку) покажчик на сусідній елемент має значення NULL. Одержуваний списокзображений на мал.2. /> Операції зі списками при послідовному збереженні
При виборі методу збереження лінійногосписку варто враховувати, які операції будуть виконуватися і з якою частотою,час їхнього виконання й обсяг пам'яті, необхідний для збереження списку.
Нехай мається лінійний список з цілимизначеннями і для його збереження використовується масив d (з числом елементів100), а кількість елементів у списку вказується перемінної l. Реалізаціязазначених раніше операцій над списком представляється наступними фрагментамипрограм які використовують оголошення:
 float d[100];
int i,j,l;
1) печатка значення першого елемента (вузла)
if (іl) printf("\n немає елемента");
else printf(«d[%d]=%f »,і,d[і]);
2) видалення елемента, що випливає за i-тым вузлом
if (і>=l) printf("\n немає наступного ");
l--;
for (j=і+1;j=l) printf("\n немає сусіда");
else printf("\n %d %d",d[і-1],d[і+1]);
4) додавання нового елемента new за i-тым вузлом
if (і==l || і>l) printf("\n не можна додати");
else
{ for (j=l; j>i+1; j--) d[j+1]=d[j];
d[i+1]=new; l++;
}
5) часткове упорядкування списку з елементами ДО1, ДО2,..., Кl у
список K1',K2',...,Ks,K1,Kt",...,Kt", s+t+1=l так, щоб K1'= K1.
 
{ int t=1;
float aux;
for (i=2; i
t++;
d[i]=aux;
}
}
Кількість дій Q, необхідних длявиконання приведених операцій над списком, визначаєтьсяспіввідношеннями: дляоперацій 1 і 2 — Q=1; для операцій 3,4 — Q=l; для операції 5 — Q=l*l.
Помітимо, що взагалі операцію 5 можнавиконати при кількості дій порядку l, а операції 3 і 4 для включення івиключення елементів наприкінці списку, що часто зустрічаються при роботі зістеками, — при кількості дій 1.
Більш складна організація операційпотрібно при розміщенні в масиві d декількох списків, або при розміщенні спискубез прив'язки його початку до першого елемента масиву. /> Операції зі списками при зв'язному збереженні
 
При простому зв'язаному збереженні коженелемент списку являє собою структуру nd, що складається з двох елементів: val — призначений для збереження елемента списку, n — для покажчика на структуру, щомістить наступний елемент списку. На перший елемент списку вказує покажчик dl.Для всіх операцій над списком використовується опис:
 typedef struct nd
{ float val;
struct nd * n; } ND;
int i,j;
ND * dl, * r, * p;
Для реалізації операцій можутьвикористовуватися наступні фрагменти програм:
1) печатка значення i-го елемента
 r=dl;j=1;
while(r!=NULL && j++n ;
if (r==NULL) printf("\n немає вузла %d ",i);
else printf("\n елемент %d дорівнює %f ",i,r->val);
2) печатка обох сусідів вузла(елемента),обумовленого покажчиком p (див. мал.4)
 if((r=p->n)==NULL) printf("\n немає сусіда праворуч");
else printf("\n сусід праворуч %f", r->val);
if(dl==p) printf("\n немає сусіда ліворуч" );
else { r=dl;
while( r->n!=p ) r=r->n;
printf("\n лівий сусід %f", r->val);
}
3) видалення елемента, що випливає завузлом, на який указує р (див. мал.5)
 if ((r=p->n)==NULL) printf("\n немає наступного");
p->n=r->n; free(r->n);
4) вставка нового вузла зі значенням newза елементом, визначеним покажчиком р (див. мал.6)
r=malloc(1,sizeof(ND));
r->n=p->n; r->val=new; p->n=r;
5) часткове упорядкування списку впослідовність значень, s+t+1=l, так що K1'=K1; після упорядкування покажчик vуказує на елемент K1' (див. мал.7)
 ND *v;
float k1;
k1=dl->val;
r=dl;
while( r->n!=NULL )
{ v=r->n;
if (v->valn=v->n;
v->n=dl;
dl=v;
}
else r=v;
}
Кількість дій, необхідних для виконаннязазначених операцій над списком у зв'язаному збереженні, оцінюєтьсяспіввідношеннями: для операцій 1 і 2 — Q=l; для операцій 3 і 4 — Q=1; дляоперації 5 — Q=l. /> Організація двузв‘язних списків
Зв'язане збереження лінійного спискуназивається списком із двома зв'язками або двузв‘язним списком, якщо коженелемент збереження має два компоненти покажчика (посилання на попередній інаступний елементи лінійного списку).
У програмі двузв‘язний список можнареалізувати за допомогою описів:
 typedef struct ndd
{ float val; /* значення елемента */
struct ndd * n; /* покажчик на наступний елемент */
struct ndd * m; /* покажчик на попередній елемент */
} NDD;
NDD * dl, * p, * r;
Графічна інтерпретація методу зв'язаногозбереження списку F= як списку з двома зв'язками приведена намал.8.
Вставка нового вузла зі значенням new заелементом, обумовленим покажчиком p, здійснюється за допомогою операторів:
 r=malloc(NDD);
r->val=new;
r->n=p->n;
(p->n)->m=r;
p->=r;
 Видалення елемента, що випливає завузлом, на який указує p
 p->n=r;
p->n=(p->n)->n;
( (p->n)->n )->m=p;
free(r);
 Зв'язане збереження лінійного спискуназивається циклічним списком, якщо його останній указує на перший елемент, апокажчик dl — на останній елемент списку.
Схема циклічного збереження спискуF= приведена на мал.9.
При рішенні конкретних задач можутьвиникати різні види зв'язаного збереження.
Нехай на вході задана послідовністьцілих чисел B1,B2,...,Bn з інтервалу від 1 до 9999, і нехай Fi (1
 При рішенні задачі в кожен момент часумаємо упорядкований список Fi і при введенні елемента Bi+1 уставляємо його впотрібне місце списку Fi, одержуючи упорядкований список Fi+1. Тут можливі триваріанти: у списку немає елементів; число вставляється в початок списку; числовставляється в кінець списку. Щоб уніфікувати всі можливі варіанти, початковийсписок організуємо як зв'язаний список із двох елементів .
 Розглянемо програму рішення поставленоїзадачі, у якій покажчики dl, r, p, v мають наступне значення: dl указує початоксписку; p, v — два сусідніх вузли; r фіксує вузол, що містить чергове введенезначення in.
 #include
#include
typedef struct str1
{ float val;
struct str1 *n; } ND;
main()
{ ND *arrange(void);
ND *p;
p=arrange();
while(p!=NULL)
{
printf("\n %f ",p->val);
p=p->n;
}
}
ND *arrange() /* формування упорядкованого списку */
{ ND *dl, *r, *p, *v;
float in=1;
char *is;
dl=malloc(sizeof(ND));
dl->val=0; /* перший елемент */
dl->n=r=malloc(sizeof(ND));
r->val=10000; r->n=NULL; /* останній елемент */
while(1)
{
scanf(" %s",is);
if(* is=='q') break;
in=atof(is);
r=malloc(sizeof(ND));
r->val=in;
p=dl;
v=p->n;
while(v->valn;
}
r->n=v;
p->n=r;
}
return(dl);
}/> Стеки і черги
У залежності від методу доступу доелементів лінійного списку розрізняють різновиду лінійних списків називаністеком, чергою і двосторонньою чергою.
Стек — це кінцева послідовність деякиходнотипних елементів — скалярних перемінних, масивів, структур або об'єднань,серед яких можуть бути й однакові. Стік позначається у виді: S= і представляєдинамічну структуру даних; її кількість елементів заздалегідь не вказується й упроцесі роботи, як правило змінюється. Якщо в стеці елементів ні, то вінназивається порожнім і позначається S=.
Припустимими операціями над стеком є:
— перевірка стека на порожнечуS=,
— додавання нового елемента Sn+1 укінець стека — перетворення у ;
— вилучення останнього елемента зі стека- перетворення у ;
— доступ до його останнього елемента Sn,якщо стік не порожній.
Таким чином, операції додавання івидалення елемента, а також доступу до елемента виконуються тільки наприкінцісписку. Стік можна представити як стопку книг на столі, де додавання або узяттянової книги можливо тільки зверху.
Черга — це лінійний список, де елементивіддаляються з початку списку, а додаються наприкінці списку (як звичайна чергав магазині).
Двостороння черга — це лінійний список,у якого операції додавання і видалення елементів і доступу до елементів можливіяк спочатку так і наприкінці списку. Таку чергу можна представити якпослідовність книг на полку, так що доступ до них можливий з обох кінців.
Реалізація стеков і черг у програмі можебути виконана у виді послідовного або зв'язаного збереження. Розглянемоприклади організації стека цими способами.
Однієї з форм представлення виражень єпольський інверсний запис, що задає вираження так, що операції в ньомузаписуються в порядку виконання, а операнди знаходяться безпосередньо передоперацією.
Наприклад, вираз
(6+8)*5-6/2
у польському інверсному записі маєвигляд
6 8 + 5 * 6 2 / —
Особливість такого запису полягає втому, що значення вираження можна обчислити за один перегляд запису ліворучправоруч, використовуючи стек, що до цього повинний бути порожній. Кожне новечисло заноситься в стек, а операції виконуються над верхніми елементами стека,заміняючи ці елементи результатом операції. Для приведеного вираження динаміказміни стека буде мати вигляд
S = ; ; ; ; ; ;
; ; ; .
Нижче приведена функція eval, щообчислює значення вираження, заданого в масиві m у формі польського інверсногозапису, причому m[i]>0 означає ненегативне число, а значення m[i]
float eval (float *m, int l) { int p,n,i; float stack[50],c;
for(i=0; i
Розглянемо іншу задачу. Нехай потрібноввести деяку послідовність символів, що закінчується крапкою, і надрукувати неїв зворотному порядку (тобто якщо на вході буде «ABcEr-1.» те навиході повинне бути «1-rEcBA»). Представлена нижче програма спочаткууводить усі символи послідовності, записуючи них у стек, а потім уміст стекадрукується в зворотному порядку. Це основна особливість стека — чим пізнішеелемент занесений у стек, тим раніш він буде витягнутий зі стека. Реалізаціястека виконана в зв'язаному збереженні за допомогою покажчиків p і q на тип,іменований ім'ям STACK.
 #include
typedef struct st /* оголошення типу STACK */
{ char ch;
struct st *ps; } STACK;
main()
{ STACK *p,*q;
char a;
p=NULL;
do /* заповнення стека */
{ a=getch();
q=malloc(sizeof(STR1));
q->ps=p; p=q;
q->ch=a;
} while(a!='.');
do /* печатка стека */
{ p=q->ps;free(q);q=p;
printf("%c",p->ch);
} while(p->ps!=NULL);
}/> Стиснуте й індексне збереження лінійних списків
При збереженні великих обсягівінформації у формі лінійних списків небажано зберігати елементи з однаковимзначенням, тому використовують різні методи стиску списків.
Стиснуте збереження. Нехай у списку B=кілька елементів мають однакове значення V, а список В'= виходить з B заміноюкожного елемента Ki на пари Ki'=(і,Ki). Нехай далі B"= — підсписок В', щовиходить викреслюванням усіх пар Ki=(і,V). Стиснутим збереженням У є методзбереження В", у якому елементи зі значенням V. Розрізняють послідовнестиснуте збереження і зв'язане стиснуте збереження. Наприклад, для списку B=,що містить кілька вузлів зі значенням Х, послідовного стиснутого і зв'язанестиснуте збереження, з умовчуванням елементів зі значенням Х, представлені намал.22,23.
Достоїнство стиснутого збереження спискупри великому числі елементів зі значенням V полягає в можливості зменшенняобсягу пам'яті для його збереження.
Пошук i-го елемента в зв'язаномустиснутому збереженні здійснюється методом повного перегляду, при послідовномузбереженні — методом бінарного пошуку.
Переваги і недоліки послідовногостиснутого і зв'язаного стиснутого аналогічні перевагам і недолікампослідовного і зв'язаного збереження.
Розглянемо наступну задачу. На входізадані дві послідовності цілих чисел M=, N=, причому 92% елементівпослідовності М дорівнюють нулеві. Скласти програму для обчислення сумидобутків Mi * Ni, і=1,2,...,10000.
Припустимо, що список М зберігаєтьсяпослідовно стисло в масиві структур m з оголошенням:
 
struct
{ int nm;
float val; } m[10000];
Для визначення кінця списку додамо щеодин елемент із порядковим номером m[j].nm=10001, що називається стопером(stopper) і розташовується за останнім елементом стиснутого збереження списку вмасиві m.
 Програма для перебування шуканої сумимає вигляд:
 # include
 main()
{ int і,j=0;
float inp,sum=0;
struct /* оголошення масиву */
{ int nm; /* структур */
float val; } m[10000];
 
for(i=0;i
Індексне збереження використовується длязменшення часу пошуку потрібного елемента в списку і полягає в наступному.Вихідний список B = розбивається на трохи підсписків У1, У2, ..., Вм таким чином,що кожен елемент списку В попадає тільки в один з підсписків, і додаткововикористовується індексний список з М елементами, що вказують на початоксписків У1, У2, ..., Ум.
Вважається, що список зберігаєтьсяіндексно за допомогою підсписків B1,B2, ...,Bm і індексного списку X =, деADGj — адреса початку підсписка Bj, j=1,M.
При індексному збереженні елемент Допідсписка Bj має індекс j. Для одержання індексного збереження вихідний списокУ часто перетвориться в список В' шляхом включення в кожен вузол ще і йогопорядкового номера у вихідному списку В, а в j-ий елемент індексного списку Х,крім ADGj, може включатися деяка додаткова інформація про підсписок Bj.Розбивка списку В на підсписки здійснюється так, щоб всі елементи В, щоволодіють визначеною властивістю Рj, попадали в один підсписок Bj.
Достоїнством індексного збереження є те,що для перебування елемента К с заданою властивістю Pj досить переглянутитільки елементи підсписка Bj; його початок знаходиться по індексному списку Х,тому що для кожного ДО, що належить Bi, при і не рівному j властивість Pj невиконується.
У розбивці В часто використовуєтьсяіндексна функція G(K), що обчислює по елементі До його індекс j, тобто G(K)=j.Функція G звичайно залежить від позиції ДО, що позначається поз.K, у підспискуВ або від значення визначеної частини компоненти ДО — її ключа.
Розглянемо список B= з елементами
ДО1=(17,Y), K2=(23,H), K3=(60,I), K4=(90,S), K5=(66,T),
K6=(77,T), K7=(50,U), K8=(88,W), K9=(30,S).
Якщо для розбивки цього списку напідсписки як індексну функцію взяти Ga(K)=1+(поз.K-1)/3, то список розділитьсяна три підсписка:
B1a=,
B2a=,
B3a=.
Додаючи усюди ще і початкову позиціюелемента в списку, одержуємо:
B1a'=,
B2a'=,
B3а'=.
Якщо як індексну функцію вибрати іншуфункцію Gb(K)=1+(поз.K-1)%3, то одержимо списки:
B1b"=,
B2b"=,
B3b"=.
Тепер для перебування вузла K6 доситьпереглянути тільки одну з трьох послідовностей (списків). При використанніфункції Ga(K) це список B2а', а при функції Gb(K) список B3b".
Для індексної функції Gc(K)=1+K1/100, деK1 — перший компонент елемента ДО, знаходимо:
B1=,
B2=,
B3=,
B4=.
Щоб знайти тут вузол К с першимкомпонентом-ключем ДО1=77, досить переглянути список B2.
При реалізації індексного збереженнязастосовується методика А для збереження індексного списку Х (функція Ga(X) ) іметодика C для збереження підсписків B1,B2,...,Bm (функція Gc(Bi)), тобтовикористовується, так називане, A-C індексне збереження.
У практиці часто використовуєтьсяпослідовно-зв'язане індексне збереження. Тому що звичайно довжина спискуіндексів відома, те його зручно зберігати послідовно, забезпечуючи прямійдоступ до будь-якого елемента списку індексів. Підсписки B1,B2,...,Bmзберігаються пов'язано, що спрощує вставку і видалення вузлів(елементів).Зокрема, подібний метод збереження використовується в ЄС ЕОМ для організації,так званих, індексно-послідовних наборів даних, у яких доступ до окремихзаписів можливий як послідовно, так і за допомогою ключа.
Послідовно-зв‘язане індексне збереженнядля приведеного приклада зображене на мал.24, де X=.
 Розглянемо ще одну задачу. На входізадана послідовність цілих позитивних чисел, що закінчується нулем. Скластипроцедуру для введення цієї послідовності й організації її індексногозбереження таким чином, щоб числа, що збігаються в двох останніх цифрах,містилися в один підсписок.
Виберемо як індексну функціюG(K)=K%100+1, а як індексний список Х — масив з 100 елементів. Наступна функціявирішує поставлену задачу:
 #include
 #include
 typedef struct nd
{ float val;
struct nd *n; } ND;
int index (ND *x[100])
{ ND *p;
int i,j=0;
float inp;
for (i=0; ival=inp;
p->n=x[i];
x[i]=p;
scanf("%d",&inp);
}
return j;
}
Значенням функції, що повертається,index буде число оброблених елементів списку.
Для індексного списку також можевикористовуватися індексне збереження. Нехай, наприклад, мається список B= зелементами
K1=(338,Z), K2=(145,A), K3=(136,H), K4=(214,I), K5 =(146,C),
K6=(334,Y), K7=(333,P), K8=(127,G), K9=(310,O), K10=(322,X).
Потрібно розділити його на сімохпідсписків, тобто X= таким чином, щоб у кожен список B1,B2,...,B7 попадалиелементи, що збігаються в першому компоненті першими двома цифрами. Список Х, усвою чергу, будемо індексувати списком індексів Y=, щоб у кожен список Y1,Y2,Y3попадали елементи з X, у яких у першому компоненті збігаються перші цифри. Якщосписки B1,B2,...,B7 зберігати пов'язано, а списки індексів X,Y індексно, те такийспосіб збереження списку B називається зв'язаним індексним збереженням.Графічне зображення цього збереження приведене на мал.25.

Практична частина
 
Лістінг програми
 
Основний модуль golf.c
#include
#include
#include
#include
#include
#include
#define GRIDSIZE 80 /* Must be bigger than VIEWSIZE */
#define VIEWSIZE 61 /* MUST be odd */
#define DIFF (GRIDSIZE-VIEWSIZE)
#define DEF_DIST -1100
#define DEF_PITCH 122
#define DEF_HEIGHT 120
#define DEF_ROLL 315
#define sine(X) ((long)(sn_tbl[X]))
#define cosine(X) ((long)(sn_tbl[((X)+90) % 360]))
#define C_Plot(X,Y,C) pokeb(0xa000, (X) + 320U*(Y), C)
#define SHIFT 14
#define MASK (GRIDSIZE*GRIDSIZE)
/*
#define GetGrid(X,Y) ((unsigned)grid[((X) + GRIDSIZE*(Y)+idx) % MASK])
#define PutGrid(X,Y,C) grid[((X) + GRIDSIZE*(Y) +idx) % MASK]= (unsigned char)(C)
*/
#define CalcAddress(X,Y) (&grid[((X) + GRIDSIZE*(Y) +idx) % MASK])
extern void far *view_screen;
extern void far *screen;
extern int sn_tbl[360];
extern unsigned char grid[GRIDSIZE*GRIDSIZE];
extern unsigned rand_seed;
unsigned idx = 0;
extern long pitch_sine;
extern long pitch_cosine;
extern long roll_sine;
extern long roll_cosine;
int num_points = GRIDSIZE*GRIDSIZE;
#define START (DIFF/2)
int gx = START,gy = START;
unsigned char *gp;
int cz = DEF_DIST;
int cy = DEF_HEIGHT;
int roll = DEF_ROLL;
int cpitch = DEF_PITCH;
extern void SetMyMode(void);
extern void ClearMyScreen(void);
extern void Project(void);
extern void SwapScreens(void);
extern void DoPlasma(int,int,int,int);
extern int GetRand(void);
extern unsigned GetGrid(void);
extern void PutGrid(void);
#define _GetGrid(X,Y) (_AX = (X), _BX = (Y), GetGrid())
#define _PutGrid(X,Y,C) { _CX = (C); _AX = (X); _BX = (Y);PutGrid(); }
void SetMode(void)
{
         struct REGPACK regs;
         regs.r_ax = 0x13;
         intr(0x10, ®s);
}
void SetTextMode(void)
{
         struct REGPACK regs;
         regs.r_ax = 0x3;
         intr(0x10, ®s);
}
void SetPalette(void)
{
         register int i;
         register int j;
#define DEPTH(X) max((((X)*(3-j))/3), 3)
         for (j = 0; j
                   for (i = 0; i
                   {
                            if (i+j > 0)
                            {
                                      disable();
                                      outportb(0x3c8, (i>> 2)+64*j);
                                      outportb(0x3c9, 0);
                                      outportb(0x3c9, 0);
                                      outportb(0x3c9, DEPTH(2*i/3));
                                      enable();
                            }
                            disable();
                            outportb(0x3c8, (i >>2)+64*j+16);
                            outportb(0x3c9, DEPTH(i/2+10));
                            outportb(0x3c9, DEPTH(i/4+10));
                            outportb(0x3c9, DEPTH(i/6+10));
                            enable();
                            disable();
                            outportb(0x3c8, (i >>2)+64*j+32);
                            outportb(0x3c9,DEPTH(max(63/2+10-i,0)));
                            outportb(0x3c9,DEPTH(min(64/4+10+3*i/4,63)));
                            outportb(0x3c9,DEPTH(max(63/6+10-i,0)));
                            enable();
                            disable();
                            outportb(0x3c8, (i >>2)+64*j+48);
                            outportb(0x3c9, DEPTH(i));
                            outportb(0x3c9, DEPTH(63));
                            outportb(0x3c9, DEPTH(i));
                            enable();
                   }
}
/*
int RandPixel(int x,int y,int x1,int y1,int x2,int y2)
{
         int col;
         col = (GetRand()%200 — 100) * (abs(x-x1)+abs(y-y1))/ (GRIDSIZE/6)
                            +((_GetGrid(x1,y1)+_GetGrid(x2,y2))>> 1);
         if (col
         if (col > 255) col = 255;
         _PutGrid(x,y,col);
         return col;
}
*/
/*
void DoPlasma(int x1, int y1, int x2, int y2)
{
         int x,y,s,p;
         if (x2-x1
                   return;
         x = (x1+x2) >> 1;
         y = (y1+y2) >> 1;
         if ((p = _GetGrid(x, y1)) == 0)
                   p = RandPixel(x,y1,x1,y1,x2,y1);
         s = p;
         if ((p = _GetGrid(x2,y)) == 0)
                   p = RandPixel(x2,y,x2,y1,x2,y2);
         s += p;
         if ((p = _GetGrid(x,y2)) == 0)
                   p = RandPixel(x,y2,x1,y2,x2,y2);
         s += p;
         if ((p = _GetGrid(x1,y)) == 0)
                   p = RandPixel(x1,y,x1,y1,x1,y2);
         s += p;
         if (_GetGrid(x,y) == 0)
                   _PutGrid(x,y,s >> 2);
         DoPlasma(x1,y1,x,y);
         DoPlasma(x,y1,x2,y);
         DoPlasma(x1,y,x,y2);
         DoPlasma(x,y,x2,y2);
}
*/
void BlankGrid(int x1,int y1,int x2,int y2)
{
         register int x,y;
         for (y = y1; y
                   for (x = x1; x
                            _PutGrid(x,y,0);
}
void NewLand(int x1,int y1,int x2,int y2)
{
         unsigned av = 0;
         int val;
         int num = 0;
         if ((val = _GetGrid(x1,y1)) > 0)
         {
                   av += val;
                   num++;
         }
         if ((val = _GetGrid(x2,y1)) > 0)
         {
                   av += val;
                   num++;
         }
         if ((val = _GetGrid(x2,y2)) > 0)
         {
                   av += val;
                   num++;
         }
         if ((val = _GetGrid(x1,y2)) > 0)
         {
                   av += val;
                   num++;
         }
         if (!av || GetRand() % 32 == 0)
                   av = GetRand() % 256;
         else
                   av /= num;
         if (_GetGrid(x1,y1) == 0)
                   _PutGrid(x1,y1, av + (GetRand() % 80-40));
         if (_GetGrid(x2,y1) == 0)
                   _PutGrid(x2,y1, av + (GetRand() % 80-40));
         if (_GetGrid(x2,y2) == 0)
                   _PutGrid(x2,y2, av + (GetRand() % 80-40));
         if (_GetGrid(x1,y2) == 0)
                   _PutGrid(x1,y2, av + (GetRand() % 80-40));
         DoPlasma(x1,y1,x2,y2);
}
void Test(void)
{
         register int p;
         register int x;
         int y;
         for (y = 0,p = idx; y
                   for (x = 0; x
                            C_Plot(x,y,max(grid[p],63)>> 2);
         for (x = 0; x
         {
                   C_Plot(gx+x, gy, 0);
                   C_Plot(gx+x, gy+VIEWSIZE, 0);
                   C_Plot(gx, gy+x, 0);
                   C_Plot(gx+VIEWSIZE, gy+x, 0);
         }
/*
         for (y = 0, p = gp; y
                   for (x = 0; x
                            C_Plot(gx+x,gy+y,*p >> 3);
*/
}
void ClearScr(void)
{
         register unsigned i;
         for (i = 0; i
                   pokeb(0xa000,i,0);
}
void check_gx(void)
{
         if (gx
         {
                   idx = (idx-DIFF/2 + MASK) % MASK;
                   gx = START-1;
                   BlankGrid(0,0, DIFF/2-1, GRIDSIZE-1);
                   NewLand(0,0,DIFF/2,GRIDSIZE/4);
                   NewLand(0,GRIDSIZE/4,DIFF/2,2*GRIDSIZE/4);
                   NewLand(0,2*GRIDSIZE/4,DIFF/2,3*GRIDSIZE/4);
                   NewLand(0,3*GRIDSIZE/4,DIFF/2,GRIDSIZE-1);
         }
         else if (gx >= DIFF)
         {
                   idx = (idx+DIFF/2) % MASK;
                   gx = START+1;
                   BlankGrid(GRIDSIZE-DIFF/2,0, GRIDSIZE-1,GRIDSIZE-1);
                   NewLand(GRIDSIZE-DIFF/2-1,0,GRIDSIZE-1,GRIDSIZE/4);
                   NewLand(GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1,
                                                                                                                 2*GRIDSIZE/4);
                   NewLand(GRIDSIZE-DIFF/2-1,2*GRIDSIZE/4,GRIDSIZE-1,
                                                                                                                 3*GRIDSIZE/4);
                   NewLand(GRIDSIZE-DIFF/2-1,3*GRIDSIZE/4,GRIDSIZE-1,
                                                                                                                 GRIDSIZE-1);
         }
}
void check_gy(void)
{
         if (gy
         {
                   idx = (idx-DIFF/2*GRIDSIZE + MASK) % MASK;
                   gy = START-1;
                   BlankGrid(0,0, GRIDSIZE-1, DIFF/2-1);
                   NewLand(0,0,GRIDSIZE/4,DIFF/2);
                   NewLand(GRIDSIZE/4,0,2*GRIDSIZE/4,DIFF/2);
                   NewLand(2*GRIDSIZE/4,0,3*GRIDSIZE/4,DIFF/2);
                   NewLand(3*GRIDSIZE/4,0,GRIDSIZE-1,DIFF/2);
         }
         else if (gy >= DIFF)
         {
                   idx = (idx+DIFF/2*GRIDSIZE) % MASK;
                   gy = START+1;
                   BlankGrid(0,GRIDSIZE-DIFF/2,GRIDSIZE-1,GRIDSIZE-1);
                   NewLand(0,GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1);
                   NewLand(GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
                                                                           2*GRIDSIZE/4,GRIDSIZE-1);
                   NewLand(2*GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
                                                                           3*GRIDSIZE/4,GRIDSIZE-1);
                   NewLand(3*GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
                                                                           GRIDSIZE-1,GRIDSIZE-1);
         }
}
void main(void)
{
         int rollspeed = 0;
         int xspeed = 0, yspeed = 0;
         int i;
         rand_seed = (unsigned) time(NULL);
/*       rand_seed = 2; */
         for (i = 0; i
                   sn_tbl[i]=(int)(sin((double)i /180.0*3.14159265) * (double)(1
         NewLand(0,0,GRIDSIZE-1,GRIDSIZE-1);
         SetMode();
         SetPalette();
//       goto skip;
         for (;;)
         {
                   Test();
                   switch(getch())
                   {
                            case 27:
                                      SetTextMode();
                                      exit(0);
                            case 'e':
                                      gx--;
                                      check_gx();
                                      break;
                            case 'r':
                                      gx++;
                                      check_gx();
                                      break;
                            case 'w':
                                      gy--;
                                      check_gy();
                                      break;
                            case 's':
                                      gy++;
                                      check_gy();
                                      break;
                            case ' ':
                                      goto skip;
                   }
                   gp = CalcAddress(gx,gy);
                   while (kbhit())
                            getch();
         }
skip:
         ;
         SetMyMode();
         SetPalette();
         gp = CalcAddress(gx,gy);
//       yspeed = -1;
//       rollspeed = (rollspeed+358) % 360;
         for (;;)
         {
                   if (kbhit())
                   {
                            switch(getch())
                            {
                            case 27:
                                      SetTextMode();
                                      exit(0);
                            case 'q':
                                      cz += 50;
                                      break;
                            case 'a':
                                      cz -= 50;
                                      break;
                            case 'u':
                                      cy -= 50;
                                      break;
                            case 'j':
                                      cy += 50;
                                      break;
                            case 'Q':
                                      cpitch = (cpitch+1) %360;
                                      break;
                            case 'A':
                                      cpitch = (cpitch+359) %360;
                                      break;
                            case 'E':
                                      if (xspeed > -1)xspeed--;
                                      break;
                            case 'R':
                                      if (xspeed
                                      break;
                            case 'e':
                                      gx--;
                                      break;
                            case 'r':
                                      gx++;
                                      break;
                            case 'W':
                                      if (yspeed > -1)yspeed--;
                                      break;
                            case 'S':
                                      if (yspeed
                                      break;
                            case 'w':
                                      gy--;
                                      break;
                            case 's':
                                      gy++;
                                      break;
                            case 'i':
                                      roll = (roll+1) % 360;
                                      break;
                            case 'o':
                                      roll = (roll+359) %360;
                                     break;
                            case 'I':
                                      rollspeed =(rollspeed+1) % 360;
                                      break;
                            case 'O':
                                      rollspeed =(rollspeed+359) % 360;
                                      break;
                            case ' ':
                                      rollspeed = 0;
                                      xspeed = yspeed = 0;
                                      cz = DEF_DIST;
                                      cy = DEF_HEIGHT;
                                      roll = DEF_ROLL;
                                      cpitch = DEF_PITCH;
                                      break;
                            }
                            while (kbhit())
                                      getch();
                   }
                   gy += yspeed;
                   gx += xspeed;
                   check_gx();
                   check_gy();
                   gp = CalcAddress(gx,gy);
                   roll = (roll+rollspeed) % 360;
                   roll_sine = sine(roll);
                   roll_cosine = cosine(roll);
                   pitch_sine = sine(cpitch);
                   pitch_cosine = cosine(cpitch);
                   ClearMyScreen();
                   Project();
                   SwapScreens();
         }
}

Робота з програмою
Далі наведено три скріншоти, які описують процес удару по м”ячику.
/>
/>

Висновки
Була розроблена комп’ютерна гра “Гольф 3D” з елементами трьохвимірної графікина основі функцій прямого доступу до відеопам’яті в системі MS DOS. При розробці програмивикористовувався пакет BORLAND C++ 3.0 табібліотека BGI.

Література.
[1] Касаткин А.И., Вальвачев А.Н.Профессиональное прогрпммирование на языке Си. Мн., 1992. 240 С.
[2] Нейбауэр А. Моя перваяпрограмма на С/С++. П., 1995. 368 С.
[3] Бруно Бабэ. Просто и ясно оBorland C++. М., 1996. 400 С.
[4] Шамас Н.К. Основы С++ иобьектно-ориентированного программирования. К., 1996. 448 С.
[5] Справочник по классам BorlandC++ 4.0. К., 1994. 256 С.
[6] ObjectWindows для C++. К., 1993., 208 С.
[7] Том Сван. Программированиедля Windows в Borland C++. М., 480 С.
[8] Н. Барканати.Программирование игр для Windows на Borland C++. М., 1994. 512 С.


Не сдавайте скачаную работу преподавателю!
Данный реферат Вы можете использовать для подготовки курсовых проектов.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем реферат самостоятельно:
! Как писать рефераты
Практические рекомендации по написанию студенческих рефератов.
! План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом.
! Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач.
! Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты.
! Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ.

Читайте также:
Виды рефератов Какими бывают рефераты по своему назначению и структуре.

Сейчас смотрят :

Реферат Использование методики ролевых игр при обучении информатике
Реферат Вальтер Ратенау - человек, предприниматель, философ
Реферат Межі та стадії негативної кримінальної відповідальності
Реферат Бюджетное планирование для многономенклатурного производства
Реферат Criticism Alexander Kerenskys Leading Of The Provisional
Реферат Правовые основы территориальной организации местного самоуправления и их реализация на примере Добровского района
Реферат Григорий Печорин и Максим Максимыч, смысл их противопоставления
Реферат Проектная методика на уроках английского языка
Реферат Governments Today Essay Research Paper Should governments
Реферат Рекомендуемые способы электропрогрева бетонных конструкций
Реферат Види діяльності та доходи підприємств АПК
Реферат Darwin Awards Essay Research Paper The Darwin
Реферат Abortion Essay Research Paper Abortion Ever since
Реферат Работа с инифайлами (ini)
Реферат Alexander The Great Essay Research Paper He