Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.11.2012, 14:45   #1
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию Тернистым путём через "Морской бой"

Собственно, кто знаком с темой Шахматной игры
то объясню вкратце: начну с морского боя, чтобы разобраться с массивами, работой массивов, классами, работой и взаимодействием классов и так далее.

Я знаю, здесь есть темы других пользователей про морской бой - читала, но там нет ответа на некоторые мои вопросы. поэтому, собственно, буду выкладывать игру кусками здесь, авось, быстро пойму что к чему!
Fanyuus вне форума Ответить с цитированием
Старый 28.11.2012, 15:09   #2
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию

Продумывая программу, я делала с пояснениями и комментариями. Из-за этого, я подумала сделать отдельные функции и глобал.переменные:

Код:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <conio.h>
#include <Windows.h>
#include <stdio.h>
#include <cstdio>
using namespace std;

void privetstvie(); ------ здесь типа надо объяснить игроку как играть
void shipplayer1();  ----- изменение массива 1.1 - расстановка кораблей 1 игрока
void shipplayer2();  ----- изменение массива 2.1 - расстановка кораблей 2 игрока
void ProverkaPole1(); --- изменение массива 1.2 - поле для выстрелов
void ProverkaPole2(); --- изменение массива 2.2 - поле для выстрелов


char POLEBOJA1[10][10],POLEBOJA2[10][10];

int main()
{
	setlocale (0,"");

	privetstvie();

	cin.get();
	cin.get();
	return 0;
}
поскольку у меня код не доработан, то я буду выкладывать всё, что есть пока что и где, собственно идёт косяк.

Так же хочу сказать о процессе игры: играем на 1 компьютере, сначала игрок А заполняет поле, потом игрок Б заполняет своё поле, а потом их поля хранятся как переменные, появляются два новых пустых поля и в процессе игры, каждый раз меня 1 поле (то есть, каждый игрок не видит своего поля, но он видит одно поле - куда ему надо стрелять), стреляют и программа, по идее, должна сама писать "мимо\ранил\убил".

Идея пока что такая.

так вот, при заполнении поля, пока что самым корявым и простым способом вот что получается:

Код:
void privetstvie()
{
cout << "\t Это простая программа для игры в морской бой между двумя пользователями на одном компьютере. \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";

getch();
system("cls");
cout << "\t Для удобства игры, мы спользуем числа не от 1 до 10, а от 0 до 9, и \n вместо букв от \"а\" до \"к\" тоже используем цифры от 0 до 9. \n \n \t Приведём пример игрового поля: \n \n";

	int i,j;
	char POLEBOJA[10][10];
cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i=0; i<10; i++)
	{
		cout << i << " ";
		for (j=0; j<10; j++)
		{
			POLEBOJA[i][j]=48;
			cout << POLEBOJA[i][j] << " ";
			
		}
		cout << "\n";
	}
cout << "\n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";
getch();
system("cls");

cout << "\n  \t Предлагаем сейчас PLAYER-1 заполнить своё игровое поле. \n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";
getch();
system("cls");

shipplayer1();
	
}

void shipplayer1()
{

int i1,ii1,ii2,ii3,ii4,j1,jj1,jj2,jj3,jj4,k;

cout << "\n \t Определим положение четырёхпалубного корабля.\n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";

cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i1=0; i1<10; i1++)
	{
		cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			POLEBOJA1[i1][j1]=48;
			cout << POLEBOJA1[i1][j1] << " ";
			
		}
		cout << "\n";
	}


cout <<" \n Введите 4 координаты для горизонтали клетки корабля \n";
cin >> ii1 >> ii2 >> ii3 >> ii4;
cout <<" \n \n Введите 4 координаты для вертикальной клетки корабля \n";
cin	>> jj1 >> jj2 >> jj3 >> jj4;

getch();
system("cls");

	for (i1=0; i1<10; i1++)
	{
		for (j1=0; j1<10; j1++)
		{

			if ((i1==ii1) && (j1==jj1))
			POLEBOJA1[i1][j1]=245;
			
			if ((i1==ii2) && (j1==jj2))
			POLEBOJA1[i1][j1]=245;

			if ((i1==ii3) && (j1==jj3))
			POLEBOJA1[i1][j1]=245;

			if ((i1==ii4) && (j1==jj4))
			POLEBOJA1[i1][j1]=245;

			cout << POLEBOJA1[i1][j1] << " ";
			
		}
		cout << "\n";
	}


	cout << "\n \t Определим положение трёхпалубных кораблей.\n \n ";
	
	for (k=0; k<2; k++)
	{
	cout << "\n \n \t Введите 3 координаты для горизонтали клетки корабля \n";
cin >> ii1 >> ii2 >> ii3;
cout <<" \n \n Введите 3 координаты для вертикальной клетки корабля \n";
cin	>> jj1 >> jj2 >> jj3;

getch();
system("cls");

cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i1=0; i1<10; i1++)
	{
		cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			
			if ((i1==ii1) && (j1==jj1))
			{
			POLEBOJA1[i1][j1]=245;
			cout << POLEBOJA1[i1][j1] << " ";
			}
			
			if ((i1==ii2) && (j1==jj2))
			{
			POLEBOJA1[i1][j1]=245;
			cout << POLEBOJA1[i1][j1] << " ";
			}

			if ((i1==ii3) && (j1==jj3))
			{
			POLEBOJA1[i1][j1]=245;
			cout << POLEBOJA1[i1][j1] << " ";
			}
		}
		cout << "\n";
	}


	}

	//конец функции "кораблики"
}
и вот что выходит при выполнении:



