Форум программистов, компьютерный форум CyberForum.ru

Консольный морской бой. Stack overflow - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Ошибка в завершении работы программы http://www.cyberforum.ru/cpp-beginners/thread1179046.html
... char s1; std::cout<<"Enter the file name\n"; std::cin>>s1; if ((f=fopen(s1,"r"))==NULL) { perror(""); std::cout<<"please enter someone key to exit...\n"; _getch(); return 2;
C++ Хочу вывести информацию о доступном месте на диске Не могу понять, что не так, ругается на структуру if и else #include<windows.h> #include<iostream> #include<stdio.h> #include<stdlib.h> DWORD FreeBytesAvailable; DWORD TotalNumberOfBytes; DWORD TotalNumberOfFreeBytes; http://www.cyberforum.ru/cpp-beginners/thread1179043.html
Как читать целые числа из файла в аргумент функции без временных переменных? C++
Следующая программа читает первые 2 целых числа, записанные в файле file.txt и передает их как аргументы в функцию foo: #include <iostream> #include <fstream> void foo(int a,int b) { // делаем что-то с a и b; } int main() { std::ifstream ifs("file.txt");
C++ Не подается звуковой сигнал
В общем, должен написать будильник, основную часть сделал, но не подается звуковой сигнал по наступлении заданного времени, скорее всего сравниваю как - то не так, посмотрите, помогите. #include <stdio.h> #include <windows.h> #include <iostream> int main(){ int a,b,c; printf("hours\n"); scanf("%d", &a); printf("minutes\n"); scanf("%d", &b);
C++ Почему в с++ бинарные операции должны перегружаться внешними функциями? http://www.cyberforum.ru/cpp-beginners/thread1179031.html
почему в с++ бинарные операции должны перегружаться внешними функциями?
C++ Метод рунге-кутта 3 порядка дана функция d(y(x))/dx=e^x-2y(x) Нач. условия y(0)=e Код#include<stdio.h> #include<conio.h> #include<math.h> float fun(float x, float y) { return exp(x)-2*y; } подробнее

Показать сообщение отдельно
Michall
 Аватар для Michall
1 / 1 / 0
Регистрация: 31.10.2008
Сообщений: 52
17.05.2014, 19:45     Консольный морской бой. Stack overflow
Вечер добрый! Очень надеюсь на помощь.
Мучаюсь уже который день, уйму часов потратил, а результата нет.

Пытаюсь написать консольный морской бой. Завис на функции ИИ. А именно, чтобы компьютер добивал корабли, по которым он попал (рандомно).

Программу прокомментил, переопределил ключи через дефайны, чтобы не путаться.
Метод set(), единственно, может показать сложным для понимания.
Часть кода в мэйн, отведенную ходу игрока, закомментил.


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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
#include <iostream> // cin, cout
#include <clocale>  // поддержка русского языка
#include <conio.h>  // _getch()
#include <stdlib.h> // поддержка функции очистки экрана system("cls")
#include <ctime>    // srand( static_cast<unsigned int>(time(NULL)) );
#include <iomanip>  // setw()
 
// hits[][] и maps[][]
#define EMPTY 0
#define MISS  1
#define KILL  2
#define HIT   3
 
#define REHIT 4 // повторное попадание
 
// maps[][]
#define ONE     11  // длина корабля в клетках (1, 2, 3, 4)
#define TWO     12
#define THREE   13
#define FOUR    14
#define AROUND  55 // область вокруг корабля (это нужно, чтобы нормально расставлять корабли (не касались друг друга))
 
 
using namespace std;
 
const int s = 13, c = 30; //количество строк и столбцов
enum direction { V, H };     // объединение
 
 
class player{
private:
    int ships[10][10]; // массив кораблей объекта
    int hits[10][10]; // массив "выстрелов" объекта
 
public:
 
    player(){
        for (int i = 0; i<10; i++)
        for (int j = 0; j<10; j++){
            ships[i][j] = EMPTY;
            hits[i][j] = EMPTY;
        }
    } // конструктор
 
    void locateships(){ // поместить в массив ship корабли соответствующей размерности
        set(FOUR);
        set(THREE);
        set(THREE);
        set(THREE);
        set(THREE);
        set(TWO);
        set(TWO);
        set(TWO);
        set(TWO);
        set(ONE);
    }
 
    void set(int size){ // помещение корабля в массив
        size -= 10;
 
        int s, c;
        direction dir; // ориентация (вертикальная или горизонтальная)
        bool b;
        short int cycle = 99;
 
        while (true){
            s = rand() % 10; // случайным образом определяются координаты
            c = rand() % 10; // от 0 до 9
            dir = static_cast<direction>(rand() % 2); // выбираем направление {V, H}
            b = 0;
 
            cycle--;
            if (!cycle){
                cout << "Не удалось расположить все корабли \n";
                for (int i = 0; i<10; i++)
                for (int j = 0; j<10; j++)
                    ships[i][j] = EMPTY;
                locateships();
                break;
            }
 
            if (dir == H){
                ////-------------------------------------------------------------- проверка на касание соседнего корабля
                for (int i = 0; i <size; i++) // не накладывается ли по прямой
                if (ships[s][c + i] == ONE || ships[s][c + i] == TWO || ships[s][c + i] == THREE || ships[s][c + i] == FOUR)
                    b = 1;
 
                if (s<9)        // снизу зона от корабля есть
                for (int i = 0; i <size; i++)
                if (ships[s + 1][c + i] == ONE || ships[s + 1][c + i] == TWO || ships[s + 1][c + i] == THREE || ships[s + 1][c + i] == FOUR)
                    b = 1;
 
                if (s>0)        // сверху зона от корабля есть
                for (int i = 0; i <size; i++)
                if (ships[s - 1][c + i] == ONE || ships[s - 1][c + i] == TWO || ships[s - 1][c + i] == THREE || ships[s - 1][c + i] == FOUR)
                    b = 1;
                if (b == 1)
                    continue;
 
                if (c<10 - size) // справа
                if (ships[s][c + size] == ONE || ships[s][c + size] == TWO || ships[s][c + size] == THREE || ships[s][c + size] == FOUR)
                    continue;
 
                if (c>0)         // слева
                if (ships[s][c - 1] == ONE || ships[s][c - 1] == TWO || ships[s][c - 1] == THREE || ships[s][c - 1] == FOUR)
                    continue;
 
 
 
                if (s<9 && c<10 - size) // снизу, справа
                if (ships[s + 1][c + size] == ONE || ships[s + 1][c + size] == TWO || ships[s + 1][c + size] == THREE || ships[s + 1][c + size] == FOUR)
                    continue;
 
                if (s<9 && c>0)         // снизу, слева
                if (ships[s + 1][c - 1] == ONE || ships[s + 1][c - 1] == TWO || ships[s + 1][c - 1] == THREE || ships[s + 1][c - 1] == FOUR)
                    continue;
 
                if (s>0 && c<10 - size) // сверху, справа
                if (ships[s - 1][c + size] == ONE || ships[s - 1][c + size] == TWO || ships[s - 1][c + size] == THREE || ships[s - 1][c + size] == FOUR)
                    continue;
 
                if (s>0 && c>0)         // сверху, слева
                if (ships[s - 1][c - 1] == ONE || ships[s - 1][c - 1] == TWO || ships[s - 1][c - 1] == THREE || ships[s - 1][c - 1] == FOUR)
                    continue;
                ////------------------------------------------------------
 
                // заполнение соответствующими цифрами
                if (c <= 10 - size)
                for (int i = 0; i <size; i++)
                    ships[s][c + i] = size + 10;
                else
                    continue;
 
                //--------// заполение области вокруг корабля
 
                if (s<9)        //снизу зона от корабля есть
                for (int i = 0; i <size; i++)
                    ships[s + 1][c + i] = AROUND;
                if (s>0)        //сверху зона от корабля есть
                for (int i = 0; i <size; i++)
                    ships[s - 1][c + i] = AROUND;
                if (c<10 - size)   //справа
                    ships[s][c + size] = AROUND;
                if (c>0)           //слева
                    ships[s][c - 1] = AROUND;
 
 
                if (s<9 && c<10 - size) // снизу, справа
                    ships[s + 1][c + size] = AROUND;
                if (s<9 && c>0)         // снизу, слева
                    ships[s + 1][c - 1] = AROUND;
                if (s>0 && c<10 - size) // сверху, справа
                    ships[s - 1][c + size] = AROUND;
                if (s>0 && c>0)         // сверху, слева
                    ships[s - 1][c - 1] = AROUND;
 
 
            } //if (dir == H)
 
            if (dir == V){
 
                ////--------------------------------------------------------------------- проверка на касание соседнего корабля
                for (int i = 0; i <size; i++) // не накладывается ли по прямой
                if (ships[s + i][c] == ONE || ships[s + i][c] == TWO || ships[s + i][c] == THREE || ships[s + i][c] == FOUR)
                    b = 1;
 
                if (c<9)        //снизу зона от корабля есть
                for (int i = 0; i <size; i++)
                if (ships[s + i][c + 1] == ONE || ships[s + i][c + 1] == TWO || ships[s + i][c + 1] == THREE || ships[s + i][c + 1] == FOUR)
                    b = 1;
 
                if (c>0)        //сверху зона от корабля есть
                for (int i = 0; i <size; i++)
                if (ships[s + i][c - 1] == ONE || ships[s + i][c - 1] == TWO || ships[s + i][c - 1] == THREE || ships[s + i][c - 1] == FOUR)
                    b = 1;
                if (b == 1)
                    continue;
 
                if (s<10 - size)   //справа
                if (ships[s + size][c] == ONE || ships[s + size][c] == TWO || ships[s + size][c] == THREE || ships[s + size][c] == FOUR)
                    continue;
 
                if (s>0)         //слева
                if (ships[s - 1][c] == ONE || ships[s - 1][c] == TWO || ships[s - 1][c] == THREE || ships[s - 1][c] == FOUR)
                    continue;
 
 
 
                if (c<9 && s<10 - size) // снизу, справа
                if (ships[s + size][c + 1] == ONE || ships[s + size][c + 1] == TWO || ships[s + size][c + 1] == THREE || ships[s + size][c + 1] == FOUR)
                    continue;
 
                if (c<9 && s>0)        // снизу, слева
                if (ships[s - 1][c + 1] == ONE || ships[s - 1][c + 1] == TWO || ships[s - 1][c + 1] == THREE || ships[s - 1][c + 1] == FOUR)
                    continue;
 
                if (c>0 && s<10 - size) // сверху, справа
                if (ships[s + size][c - 1] == ONE || ships[s + size][c - 1] == TWO || ships[s + size][c - 1] == THREE || ships[s + size][c - 1] == FOUR)
                    continue;
 
                if (c>0 && s>0)        // сверху, слева
                if (ships[s - 1][c - 1] == ONE || ships[s - 1][c - 1] == TWO || ships[s - 1][c - 1] == THREE || ships[s - 1][c - 1] == FOUR)
                    continue;
                ////---------------------------------------------------
 
 
                if (s <= 10 - size)
                for (int i = 0; i <size; i++)
                    ships[s + i][c] = size + 10;
                else
                    continue;
 
                //--------// заполение области вокруг корабля
 
                if (c<9)        //снизу зона от корабля есть
                for (int i = 0; i <size; i++)
                    ships[s + i][c + 1] = AROUND;
                if (c>0)        //сверху зона от корабля есть
                for (int i = 0; i <size; i++)
                    ships[s + i][c - 1] = AROUND;
                if (s<10 - size)   //справа
                    ships[s + size][c] = AROUND;
                if (s>0)           //слева
                    ships[s - 1][c] = AROUND;
 
                if (c<9 && s<10 - size) // снизу, справа
                    ships[s + size][c + 1] = AROUND;
                if (c<9 && s>0)         // снизу, слева
                    ships[s - 1][c + 1] = AROUND;
                if (c>0 && s<10 - size) // сверху, справа
                    ships[s + size][c - 1] = AROUND;
                if (c>0 && s>0)         // сверху, слева
                    ships[s - 1][c - 1] = AROUND;
            } //if (dir == V)
 
            break;
        } //while(true)
    } // void set(int size)
 
    void fill_map(char map[s][c]){ // заполнить первое поле кораблями
        for (int i = 0; i<10; i++)
        for (int j = 0; j<10; j++)
        if (ships[i][j] == ONE || ships[i][j] == TWO || ships[i][j] == THREE || ships[i][j] == FOUR)
            map[i + 2][j + 2] = 'H';
    }
    void fill_map2(char map[s][c], int& i, int& j){ // отметить на втором поле выстрелы
        if (hits[i][j] == MISS)
            map[i + 2][j + 18] = '.';
        if (hits[i][j] == KILL)
            map[i + 2][j + 18] = 'D';
        if (hits[i][j] == HIT)
            map[i + 2][j + 18] = 'X';
    }
 
    void fill_map3(char map[s][c]){ //вывод кораблей во 2м поле( используется для теста)
        for (int i = 0; i<10; i++)
        for (int j = 0; j<10; j++)
        if (ships[i][j] == ONE || ships[i][j] == TWO || ships[i][j] == THREE || ships[i][j] == FOUR)
            map[i + 2][j + 18] = 'H';
    }
 
 
 
    int killorhit(const int& y, const int& x){ // 1 - KILL, 2 - JUST HIT
 
        int m1 = 0, m2 = 0, m3 = 0, m4 = 0;
 
        if (ships[y + 1][x] == HIT || ships[y - 1][x] == HIT || ships[y][x + 1] == HIT || ships[y][x - 1] == HIT){ //если рядом подбитая клетка
 
            if (ships[y][x] == TWO)// при этоv корабль был 2-х клеточным
                return KILL;
 
            if (ships[y][x] == THREE){ // трех клеточный
                if (ships[y + 1][x] == HIT)
                    m1++;
                if (ships[y - 1][x] == HIT)
                    m2++;
                if (ships[y][x + 1] == HIT)
                    m3++;
                if (ships[y][x - 1] == HIT)
                    m4++;
 
                //   if ((m1 + m2 + m3 + m4) == 2) //если корабль 3-х палубный и подбиты все 3 клетки (клетки по обе стороны)
                //       return KILL;
 
                if (m1 == 1) // если через клетку еще 1 палуба тоже потоплена
                if (ships[y + 2][x] == HIT)
                    return KILL;
                if (m2 == 1)
                if (ships[y - 2][x] == HIT)
                    return KILL;
                if (m3 == 1)
                if (ships[y][x + 2] == HIT)
                    return KILL;
                if (m4 == 1)
                if (ships[y][x - 2] == HIT)
                    return KILL;
 
                return HIT; // иначе просто попадание!
            } // if(ships[y][x] == 3)
 
            if (ships[y][x] == FOUR){ // 4-клеточный
                if (ships[y + 1][x] == HIT)//проверяем смежные клетки, если они подбиты (и являются часть корабля), то ++
                    m1++;
                if (ships[y - 1][x] == HIT)
                    m2++;
                if (ships[y][x + 1] == HIT)
                    m3++;
                if (ships[y][x - 1] == HIT)
                    m4++;
 
                /*    if ((m1 + m2 + m3 + m4) == 2){ //если корабль 4-х палубный и подбиты 2 смежные клетки ( по обе стороны)
 
                if (m1 == 1){//если в горизонт. плоскости
                if (ships[y + 2][x] == HIT || ships[y - 2][x] == HIT)
                return KILL;
                }
 
                if (m3 == 1){//если в верт. пл.
                if (ships[y][x + 2] == HIT || ships[y][x - 2] == HIT)
                return KILL;
                }
                } */
                if ((m1 + m2 + m3 + m4) == 1){
                    if (m1 == 1){
                        if (ships[y + 2][x] == HIT && ships[y + 3][x] == HIT)
                            return KILL;
                    }
                    if (m2 == 1){
                        if (ships[y - 2][x] == HIT && ships[y - 3][x] == HIT)
                            return KILL;
                    }
                    if (m3 == 1){
                        if (ships[y][x + 2] == HIT && ships[y][x + 3] == HIT)
                            return KILL;
                    }
                    if (m4 == 1){
                        if (ships[y][x - 2] == HIT && ships[y][x - 3] == HIT)
                            return KILL;
                    }
                } //if ((m1+m2+m3+m4)==1)
                return HIT;
            } // if(ships[y][x]==4)       
        } // if (ships[y+1][x] == HIT || ships[y-1][x] == HIT || ships[y][x+1] == HIT ||ships[y][x-1] == HIT)
        return HIT; // если рядом нет подбитых клеток
    } // int killorhit(int& y, int& x)
 
 
    int does_he_shot_me(int& y, int& x){ // что произошло от выстрела по мне 0 - miss, 1 - kill, 2 - hit
 
        if ((ships[y][x] == EMPTY) || (ships[y][x] == AROUND))
            return MISS; // miss
        if (ships[y][x] == ONE)
            return KILL; // kill
        if (ships[y][x] == TWO || ships[y][x] == THREE || ships[y][x] == FOUR)
            //проверить, есть ли рядом подбитые клетки кораблей
            return killorhit(y, x); // kill or hit
        if (ships[y][x] == MISS || ships[y][x] == KILL || ships[y][x] == HIT)
            return REHIT; // miss, но сюда уже стреляли
    }
 
    // для доступа к private
    void setship(int& y, int& x, int z){
        ships[y][x] = z;
    }
    void addhit(int& y, int& x, int& z){
        hits[y][x] = z;
    }
    int returnhit(int& y, int& x){
        return hits[y][x];
    }
 
 
    void print_number() //отладочная2
    {
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++)
                cout << setw(4) << ships[i][j] << setw(0);
            cout << "\n";
        }
    }
 
}; // конец описания класса player
 
 
inline void print_out(char map[s][c]){
    for (int i = 0; i < s; i++){
        for (int j = 0; j < c; j++)
            cout << map[i][j]; // в циклах поэлементно выводится массив
        cout << "\n"; // переход на новую строку после каждого "ряда"
    }
}
 
 
void do_you_shot_there(player& gamer, int& y, int& x, char map[s][c]){ //ввод координат выстрела и их проверка
    cout << endl << endl;
    while (true){
        cout << "Введите y и x: ";
        cin >> y >> x;
        if (gamer.returnhit(y, x) == EMPTY) // пусто - не стрелял сюда
            break;
        if (gamer.returnhit(y, x) == MISS || gamer.returnhit(y, x) == KILL || gamer.returnhit(y, x) == HIT){ // попал или мимо - стрелял уже сюда
            system("cls");
            print_out(map);// напечатать доску заново
            cout << endl << "Вы уже стреляли сюда (" << y << ", " << x << ")!\n";
            continue;
        }
    }
}
 
 
/*
int* k = new int;
int* flag = new int; // если равен нулю - выбираем клетку рандомно, если 1 - вручную
int* y2 = new int, *x2 = new int;
int* endeavour = new int; // номер попытки добить корабль
int* helper2 = new int;
int* helper3 = new int;*/
 
