Pacman

Тема в разделе "LANGS.C", создана пользователем Antolflash, 29 ноя 2009.

  1. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Пишу пакмана, точнее - вариацию на тему.
    Пишу под консоль винды. Может ли функция ReadConsoleInput не останавливать исполнения программы, ожидая события? Т.е. буфер событий заполняется всё время исполнения программы, а сама функция при вызове лишь записывает его в мой массив. Как я понимаю без многопоточности это не реализуемо. Придёся читать msdn.

    И ещё. Помогите реализовать волновой алгоритм (метод у меня называется intellect). Как он работает я понял, а вот реализовать - в голову не идёт.

    Моя прога работает так: карта представляет собой массив структуры, содержащей битовые поля.

    Прошу помощи, с одной стороны хочется сделать, а с другой время поджимет. Могу вообще забить, но я уже погрузился в задачу, очень обидно её бросать.

    Код (Text):
    1. #include <iostream>
    2. //#include <stdio.h>
    3. //#include <conio.h>
    4. #include <windows.h>
    5. //#include <stdlib.h>
    6. //#include <process.h>
    7. #include <time.h>
    8. #include <math.h>
    9. #include <conio.h>
    10.  
    11.  // 174еда  0стена 164зло 169пак
    12. class MOVING_UNITS {
    13. protected:
    14.     enum direction { Up, Right, Left, Down } dir;
    15.     virtual bool move(direction dir, int x, int y) = 0;
    16.  };
    17.  
    18.  
    19. class WALL {
    20. protected:
    21.     virtual void place_walls() = 0;
    22.     unsigned char wall_smile;
    23.     WORD wall_attr;
    24.     int MAX_WALL_LENGTH;
    25.     int NUMBER_OF_WALLS;
    26.     WALL();    
    27. };
    28.  
    29. WALL::WALL()
    30. {
    31.     MAX_WALL_LENGTH = 3;
    32.     NUMBER_OF_WALLS = 4;
    33.     wall_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    34.     wall_smile = 0;
    35. }
    36.  
    37.  
    38. class PACMAN : protected MOVING_UNITS {
    39. protected:
    40.     virtual void place_pacman() = 0;
    41.     unsigned char pacman_smile;
    42.     WORD pacman_attr;
    43.     PACMAN();
    44.  
    45. };
    46.  
    47. PACMAN::PACMAN()
    48. {
    49.     pacman_smile = 169;
    50.     pacman_attr = FOREGROUND_GREEN | BACKGROUND_RED;
    51. }
    52.  
    53.  
    54. class EVIL : protected MOVING_UNITS {
    55. protected:
    56.     virtual void place_evils() = 0;
    57.     virtual void intellect(int x, int y) = 0;
    58.     int NUMBER_OF_EVILS;
    59.     unsigned char evil_smile;
    60.     WORD evil_attr;
    61.     EVIL();
    62. };
    63.  
    64. EVIL::EVIL()
    65. {
    66.     evil_smile = 164;
    67.     evil_attr = FOREGROUND_RED;
    68.     NUMBER_OF_EVILS = 1;
    69. }
    70.  
    71. class FOOD {
    72. protected:
    73.     virtual void place_food() = 0;
    74.     int NUMBER_OF_FOOD;
    75.     unsigned char food_smile;
    76.     WORD food_attr;
    77.     int food_counter;
    78.     FOOD();
    79. };
    80.  
    81. FOOD::FOOD()
    82. {
    83.     food_smile = 174;
    84.     food_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    85.     NUMBER_OF_FOOD = 2;
    86.     food_counter = 0;
    87. }
    88.  
    89. class WORLD_MAP : protected WALL, protected PACMAN, protected EVIL, protected FOOD {
    90.     int WORLD_SIZE_X, WORLD_SIZE_Y;
    91.     struct WORLD_MAP_STRUCT {
    92.         unsigned Wall: 1;
    93.         unsigned Evil: 1;
    94.         unsigned Turn: 1;
    95.         unsigned Food: 1;
    96.         unsigned Space: 1;
    97.                
    98.     } *map;
    99.  
    100.     struct PACMAN_COORDINATE {
    101.         int _X_;
    102.         int _Y_;
    103.     } pac;
    104.  
    105.  
    106.    
    107.     HANDLE hConsoleOutput;
    108.     COORD dwCursorPosition;
    109.     WCHAR cCharacter;
    110.     DWORD lpNumberOfCharsWritten;
    111.     DWORD lpNumberOfAttrsWritten;
    112.  
    113.     HANDLE hConsoleInput;
    114.     INPUT_RECORD lpBuffer[128];
    115.     DWORD lpNumberOfEventsRead;
    116.    
    117.     unsigned char space_smile;
    118.     WORD space_attr;
    119.     WORD prev_key;
    120.     void place_walls();
    121.     void place_food();
    122.     void place_evils();
    123.     void place_pacman();
    124.     bool move(direction dir, int x, int y);
    125.     void paint(int x, int y);
    126.     void intellect(int x, int y);
    127.     void Game();
    128.     void KeyEventProc(int x, int y);
    129. public:
    130.     WORLD_MAP();
    131. };
    132.  
    133. void WORLD_MAP::intellect(int x, int y)
    134. {  
    135.    
    136.     Sleep(100);
    137.     if(abs(x - pac._X_) > abs(y - pac._Y_)) {
    138.         if(x > pac._X_) {
    139.             if(move(Left, x, y))
    140.                 ;
    141.             else {
    142.                 if(move(Up, x, y))
    143.                     ;
    144.                 else
    145.                     move(Down, x, y);
    146.             }
    147.         }
    148.         else if(move(Right, x, y))
    149.                 ;
    150.         else {
    151.             if(y > pac._Y_) {
    152.                 if(move(Up, x, y))
    153.                     ;
    154.             }
    155.             else
    156.                 move(Down, x, y);
    157.         }  
    158.     }
    159. // *******************************************************
    160.     else {
    161.         if(y > pac._Y_) {
    162.             if(move(Up, x, y))
    163.                 ;
    164.             else {
    165.                 if(move(Left, x, y))
    166.                     ;
    167.                 else
    168.                     move(Right, x, y);
    169.             }
    170.         }
    171.         else if(move(Down, x, y))
    172.             ;
    173.         else {
    174.             if(move(Left, x, y))
    175.                 ;
    176.             else
    177.                 move(Right, x, y);
    178.         }
    179.     }
    180. }
    181.  
    182.  
    183.  
    184. void WORLD_MAP::paint(int x, int y)
    185. {
    186.     dwCursorPosition.X = x;
    187.     dwCursorPosition.Y = y;
    188.     WORD wAttribute;
    189.  
    190.     if((x == pac._X_) && (y == pac._Y_)) {
    191.         cCharacter = pacman_smile;
    192.         wAttribute = pacman_attr;
    193.     }
    194.    
    195.     else if((map[y*WORLD_SIZE_X+x].Space) && (map[y*WORLD_SIZE_X+x].Food) ) {
    196.             cCharacter = food_smile;
    197.             wAttribute = food_attr;
    198.     }
    199.    
    200.     else if(map[y*WORLD_SIZE_X+x].Space) {
    201.             cCharacter = space_smile;
    202.             wAttribute = space_attr;
    203.     }
    204.    
    205.     else if(map[y*WORLD_SIZE_X+x].Evil) {
    206.         cCharacter = evil_smile;
    207.         wAttribute = evil_attr;
    208.     }
    209.  
    210.     else if(map[y*WORLD_SIZE_X+x].Wall) {
    211.         cCharacter = wall_smile;
    212.         wAttribute = wall_attr;
    213.     }
    214.  
    215.     else
    216.         return;
    217.    
    218.     FillConsoleOutputAttribute(hConsoleOutput, wAttribute, 1, dwCursorPosition, &lpNumberOfAttrsWritten);
    219.     FillConsoleOutputCharacter(hConsoleOutput, cCharacter, 1, dwCursorPosition, &lpNumberOfCharsWritten);  
    220. }
    221.  
    222. void WORLD_MAP::KeyEventProc(int x, int y)
    223. {
    224.    
    225.     if(map[pac._Y_*WORLD_SIZE_X+pac._X_].Evil) {
    226.         FreeConsole();
    227.         AllocConsole();
    228.         std::cout << "You loose!";
    229.         getch();
    230.         exit(0);
    231.     }
    232.    
    233.    
    234.     //38вверх 37влево 40вниз 39вправо
    235.     Sleep(150);
    236.     WCHAR smth = lpBuffer[0].Event.KeyEvent.wVirtualKeyCode;
    237.     switch(smth) {
    238.         case 38:
    239.             prev_key = 38;
    240.             if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    241.                 food_counter++;
    242.                 map[(y-1)*WORLD_SIZE_X+x].Food = false;
    243.             }
    244.             pac._Y_--;
    245.             if(!move(Up, x, y))
    246.                 pac._Y_++;
    247.             break;
    248.         case 37:
    249.             prev_key = 37;
    250.             if(map[y*WORLD_SIZE_X+x-1].Food) {
    251.                 food_counter++;
    252.                 map[y*WORLD_SIZE_X+x-1].Food = false;
    253.             }
    254.             pac._X_--;
    255.             if(!move(Left, x, y))
    256.                 pac._X_++;
    257.                
    258.             break;
    259.         case 39:
    260.             prev_key = 39;
    261.             if(map[y*WORLD_SIZE_X+x+1].Food) {
    262.                 food_counter++;
    263.                 map[y*WORLD_SIZE_X+x+1].Food = false;
    264.             }
    265.             pac._X_++;
    266.             if(!move(Right, x, y))
    267.                 pac._X_--;
    268.             break;
    269.         case 40:
    270.             prev_key = 40;
    271.             if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    272.                 food_counter++;
    273.                 map[(y+1)*WORLD_SIZE_X+x].Food = false;
    274.             }
    275.             pac._Y_++;
    276.             if(!move(Down, x, y))
    277.                 pac._Y_--;
    278.             break;
    279.        
    280.         default:
    281.             switch(prev_key) {
    282.  
    283.                 case 38:
    284.                     if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    285.                         food_counter++;
    286.                         map[(y-1)*WORLD_SIZE_X+x].Food = false;
    287.                     }
    288.                     pac._Y_--;
    289.                     if(!move(Up, x, y))
    290.                         pac._Y_++;
    291.                     break;
    292.                 case 37:
    293.                     if(map[y*WORLD_SIZE_X+x-1].Food) {
    294.                         food_counter++;
    295.                         map[y*WORLD_SIZE_X+x-1].Food = false;
    296.                     }
    297.                     pac._X_--;
    298.                     if(!move(Left, x, y))
    299.                         pac._X_++;
    300.                        
    301.                     break;
    302.                 case 39:
    303.                     if(map[y*WORLD_SIZE_X+x+1].Food) {
    304.                         food_counter++;
    305.                         map[y*WORLD_SIZE_X+x+1].Food = false;
    306.                     }
    307.                     pac._X_++;
    308.                     if(!move(Right, x, y))
    309.                         pac._X_--;
    310.                     break;
    311.                 case 40:
    312.                     if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    313.                         food_counter++;
    314.                         map[(y+1)*WORLD_SIZE_X+x].Food = false;
    315.                     }
    316.                     pac._Y_++;
    317.                     if(!move(Down, x, y))
    318.                         pac._Y_--;
    319.                     break;
    320.  
    321.                 default:
    322.                     //std::cout << "AA";
    323.                     break;
    324.                
    325.    
    326.             }
    327.             break;
    328.     }
    329.  
    330.     if(food_counter >= NUMBER_OF_FOOD) {
    331.         FreeConsole();
    332.         AllocConsole();
    333.         std::cout << "You win!";
    334.         getch();
    335.         exit(0);
    336.     }
    337.  
    338.  
    339.     for(y=0; y<WORLD_SIZE_Y; y++)
    340.         for(x=0; x<WORLD_SIZE_X; x++)
    341.             map[y*WORLD_SIZE_X+x].Turn = false;
    342.  
    343.  
    344.     for(y=0; y<WORLD_SIZE_Y; y++)
    345.         for(x=0; x<WORLD_SIZE_X; x++)
    346.             if((map[y*WORLD_SIZE_X+x].Evil) && (!(map[y*WORLD_SIZE_X+x].Turn)))
    347.                 intellect(x, y);           
    348. }
    349.  
    350.  
    351. void WORLD_MAP::Game()
    352. {      
    353.     int x, y;
    354.     std::cout << "\nGame starts!";
    355.     FreeConsole();
    356.     AllocConsole();
    357.    
    358.  
    359.    
    360.  
    361.     hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    362.     hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
    363.  
    364.     for(x=0; x<WORLD_SIZE_X; x++)
    365.         for(y=0; y<WORLD_SIZE_Y; y++)
    366.             paint(x, y);
    367.    
    368.     while(true) {
    369.  
    370.    
    371.         ReadConsoleInput(hConsoleInput, lpBuffer, 128, &lpNumberOfEventsRead); //как scanf, пока не произойдёт событие, выполнять программу дальше не будет
    372.  
    373.         KeyEventProc(pac._X_, pac._Y_);
    374.  
    375.    
    376.  
    377.  
    378.  
    379.  
    380.     }
    381. }
    382.                
    383.    
    384.  
    385. void WORLD_MAP::place_pacman()
    386. {
    387.     int x, y;
    388.     std::cout << "\nGenerating pacman...";
    389.     srand(time(0));
    390.     do {
    391.         x = abs( (rand()) % WORLD_SIZE_X );
    392.         y = abs( (rand()) % WORLD_SIZE_Y );
    393.     }
    394.     while(   !( (map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food) )   );
    395.     pac._X_ = x;
    396.     pac._Y_ = y;
    397. }
    398.  
    399. void WORLD_MAP::place_food()
    400. {
    401.     int x, y, i;
    402.     std::cout << "\nGenerating food...";
    403.     srand(time(0));
    404.     for(i=0; i<NUMBER_OF_FOOD; i++) {
    405.         x = abs( (rand()) % WORLD_SIZE_X );
    406.         y = abs( (rand()) % WORLD_SIZE_Y );
    407.         if(map[y*WORLD_SIZE_X+x].Space)
    408.             map[y*WORLD_SIZE_X+x].Food = true;
    409.         else
    410.             i--;       
    411.     }
    412. }
    413.  
    414. void WORLD_MAP::place_evils()
    415. {
    416.     int x, y, i;
    417.     std::cout << "\nGenerating evils...";
    418.     srand(time(0));
    419.     for(i=0; i<NUMBER_OF_EVILS; i++) {
    420.         x = abs( (rand()) % WORLD_SIZE_X );
    421.         y = abs( (rand()) % WORLD_SIZE_Y );
    422.         if(map[y*WORLD_SIZE_X+x].Space && (!map[y*WORLD_SIZE_X+x].Food)) {
    423.             map[y*WORLD_SIZE_X+x].Evil = true;
    424.             map[y*WORLD_SIZE_X+x].Space = false;
    425.         }
    426.         else
    427.             i--;
    428.     }
    429. }
    430.  
    431. void WORLD_MAP::place_walls()
    432. {
    433.     int x, y, i, j;
    434.     std::cout << "\nGenerating walls...";
    435.     for(i=0; i<NUMBER_OF_WALLS; i++) {
    436.         srand(time(0));
    437.         x = abs( (rand()) % WORLD_SIZE_X );
    438.         y = abs( (rand()) % WORLD_SIZE_Y );
    439.  
    440.         for(j=0; j<MAX_WALL_LENGTH; j++) {
    441.             if((map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food)) {
    442.                 map[y*WORLD_SIZE_X+x].Wall = true;
    443.                 map[y*WORLD_SIZE_X+x].Space = false;
    444.             }
    445.             else
    446.                 j--;
    447.             x = abs( (rand()) > 16000 ? (x+1)%WORLD_SIZE_X : (x-1)%WORLD_SIZE_X );
    448.             y = abs( (rand()) > 16000 ? (y+1)%WORLD_SIZE_Y : (y-1)%WORLD_SIZE_Y );
    449.         }
    450.     }
    451. }
    452.  
    453. WORLD_MAP::WORLD_MAP()
    454. {
    455.     int i, j;
    456.     std::cout << "This is pacman!";
    457.     prev_key = 0;
    458.     WORLD_SIZE_X = 25;
    459.     WORLD_SIZE_Y = 15;
    460.     map = new WORLD_MAP_STRUCT [WORLD_SIZE_X*WORLD_SIZE_Y];
    461.     space_smile = 199;
    462.     space_attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_BLUE;
    463.  
    464.     for(i=0; i<WORLD_SIZE_Y; i++)
    465.         for(j=0; j<WORLD_SIZE_X; j++) {
    466.             map[i*WORLD_SIZE_X+j].Space = true;
    467.             map[i*WORLD_SIZE_X+j].Food = false;
    468.             map[i*WORLD_SIZE_X+j].Wall = false;
    469.             map[i*WORLD_SIZE_X+j].Evil = false;
    470.             map[i*WORLD_SIZE_X+j].Turn = false;
    471.  
    472.         }
    473.  
    474.  
    475.     place_walls();
    476.     place_food();
    477.     place_evils();
    478.     place_pacman();
    479.  
    480.     Game();
    481. }
    482.  
    483.  
    484.  
    485. bool WORLD_MAP::move(direction dir, int x, int y)
    486. {
    487.     switch (dir) {
    488.         case Up:
    489.             if((map[(y-1)*WORLD_SIZE_X+x].Space) && (!map[(y-1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    490.                 map[(y-1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    491.                 map[(y-1)*WORLD_SIZE_X+x].Turn = true;
    492.                 paint(x, y-1);         
    493.             }
    494.             else
    495.                 return false;
    496.             break;
    497.         case Down:
    498.             if((map[(y+1)*WORLD_SIZE_X+x].Space) && (!map[(y+1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    499.                 map[(y+1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    500.                 map[(y+1)*WORLD_SIZE_X+x].Turn = true;
    501.                 paint(x, y+1);
    502.             }
    503.             else
    504.                 return false;
    505.             break;
    506.         case Left:
    507.             if((map[y*WORLD_SIZE_X+x-1].Space) && (!map[y*WORLD_SIZE_X+x-1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    508.                 map[y*WORLD_SIZE_X+x-1] = map[y*WORLD_SIZE_X+x];
    509.                 map[y*WORLD_SIZE_X+x-1].Turn = true;
    510.                 paint(x-1, y);         
    511.             }
    512.             else
    513.                 return false;
    514.             break;
    515.         case Right:
    516.             if((map[y*WORLD_SIZE_X+x+1].Space) && (!map[y*WORLD_SIZE_X+x+1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    517.                 map[y*WORLD_SIZE_X+x+1] = map[y*WORLD_SIZE_X+x];
    518.                 map[y*WORLD_SIZE_X+x+1].Turn = true;
    519.                 paint(x+1, y);     
    520.             }
    521.             else
    522.                 return false;
    523.             break;
    524.     }
    525.     map[y*WORLD_SIZE_X+x].Food = false;
    526.     map[y*WORLD_SIZE_X+x].Space = true;
    527.     map[y*WORLD_SIZE_X+x].Evil = false;
    528.     map[y*WORLD_SIZE_X+x].Turn = false;
    529.     paint(x, y);
    530.     return true;
    531. }
    532.  
    533.  
    534.  
    535. int main()
    536. {
    537.     WORLD_MAP the_very_game;
    538.     return 0;
    539. }
     
  2. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Вот код с потоками. Почему не получается открыть поток по адрессу функции? Пишет, что что-то с адрессом поточной функции

    Код (Text):
    1. #include <iostream>
    2. //#include <stdio.h>
    3. //#include <conio.h>
    4. #include <windows.h>
    5. //#include <stdlib.h>
    6. //#include <process.h>
    7. #include <time.h>
    8. #include <math.h>
    9. #include <conio.h>
    10.  
    11.  // 174еда  0стена 164зло 169пак
    12. class MOVING_UNITS {
    13. protected:
    14.     enum direction { Up, Right, Left, Down } dir;
    15.     virtual bool move(direction dir, int x, int y) = 0;
    16.  };
    17.  
    18.  
    19. class WALL {
    20. protected:
    21.     virtual void place_walls() = 0;
    22.     unsigned char wall_smile;
    23.     WORD wall_attr;
    24.     int MAX_WALL_LENGTH;
    25.     int NUMBER_OF_WALLS;
    26.     WALL();    
    27. };
    28.  
    29. WALL::WALL()
    30. {
    31.     MAX_WALL_LENGTH = 3;
    32.     NUMBER_OF_WALLS = 4;
    33.     wall_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    34.     wall_smile = 0;
    35. }
    36.  
    37.  
    38. class PACMAN : protected MOVING_UNITS {
    39. protected:
    40.     virtual void place_pacman() = 0;
    41.     unsigned char pacman_smile;
    42.     WORD pacman_attr;
    43.     PACMAN();
    44.  
    45. };
    46.  
    47. PACMAN::PACMAN()
    48. {
    49.     pacman_smile = 169;
    50.     pacman_attr = FOREGROUND_GREEN | BACKGROUND_RED;
    51. }
    52.  
    53.  
    54. class EVIL : protected MOVING_UNITS {
    55. protected:
    56.     virtual void place_evils() = 0;
    57.     virtual void intellect(int x, int y) = 0;
    58.     int NUMBER_OF_EVILS;
    59.     unsigned char evil_smile;
    60.     WORD evil_attr;
    61.     EVIL();
    62. };
    63.  
    64. EVIL::EVIL()
    65. {
    66.     evil_smile = 164;
    67.     evil_attr = FOREGROUND_RED;
    68.     NUMBER_OF_EVILS = 1;
    69. }
    70.  
    71. class FOOD {
    72. protected:
    73.     virtual void place_food() = 0;
    74.     int NUMBER_OF_FOOD;
    75.     unsigned char food_smile;
    76.     WORD food_attr;
    77.     int food_counter;
    78.     FOOD();
    79. };
    80.  
    81. FOOD::FOOD()
    82. {
    83.     food_smile = 174;
    84.     food_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    85.     NUMBER_OF_FOOD = 2;
    86.     food_counter = 0;
    87. }
    88.  
    89. class WORLD_MAP : protected WALL, protected PACMAN, protected EVIL, protected FOOD {
    90.     int WORLD_SIZE_X, WORLD_SIZE_Y;
    91.     struct WORLD_MAP_STRUCT {
    92.         unsigned Wall: 1;
    93.         unsigned Evil: 1;
    94.         unsigned Turn: 1;
    95.         unsigned Food: 1;
    96.         unsigned Space: 1;
    97.                
    98.     } *map;
    99.  
    100.     struct PACMAN_COORDINATE {
    101.         int _X_;
    102.         int _Y_;
    103.     } pac;
    104.    
    105.     HANDLE hConsoleOutput;
    106.     HANDLE hConsoleInput;
    107.        
    108.     unsigned char space_smile;
    109.     WORD space_attr;
    110.     WORD prev_key;
    111.     void place_walls();
    112.     void place_food();
    113.     void place_evils();
    114.     void place_pacman();
    115.     bool move(direction dir, int x, int y);
    116.     void paint(int x, int y);
    117.     void intellect(int x, int y);
    118.     void Game();
    119.     DWORD WINAPI MyThreadFunction(LPVOID lpParameter);
    120.     void KeyEventProc(int x, int y, INPUT_RECORD *lpBuffer);
    121. public:
    122.     WORLD_MAP();
    123. };
    124.  
    125.  
    126. DWORD WINAPI WORLD_MAP::MyThreadFunction(LPVOID lpParameter)
    127. {
    128.     DWORD lpNumberOfEventsRead;
    129.     if(ReadConsoleInput(hConsoleInput, (PINPUT_RECORD)lpParameter, 128, &lpNumberOfEventsRead))
    130.         return 0;
    131.     else return 1;
    132. }
    133.  
    134.  
    135.  
    136. void WORLD_MAP::intellect(int x, int y)
    137. {  
    138.    
    139.     Sleep(100);
    140.     if(abs(x - pac._X_) > abs(y - pac._Y_)) {
    141.         if(x > pac._X_) {
    142.             if(move(Left, x, y))
    143.                 ;
    144.             else {
    145.                 if(move(Up, x, y))
    146.                     ;
    147.                 else
    148.                     move(Down, x, y);
    149.             }
    150.         }
    151.         else if(move(Right, x, y))
    152.                 ;
    153.         else {
    154.             if(y > pac._Y_) {
    155.                 if(move(Up, x, y))
    156.                     ;
    157.             }
    158.             else
    159.                 move(Down, x, y);
    160.         }  
    161.     }
    162. // *******************************************************
    163.     else {
    164.         if(y > pac._Y_) {
    165.             if(move(Up, x, y))
    166.                 ;
    167.             else {
    168.                 if(move(Left, x, y))
    169.                     ;
    170.                 else
    171.                     move(Right, x, y);
    172.             }
    173.         }
    174.         else if(move(Down, x, y))
    175.             ;
    176.         else {
    177.             if(move(Left, x, y))
    178.                 ;
    179.             else
    180.                 move(Right, x, y);
    181.         }
    182.     }
    183. }
    184.  
    185.  
    186.  
    187. void WORLD_MAP::paint(int x, int y)
    188. {
    189.     COORD dwCursorPosition;
    190.     WCHAR cCharacter;
    191.     DWORD lpNumberOfCharsWritten;
    192.     DWORD lpNumberOfAttrsWritten;
    193.     WORD wAttribute;
    194.    
    195.     dwCursorPosition.X = x;
    196.     dwCursorPosition.Y = y;
    197.  
    198.  
    199.  
    200.  
    201.  
    202.  
    203.     if((x == pac._X_) && (y == pac._Y_)) {
    204.         cCharacter = pacman_smile;
    205.         wAttribute = pacman_attr;
    206.     }
    207.    
    208.     else if((map[y*WORLD_SIZE_X+x].Space) && (map[y*WORLD_SIZE_X+x].Food) ) {
    209.             cCharacter = food_smile;
    210.             wAttribute = food_attr;
    211.     }
    212.    
    213.     else if(map[y*WORLD_SIZE_X+x].Space) {
    214.             cCharacter = space_smile;
    215.             wAttribute = space_attr;
    216.     }
    217.    
    218.     else if(map[y*WORLD_SIZE_X+x].Evil) {
    219.         cCharacter = evil_smile;
    220.         wAttribute = evil_attr;
    221.     }
    222.  
    223.     else if(map[y*WORLD_SIZE_X+x].Wall) {
    224.         cCharacter = wall_smile;
    225.         wAttribute = wall_attr;
    226.     }
    227.  
    228.     else
    229.         return;
    230.    
    231.     FillConsoleOutputAttribute(hConsoleOutput, wAttribute, 1, dwCursorPosition, &lpNumberOfAttrsWritten);
    232.     FillConsoleOutputCharacter(hConsoleOutput, cCharacter, 1, dwCursorPosition, &lpNumberOfCharsWritten);  
    233. }
    234.  
    235. void WORLD_MAP::KeyEventProc(int x, int y, INPUT_RECORD *lpBuffer)
    236. {
    237.    
    238.     if(map[pac._Y_*WORLD_SIZE_X+pac._X_].Evil) {
    239.         FreeConsole();
    240.         AllocConsole();
    241.         std::cout << "You loose!";
    242.         getch();
    243.         exit(0);
    244.     }
    245.    
    246.    
    247.     //38вверх 37влево 40вниз 39вправо
    248.     Sleep(150);
    249.     WCHAR smth = lpBuffer[0].Event.KeyEvent.wVirtualKeyCode;
    250.     switch(smth) {
    251.         case 38:
    252.             prev_key = 38;
    253.             if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    254.                 food_counter++;
    255.                 map[(y-1)*WORLD_SIZE_X+x].Food = false;
    256.             }
    257.             pac._Y_--;
    258.             if(!move(Up, x, y))
    259.                 pac._Y_++;
    260.             break;
    261.         case 37:
    262.             prev_key = 37;
    263.             if(map[y*WORLD_SIZE_X+x-1].Food) {
    264.                 food_counter++;
    265.                 map[y*WORLD_SIZE_X+x-1].Food = false;
    266.             }
    267.             pac._X_--;
    268.             if(!move(Left, x, y))
    269.                 pac._X_++;
    270.                
    271.             break;
    272.         case 39:
    273.             prev_key = 39;
    274.             if(map[y*WORLD_SIZE_X+x+1].Food) {
    275.                 food_counter++;
    276.                 map[y*WORLD_SIZE_X+x+1].Food = false;
    277.             }
    278.             pac._X_++;
    279.             if(!move(Right, x, y))
    280.                 pac._X_--;
    281.             break;
    282.         case 40:
    283.             prev_key = 40;
    284.             if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    285.                 food_counter++;
    286.                 map[(y+1)*WORLD_SIZE_X+x].Food = false;
    287.             }
    288.             pac._Y_++;
    289.             if(!move(Down, x, y))
    290.                 pac._Y_--;
    291.             break;
    292.        
    293.         default:
    294.             switch(prev_key) {
    295.  
    296.                 case 38:
    297.                     if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    298.                         food_counter++;
    299.                         map[(y-1)*WORLD_SIZE_X+x].Food = false;
    300.                     }
    301.                     pac._Y_--;
    302.                     if(!move(Up, x, y))
    303.                         pac._Y_++;
    304.                     break;
    305.                 case 37:
    306.                     if(map[y*WORLD_SIZE_X+x-1].Food) {
    307.                         food_counter++;
    308.                         map[y*WORLD_SIZE_X+x-1].Food = false;
    309.                     }
    310.                     pac._X_--;
    311.                     if(!move(Left, x, y))
    312.                         pac._X_++;
    313.                        
    314.                     break;
    315.                 case 39:
    316.                     if(map[y*WORLD_SIZE_X+x+1].Food) {
    317.                         food_counter++;
    318.                         map[y*WORLD_SIZE_X+x+1].Food = false;
    319.                     }
    320.                     pac._X_++;
    321.                     if(!move(Right, x, y))
    322.                         pac._X_--;
    323.                     break;
    324.                 case 40:
    325.                     if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    326.                         food_counter++;
    327.                         map[(y+1)*WORLD_SIZE_X+x].Food = false;
    328.                     }
    329.                     pac._Y_++;
    330.                     if(!move(Down, x, y))
    331.                         pac._Y_--;
    332.                     break;
    333.  
    334.                 default:
    335.                     //std::cout << "AA";
    336.                     break;
    337.                
    338.    
    339.             }
    340.             break;
    341.     }
    342.  
    343.     if(food_counter >= NUMBER_OF_FOOD) {
    344.         FreeConsole();
    345.         AllocConsole();
    346.         std::cout << "You win!";
    347.         getch();
    348.         exit(0);
    349.     }
    350.  
    351.  
    352.     for(y=0; y<WORLD_SIZE_Y; y++)
    353.         for(x=0; x<WORLD_SIZE_X; x++)
    354.             map[y*WORLD_SIZE_X+x].Turn = false;
    355.  
    356.  
    357.     for(y=0; y<WORLD_SIZE_Y; y++)
    358.         for(x=0; x<WORLD_SIZE_X; x++)
    359.             if((map[y*WORLD_SIZE_X+x].Evil) && (!(map[y*WORLD_SIZE_X+x].Turn)))
    360.                 intellect(x, y);           
    361. }
    362.  
    363.  
    364. void WORLD_MAP::Game()
    365. {      
    366.     int x, y;
    367.     INPUT_RECORD lpBuffer[128];
    368.     HANDLE hThread;
    369.     //LPTHREAD_START_ROUTINE lpStartAdress;
    370.     //lpStartAdress = &MyThreadFunction;
    371.    
    372.  
    373.    
    374.     hThread = CreateThread(NULL, 0, MyThreadFunction, lpBuffer, 0, NULL); // ПОЧЕМУ НЕ УДАЁТСЯ ВЫЗВАТЬ?????
    375.    
    376.  
    377.    
    378.  
    379.     std::cout << "\nGame starts!";
    380.     FreeConsole();
    381.     AllocConsole();
    382.    
    383.  
    384.    
    385.  
    386.     hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    387.     hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
    388.  
    389.     for(x=0; x<WORLD_SIZE_X; x++)
    390.         for(y=0; y<WORLD_SIZE_Y; y++)
    391.             paint(x, y);
    392.    
    393.    
    394.    
    395.        
    396.  
    397.  
    398.     while(true)
    399.         KeyEventProc(pac._X_, pac._Y_, lpBuffer);
    400.  
    401.  
    402. }
    403.                
    404.    
    405.  
    406. void WORLD_MAP::place_pacman()
    407. {
    408.     int x, y;
    409.     std::cout << "\nGenerating pacman...";
    410.     srand(time(0));
    411.     do {
    412.         x = abs( (rand()) % WORLD_SIZE_X );
    413.         y = abs( (rand()) % WORLD_SIZE_Y );
    414.     }
    415.     while(   !( (map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food) )   );
    416.     pac._X_ = x;
    417.     pac._Y_ = y;
    418. }
    419.  
    420. void WORLD_MAP::place_food()
    421. {
    422.     int x, y, i;
    423.     std::cout << "\nGenerating food...";
    424.     srand(time(0));
    425.     for(i=0; i<NUMBER_OF_FOOD; i++) {
    426.         x = abs( (rand()) % WORLD_SIZE_X );
    427.         y = abs( (rand()) % WORLD_SIZE_Y );
    428.         if(map[y*WORLD_SIZE_X+x].Space)
    429.             map[y*WORLD_SIZE_X+x].Food = true;
    430.         else
    431.             i--;       
    432.     }
    433. }
    434.  
    435. void WORLD_MAP::place_evils()
    436. {
    437.     int x, y, i;
    438.     std::cout << "\nGenerating evils...";
    439.     srand(time(0));
    440.     for(i=0; i<NUMBER_OF_EVILS; i++) {
    441.         x = abs( (rand()) % WORLD_SIZE_X );
    442.         y = abs( (rand()) % WORLD_SIZE_Y );
    443.         if(map[y*WORLD_SIZE_X+x].Space && (!map[y*WORLD_SIZE_X+x].Food)) {
    444.             map[y*WORLD_SIZE_X+x].Evil = true;
    445.             map[y*WORLD_SIZE_X+x].Space = false;
    446.         }
    447.         else
    448.             i--;
    449.     }
    450. }
    451.  
    452. void WORLD_MAP::place_walls()
    453. {
    454.     int x, y, i, j;
    455.     std::cout << "\nGenerating walls...";
    456.     for(i=0; i<NUMBER_OF_WALLS; i++) {
    457.         srand(time(0));
    458.         x = abs( (rand()) % WORLD_SIZE_X );
    459.         y = abs( (rand()) % WORLD_SIZE_Y );
    460.  
    461.         for(j=0; j<MAX_WALL_LENGTH; j++) {
    462.             if((map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food)) {
    463.                 map[y*WORLD_SIZE_X+x].Wall = true;
    464.                 map[y*WORLD_SIZE_X+x].Space = false;
    465.             }
    466.             else
    467.                 j--;
    468.             x = abs( (rand()) > 16000 ? (x+1)%WORLD_SIZE_X : (x-1)%WORLD_SIZE_X );
    469.             y = abs( (rand()) > 16000 ? (y+1)%WORLD_SIZE_Y : (y-1)%WORLD_SIZE_Y );
    470.         }
    471.     }
    472. }
    473.  
    474. WORLD_MAP::WORLD_MAP()
    475. {
    476.     int i, j;
    477.     std::cout << "This is pacman!";
    478.     prev_key = 0;
    479.     WORLD_SIZE_X = 25;
    480.     WORLD_SIZE_Y = 15;
    481.     map = new WORLD_MAP_STRUCT [WORLD_SIZE_X*WORLD_SIZE_Y];
    482.     space_smile = 199;
    483.     space_attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_BLUE;
    484.  
    485.     for(i=0; i<WORLD_SIZE_Y; i++)
    486.         for(j=0; j<WORLD_SIZE_X; j++) {
    487.             map[i*WORLD_SIZE_X+j].Space = true;
    488.             map[i*WORLD_SIZE_X+j].Food = false;
    489.             map[i*WORLD_SIZE_X+j].Wall = false;
    490.             map[i*WORLD_SIZE_X+j].Evil = false;
    491.             map[i*WORLD_SIZE_X+j].Turn = false;
    492.  
    493.         }
    494.  
    495.  
    496.     place_walls();
    497.     place_food();
    498.     place_evils();
    499.     place_pacman();
    500.  
    501.     Game();
    502. }
    503.  
    504.  
    505.  
    506. bool WORLD_MAP::move(direction dir, int x, int y)
    507. {
    508.     switch (dir) {
    509.         case Up:
    510.             if((map[(y-1)*WORLD_SIZE_X+x].Space) && (!map[(y-1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    511.                 map[(y-1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    512.                 map[(y-1)*WORLD_SIZE_X+x].Turn = true;
    513.                 paint(x, y-1);         
    514.             }
    515.             else
    516.                 return false;
    517.             break;
    518.         case Down:
    519.             if((map[(y+1)*WORLD_SIZE_X+x].Space) && (!map[(y+1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    520.                 map[(y+1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    521.                 map[(y+1)*WORLD_SIZE_X+x].Turn = true;
    522.                 paint(x, y+1);
    523.             }
    524.             else
    525.                 return false;
    526.             break;
    527.         case Left:
    528.             if((map[y*WORLD_SIZE_X+x-1].Space) && (!map[y*WORLD_SIZE_X+x-1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    529.                 map[y*WORLD_SIZE_X+x-1] = map[y*WORLD_SIZE_X+x];
    530.                 map[y*WORLD_SIZE_X+x-1].Turn = true;
    531.                 paint(x-1, y);         
    532.             }
    533.             else
    534.                 return false;
    535.             break;
    536.         case Right:
    537.             if((map[y*WORLD_SIZE_X+x+1].Space) && (!map[y*WORLD_SIZE_X+x+1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    538.                 map[y*WORLD_SIZE_X+x+1] = map[y*WORLD_SIZE_X+x];
    539.                 map[y*WORLD_SIZE_X+x+1].Turn = true;
    540.                 paint(x+1, y);     
    541.             }
    542.             else
    543.                 return false;
    544.             break;
    545.     }
    546.     map[y*WORLD_SIZE_X+x].Food = false;
    547.     map[y*WORLD_SIZE_X+x].Space = true;
    548.     map[y*WORLD_SIZE_X+x].Evil = false;
    549.     map[y*WORLD_SIZE_X+x].Turn = false;
    550.     paint(x, y);
    551.     return true;
    552. }
    553.  
    554.  
    555.  
    556. int main()
    557. {
    558.     WORLD_MAP the_very_game;
    559.     return 0;
    560. }
     
  3. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    А... как я понял, нельзя поточную функцию делать закрытым членом класса.
    Только глобально можно объявлять?
     
  4. Voodoo

    Voodoo New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2003
    Сообщения:
    297
    Адрес:
    Новосибирск
    Antolflash
    Статический метод тоже можно использовать. А с некоторым извращением(см. листинг 2) можно запускать вообще любой метод в отдельном потоке.
     
  5. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Прошу прощения за плохой пример.
    Надо вот так)
    Код (Text):
    1. #include <windows.h>
    2. #include <iostream>
    3.  
    4. class MY {
    5.     static DWORD WINAPI MyThreadFunction(LPVOID lpParam);
    6.     HANDLE hThread;
    7. public:
    8.     MY();
    9.     ~MY();
    10.  
    11. };
    12. MY::MY()
    13. {
    14.     int j, i;
    15.     LPVOID lpParam;
    16.     //LPTHREAD_START_ROUTINE lpStartAdress;
    17.     //lpStartAdress = (LPTHREAD_START_ROUTINE)&MY::MyThreadFunction;
    18.     i = 0;
    19.     lpParam = &i;
    20.     //hThread = CreateThread(NULL, 0, lpStartAdress, lpParam, 0, NULL);
    21.     hThread = CreateThread(NULL, 0, MyThreadFunction, lpParam, 0, NULL);
    22.     for(j = 0; j < 15; j++)
    23.         std::cout << j;
    24.    
    25. }
    26.  
    27. MY::~MY()
    28. {
    29.     WaitForSingleObject(hThread, INFINITE);
    30.     CloseHandle(hThread);
    31. }
    32.  
    33. DWORD WINAPI MY::MyThreadFunction(LPVOID lpParam)
    34. {
    35.    
    36.     for(; ((int *)lpParam)[0] < 15; ((int *)lpParam)[0]++)
    37.         std::cout << ((int *)lpParam)[0];
    38.     return 0;
    39. }
    40.  
    41. int main()
    42. {
    43.     std::cout << "MAIN";
    44.     MY my;
    45.  
    46.     return 0;
    47. }
     
  6. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Как сделать так, чтобы выполнение определённого куска кода в одном потоке было непрерывным?
    Т.е. главный поток и мой поток выполняются параллельно. Вдруг бац, пока полностью не выполнится заданный целостный кусок кода в главном потоке, мой поток не выполняется. Т.е. нужно что-то что выключает, а потом включает многопоточность.
     
  7. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    Создай эвент (CreateEvent) и заюзай WaitForSingleObject. Тогда ты сможешь устанавливая эвент, включать процедуру, процедура выполнилась, выключила эвент, далее при новом выполнении ожидать прихода эвента. Можно это реализовать даже в процедуре потока, в цикле, чтобы не выходить из процедуры. Потом просто терминейтишь поток, когда он будет находиться в режиме ожидания.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Antolflash
    Ради такой ерунды создавать потоки? Жесть. Зачем ReadConsoleInput? getch, тем более, что соnio и так юзаете.
     
  9. Antolflash

    Antolflash New Member

    Публикаций:
    0
    Регистрация:
    14 дек 2008
    Сообщения:
    167
    Вот, кстати, последний рабочий вариант.
    Код (Text):
    1. #include <iostream>
    2. #include <windows.h>
    3. #include <time.h>
    4. #include <math.h>
    5. #include <conio.h>
    6.  
    7.  // 174еда  0стена 164зло 169пак
    8. class MOVING_UNITS {
    9. protected:
    10.     enum direction { Up, Right, Left, Down } dir;
    11.     virtual bool move(direction dir, int x, int y) = 0;
    12.  };
    13.  
    14.  
    15. class WALL {
    16. protected:
    17.     virtual void place_walls() = 0;
    18.     unsigned char wall_smile;
    19.     WORD wall_attr;
    20.     int MAX_WALL_LENGTH;
    21.     int NUMBER_OF_WALLS;
    22.     WALL();    
    23. };
    24.  
    25. WALL::WALL()
    26. {
    27.     MAX_WALL_LENGTH = 3;
    28.     NUMBER_OF_WALLS = 4;
    29.     wall_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    30.     wall_smile = 0;
    31. }
    32.  
    33.  
    34. class PACMAN : protected MOVING_UNITS {
    35. protected:
    36.     virtual void place_pacman() = 0;
    37.     unsigned char pacman_smile;
    38.     WORD pacman_attr;
    39.     PACMAN();
    40.  
    41. };
    42.  
    43. PACMAN::PACMAN()
    44. {
    45.     pacman_smile = 169;
    46.     pacman_attr = FOREGROUND_GREEN | BACKGROUND_RED;
    47. }
    48.  
    49.  
    50. class EVIL : protected MOVING_UNITS {
    51. protected:
    52.     virtual void place_evils() = 0;
    53.     virtual void intellect(int x, int y) = 0;
    54.     int NUMBER_OF_EVILS;
    55.     unsigned char evil_smile;
    56.     WORD evil_attr;
    57.     EVIL();
    58. };
    59.  
    60. EVIL::EVIL()
    61. {
    62.     evil_smile = 164;
    63.     evil_attr = FOREGROUND_RED;
    64.     NUMBER_OF_EVILS = 4;
    65. }
    66.  
    67. class FOOD {
    68. protected:
    69.     virtual void place_food() = 0;
    70.     int NUMBER_OF_FOOD;
    71.     unsigned char food_smile;
    72.     WORD food_attr;
    73.     int food_counter;
    74.     FOOD();
    75. };
    76.  
    77. FOOD::FOOD()
    78. {
    79.     food_smile = 174;
    80.     food_attr = FOREGROUND_BLUE | FOREGROUND_GREEN;
    81.     NUMBER_OF_FOOD = 4;
    82.     food_counter = 0;
    83. }
    84.  
    85. class WORLD_MAP : protected WALL, protected PACMAN, protected EVIL, protected FOOD {
    86.     int WORLD_SIZE_X, WORLD_SIZE_Y;
    87.     struct WORLD_MAP_STRUCT {
    88.         unsigned Wall: 1;
    89.         unsigned Evil: 1;
    90.         unsigned Turn: 1;
    91.         unsigned Food: 1;
    92.         unsigned Space: 1;
    93.                
    94.     } *map;
    95.  
    96.     struct PACMAN_COORDINATE {
    97.         int _X_;
    98.         int _Y_;
    99.     } pac;
    100.    
    101.     static HANDLE hConsoleOutput;
    102.     static HANDLE hConsoleInput;
    103.        
    104.     unsigned char space_smile;
    105.     WORD space_attr;
    106.     WORD prev_key;
    107.     void place_walls();
    108.     void place_food();
    109.     void place_evils();
    110.     void place_pacman();
    111.     bool move(direction dir, int x, int y);
    112.     void paint(int x, int y);
    113.     int skip;
    114.     int skip_c;
    115.     DWORD SLEEP_TIME;
    116.     void intellect(int x, int y);
    117.     void Game();
    118.    
    119.     void KeyEventProc(int x, int y);
    120.     static DWORD WINAPI MyThreadFunction(LPVOID lpParameter);
    121.     static bool terminator;
    122.     static CRITICAL_SECTION CS;
    123.     static HANDLE hThread;
    124.     static bool win_loose;
    125.     static INPUT_RECORD lpBuffer[128];
    126. public:
    127.     WORLD_MAP();
    128.     ~WORLD_MAP();
    129. };
    130.  
    131. bool WORLD_MAP::terminator = true;
    132. HANDLE WORLD_MAP::hConsoleInput;
    133. HANDLE WORLD_MAP::hConsoleOutput;
    134. INPUT_RECORD WORLD_MAP::lpBuffer[128];
    135. HANDLE WORLD_MAP::hThread;
    136. bool WORLD_MAP::win_loose;
    137.  
    138.  
    139. DWORD WINAPI WORLD_MAP::MyThreadFunction(LPVOID lpParameter)
    140. {
    141.     DWORD lpNumberOfEventsRead;
    142.    
    143.     while(true){
    144.         if(terminator)     
    145.             PeekConsoleInput(hConsoleInput, (PINPUT_RECORD)lpParameter, 128, &lpNumberOfEventsRead);
    146.         else {
    147.             FreeConsole();
    148.             AllocConsole();
    149.             if(win_loose)
    150.                 std::cout << "You win!";
    151.             else
    152.                 std::cout << "You loose!";
    153.             CloseHandle(hThread);
    154.             ExitThread(0);
    155.  
    156.         }
    157.    
    158.     }
    159.    
    160.     return 0;
    161. }
    162.  
    163.  
    164.  
    165.  
    166. void WORLD_MAP::intellect(int x, int y)
    167. {  
    168.     if(abs(x - pac._X_) > abs(y - pac._Y_)) {
    169.         if(x > pac._X_) {
    170.             if(move(Left, x, y))
    171.                 ;
    172.             else {
    173.                 if(move(Up, x, y))
    174.                     ;
    175.                 else
    176.                     move(Down, x, y);
    177.             }
    178.         }
    179.         else if(move(Right, x, y))
    180.                 ;
    181.         else {
    182.             if(y > pac._Y_) {
    183.                 if(move(Up, x, y))
    184.                     ;
    185.             }
    186.             else
    187.                 move(Down, x, y);
    188.         }  
    189.     }
    190. // *******************************************************
    191.     else {
    192.         if(y > pac._Y_) {
    193.             if(move(Up, x, y))
    194.                 ;
    195.             else {
    196.                 if(move(Left, x, y))
    197.                     ;
    198.                 else
    199.                     move(Right, x, y);
    200.             }
    201.         }
    202.         else if(move(Down, x, y))
    203.             ;
    204.         else {
    205.             if(move(Left, x, y))
    206.                 ;
    207.             else
    208.                 move(Right, x, y);
    209.         }
    210.     }
    211. }
    212.  
    213.  
    214.  
    215. void WORLD_MAP::paint(int x, int y)
    216. {
    217.     COORD dwCursorPosition;
    218.     WCHAR cCharacter;
    219.     DWORD lpNumberOfCharsWritten;
    220.     DWORD lpNumberOfAttrsWritten;
    221.     WORD wAttribute;
    222.    
    223.     dwCursorPosition.X = x;
    224.     dwCursorPosition.Y = y;
    225.  
    226.  
    227.     if((x == pac._X_) && (y == pac._Y_)) {
    228.         cCharacter = pacman_smile;
    229.         wAttribute = pacman_attr;
    230.     }
    231.    
    232.     else if((map[y*WORLD_SIZE_X+x].Space) && (map[y*WORLD_SIZE_X+x].Food) ) {
    233.             cCharacter = food_smile;
    234.             wAttribute = food_attr;
    235.     }
    236.    
    237.     else if(map[y*WORLD_SIZE_X+x].Space) {
    238.             cCharacter = space_smile;
    239.             wAttribute = space_attr;
    240.     }
    241.    
    242.     else if(map[y*WORLD_SIZE_X+x].Evil) {
    243.         cCharacter = evil_smile;
    244.         wAttribute = evil_attr;
    245.     }
    246.  
    247.     else if(map[y*WORLD_SIZE_X+x].Wall) {
    248.         cCharacter = wall_smile;
    249.         wAttribute = wall_attr;
    250.     }
    251.  
    252.     else
    253.         return;
    254.    
    255.     FillConsoleOutputAttribute(hConsoleOutput, wAttribute, 1, dwCursorPosition, &lpNumberOfAttrsWritten);
    256.     FillConsoleOutputCharacter(hConsoleOutput, cCharacter, 1, dwCursorPosition, &lpNumberOfCharsWritten);  
    257. }
    258.  
    259. void WORLD_MAP::KeyEventProc(int x, int y)
    260. {
    261.     if(map[pac._Y_*WORLD_SIZE_X+pac._X_].Evil) {
    262.             terminator = false;
    263.             win_loose = false;
    264.            
    265.         }
    266.  
    267.     if(food_counter >= NUMBER_OF_FOOD) {
    268.             terminator = false;
    269.             win_loose = true;
    270.            
    271.         }
    272.        
    273.    
    274.     //38вверх 37влево 40вниз 39вправо
    275.     WCHAR smth = lpBuffer[0].Event.KeyEvent.wVirtualKeyCode;
    276.     switch(smth) {
    277.         case 38:
    278.             prev_key = 38;
    279.             if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    280.                 food_counter++;
    281.                 map[(y-1)*WORLD_SIZE_X+x].Food = false;
    282.             }
    283.             pac._Y_--;
    284.             if(!move(Up, x, y))
    285.                 pac._Y_++;
    286.             break;
    287.         case 37:
    288.             prev_key = 37;
    289.             if(map[y*WORLD_SIZE_X+x-1].Food) {
    290.                 food_counter++;
    291.                 map[y*WORLD_SIZE_X+x-1].Food = false;
    292.             }
    293.             pac._X_--;
    294.             if(!move(Left, x, y))
    295.                 pac._X_++;
    296.                
    297.             break;
    298.         case 39:
    299.             prev_key = 39;
    300.             if(map[y*WORLD_SIZE_X+x+1].Food) {
    301.                 food_counter++;
    302.                 map[y*WORLD_SIZE_X+x+1].Food = false;
    303.             }
    304.             pac._X_++;
    305.             if(!move(Right, x, y))
    306.                 pac._X_--;
    307.             break;
    308.         case 40:
    309.             prev_key = 40;
    310.             if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    311.                 food_counter++;
    312.                 map[(y+1)*WORLD_SIZE_X+x].Food = false;
    313.             }
    314.             pac._Y_++;
    315.             if(!move(Down, x, y))
    316.                 pac._Y_--;
    317.             break;
    318.        
    319.         default:
    320.             switch(prev_key) {
    321.  
    322.                 case 38:
    323.                     if(map[(y-1)*WORLD_SIZE_X+x].Food) {
    324.                         food_counter++;
    325.                         map[(y-1)*WORLD_SIZE_X+x].Food = false;
    326.                     }
    327.                     pac._Y_--;
    328.                     if(!move(Up, x, y))
    329.                         pac._Y_++;
    330.                     break;
    331.                 case 37:
    332.                     if(map[y*WORLD_SIZE_X+x-1].Food) {
    333.                         food_counter++;
    334.                         map[y*WORLD_SIZE_X+x-1].Food = false;
    335.                     }
    336.                     pac._X_--;
    337.                     if(!move(Left, x, y))
    338.                         pac._X_++;
    339.                        
    340.                     break;
    341.                 case 39:
    342.                     if(map[y*WORLD_SIZE_X+x+1].Food) {
    343.                         food_counter++;
    344.                         map[y*WORLD_SIZE_X+x+1].Food = false;
    345.                     }
    346.                     pac._X_++;
    347.                     if(!move(Right, x, y))
    348.                         pac._X_--;
    349.                     break;
    350.                 case 40:
    351.                     if(map[(y+1)*WORLD_SIZE_X+x].Food) {
    352.                         food_counter++;
    353.                         map[(y+1)*WORLD_SIZE_X+x].Food = false;
    354.                     }
    355.                     pac._Y_++;
    356.                     if(!move(Down, x, y))
    357.                         pac._Y_--;
    358.                     break;
    359.  
    360.                 default:
    361.                     //std::cout << "AA";
    362.                     break;
    363.                
    364.    
    365.             }
    366.             break;
    367.     }
    368.  
    369.     FlushConsoleInputBuffer(hConsoleInput);
    370.  
    371.     for(y=0; y<WORLD_SIZE_Y; y++)
    372.         for(x=0; x<WORLD_SIZE_X; x++)
    373.             map[y*WORLD_SIZE_X+x].Turn = false;
    374.  
    375.     Sleep(SLEEP_TIME);
    376.     skip_c++;
    377.     if(!(skip_c % skip))
    378.         for(y=0; y<WORLD_SIZE_Y; y++)
    379.             for(x=0; x<WORLD_SIZE_X; x++)
    380.                 if((map[y*WORLD_SIZE_X+x].Evil) && (!(map[y*WORLD_SIZE_X+x].Turn)))
    381.                     intellect(x, y);
    382.        
    383.  
    384.        
    385. }
    386.  
    387.  
    388. void WORLD_MAP::Game()
    389. {      
    390.     int x, y;
    391.    
    392.     std::cout << "\nGame starts!";
    393.     FreeConsole();
    394.     AllocConsole();
    395.  
    396.     hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    397.     hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
    398.  
    399.     for(x=0; x<WORLD_SIZE_X; x++)
    400.         for(y=0; y<WORLD_SIZE_Y; y++)
    401.             paint(x, y);
    402.    
    403.    
    404.     hThread = CreateThread(NULL, 0, MyThreadFunction, lpBuffer, 0, NULL);
    405.  
    406.     while(terminator)
    407.         KeyEventProc(pac._X_, pac._Y_);
    408.     if(!terminator)
    409.         getch();
    410.    
    411. }
    412.                
    413.    
    414.  
    415. void WORLD_MAP::place_pacman()
    416. {
    417.     int x, y;
    418.     std::cout << "\nGenerating pacman...";
    419.     srand(time(0));
    420.     do {
    421.         x = abs( (rand()) % WORLD_SIZE_X );
    422.         y = abs( (rand()) % WORLD_SIZE_Y );
    423.     }
    424.     while(   !( (map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food) )   );
    425.     pac._X_ = x;
    426.     pac._Y_ = y;
    427. }
    428.  
    429. void WORLD_MAP::place_food()
    430. {
    431.     int x, y, i;
    432.     std::cout << "\nGenerating food...";
    433.     srand(time(0));
    434.     for(i=0; i<NUMBER_OF_FOOD; i++) {
    435.         x = abs( (rand()) % WORLD_SIZE_X );
    436.         y = abs( (rand()) % WORLD_SIZE_Y );
    437.         if(map[y*WORLD_SIZE_X+x].Space)
    438.             map[y*WORLD_SIZE_X+x].Food = true;
    439.         else
    440.             i--;       
    441.     }
    442. }
    443.  
    444. void WORLD_MAP::place_evils()
    445. {
    446.     int x, y, i;
    447.     std::cout << "\nGenerating evils...";
    448.     srand(time(0));
    449.     for(i=0; i<NUMBER_OF_EVILS; i++) {
    450.         x = abs( (rand()) % WORLD_SIZE_X );
    451.         y = abs( (rand()) % WORLD_SIZE_Y );
    452.         if(map[y*WORLD_SIZE_X+x].Space && (!map[y*WORLD_SIZE_X+x].Food)) {
    453.             map[y*WORLD_SIZE_X+x].Evil = true;
    454.             map[y*WORLD_SIZE_X+x].Space = false;
    455.         }
    456.         else
    457.             i--;
    458.     }
    459. }
    460.  
    461. void WORLD_MAP::place_walls()
    462. {
    463.     int x, y, i, j;
    464.     std::cout << "\nGenerating walls...";
    465.     for(i=0; i<NUMBER_OF_WALLS; i++) {
    466.         srand(time(0));
    467.         x = abs( (rand()) % WORLD_SIZE_X );
    468.         y = abs( (rand()) % WORLD_SIZE_Y );
    469.  
    470.         for(j=0; j<MAX_WALL_LENGTH; j++) {
    471.             if((map[y*WORLD_SIZE_X+x].Space) && (!map[y*WORLD_SIZE_X+x].Food)) {
    472.                 map[y*WORLD_SIZE_X+x].Wall = true;
    473.                 map[y*WORLD_SIZE_X+x].Space = false;
    474.             }
    475.             else
    476.                 j--;
    477.             x = abs( (rand()) > 16000 ? (x+1)%WORLD_SIZE_X : (x-1)%WORLD_SIZE_X );
    478.             y = abs( (rand()) > 16000 ? (y+1)%WORLD_SIZE_Y : (y-1)%WORLD_SIZE_Y );
    479.         }
    480.     }
    481. }
    482.  
    483. WORLD_MAP::WORLD_MAP()
    484. {
    485.     int i, j;
    486.     std::cout << "This is pacman!";
    487.     prev_key = 0;
    488.     WORLD_SIZE_X = 30;
    489.     WORLD_SIZE_Y = 20;
    490.     terminator = true;
    491.     skip = 4;
    492.     skip_c = 0;
    493.     SLEEP_TIME = 250;
    494.     map = new WORLD_MAP_STRUCT [WORLD_SIZE_X*WORLD_SIZE_Y];
    495.     space_smile = 199;
    496.     space_attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_BLUE;
    497.  
    498.     for(i=0; i<WORLD_SIZE_Y; i++)
    499.         for(j=0; j<WORLD_SIZE_X; j++) {
    500.             map[i*WORLD_SIZE_X+j].Space = true;
    501.             map[i*WORLD_SIZE_X+j].Food = false;
    502.             map[i*WORLD_SIZE_X+j].Wall = false;
    503.             map[i*WORLD_SIZE_X+j].Evil = false;
    504.             map[i*WORLD_SIZE_X+j].Turn = false;
    505.  
    506.         }
    507.  
    508.     place_walls();
    509.     place_food();
    510.     place_evils();
    511.     place_pacman();
    512.  
    513.     Game();
    514. }
    515.  
    516. WORLD_MAP::~WORLD_MAP()
    517. {
    518.     delete map;
    519. }
    520.  
    521.  
    522.  
    523. bool WORLD_MAP::move(direction dir, int x, int y)
    524. {
    525.     switch (dir) {
    526.         case Up:
    527.             if((map[(y-1)*WORLD_SIZE_X+x].Space) && (!map[(y-1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    528.                 map[(y-1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    529.                 map[(y-1)*WORLD_SIZE_X+x].Turn = true;
    530.                 paint(x, y-1);         
    531.             }
    532.             else
    533.                 return false;
    534.             break;
    535.         case Down:
    536.             if((map[(y+1)*WORLD_SIZE_X+x].Space) && (!map[(y+1)*WORLD_SIZE_X+x].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    537.                 map[(y+1)*WORLD_SIZE_X+x] = map[y*WORLD_SIZE_X+x];
    538.                 map[(y+1)*WORLD_SIZE_X+x].Turn = true;
    539.                 paint(x, y+1);
    540.             }
    541.             else
    542.                 return false;
    543.             break;
    544.         case Left:
    545.             if((map[y*WORLD_SIZE_X+x-1].Space) && (!map[y*WORLD_SIZE_X+x-1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    546.                 map[y*WORLD_SIZE_X+x-1] = map[y*WORLD_SIZE_X+x];
    547.                 map[y*WORLD_SIZE_X+x-1].Turn = true;
    548.                 paint(x-1, y);         
    549.             }
    550.             else
    551.                 return false;
    552.             break;
    553.         case Right:
    554.             if((map[y*WORLD_SIZE_X+x+1].Space) && (!map[y*WORLD_SIZE_X+x+1].Food) && (y < WORLD_SIZE_Y) && (x < WORLD_SIZE_X)) {
    555.                 map[y*WORLD_SIZE_X+x+1] = map[y*WORLD_SIZE_X+x];
    556.                 map[y*WORLD_SIZE_X+x+1].Turn = true;
    557.                 paint(x+1, y);     
    558.             }
    559.             else
    560.                 return false;
    561.             break;
    562.     }
    563.     map[y*WORLD_SIZE_X+x].Food = false;
    564.     map[y*WORLD_SIZE_X+x].Space = true;
    565.     map[y*WORLD_SIZE_X+x].Evil = false;
    566.     map[y*WORLD_SIZE_X+x].Turn = false;
    567.     paint(x, y);
    568.     return true;
    569. }
    570.  
    571.  
    572.  
    573. int main()
    574. {
    575.     WORLD_MAP the_very_game;
    576.     return 0;
    577. }
    А как реализовать постоянное движение пакмана иначе? Я потоки использовал, чтобы он при нажатиях клавишь лишь менял направление, а двигается он всегда.
    Какие есть замечания по коду, советы?
     
  10. Voodoo

    Voodoo New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2003
    Сообщения:
    297
    Адрес:
    Новосибирск
    Antolflash
    омг. зачем такой страшный огород?..
    например, добавляешь в WORLD_MAP список движущихся объектов, у которых есть метод move_self, в цикле вызываешь этот метод поочередно для каждого. соответственно, в цикле в первую очередь провяряешь нажаты/отпущены ли клавиши поворота, соответственно меняешь направления движения.
    как-то так.
     
  11. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    Antolflash

    микрозамечание

    WORLD_MAP::~WORLD_MAP()
    {
    //delete map;
    delete[] map;
    }


    а вообще - множественное наследование типа

    class WORLD_MAP : protected WALL, protected PACMAN, protected EVIL, protected FOOD{

    не загусто ли?