Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.64/14: Рейтинг темы: голосов - 14, средняя оценка - 4.64
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
1

Консольная игра, не могу разобраться со ссылками

04.05.2019, 18:35. Просмотров 2916. Ответов 36
Метки нет (Все метки)

Всем приветик! Делаю игру, в которой игрок и комп бросают кубик

класс игрока:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <string>
#include <iostream>
#pragma once
using namespace std;
 
class Player
{
public:
    string name;
    int playerScore;
    int playerThrows;
 
    Player()
    {
 
    }
    
    void playerThrow(int& playerScore, int& playerThrows, bool& gameover, string& goOn)
    {
        int t = 1 + rand() % 6; //t=throw
        if (t == 1)
        {
            playerScore = t * 0;
        }
        else playerScore += t;
 
        playerThrows += 1;
        gameover = (playerScore >= 0);
 
        
        cout << "Your throw was: " << t << endl;
        cout << "Your total score = " << playerScore << endl;
        cout << "You throw a bone " << playerThrows << endl;
        cout << "Wanna do one more throw? [y/n]" << endl;
 
        cin >> goOn;
    }
};
сама программа

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "Player.h"
#include "Computer.h"
#include <iostream>
 
 
using namespace std;
 
 
 
int main()
{
    string name;
    string goOn;
    bool gameover = false;
 
    cout << "Tell me your name?" << endl;
    getline(cin, name);
    cout << "Hey, " << name << "!" << endl;
 
    Player firstPlayer;
 
    
    firstPlayer.name = name;
    firstPlayer.playerScore = 0;
    firstPlayer.playerThrows = 0;
    
 
    Computer comp;
    comp.name = "Computer";
    comp.compScore = 0;
    comp.compThrows = 0;
    
    int playerFirstThrow = 1 + rand() % 6;
    int compFirstThrow = 1 + rand() % 6;
    cout << "Player's first throw was: " << playerFirstThrow << endl;
    cout << "Comp's first throw was: " << compFirstThrow << endl;
    cout << endl;
 
    if (playerFirstThrow >= compFirstThrow)
    {
        //игрок делает первым серию бросков
        cout << endl;
        cout << "Player throws first!" << endl;
        cout << endl;
 
        while (!gameover)
        {
            do
            {
                firstPlayer.playerThrow(firstPlayer.playerScore, firstPlayer.playerThrows, gameover, goOn);
            } while (goOn == "y" && firstPlayer.playerScore > 0 && !gameover);
                if (gameover) break;
        
            cout << endl;
            cout << ">>>> It's computer's turn now!" << endl;
            cout << endl;
 
            do
            {
                comp.compThrow(comp.compScore, comp.compThrows, gameover);
            } while (comp.compScore > 0 && !gameover);
        }
    }
    else {
        //компьютер делает первым серию бросков
        cout << endl;
        cout << "Comp throws first!" << endl;
        cout << endl;
 
        while (!gameover)
        {
            do
            {
                comp.compThrow(comp.compScore, comp.compThrows, gameover);
            } while (comp.compScore > 0 && !gameover);
                
                cout << endl;
                cout << ">>>> It's player's turn now!" << endl;
                cout << endl;
            do
            {
                firstPlayer.playerThrow(firstPlayer.playerScore, firstPlayer.playerThrows, gameover, goOn);
            } while (goOn == "y" && firstPlayer.playerScore > 0 && !gameover);
            
            if (gameover) break;
        }
    }
 
    if (firstPlayer.playerScore > comp.compScore)
    {
        cout << firstPlayer.name << " won with the score: " << firstPlayer.playerScore << endl;
    }
 
    else if (comp.compScore > firstPlayer.playerScore)
    {
        cout << comp.name << " won with the score: " << comp.compScore << endl;
    }
 
    else
        cout << "Draw! Friendship won!" << endl;
 
 
    system("pause");
    return 0;
}
Никак не получается сделать, чтобы метод firstPlayer.playerThrow(firstPlayer.playerScore, firstPlayer.playerThrows, gameover, goOn) работал с переменной bool gameover = false;
В момент, когда доходит до gameover = (playerScore >= 0); - она принимает значение true и игра заканчивается