то есть, вопрос вот в чём: почему он не заменил элементы "0" на "Х", а будто новое поле нарисовал?

даже если вводить другие цифры для i и j, то он всё равно такую же строчку выдаёт.

Вопрос именно по этой ситуации, как проще и лучше мне не нужно, подскажите, пожалуйста, где конкретно здесь ошибка.
Fanyuus вне форума Ответить с цитированием
Старый 28.11.2012, 17:52   #3
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

У трёхпалубников выводится элемент только если срабатывает условие, т.е. там выводятся только сами трёхпалубники.
Предлагаю вынести строку:
cout << POLEBOJA1[i1][j1] << " ";
из под условия, т.е. она должна быть после трёх if.
Код:
cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			
			if ((i1==ii1) && (j1==jj1))
			{
			POLEBOJA1[i1][j1]=245;
			}
			
			if ((i1==ii2) && (j1==jj2))
			{
			POLEBOJA1[i1][j1]=245;
			}

			if ((i1==ii3) && (j1==jj3))
			{
			POLEBOJA1[i1][j1]=245;
			}
cout << POLEBOJA1[i1][j1] << " ";
		}
		cout << "\n";
Так же эти три ифа должны быть минимум if... else if... else if..., а в идеале свернуть в один if, чтобы не дублировать тела (просто сложное условие будет с использованием ||).
pu4koff вне форума Ответить с цитированием
Старый 28.11.2012, 19:55   #4
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию

Код:
cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i1=0; i1<10; i1++)
	{
		cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			
			if ((i1==ii1) && (j1==jj1) || (i1==ii2) && (j1==jj2) ||(i1==ii3) && (j1==jj3))
					{
					POLEBOJA1[i1][j1]=245;
					cout << POLEBOJA1[i1][j1] << " ";
					}		
		}
		cout << "\n";
	}
точно! ИЛИ! Да, это упрощает условие))
но есть одно НО - он его не двигает. Вроде бы по J выравнивает, по I не двигает. или наоборот - но он так и привязан к началу координат по I, что странно.
Fanyuus вне форума Ответить с цитированием
Старый 28.11.2012, 20:41   #5
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