void funcAI(player& PC, player& you, char map[s][c], int& t){
 
    static int k = 0;
    static int flag = 0; // если равен нулю - выбираем клетку рандомно, если 1 - вручную
    static int y2 = 0, x2 = 0;
    static int endeavour = 0; // номер попытки добить корабль
    static int helper3 = 0;
 
    static int m[100][2] = { { 0 } };
    int y = 0, x = 0;
 
 
    if (flag == 0) // выбираем клетку автоматически (рандомно)
    while (true){
        y = rand() % 10; // случайным образом определяются координаты
        x = rand() % 10; // от 0 до 9
        if (!PC.returnhit(y, x)) // если в эту точку мы еще не стреляли // (... == 0)
            break;
    }
 
    if (flag == 1){ // выбираем клетку с помощью алгоритма
        if (k == 1){
            x = x2 + 1;  //при первой попытке добивания - стреляю правее
            if (x>9 && endeavour == 1){ // если выходит за границы поля (при первом попадании) ищем другую точку
                x--; // возвращаю обратно значение
                k += 1;
            }
            y = y2;
        }
        if (k == 2){
            x = x2 - 1; // стреляю левее
            if (x<0 && endeavour == 1){
                x++;
                k += 1;
            }
            y = y2;
        }
        if (k == 3){
            x = x2; // стреляю ниже
            y = y2 + 1;
            if (y>9 && endeavour == 1){
                y--;
                k += 1;
            }
        }
        if (k == 4){
            x = x2; // стреляю выше
            y = y2 - 1;
            if (y<0 && endeavour == 1){
                y++;
                k += 1;
            }
        }
 
        if (k == 5){
            k = 1;
            x = x2;
            y = y2;
 
            /*  cout << " WTF?! Code: 003 y=" << y << " x=" << x << endl;
            for (int i = 0; i<t; i++){
            cout << setw(2) << m[i][0] << setw(3) << m[i][1] << endl;
            }
 
            _getch();*/
        }
 
        if (x>9 || x<0 || y>9 || y<0){ // если точка вышла за границы поля helper3 = 1;
            // cout << "Shit 1 k=" << k; //char p=_getch();
            if (k == 1){// справа
                x--;
            }
            if (k == 2){// слева
                x++;
            }
            if (k == 3){// снизу
                y--;
            }
            if (k == 4){// сверху
                y++;
            }
            helper3 = 1;
        }
    }
 
    int z = you.does_he_shot_me(y, x); // ( выстрел по вам ) что произошло
    //PC.addhit(y, x, z); /// сюда можно добавить you.setship(,,,+you)
    /// перенес в конец
 
    if (z == REHIT){ // если уже стрелял в эту точку
        if (endeavour == 1){
            k += 1;
            //t--;     // либо так, либо рекурсию
            //return;  //
            funcAI(PC, you, map, t);
        }
    }
 
    if (z == REHIT || z == MISS){
        if (!helper3 && z == MISS){
            you.setship(y, x, MISS); // не попали данным выстрелом
            map[y + 2][x + 2] = '.';
        }
        if (helper3){//обратно возвращаю координаты на прежнее место, чтобы работали с функциями
            if (k == 1){// справа
                x++;
            }
            if (k == 2){// слева
                x--;
            }
            if (k == 3){// снизу
                y++;
            }
            if (k == 4){// сверху
                y--;
            }
        }
 
        if (k && endeavour == 1){// есть пытался добить, но мимо
            k += 1; // пробуем еще раз // т.е определяю ориентацию корабля
        }
 
        bool helper = 1; // помогает выполнить лишь одно условие в ветлении if
        if (endeavour == 2){ // если было два в ряд (попадания), а сейчас промахнулись, стрельнем по клетке, что была соседней с первоначальной(куда попали первый раз), располагающаяся в том же направлении выстрелов
            if (k == 1 && helper){
                x2 -= 1;
                k = 2;
                helper = 0;                   // разворачиваемся
            }
            if (k == 2 && helper){
                x2 += 1;
                k = 1;
                helper = 0;
            }
            if (k == 3 && helper){
                y2 -= 1;
                k = 4;
                helper = 0;
            }
            if (k == 4 && helper){
                y2 += 1;
                k = 3;
                helper = 0;
            }
        }
 
        if (endeavour == 3){// если было три в ряд (попадания), а сейчас промахнулись, стрельнем по клетке, что была соседней с первоначальной(куда попали первый раз), располагающаяся в том же направлении выстрелов
            if (k == 1 && helper){
                x2 -= 2;
                k = 2;
                helper = 0;
            }
            if (k == 2 && helper){
                x2 += 2;
                k = 1;
                helper = 0;
            }
            if (k == 3 && helper){
                y2 -= 2;
                k = 4;
                helper = 0;
            }
            if (k == 4 && helper){
                y2 += 2;
                k = 3;
                helper = 0;
            }
        }
 
        if (helper3){
            helper3 = 0; // обнуляем
            //t--; return; //
            funcAI(PC, you, map, t); // стреляем
        }
    }
 
    if (z == KILL){
        you.setship(y, x, KILL); // заношу инфу, что убили корабль
        map[y + 2][x + 2] = 'D';       // отображаю результат выстрела на карте
 
        k = 0;    // если убили, сбрасываем вариатор выстрела
        flag = 0; // выключаем флаг поиска клетки по алгоритму (теперь снова ищем случайным образом)
        endeavour = 0; // обнуляем очередь попаданий
    }
    if (z == HIT){
        you.setship(y, x, HIT); // заношу инфу, что попали в корабль /// есть в функции addhit
        map[y + 2][x + 2] = 'X';       // отображаю результат выстрела на карте
 
        endeavour += 1; // увеличиваю счетчик попыток убить корабль
 
        if (k == 0 && endeavour == 1){ // если это 1й вызов
            // _getch();
            flag = 1; // следующую клетку будем выбирать вручную
            y2 = y;   //запоминаю координаты попадания (именно первого)
            x2 = x;
            k = 1;    // теперь нужно проверить соседние клетки
        }
 
        if (k && (endeavour == 2 || endeavour == 3)){ // если 2й  или 3й выстрел также попал, но не убил, сдвигаемся на следующую клетку
            if (k == 1)
                x2 += 1;
            if (k == 2)
                x2 -= 1;
            if (k == 3)
                y2 += 1;
            if (k == 4)
                y2 -= 1;
        }
 
    }
    PC.addhit(y, x, z); /// сюда можно добавить you.setship(,,,+you)
 
    //_getch();
    m[t][0] = y;
    m[t][1] = x;
}
 
 
 