Добавлено через 15 минут
Ещё получается он записывает счёт в переменную playerScore, а должен в firstPlayer.playerScore
чуть обновила метод
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void playerThrow(int playerScore, int playerThrows, bool gameover, string goOn)
    {
        this->playerScore = playerScore;
        this->playerThrows = playerThrows;
 
        int t = 1 + rand() % 6; //t=throw
        if (t == 1)
        {
            playerScore = t * 0;
        }
        else playerScore += t;
 
        playerThrows += 1;
        gameover = (playerScore >= 0);
 
        
        cout << "Your throw was: " << t << endl;
        cout << "Your total score = " << playerScore << endl;
        cout << "You throw a bone " << playerThrows << endl;
        cout << "Wanna do one more throw? [y/n]" << endl;
 
        cin >> goOn;
    }
теперь счёт записывается правильно, а gameover по прежнему true ставит. Как сделать, чтобы метод работал с тем bool gameover = false;, который в main инициализирован?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.05.2019, 18:35
Ответы с готовыми решениями:

Консольная игра в 21
Вообще это только реализация алгоритма игры, но работает. Если кому сильно заняться нечем-гляньте...

Полиморфизм и консольная игра
Всем привет! Можно ли написать какую-то консольную игру вроде змейки на c++, но используя...

Консольная игра с кубиком
Решил написать консольную игру: игрок и компьютер кидают кубик и счет выводится на экран. Дело в...

Моя первая консольная игра :D
Всем доброго времени суток! Сегодня я хочу показать вам свою первую игру, правда пока она работает...

36
5 / 5 / 0
Регистрация: 04.05.2019
Сообщений: 32
04.05.2019, 18:47 2
Я вообще не эксперт конешно и наверное просто ничего не понимаю, но в каком куске кода у: playerScore появляется возможность стать отрицательным, чтобы (playerScore => 0) было false?

Добавлено через 3 минуты
Это как вариант
1) Глобальная константа bool TrueGameOver = false;
2)Передавать в качестве аргумента ещё одно занчение bool TrueGameOver, на ряду с обычным gameover
0
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 18:48  [ТС] 3
Цитата Сообщение от Clagron Посмотреть сообщение
чтобы (playerScore => 0) было false?
точно, ошибкочка, должно быть playerScore => 100
Правда теперь значение firstPlayer.playerScore = 0; не меняется, т.е после броска кубика он результат не приплюсовывает и firstPlayer.playerThrows = 0; тоже не считаются
0
6 / 4 / 2
Регистрация: 04.05.2019
Сообщений: 9
04.05.2019, 19:06 4
kulichiki96, надо инициализировать данные класса в конструкторе, иначе непонятно, какое значение они примут.
Чтобы менять значения полей класса надо писать this->playerScore =0.
0
5 / 5 / 0
Регистрация: 04.05.2019
Сообщений: 32
04.05.2019, 19:08 5
Последний дурацки вопрос на сегодня:
rand() выдаёт разные значения?
просто не видно под него классической пары в виде какого-нить srand(time(NULL));

P.S. Я слишком ленивый шоб читать код каюсь
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 19:12 6
Цитата Сообщение от kulichiki96 Посмотреть сообщение
Как сделать, чтобы метод работал с тем bool gameover = false;, который в main инициализирован?
в первопосте вы дали два варианта метода playerThrow(...)
для того чтобы работать(изменять) с внешней переменной gameover используйте ccылку:
void playerThrow(int playerScore, int playerThrows, bool& gameover, string goOn)
{
...
}
1
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 19:17  [ТС] 7
Цитата Сообщение от Clagron Посмотреть сообщение
rand() выдаёт разные значения?
да, только когда первые броски идут
C++
1
2
3
4
5
    int playerFirstThrow = 1 + rand() % 6;
    int compFirstThrow = 1 + rand() % 6;
    cout << "Player's first throw was: " << playerFirstThrow << endl;
    cout << "Comp's first throw was: " << compFirstThrow << endl;
    cout << endl;
Всегда выпадает 6 и 6

Подскажите как починить? или как написать правильно используя rand(time(NULL));

