Вход

Программирование игры "Дурак" (карточная) на языке программирования С++

Рекомендуемая категория для самостоятельной подготовки:
Курсовая работа*
Код 113010
Дата создания 2011
Страниц 32
Источников 1
Мы сможем обработать ваш заказ (!) 31 мая в 16:00 [мск]
Файлы будут доступны для скачивания только после обработки заказа.
2 930руб.
КУПИТЬ

Содержание

ЗАДАНИЕ НА ПРОЕКТИРОВАНИЕ
1. ПОСТАНОВКА ЗАДАЧИ
2. ОТОБРАЖЕНИЕ КАРТ
3. СТРУКТУРЫ ДАННЫХ
4. АЛГОРИТМ ОБРАБОТКИ ДЕЙСТВИЙ ИГРОКА-ЧЕЛОВЕКА
5. АЛГОРИТМ ДЕЙСТВИЙ ПРОГРАММНОГО ИГРОКА
6. ОРГАНИЗАЦИЯ ИГРОВОГО ЦИКЛА
7. СОЗДАНИЕ ПРИЛОЖЕНИЯ
8. ЗАКЛЮЧЕНИЕ
СПИСОК ЛИТЕРАТУРЫ
ПРИЛОЖЕНИЕ 1
ПРИЛОЖЕНИЕ 2

Фрагмент работы для ознакомления