1. Скобочки нужно расставить в условии, чтобы был правильный приоритет расчета:
Код:
((i1==ii1) && (j1==jj1)) || ((i1==ii2) && (j1==jj2)) || ((i1==ii3) && (j1==jj3))
2. Почему опять не вынесен вывод элемента из условия? Где вывод не трёхпалубного корабля? Привязан он к началу координат, потому что ничего другого не выводится. При любом раскладе выведется всё в первом столбце, пока этот несчастный cout не уйдет после if между двух закрывающихся фигурных скобок
pu4koff вне форума Ответить с цитированием
Старый 28.11.2012, 21:18   #6
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Несколько концептуальных и не очень замечаний.
1. Инклюды должны выглядеть скорее как-то так:
Код:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <сmath>
#include <cstdio>
#include <conio.h>
(порядок неважен, так просто немного нагляднее). Части стандартной библиотеки Си должны быть вместо <file.h> - <cfile>, плюс у вас дублирование у stdio (в двух вариациях).
2. Пары функций shipplayer и ProverkaPole - если режим "Игрок против Игрока", то нет никакого особого смысла делать по две функции. Просто сделайте по одной и передавайте в качестве аргументов поле то одного, то второго. Если "Игрок против Компьютера", тогда, конечно, есть разница. Но тогда хотя бы назовите функции, чтобы было видно, кто и что в ней делает.
3. Для создания поля игроком есть более эргономичный способ. Как это должно выглядеть: пользователь нажимает клавиши со стрелками, и согласно этим нажатиям текстовый курсор перемещается в пределах поля на одну позицию влево/вверх/вправо/вниз. При нажатии клавиши Enter клетка поля меняется на противоположную (свободна/занята), при нажатии Escape - поле считается законченным. Или можно пробел - поменять, Enter - поле закончено, Escape - отмена.
Можно оставить корректность созданного таким образом поля на совести игрока, можно и сделать потом проверку на корректность. Для начала проще не заморачиваться.
Теперь по поводу того, что вам для реализации этого понадобится. Во-первых, цикл пока пользователь не нажмет клавишу Escape или Enter. Во-вторых, считывать клавишу функцией getch (подключаем conio.h). В-третьих, коды клавиш:
72 - вверх
75 - влево
77 - вправо
80 - вниз
27 - Escape
13 - Enter
Пробел не помню, но это просто ' '. Наконец, в-четвертых, функция gotoxy для перемещения текстового курсора (есть такая, если вы используете, например, C++ Builder, в других средах не факт что есть, но ее аналог легко написать с помощью пары функций WinAPI; в общем, функция не слишком-то переносима, и этим плоха, но в принципе это сейчас не страшно). И не забывайте проверять, не собираетесь ли вы выйти за пределы поля, нажимая в очередной раз стрелочку.
Попробуйте пока сделать сами, если не получится - выложу решение, оно очень простое, но советую вам потренироваться лишний раз.
4. Вообще не стоит лишний раз заморачивать пользователя с индексацией начиная с нуля и цифрами вместо букв. Просто вычитайте единичку из того, что он ввел (от 1 до 10), а буквы можно вбить в константный массив и при вводе пользователем одной такой буквы пробегать массив в поисках введенной буквы, и работать уже с индексом найденной в массиве. Ну а можно в данном случае вообще эту проблему обойти как я написал чуть выше. Ту функцию можно использовать как для создания поля, так и для выбора куда стрелять, только немного доработать напильником.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 29.11.2012, 17:29   #7
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию

pu4koff

Код:
if (((i1==ii1) && (j1==jj1)) || ((i1==ii2) && (j1==jj2)) ||((i1==ii3) && (j1==jj3)))
					{
					POLEBOJA1[i1][j1]=245;
					}	
				
		}cout << POLEBOJA1[i1][j1] << " ";
или

Код:
if (((i1==ii1) && (j1==jj1)) || ((i1==ii2) && (j1==jj2)) ||((i1==ii3) && (j1==jj3)))
					{
					POLEBOJA1[i1][j1]=245;
					}	
                                        cout << POLEBOJA1[i1][j1] << " ";
				
		}
А всё равно не делает))

И тут пока читала и думала про "не трёхпалубный", пришла мысль, что он просто выводит 2 элемента и всё. Только вопрос до сих пор не понятен - почему всё в первом столбце? - ну да ладно.
Мне как бы нужно сделать замену. Смотрю на четырёхпалубник - вроде уже точно так же сделала. Даже там упростила до 1 if с && и ||.


а потом ещё такой момент

Код:
cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i1=0; i1<10; i1++)
	{
		cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			//POLEBOJA1[i1][j1]=48;

			if (((i1==ii1) && (j1==jj1)) || ((i1==ii2) && (j1==jj2)) || ((i1==ii3) && (j1==jj3)) || ((i1==ii4) && (j1==jj4)))
			POLEBOJA1[i1][j1]=245;

			cout << POLEBOJA1[i1][j1] << " ";
			
		} //или даже если сюда поставлю этот сout
		cout << "\n";
	}
значит смотрю я на этот четырёхпалубный и вижу: у него нет "цифры по горизонтали,
цифры по диагонали". Ну ладно, думаю поставлю - ставлю, а у меня ничего не выводит. То есть, "старую песню запевает". Это что за чудеса?!


Гром, идея отличная - будет второй версией морского боя))
хорошо, инклуды подправлю!

если что, я работаю в visual studio 2010

проверила - math.h - другой вариант как ошибка

Последний раз редактировалось Fanyuus; 29.11.2012 в 17:32.
Fanyuus вне форума Ответить с цитированием
Старый 30.11.2012, 21:39   #8
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Попробовал. Вроде работает, вроде так, как планировалось.
Код:
// sea_battle.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <conio.h>
#include <Windows.h>
#include <stdio.h>
#include <cstdio>

using namespace std;

void privetstvie();
void shipplayer1();


char POLEBOJA1[10][10],POLEBOJA2[10][10];

int main()
{
	setlocale (0,"");

	privetstvie();

	cin.get();
	cin.get();
	return 0;
}