Добавлено через 3 минуты
Цитата Сообщение от XLAT Посмотреть сообщение
для того чтобы работать(изменять) с внешней переменной gameover используйте ccылку:
void playerThrow(int playerScore, int playerThrows, bool& gameover, string goOn)
{
...
}
сейчас выглядит так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <string>
#include <iostream>
#pragma once
using namespace std;
 
class Player
{
public:
    string name;
    int playerScore;
    int playerThrows;
    bool gameover = false;
 
    Player()
    {
 
    }
    
    void playerThrow(int& playerScore, int& playerThrows, bool& gameover, string& goOn)
    {
        this->playerScore = playerScore;
        this->playerThrows = playerThrows;
        this->gameover = gameover;
 
        int t = 2 + rand() % 6; //t=throw
        if (t == 1)
        {
            playerScore = t * 0;
        }
        else playerScore += t;
 
        playerThrows += 1;
        gameover = (playerScore >= 100);
 
        
        cout << "Your throw was: " << t << endl;
        cout << "Your total score = " << playerScore << endl;
        cout << "You throw a bone " << playerThrows << endl;
        cout << "Wanna do one more throw? [y/n]" << endl;
 
        cin >> goOn;
    }
};
поправила по вашему совету. Плюс сделала int& playerScore, int& playerThrows, иначе он не суммирует очки и броски
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 19:18 8
т.к. playerScore, playerThrows поля класса, то правильно использовать только такие аргументы,
которые не являются данными текущего объекта класса.
вот так:
C++
1
2
3
4
void playerThrow(bool& gameover, string& goOn)
{
...
}
1
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 19:18  [ТС] 9
XLAT,

this->gameover = gameover; и bool gameover = false; убрать из класса? С этими ссылками и указателями пока не совсем освоилась
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 19:26 10
Цитата Сообщение от kulichiki96 Посмотреть сообщение
this->gameover = gameover; и bool gameover = false; убрать из класса?
если вам нужна внутри класса переменная gameover, то чтобы их не путать дайте им разные имена.

в семантике вашей проги я не пытаюсь разбираться, но чисто логически хотелось бы иметь только одну переменную, через которую передавалось бы завершение игры.
Совет: избавьтесь от альтернативной gameover.
1
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 19:28  [ТС] 11
и ещё вопросик:

вот в этой части кода:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
while (!gameover)
        {
            do
            {
                firstPlayer.playerThrow(gameover, goOn);
            } while (goOn == "y" && firstPlayer.playerScore > 0 && !gameover);
            if (gameover) break;
        
            cout << endl;
            cout << ">>>> It's computer's turn now!" << endl;
            cout << endl;
 
            do
            {
                comp.compThrow(gameover);
            } while (comp.compScore > 0 && !gameover);
        }
Получается, что если я набью больше 100 очков, например 101 - я выиграю, не дав компьютеру сделать ни 1 броска

Код компьютера

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <string>
#include <iostream>
#pragma once
using namespace std;
 
class Computer
{
public:
    string name;
    int compScore;
    int compThrows;
    //bool gameover = false;
 
 
    void compThrow(bool& gameover)
    {
        this->compScore = compScore;
        this->compThrows = compThrows;
        //this->gameover = gameover;
 
        int t = 1 + rand() % 6; //t=throw
        if (t == 1)
        {
            compScore = t * 0;
        }
        else compScore += t;
 
        compThrows += 1;
        gameover = (compThrows >= 100);
 
 
        cout << "Comp's throw was: " << t << endl;
        cout << "Comp's total score = " << compScore << endl;
        cout << "Comp throw a bone " << compThrows << endl;
        cout << endl;
    }
};
Как бы сделать так, что если я набрала больше 100 очков - ход перешёл к компьютеру, возможно он наберёт 102 очка и победит
0
5 / 5 / 0
Регистрация: 04.05.2019
Сообщений: 32
04.05.2019, 19:39 12
По поводу вопроса о рандоме
Цитата Сообщение от kulichiki96 Посмотреть сообщение
Подскажите как починить? или как написать правильно используя rand(time(NULL));
вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <cstdlib>
#include <ctime>
 
 
class ExampleClass
{
    private:
        int ExampleVar;
    public:
        ExampleClass();
        