int main()
{
    srand(static_cast<unsigned int>(time(NULL))); // установка начального значения генератора случайных чисел
    setlocale(LC_CTYPE, "Russian");
 
    char map[s][c] = {
        "  0123456789      0123456789 ",
        " #----------#    #----------#",
        "0|          |   0|          |",
        "1|          |   1|          |",
        "2|          |   2|          |",
        "3|          |   3|          |",
        "4|          |   4|          |",
        "5|          |   5|          |",
        "6|          |   6|          |",
        "7|          |   7|          |",
        "8|          |   8|          |",
        "9|          |   9|          |",
        " #----------#    #----------#" };
 
    player you;
    player computer;
 
    you.locateships(); // разместить корабли
    you.fill_map(map); // теперь отметить их на доске
    //  you.print_number();
    //  _getch();
 
 
    computer.locateships();
    computer.fill_map3(map);// показать корабли противника на карте // тестовая ф.
 
    int y, x, z;
 
    int t = 0;
 
 
    while (true)
    {
        system("cls");  // вызов функции очистки экрана
        print_out(map); // напечатать доску
 
        cout << " t=" << t;
 
        /// этот кусок кода давно не редактировал, так и был закомменчен
        /*do_you_shot_there(you,y,x,map);
 
        z=computer.does_he_shot_me(y,x); // если убил - 1, мимо - 0, ранил - 2
        if(z==0)
        cout << "Miss! ";
        if(z==1)
        cout << "Kill! ";
        if(z==2)
        cout << "Hit! ";
 
 
        you.addhit(y,x,z, computer);      // в hits[y][x] добавляю 1 - мимо, 2 - килл, 3 - попал. (0 - по-умолчанию)
        you.fill_map2(map,y,x); // отмечаю на 2 поле выстрел совершенный
        */
 
 
 
        funcAI(computer, you, map, t);
        t++;
 
        if (t == 100)
            break;
 
    } //while (true)
 
 
    system("cls");
    print_out(map);
    cout << " t=" << t << " End";
//
    _getch();
    return 0;
}