Top=card->c.X; // прямоугольник для обмена
r.Left=card->c.Y;
r.Bottom=r.Top+3;
r.Right=r.Left+5;
WriteConsoleOutput(h,card->buf,size,coord,&r); // восстанавливаем стол из буфера
card->c.X=c.X; // перемещаем карту
card->c.Y=c.Y;
r.Top=card->c.X;
r.Left=card->c.Y;
r.Bottom=r.Top+3;
r.Right=r.Left+5;
ReadConsoleOutput(h,card->buf,size,coord,&r); // считываем новый участок стола
WriteConsoleOutput(h,card->cur,size,coord,&r); // выводим карту
}
void TurnCard(int t,struct CCard *card) // повернуть карту
{
if(t)
card->cur=card->avers; // лицом
else
card->cur=Revers; // рубашкой
}
void CreateRevers() // создание рубашки карты
{
// рубащке рисуем псевдографикой
// рамка черным по белому
// середина ярко-синим по белому
Revers[0].Char.AsciiChar=(unsigned char)218;
Revers[0].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[1].Char.AsciiChar=(unsigned char)196;
Revers[1].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[2].Char.AsciiChar=(unsigned char)196;
Revers[2].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[3].Char.AsciiChar=(unsigned char)196;
Revers[3].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[4].Char.AsciiChar=(unsigned char)191;
Revers[4].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[5].Char.AsciiChar=(unsigned char)179;
Revers[5].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[6].Char.AsciiChar=(unsigned char)177;
Revers[6].Attributes=FOREGROUND_INTENSITY|FOREGROUND_BLUE|BACKGROUND_RED|
BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[7].Char.AsciiChar=(unsigned char)177;
Revers[7].Attributes=FOREGROUND_INTENSITY|FOREGROUND_BLUE|BACKGROUND_RED|
BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[8].Char.AsciiChar=(unsigned char)177;
Revers[8].Attributes=FOREGROUND_INTENSITY|FOREGROUND_BLUE|BACKGROUND_RED|
BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[9].Char.AsciiChar=(unsigned char)179;
Revers[9].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[10].Char.AsciiChar=(unsigned char)192;
Revers[10].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[11].Char.AsciiChar=(unsigned char)196;
Revers[11].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[12].Char.AsciiChar=(unsigned char)196;
Revers[12].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[13].Char.AsciiChar=(unsigned char)196;
Revers[13].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
Revers[14].Char.AsciiChar=(unsigned char)217;
Revers[14].Attributes=BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE;
}
void CreateArrow() // создание стрелки
{
COORD size,coord;
SMALL_RECT r;
size.X=1; // размер
size.Y=1;
coord.X=0; // координаты в буфере
coord.Y=0;
r.Top=0; // прямоугольник для обмена
r.Left=0;
r.Bottom=1;
r.Right=1;
arr.pic.Char.AsciiChar=(unsigned char)'^'; // собственно стрелка желтым по зеленому
arr.pic.Attributes=FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|
BACKGROUND_GREEN;
ReadConsoleOutput(h,&arr.buf,size,coord,&r);// считываем подстилающий прямоугольник
}
void MoveArrow(COORD c) // перемещение стрелки
{
COORD size,coord;
SMALL_RECT r;
size.X=1; // размер
size.Y=1;
coord.X=0; // координаты в буфере
coord.Y=0;
r.Top=arr.c.X; // прямоугольник для обмена
r.Left=arr.c.Y;
r.Bottom=r.Top+1;
r.Right=r.Left+1;
// восстанавливаем поверхность из буфера
WriteConsoleOutput(h,&arr.buf,size,coord,&r);
arr.c.X=c.X; // координаты стрелки
arr.c.Y=c.Y;
r.Top=arr.c.X; // прямоугольник для обмена
r.Left=arr.c.Y;
r.Bottom=r.Top+1;
r.Right=r.Left+1;
ReadConsoleOutput(h,&arr.buf,size,coord,&r);// считываем подстилающий прямоугольник
WriteConsoleOutput(h,&arr.pic,size,coord,&r);// выводим стрелку в новом положении
}
void FillRect(COORD c,COORD d,int att) // заполнить прямоугольник
{
COORD size,coord;
SMALL_RECT r;
CHAR_INFO *rect;
int i,num;
num=d.X*d.Y; // вычисляем размер прямоугольника
rect=new CHAR_INFO[num]; // выделяем память
for(i=0; i < num; i++){
// заполняем пробелами с нужным атрибутом
rect[i].Char.AsciiChar=(unsigned char)' ';
rect[i].Attributes=att;
}
size.X=d.X; // размер
size.Y=d.Y;
coord.X=0; // координаты в буфере
coord.Y=0;
r.Top=c.X; // прямоугольник для обмена
r.Left=c.Y;
r.Bottom=r.Top+d.X;
r.Right=r.Left+d.Y;
WriteConsoleOutput(h,rect,size,coord,&r);// закрашиваем прямоугольник
delete[] rect;
}
int MessageAsk(char *l1, char *l2,char **a, int n) // меню
{
COORD size,coord,c,c_arr;
SMALL_RECT r;
CHAR_INFO buf[180];
CHAR_INFO rect[180];
DWORD written;
int alt=0;
char in;
int i;
size.X=30; // устанавливаем размеры меню
size.Y=6;
coord.X=0; // координаты в буфере
coord.Y=0;
r.Top=9; // прямоугольник для обмена
r.Left=25;
r.Bottom=r.Top+7;
r.Right=r.Left+30;
ReadConsoleOutput(h,buf,size,coord,&r); // считываем подстилающую поверхность
for(i=0; i < 180; i++){ // заполняем пробелами синего цвета
rect[i].Char.AsciiChar=(unsigned char)' ';
rect[i].Attributes=BACKGROUND_BLUE;
}
WriteConsoleOutput(h,rect,size,coord,&r); // выводим синий прямоугольник
c.X=27; // координаты первой строки
c.Y=10;
SetConsoleCursorPosition(h,c); // устанавливаем позицию
WriteConsole(h,(CONST VOID *)l1,strlen(l1),&written,NULL); // выводим строку
c.Y=11; // координаты второй строки
SetConsoleCursorPosition(h,c); // устанавливаем позицию
WriteConsole(h,(CONST VOID *)l2,strlen(l2),&written,NULL); // выводим строку
c.Y=13; // строка для размещения альтернатив
for(i=0; i < n; i++){ // выводим альтернативы
c.X=27+6*i; // позиция для вывода
SetConsoleCursorPosition(h,c); // устанавливаем позицию
WriteConsole(h,(CONST VOID *)a[i],strlen(a[i]),&written,NULL); // выводим альтернативу
}
c_arr.X=14; // позиция для перемещения стрелки
for(;;){
c_arr.Y=27+6*alt; // позиция для вывода
MoveArrow(c_arr); // перемещение стрелки
in=getch(); // ждем ввода
if(in == 13){ // нажат Enter
c_arr.X=0;
c_arr.Y=0;
MoveArrow(c_arr); // убираем стрелку
WriteConsoleOutput(h,buf,size,coord,&r);// восстанавливаем поверхность
return(alt); // возвращаем выбор
}
if(in == -32){ // это стрелка
in=getch(); // дочитываем еще один символ
if(in == 77){ // стрелка вправо
if(alt+1 < n) // наращиваем позицию стрелки с учетом предела
alt++;
}
else if(in ==75){ // стрелка влево
if(alt > 0) // уменьшаем позицию стрелки с учетом предела
alt--;
}
}
}
}
void OnButton1() // Кнопка "OK"/"Бито"/"Все"/"Беру"
{
if(take) // компьютер сказал "беру", кнопка называется "все"
next=1; // устанавливаем призна "все"
else
if(turn == 0) // это ход человека, кнопка называется "бито"
next=1; // устанавливаем признак "все"
else // это ход компьютера, кнопка называется "беру"
take=1; // устанавливаем признак "беру"
}
void OnLButtonUp(int num) // Реакция на выбор карты
{
int i;
list<int>::iterator cur;
list<int>::reverse_iterator curxa;

for(cur=pls[0].player.begin(),i=0; cur != pls[0].player.end(); cur++,i++) // ищем окно с таким описателем среди карт
if(i == num)
break;
if(turn == 0){ // если ход на стороне человека
// поле атаки пусто - кидаем первую карту,которую выбрал человек без ограничений
if(playattack.size() == 0){
toAttack(0,cur);
return;
}
// если карта не первая, учитываем ограничения (не более 6 отбоев)
else if(playattack.size() < 6){
if(titleExist(Card[*cur].title)){ // такой титул найден в игровых полях
toAttack(0,cur); // кидаем выбранную карту на поле атаки
return;
}
}
else{
next=1; // устанавливаем признак "все"
return;
}
}
else{ // если ход на стороне компьютера
// определяем последнюю карту, которую кинул компьютер
curxa=playattack.rbegin();
// выбранная карта может побить ее
if(Card[*cur].title > Card[*curxa].title &&
Card[*cur].suit == Card[*curxa].suit ||
Card[*cur].suit == trump && Card[*curxa].suit != trump){
toDefend(0,cur); // кидаем выбранную карту на поле защиты
return;
}
}
}
void compPlay(){ // Компьютерный игрок
list<int>::iterator cur;
list<int>::iterator curx;
list<int>::reverse_iterator cury;
int title;
if(call == turn){ // атака
curx=NULL; // ищем подходящую карту
title=15;
if(playattack.size() == 0){ // это первая карта на игровых полях
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
// ищем минимальную некозырную карту
if(Card[*cur].suit != trump && Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
// некозырных не оказалось
if(curx == NULL)
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
// ищем минимальную козырную карту
if(Card[*cur].suit == trump && Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
}
else if(playattack.size() < 6){ // это не первая карта на игровых полях
// ищем минимальную некозырную карту с титулом, имеющимся на игровом поле
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
// карты с таким титулом есть на игровом поле
if(titleExist(Card[*cur].title) &&
Card[*cur].suit != trump && Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
// некозырных не оказалось
if(curx == NULL)
// ищем минимальную козырную карту
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
// карты с таким титулом есть на игровом поле
if(titleExist(Card[*cur].title) &&
Card[*cur].suit == trump && Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
}
else
next=1;
if(curx != NULL) // подходящая карта нашлась
toAttack(call,curx); // помещаем найденную карту в поле атаки
else
next=1; // устанавливаем признак "все"
}
else{ // защита
cury=playattack.rbegin();
curx=NULL;
title=15;
// ищем минимальную некозырную карту для отбоя
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
if(Card[*cur].title > Card[*cury].title &&
Card[*cur].suit == Card[*cury].suit &&
Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
if(curx == NULL) // некозырных не оказалось
// ищем минимальную козырную карту для отбоя
for(cur=pls[call].player.begin(); cur != pls[call].player.end(); cur++){
if(Card[*cur].suit == trump && Card[*cury].suit != trump &&
Card[*cur].title < title){
title=Card[*cur].title;
curx=cur;
}
}
if(curx != NULL) // подходящая карта нашлась
toDefend(call,curx);
else
take=1; // устанавливаем признак "беру"
}
}
// Функция генерации случайных чисел
ptrdiff_t random(ptrdiff_t i)
{
return rand()%i;
}
// указатель на генератор для random_shuffle
ptrdiff_t (*p_random)(ptrdiff_t)=random;
void ShuffleDeck() // Тасование карт, формирование колоды и определение козыря
{
int i;
vector<int> vdeck;
vector<int>::iterator curv;
list<int>::reverse_iterator curc;
COORD c;

c.X=7; // место расположения колоды в окне
c.Y=2;
playattack.clear(); // очищаем поле нападения
playdefend.clear(); // очищаем поле защиты
for(i=0; i < 6; i++)
pls[i].player.clear(); // очищаем карты на руках у игроков
refuse.clear(); // очищаем отбой
deck.clear(); // очищаем колоду (при тасовке колода формируется заново,
// это связано с особенностями алгоритма random_shuffle)
for(i=0; i < 36; i++){
TurnCard(0,&Card[i]); // переворачиваем карты рубашкой вверх
vdeck.push_back(i); // вносим их номера в вектор
}
srand((unsigned)time(NULL)); // инициализируем датчик случайных чисел
random_shuffle(vdeck.begin(),vdeck.end(),p_random);// тасуем вектор с номерами карт
// переносим элементы вектора в список колоды
for(curv=vdeck.begin(); curv != vdeck.end(); curv++)
deck.push_back(*curv);
vdeck.clear(); // очищаем вектор
// размещаем колоду на игровом поле
for(curc=deck.rbegin(),i=0; curc != deck.rend(); curc++){
if(i == 0){
TurnCard(1,&Card[*curc]); // первую карту кладем картинкой вверх
trump=Card[*curc].suit; // по ее масти устанавливаем козырь
}
MoveCard(c,&Card[*curc]);
if(i == 0){
i=1;
c.Y += 2; // смещение колоды относительно козыря
}
}
}
void TakeCards(){ // Раздача карт
list<int>::reverse_iterator curc;
int pos;
for(int j=0; j < 6; j++){
pos=nextPlayer(j); // раздача начиная с того, у кого сейчас ход
// до шести карт пока есть карты в колоде
while(pls[pos].player.size() < 6 && deck.size() > 0)
pls[pos].player.splice(pls[pos].player.begin(),deck,deck.begin());
layoutCards(pos,pls[pos].open); // выкладываем карты на поле
}
}
void toAttack(int pl,list<int>::iterator crd){ // Помещение карты в поле атаки
COORD c;
playattack.splice(playattack.end(),pls[pl].player,crd);
c.Y=12+7*(playattack.size()-1); // координаты размещения на игровом поле
c.X=9;
TurnCard(1,&Card[*crd]); // лицом вверх
MoveCard(c,&Card[*crd]);
}
void toDefend(int pl,list<int>::iterator crd){ // Помещение карты в поле защиты
COORD c;
playdefend.splice(playdefend.end(),pls[pl].player,crd);
c.Y=13+7*(playdefend.size()-1); // координаты размещения на игровом поле
c.X=13;
TurnCard(1,&Card[*crd]); // лицом вверх
MoveCard(c,&Card[*crd]);
}
void layoutCards(int pl,int t){ // Разложить карты игрока
list<int>::iterator curc;
COORD c,d;
d.X=6;
d.Y=4;
c.Y=10; // начальное смещение по y
if(pl == 0){ // этот игрок - человек
c.X=20; // смещение по x
for(curc=pls[pl].player.begin(); curc != pls[pl].player.end(); curc++){
FillRect(c,d,BACKGROUND_GREEN);
TurnCard(t,&Card[*curc]);
MoveCard(c,&Card[*curc]);
c.Y += 6;
}
}
else{ // компьютерный игрок
c.X=2; // смещение по y
if(Pl == 2){ // игроков всего два - располагаем карты компьютерного игрока свободно
for(curc=pls[pl].player.begin(); curc != pls[pl].player.end(); curc++){
FillRect(c,d,BACKGROUND_GREEN);
TurnCard(t,&Card[*curc]);
MoveCard(c,&Card[*curc]);
c.Y += 6;
}
}
else{ // игроков более двух - располагаем карты колодой
c.Y += (pl-1)*15;
for(curc=pls[pl].player.begin(); curc != pls[pl].player.end(); curc++){
FillRect(c,d,BACKGROUND_GREEN);
TurnCard(t,&Card[*curc]);
MoveCard(c,&Card[*curc]);
}
}
}
}
void refuseCards(){ // Сформировать отбой
list<int>::reverse_iterator curc;
COORD c;
c.X=14; // смещение расположения колоды отбоя
c.Y=3;
for(curc=refuse.rbegin(); curc != refuse.rend(); curc++){
TurnCard(0,&Card[*curc]);
MoveCard(c,&Card[*curc]);
}
}
// Проверка, имеются ли на игровом поле карты с указанным титулом
int titleExist(int title)
{
list<int>::iterator cura;
list<int>::iterator curd;
// есть ли карты с таким титулом на поле атаки?
for(cura=playattack.begin(); cura != playattack.end(); cura++)
if(title == Card[*cura].title)
break;
// есть ли карты с таким титулом на поле защиты?
for(curd=playdefend.begin(); curd != playdefend.end(); curd++)
if(title == Card[*curd].title)
break;
return cura != playattack.end() || curd != playdefend.end();
// есть ли карты с таким титулом на игровом поле
}
int nextPlayer(int offset) // Вычисление номера игрока, следующего за ходящим
{ // с учетом цикличности и признака существования
int pos;
pos=turn;
if(pos < 0)
pos=0;
for(int j=0; j < offset; j++){
do{
pos++;
if(pos > 5)
pos=0;
}while(!pls[pos].exist);
}
return pos;
}
22

Список литературы [ всего 1]

1.Б. Страуструп Язык программирования C++. Специальное издание.– СПб.: "Невский Диалект", 2001.–1099 с.
Очень похожие работы
Пожалуйста, внимательно изучайте содержание и фрагменты работы. Деньги за приобретённые готовые работы по причине несоответствия данной работы вашим требованиям или её уникальности не возвращаются.
* Категория работы носит оценочный характер в соответствии с качественными и количественными параметрами предоставляемого материала. Данный материал ни целиком, ни любая из его частей не является готовым научным трудом, выпускной квалификационной работой, научным докладом или иной работой, предусмотренной государственной системой научной аттестации или необходимой для прохождения промежуточной или итоговой аттестации. Данный материал представляет собой субъективный результат обработки, структурирования и форматирования собранной его автором информации и предназначен, прежде всего, для использования в качестве источника для самостоятельной подготовки работы указанной тематики.
bmt: 0.00459
© Рефератбанк, 2002 - 2024