        void ExampleRandomizer(int LeftBorder=0, int RightBorder=1)
        {
            ExampleVar=LeftBorder+rand()%RightBorder;
        }
        int GiveExapleVar()
        {
            return ExampleVar;
        }
};
 
ExampleClass::ExampleClass()
{
    ExampleVar=0;
}
 
int main(void)
{
    srand(time(NULL));
    ExampleClass Example;
    std::cout << "Before: " <<  Example.GiveExapleVar() << "\nAfter: ";
    Example.ExampleRandomizer(1,6);
    std::cout << Example.GiveExapleVar();
    return 0;
}
Собственно srand() задаёт правило для rand(), а time(NULL) выступает в качестве динамически меняющейся переменной.
1
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 19:40  [ТС] 13
Цитата Сообщение от XLAT Посмотреть сообщение
в семантике вашей проги я не пытаюсь разбираться, но чисто логически хотелось бы иметь только одну переменную, через которую передавалось бы завершение игры.
у меня gameover используется для цикла do (игрок бросает кубик, пока не выпадет 100 и более очков или не выбросит единицу, тогда ход переходит к следующему игроку)

Цикл while (!gameover) - хочу условия поменять, что завершается, как только кто-то из игроков наберёт 100+ очков

сделала так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
while (firstPlayer.playerScore < 100 || comp.compScore < 100)
        {
            do
            {
                firstPlayer.playerThrow(gameover, goOn);
            } while (goOn == "y" && firstPlayer.playerScore > 0 && !gameover);
            if (gameover) break;
        
            cout << endl;
            cout << ">>>> It's computer's turn now!" << endl;
            cout << endl;
 
            do
            {
                comp.compThrow(gameover);
            } while (comp.compScore > 0 && !gameover);
        }
набрала 102 очка, ход компьютеру не передался, сразу написало, что я победила
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 19:46 14
C++
29
30
/// Только четное число бросков решает будет ли сделан выход из игры:
gameover = (playerScore >= 0) && ((playerThrows+compThrows)%2 == 0);
это нужно править, подгонять к вашей логике.
т.е. учитывать общее количество бросков

Добавлено через 3 минуты
Цитата Сообщение от kulichiki96 Посмотреть сообщение
у меня gameover используется для цикла do (игрок бросает кубик, пока не выпадет 100 и более очков или не выбросит единицу, тогда ход переходит к следующему игроку)
вот только щас мне стало ясно

если такие правила, тогда зачем передавать то ход, если игрок набрал овер 100 очков?
0
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 19:49  [ТС] 15
XLAT,

Цикл while (!gameover) - хочу условия поменять, что завершается, как только кто-то из игроков наберёт 100+ очков

сделала так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
while (firstPlayer.playerScore < 100 || comp.compScore < 100)
        {
            do
            {
                firstPlayer.playerThrow(gameover, goOn);
            } while (goOn == "y" && firstPlayer.playerScore > 0 && !gameover);
            if (gameover) break;
        
            cout << endl;
            cout << ">>>> It's computer's turn now!" << endl;
            cout << endl;
 
            do
            {
                comp.compThrow(gameover);
            } while (comp.compScore > 0 && !gameover);
        }
т.е. gameover использовать только для того, чтобы в случае, если игрок выбросил 1 и обнулился счёт - ход передается компьютеру
набрала 102 очка, ход компьютеру не передался, сразу написало, что я победила