В 33% случаев программа зависает. Обычно это происходит потому, что происходит попадание по кораблю, но вместо того, чтобы добить, опять ищется радномноя точка (!), и при повторном попадании по этому кораблю, программа все-таки уже пытается добить, но добивает, из-за описанного ранее, – в середине. (По алгоритму такое невозможно, добивающий выстрел всегда будет "сбоку" корабля.) И все.

Отладчик Visual 2013 говорит вот что:
-> does_he_shot_me()
Необработанное исключение по адресу 0x00205D29 в ConsoleApplication1_BattleShip.exe: 0xC00000FD: Stack overflow (параметры: 0x00000001, 0x003B2F58).
Выглядит так, что второй параметр в функцию передается какой-то абсолютно левый, хотя в другом окошке Вижуала показано, что параметры нормальные, от 0 до 9.

если нажать "Продолжить":
->funcAI()
Необработанное исключение по адресу 0x00205D29 в ConsoleApplication1_BattleShip.exe: 0xC0000005: нарушение прав доступа при записи по адресу 0x003B0FA0.

Помимо этого, почему-то на 100 итерации цикла в мэйн иногда остаются точки, в которые не производись выстрелы (если увеличить число итераций, то все точки добьются). А один раз цикл остановился на 99 итерации.

Пробовал убирать рекурсивные вызовы функции (заместо этого лишнюю итерации проводил), вместо статических переменных использовал указатели, но результат не менялся.

По идее (не факт, по-моему), это стек переполняется. Но каким боком это выходит при такой простой программе?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 22:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru