Don't like ads? PRO users don't see any ads ;-)
Guest

Sea battle - finished (fixed consts)

By: VilgO on Aug 5th, 2012  |  syntax: C++  |  size: 11.80 KB  |  hits: 20  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <iostream>
  2. #include <fstream>
  3. #include <map>
  4. using namespace std;
  5.  
  6. const int SHIPAMOUNT = 10; // Количество кораблей
  7. const int MAXLENGTH = 4;   // Максимальная длина корабля
  8. const int DECKMAX[MAXLENGTH+1] = {0, 4, 3, 2, 1}; // Максимум кораблей длиной i
  9.  
  10. class player
  11. {
  12. public:
  13.         int playernum;
  14.        
  15.         map<char,bool> hit[SHIPAMOUNT]; // Поле попаданий
  16.         map<char,int>  shipmap[SHIPAMOUNT]; // Поле кораблей. Если значение равно SHIPAMOUNT, то корабля нет, иначе - номер корабля.
  17.         player* enemy;
  18.        
  19.         class ship
  20.         {
  21.         public:
  22.                 int  npos;  // Числовая координата
  23.                 char cpos;  // Буквенная координата
  24.                 int length; // Длина корабля
  25.                 int health; // Оставшиеся клетки
  26.                 bool hor;   // Корабль расположен горизонтально
  27.                 bool alive; // Корабль жив
  28.         };
  29.         ship shp[SHIPAMOUNT];
  30.         int nextship;
  31.  
  32.         int deckamount[MAXLENGTH+1]; // Количество кораблей длиной i
  33.  
  34.         bool ready;
  35.         int shipsleft;
  36.  
  37.         // Создаёт и очищает поля, устанавливает начальные значения переменных
  38.         void preset(int a, player* b)
  39.         {
  40.                 for (int num = 0; num < SHIPAMOUNT; num++)
  41.                 for (char chr = 'A'; chr <= 'J'; chr++)
  42.                 {
  43.                         shipmap[num][chr]=SHIPAMOUNT;  // Корабли игрока
  44.                         hit[num][chr]=false;  // Выстрелы по игроку
  45.                 }
  46.                 nextship=0;
  47.                 shipsleft=SHIPAMOUNT;
  48.                 playernum=a;
  49.                 enemy=b;
  50.                 ready=false;
  51.  
  52.                 for (int i = 0; i <= MAXLENGTH; i++) deckamount[i]=0;
  53.         }
  54.  
  55.         // Попадание по координатам
  56.         void hitship(int npos, char cpos) //Аргументы - координаты
  57.         {
  58.                 if ( !hit[npos][cpos] ) shp[shipmap[npos][cpos]].health--;
  59.                 if ( shp[shipmap[npos][cpos]].health==0 )
  60.                 {
  61.                         shp[shipmap[npos][cpos]].alive=false;
  62.                         cout << "Sunk!" << endl;
  63.                         shipsleft--;
  64.                         if ( shipsleft==0 ) cout << "You win!" << endl;
  65.                 }
  66.                 hit[npos][cpos]=true;
  67.         }
  68.  
  69.         // Игрок стреляет. Функция возвращает номер игрока, который ходит следующим, или 0, если партия закончена.
  70.         int shoot(int pnum, player* p) // Аргументы - номер игрока, который делает ход, и указатель на другого игрока
  71.         {
  72.                 showmap();
  73.                 char npos,cpos;
  74.                 bool correct;
  75.                 do
  76.                 {
  77.                         cout << "Type coordinates." << endl;
  78.                         cin >> npos;
  79.                         cin >> cpos;
  80.                         cpos=toupper(cpos);
  81.                         if ( npos > '9' || npos < '0' )
  82.                         {
  83.                                 correct = false;
  84.                                 cout << "Numeric coordinate incorrect.";
  85.                         }
  86.                         else if ( cpos > 'J' || cpos < 'A' )
  87.                         {
  88.                                 correct = false;
  89.                                 cout << "Character coordinate incorrect.";
  90.                         }
  91.                         else correct=true;
  92.                 } while (!correct);
  93.                 npos-='0';
  94.  
  95.                 if ( (*p).shipmap[npos][cpos]<SHIPAMOUNT ) // Если на карте другого игрока в ячейке с координатами npos и cpos лежит число < SHIPAMOUNT
  96.                 {
  97.                         cout << "Hit!" << endl;
  98.                         (*p).hitship(npos,cpos); // Запоминаем попадание
  99.                         if ( (*p).shipsleft>0 ) return pnum; // Если у другого игрока остались корабли, возвращаем номер этого игрока
  100.                         else return 0; // Иначе возвращаем 0 - это означает, что игра закончена
  101.                 }
  102.                 else
  103.                 {
  104.                         cout << "Miss!" << endl;
  105.                         (*p).hit[npos][cpos]=true; // Запоминаем, что по этим координатам стреляли
  106.                         if (pnum==1) return 2; // Возвращаем номер другого игрока
  107.                         else return 1;
  108.                 }
  109.         }
  110.  
  111.         void recordship(int num, char chr, int length, bool hor)
  112.         {
  113.                 shp[nextship].npos=num;
  114.                 shp[nextship].cpos=chr;
  115.                 shp[nextship].length=length;
  116.                 shp[nextship].hor=hor;
  117.                 shp[nextship].alive=true;
  118.                 shp[nextship].health=length;
  119.                 deckamount[length]++;
  120.                
  121.                 if (hor)
  122.                         for (int j = chr; j < chr+length; j++)
  123.                                 shipmap[num][j]=nextship;
  124.                 else
  125.                         for (int i = num; i < num+length; i++)
  126.                                 shipmap[i][chr]=nextship;
  127.  
  128.                 nextship++;
  129.         }
  130.  
  131.         bool shipcollision(int num, char chr, int length, bool hor)
  132.         {
  133.                 if (hor)
  134.                         for (int i=num-1; i <= num+1; i++)
  135.                                 for (int j=chr-1; j <= chr+length; j++)
  136.                                         if ( (i >= 0 && i < SHIPAMOUNT) && (j >= 'A' && j <= 'J') )
  137.                                                 if (shipmap[i][j] < SHIPAMOUNT)
  138.                                                 {
  139.                                                         cout << "Collision detected: " << i << char(j) << endl;
  140.                                                         return true;
  141.                                                 }
  142.                                                 else;
  143.                                         else;
  144.                 else
  145.                         for (int i=num-1; i <= num+length; i++)
  146.                                 for (int j=chr-1; j <= chr+1; j++)
  147.                                         if ( (i >= 0 && i < SHIPAMOUNT) && (j >= 'A' && j <= 'J') )
  148.                                                 if (shipmap[i][j] < SHIPAMOUNT)
  149.                                                 {
  150.                                                         cout << "Collision detected: " << i << char(j) << endl;
  151.                                                         return true;
  152.                                                 }
  153.                                                 else;
  154.                                         else;
  155.                 return false;
  156.         }
  157.  
  158.         // Добавляет корабль или выводит, что корабль не помещается
  159.         void addship(int num, char chr, int length, bool hor) // Номер клетки, буква клетки (заглавная), длина корабля, корабль горизонтальный.
  160.         {
  161.                 if (deckamount[length] < DECKMAX[length])
  162.                         if (hor)
  163.                                 if (chr-'A'+length > 10) cout << "Not enough place" << endl;
  164.                                 else
  165.                                         if (shipcollision(num, chr, length, hor)) cout << "Another ship nearby." << endl;
  166.                                         else recordship(num, chr, length, hor);
  167.                         else
  168.                                 if (num+length > 10) cout << "Not enough place" << endl;
  169.                                 else
  170.                                         if (shipcollision(num, chr, length, hor)) cout << "Another ship nearby." << endl;
  171.                                         else recordship(num, chr, length, hor);
  172.                 else cout << "Too many " << length << "-deck ships." << endl;
  173.  
  174.                 if (nextship==SHIPAMOUNT) ready=true;
  175.                 else ready=false;
  176.         }
  177.  
  178.         /*
  179.         cout << "╔═╤══════════╦═╤══════════╗" << endl;
  180.         cout << "║#│ABCDEFGHIJ║#│ABCDEFGHIJ║" << endl;
  181.         cout << "╟─┼──────────╫─┼──────────╢" << endl;
  182.         cout << "║0│          ║0│          ║" << endl;
  183.         cout << "║1│          ║1│          ║" << endl;
  184.         cout << "║2│          ║2│          ║" << endl;
  185.         cout << "║3│          ║3│          ║" << endl;
  186.         cout << "║4│          ║4│          ║" << endl;
  187.         cout << "║5│          ║5│          ║" << endl;
  188.         cout << "║6│          ║6│          ║" << endl;
  189.         cout << "║7│          ║7│          ║" << endl;
  190.         cout << "║8│          ║8│          ║" << endl;
  191.         cout << "║9│          ║9│          ║" << endl;
  192.         cout << "╚═╧══════════╩═╧══════════╝" << endl;
  193.         */
  194.  
  195.         void showmap()
  196.         {
  197.                 // Right field is enemy player's field
  198.  
  199.                 //cout << "╔═╤══════════╦═╤══════════╗" << endl;
  200.                 cout << char(201) << char(205) << char(209);
  201.                 for (int i = 0; i < 10; i++) cout << char(205);
  202.                 cout << char(203) << char(205) << char(209);
  203.                 for (int i = 0; i < 10; i++) cout << char(205);
  204.                 cout << char(187) << endl;
  205.  
  206.                 //cout << "║#│ABCDEFGHIJ║#│ABCDEFGHIJ║" << endl;
  207.                 cout << char(186) <<'#' << char(179) << "ABCDEFGHIJ" << char(186) << '#' << char(179) << "ABCDEFGHIJ" << char(186) << endl;
  208.  
  209.                 //cout << "╟─┼──────────╫─┼──────────╢" << endl;
  210.                 cout << char(199) << char(196) << char(197);
  211.                 for (int i = 0; i < 10; i++) cout << char(196);
  212.                 cout << char(215) << char(196) << char(197);
  213.                 for (int i = 0; i < 10; i++) cout << char(196);
  214.                 cout << char(182) << endl;
  215.  
  216.                
  217.                 //cout << "║0│          ║0│          ║" << endl;
  218.                 //cout << "║1│          ║1│          ║" << endl;
  219.                 //cout << "║2│          ║2│          ║" << endl;
  220.                 //cout << "║3│          ║3│          ║" << endl;
  221.                 //cout << "║4│          ║4│          ║" << endl;
  222.                 //cout << "║5│          ║5│          ║" << endl;
  223.                 //cout << "║6│          ║6│          ║" << endl;
  224.                 //cout << "║7│          ║7│          ║" << endl;
  225.                 //cout << "║8│          ║8│          ║" << endl;
  226.                 //cout << "║9│          ║9│          ║" << endl;
  227.                 for (int i = 0; i < 10; i++)
  228.                 {
  229.                         cout << char(186) << i << char(179);
  230.                         for (int j = 'A'; j <= 'J'; j++)
  231.                                 if (shipmap[i][j]<10) cout << shipmap[i][j];
  232.                                 else cout << ' ';
  233.  
  234.                         cout << char(186) << i << char(179);
  235.                         for (int j = 'A'; j <= 'J'; j++)  
  236.                                 if ((*enemy).hit[i][j])                                      // Если был выстрел
  237.                                         if ((*enemy).shipmap[i][j]<10)                                                          // Если есть корабль
  238.                                                 if ((*enemy).shp[shipmap[i][j]].alive) cout << 'X';                     // Если корабль жив - вывести 'X'
  239.                                                 else cout << char(219);                                                                         // Иначе вывести '█'
  240.                                         else cout << '*';                                                                                       // Иначе вывести '*'
  241.                                 else cout << ' ';                                                                                        // Иначе вывести ' '
  242.                         cout << char(186) << endl;
  243.                 }
  244.                
  245.                 //cout << "╚═╧══════════╩═╧══════════╝" << endl;
  246.                 cout << char(200) << char(205) << char(207) ;
  247.                 for (int i = 0; i < 10; i++) cout << char(205) ;
  248.                 cout << char(202) << char(205) << char(207) ;
  249.                 for (int i = 0; i < 10; i++) cout << char(205) ;
  250.                 cout << char(188) << endl;
  251.         }
  252.  
  253.         void getships()
  254.         {
  255.                 ship inship;
  256.                 char c[256];
  257.                 int lchar;
  258.  
  259.                 showmap();
  260.                 do
  261.                 {
  262.                         cout << "Ship #" << nextship << endl;
  263.  
  264.                         cout << "Type ship coordinates, length, direction (H or V)." << endl;
  265.                         //correct=true;
  266.                         //errortype="Input correct.";
  267.                         cin.getline(c,256);
  268.                         lchar=0;
  269.                         if (c[lchar] < '0' || c[lchar] > '9') cout << "Numeric coordinate incorrect." << endl;
  270.                         else
  271.                         {
  272.                                 inship.npos=c[lchar]-'0';
  273.                                 lchar++;
  274.  
  275.                                 if (toupper(c[lchar]) < 'A' || toupper(c[lchar]) > 'J') cout << "Character coordinate incorrect." << endl;
  276.                                 else
  277.                                 {
  278.                                         inship.cpos=toupper(c[lchar]);
  279.                                         lchar+=2;
  280.  
  281.                                         if (c[lchar] < '0' || c[lchar] > '4') cout << "Length incorrect." << endl;
  282.                                         else
  283.                                         {
  284.                                                 inship.length=c[lchar]-'0';
  285.                                                 lchar+=2;
  286.  
  287.                                                 if (toupper(c[lchar]) == 'H' || inship.length == 1)
  288.                                                 {
  289.                                                         inship.hor=true;
  290.                                                         addship(inship.npos,inship.cpos,inship.length,inship.hor);
  291.                                                 }
  292.                                                 else if (toupper(c[lchar]) == 'V')
  293.                                                 {      
  294.                                                         inship.hor=false;
  295.                                                         addship(inship.npos,inship.cpos,inship.length,inship.hor);
  296.                                                 }
  297.                                                 else cout << "Direction incorrect." << endl;
  298.  
  299.                                         }
  300.                                 }
  301.                         }
  302.                         showmap();
  303.                 }
  304.                 while (!ready);
  305.         }
  306. };
  307.  
  308. int main()
  309. {
  310.         // Объявления
  311.         player p[3];
  312.         p[1].playernum=1;
  313.         p[2].playernum=2;
  314.         bool keepplaying;
  315.         int num;
  316.         char chr;
  317.         int playerfase=1;
  318.        
  319.         // Начало
  320.         cout << "Game starts now." << endl;
  321.         do
  322.         {
  323.                 cout << "First player arranges ships." << endl;
  324.                 p[1].preset(1,&p[2]);
  325.                 p[1].getships();
  326.                 cout << "Second player arranges ships." << endl;
  327.                 p[2].preset(2,&p[1]);
  328.                 p[2].getships();
  329.  
  330.                 do
  331.                 {
  332.                         if (playerfase==1)
  333.                         {
  334.                                 cout << "First player shoots." << endl;
  335.                                 do // Передаём номер игрока и указатель на другого игрока
  336.                                 playerfase=p[1].shoot(1,&p[2]); // Возвращает номер игрока, который ходит после.
  337.                                 while (playerfase==1);
  338.                         }
  339.                         if (playerfase==2)
  340.                         {
  341.                                 cout << "Second player shoots." << endl;
  342.                                 do playerfase=p[2].shoot(2,&p[1]);
  343.                                 while (playerfase==2);
  344.                         }
  345.                 }
  346.                 while (playerfase);
  347.  
  348.                 cout << "Type 'Y' if you want to play again. Otherwise, type 'N'" << endl;
  349.                 cin >> chr;
  350.                 if (toupper(chr)=='Y') keepplaying=true;
  351.                 else keepplaying=false;
  352.         }
  353.         while (keepplaying);
  354.  
  355.         return 0;
  356. }