void privetstvie()
{
	cout << "\t Это простая программа для игры в морской бой между двумя пользователями на одном компьютере. \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";

	getch();
	system("cls");
	cout << "\t Для удобства игры, мы спользуем числа не от 1 до 10, а от 0 до 9, и \n вместо букв от \"а\" до \"к\" тоже используем цифры от 0 до 9. \n \n \t Приведём пример игрового поля: \n \n";

	int i,j;
	char POLEBOJA[10][10];
	cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i=0; i<10; i++)
	{
		cout << i << " ";
		for (j=0; j<10; j++)
		{
			POLEBOJA[i][j]=48;
			cout << POLEBOJA[i][j] << " ";
			
		}
		cout << "\n";
	}
	cout << "\n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";
	getch();
	system("cls");

	cout << "\n  \t Предлагаем сейчас PLAYER-1 заполнить своё игровое поле. \n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";
	getch();
	system("cls");

	shipplayer1();
	
}

void shipplayer1()
{

	int i1,ii1,ii2,ii3,ii4,j1,jj1,jj2,jj3,jj4,k;

	cout << "\n \t Определим положение четырёхпалубного корабля.\n \n \t Для продолжения нажмити клавишу \"Enter\". \n \n";

	cout << "  0 1 2 3 4 5 6 7 8 9 \n";
	for (i1=0; i1<10; i1++)
	{
		cout << i1 << " ";
		for (j1=0; j1<10; j1++)
		{
			POLEBOJA1[i1][j1]='0';
			cout << POLEBOJA1[i1][j1] << " ";
			
		}
		cout << "\n";
	}


	cout <<" \n Введите 4 координаты для горизонтали клетки корабля \n";
	cin >> ii1 >> ii2 >> ii3 >> ii4;
	cout <<" \n \n Введите 4 координаты для вертикальной клетки корабля \n";
	cin	>> jj1 >> jj2 >> jj3 >> jj4;

	getch();
	system("cls");

	cout << "  0 1 2 3 4 5 6 7 8 9 \n";

	for (i1=0; i1<10; i1++)
	{
		for (j1=0; j1<10; j1++)
		{

			if (((i1==ii1) && (j1==jj1)) ||
				((i1==ii2) && (j1==jj2)) ||
				((i1==ii3) && (j1==jj3)) ||
				((i1==ii4) && (j1==jj4)))
			{
				POLEBOJA1[i1][j1]='4';
			}

			cout << POLEBOJA1[i1][j1] << " ";			
		}
		cout << "\n";
	}


	cout << "\n \t Определим положение трёхпалубных кораблей.\n \n ";
	
	for (k=0; k<2; k++)
	{
		cout << "\n \n \t Введите 3 координаты для горизонтали клетки корабля \n";
		cin >> ii1 >> ii2 >> ii3;
		cout <<" \n \n Введите 3 координаты для вертикальной клетки корабля \n";
		cin	>> jj1 >> jj2 >> jj3;

		getch();
		system("cls");

		cout << "  0 1 2 3 4 5 6 7 8 9 \n";
		for (i1=0; i1<10; i1++)
		{
			cout << i1 << " ";
			for (j1=0; j1<10; j1++)
			{
			
				if (((i1==ii1) && (j1==jj1)) ||
					((i1==ii2) && (j1==jj2)) ||
					((i1==ii3) && (j1==jj3)))
				{
					POLEBOJA1[i1][j1]='3';
				}
				cout << POLEBOJA1[i1][j1] << " ";
			}
			cout << "\n";
		}
		cout << "\n";
	}
	//конец функции "кораблики"
}
pu4koff вне форума Ответить с цитированием
Старый 30.11.2012, 22:16   #9
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию

о боже мой, боже мой! Он работает!)))))
Только, один маленький "косяк" - после введения координат для "4", последний столбец не заполняется. Странно, ну да ладно (причём остальные заполняются).
Всё, буду анализировать, в чём были ошибки.
Спасибо большое!
Fanyuus вне форума Ответить с цитированием
Старый 01.12.2012, 17:32   #10
Fanyuus
Форумчанин
 
Аватар для Fanyuus
 
Регистрация: 07.05.2011
Сообщений: 169
По умолчанию

Всё, ту "проблему" я нашла,
но вот в чём вопрос - коды одинаковые, неужели это из-за того, что я присваивала 48 вместе '0'?
Fanyuus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
создать в Паскале копию игры "Морской бой" Керкси Фолс Помощь студентам 6 17.11.2013 13:19
Игра "Морской бой" на Delphi. С чего начать? Cyxarik Помощь студентам 8 16.02.2011 10:26
Слабо "Морской бой" на ассемблере? =) VenZell Gamedev - cоздание игр: Unity, OpenGL, DirectX 0 26.05.2009 21:36
Расстановка кораблей в игре "Морской бой" [MI_nor] Общие вопросы C/C++ 1 23.05.2009 00:23
"Морской бой" на "Турбе" Cezar Помощь студентам 10 15.05.2007 20:28