Добавлено через 37 секунд
Цитата Сообщение от XLAT Посмотреть сообщение
если такие правила, тогда зачем передавать то ход, если игрок набрал овер 100 очков?
а вдруг комп наберёт 101 очко? а так я ему шансов не даю))
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 19:57 16
Цитата Сообщение от kulichiki96 Посмотреть сообщение
как написать правильно используя rand(time(NULL));
C++
1
2
3
4
5
/// Инициализация генератора псевдослучайных чисел:
#include <time.h>
int main()
{   
    srand(static_cast<unsigned int>(time(NULL)));
Добавлено через 4 минуты
смотрите внимательно:
C++
1
2
3
4
do
{
    comp.compThrow(gameover);
} while (comp.compScore > 0 && !comp.gameover);
0
5 / 5 / 0
Регистрация: 04.05.2019
Сообщений: 32
04.05.2019, 20:00 17
Цитата Сообщение от kulichiki96 Посмотреть сообщение
Подскажите как починить? или как написать правильно используя rand(time(NULL));
Тут кстати ещё вместо time(NULL) можно подавать данные из какой-нибудь самописной функции...

ну или из другого рандома к примеру:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <cstdlib>
#include <ctime>
 
#define PRIME 1701
 
unsigned int PositiveRandom(const int LB, const int RB)
{
    const time_t t=time(NULL);
    int i,hash=LB;
    char* n_t=ctime(&t);
    for(i=0;n_t[i]!=0;i++)
    {
        hash=(256*hash+n_t[i])%PRIME;
    }
    return hash%RB;
}
int main()
{
    int LeftBorder=0,RightBorder=100;
    srand(PositiveRandom(LeftBorder,RightBorder));
    std::cout << PositiveRandom(LeftBorder,RightBorder) << "\n" << rand();
    //Наш рандом и наш рандом запиханый в стандартный рандом :D
    
    return 0;
}
(немножечко несерьёзности)
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 20:06 18
Логичнее заменить gameover(тот который в классе) на Throweover,
чтобы переменная отражала свой смысл.

Цитата Сообщение от Clagron Посмотреть сообщение
можно подавать данные из какой-нибудь самописной функции...
от нажатой клавиши, например )

Вот щас реально ясно почему возникла такая тема с таким вопросом.
Совет на будующее: всегда называйте вещи своими именами!
gameover в классе не является флажком окончания игры, это флажок окончания серии бросков!

Добавлено через 2 минуты
+ в первопосте class Player не имел никакой переменной gameover.
0
3 / 3 / 0
Регистрация: 01.02.2019
Сообщений: 67
04.05.2019, 20:09  [ТС] 19
Цитата Сообщение от XLAT Посмотреть сообщение
смотрите внимательно:
прошлась отладчиком, после того, как я набрала 101 очко выполнился if (gameover) break;
соответственно из цикла вышел

Добавлено через 2 минуты
Цитата Сообщение от Clagron Посмотреть сообщение
вот:
как бы у меня попроще выглядит, выбрасывает числа от 1 до 6 (как я и хотела). Вот только при первых бросках
C++
1
2
int playerFirstThrow = 1 + rand() % 6;
    int compFirstThrow = 1 + rand() % 6;
всегда и комп и игрок выкидывают 6, несправедливо
0
бах-бах и в продакшен!
1693 / 1004 / 381
Регистрация: 23.09.2014
Сообщений: 3,243
Записей в блоге: 4
04.05.2019, 20:11 20
Цитата Сообщение от kulichiki96 Посмотреть сообщение
соответственно из цикла вышел
я могу отрефакторить ваш код, но вы его не узнаете

Добавлено через 1 минуту
Цитата Сообщение от kulichiki96 Посмотреть сообщение
всегда и комп и игрок выкидывают 6, несправедливо
еще раз:
C++
1
2
3
4
5
/// Инициализация генератора псевдослучайных чисел:
#include <time.h>
int main()
{   
    srand(static_cast<unsigned int>(time(NULL)));
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.05.2019, 20:11

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

Не могу разобраться с ссылками и все!!
Первоначальный вид ссылок!! Код HTML &lt;a href=&quot;?tip=1&quot; class=&quot;menu&quot;&gt;Главная&lt;/a&gt; &lt;a...

Не могу разобраться в проекте Игра в напёрстки
Уважаемые форумчане, помогите, пожалуйста, написать код &quot;javascript&quot; или &quot;jquery&quot; в этой простейшей...

Игра крестики нолики, не могу разобраться с циклом не нахожу ошибку
Код еще не дописан во функции main но компилятор уже ругается на цикл whileбподстажите что нужно...

2D консольная игра
Хотел сделать с графикой ТЕТРИС, но потом подумал, что неплохо попробовать прощупать сначала такую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.