Simulation von Bürgern
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include <iostream>
  2. #include <sys/ioctl.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <chrono>
  6. #include <thread>
  7. #include <cmath>
  8. #include <stdlib.h>
  9. #include <ncurses.h>
  10. #include <pthread.h>
  11. #include <termios.h>
  12. #include <stdbool.h>
  13. #include <sys/select.h>
  14. #include <vector>
  15. #include <algorithm>
  16. #include <sys/socket.h>
  17. //#include <netinet/in.h>
  18. #include <string.h>
  19. #include <arpa/inet.h>
  20. #define PORT 5210
  21. using namespace std;
  22. using namespace std::chrono;
  23. string debugMsg;
  24. bool bGameLoop = true;
  25. int nScreenWidth;
  26. int nScreenHeight;
  27. string screen;
  28. float fPlayerX = 8.0f;
  29. float fPlayerY = 8.0f;
  30. float fPlayerA = 0.0f;
  31. float fElapsedTime;
  32. bool bMoveForward;
  33. bool bMoveBackwards;
  34. bool bTurnLeft;
  35. bool bTurnRight;
  36. void *keyListener(void *tid){
  37. long id = (long) tid;
  38. initscr();
  39. noecho();
  40. //raw();
  41. //cbreak();
  42. //nodelay(stdscr, TRUE);
  43. //scrollok(stdscr, TRUE);
  44. //raw();
  45. int c;
  46. while ((c = getch()) != ERR){
  47. debugMsg = "";
  48. debugMsg+=to_string(c);
  49. switch (c) {
  50. case 119: //w
  51. bMoveForward = true;
  52. break;
  53. case 97: //a
  54. bTurnLeft = true;
  55. break;
  56. case 115: //s
  57. bMoveBackwards = true;
  58. break;
  59. case 100: //d
  60. bTurnRight = true;
  61. break;
  62. default:
  63. break;
  64. }
  65. }
  66. endwin();
  67. pthread_exit(NULL);
  68. }
  69. void writeStringToScreen(int x, int y, string text){
  70. int s = (y*nScreenWidth)+x;
  71. for (int i = s; i < s+text.length(); i++){
  72. screen[i] = text[i-s];
  73. }
  74. }
  75. int main(int argc, char const *argv[]){
  76. //CLIENT STUFF
  77. struct sockaddr_in address;
  78. int sock = 0;
  79. struct sockaddr_in serv_addr;
  80. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n");return -1; }
  81. memset(&serv_addr, '0', sizeof(serv_addr));
  82. serv_addr.sin_family = AF_INET;
  83. serv_addr.sin_port = htons(PORT);
  84. if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0){ printf("\nInvalid address/ Address not supported \n"); return -1; }
  85. if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){ printf("\nConnection Failed \n"); return -1; }
  86. ///I HAVE TO LOOK INTO THIS MORE
  87. struct termios ttystate;
  88. tcgetattr(STDIN_FILENO, &ttystate);
  89. ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character
  90. ttystate.c_cc[VMIN] = 1;
  91. tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
  92. ///
  93. //cInput = {'a','b'};
  94. //fputs("\e[?25h", stdout); //get cursor back /on signal abort ~
  95. //setterm(1);
  96. pthread_t pThread[1];
  97. pthread_create(&pThread[0], NULL, keyListener, 0);
  98. struct winsize size;
  99. ioctl(STDOUT_FILENO,TIOCGWINSZ,&size);
  100. nScreenWidth = size.ws_col;
  101. nScreenHeight = size.ws_row;
  102. int nFrameRate = 60;
  103. float fFOV = 3.14159 / 4.0;
  104. float fDepth = 32.0f;
  105. char *mapwRequest = (char*)"give mapw";
  106. char bufferMapw[32] = {0};
  107. send(sock , mapwRequest , strlen(mapwRequest) , 0 );
  108. int getmapw = read( sock , bufferMapw, 32);
  109. string s_MapWidth = ("%s\n",bufferMapw);
  110. int nMapWidth = stoi(s_MapWidth);
  111. char *maphRequest = (char*)"give maph";
  112. char bufferMaph[32] = {0};
  113. send(sock , maphRequest , strlen(maphRequest) , 0 );
  114. int getmaph = read( sock , bufferMaph, 32);
  115. string s_MapHeight = ("%s\n",bufferMaph);
  116. int nMapHeight = stoi(s_MapHeight);
  117. string map = "";
  118. for (int i = 0; i < nMapHeight; i ++){
  119. char *mapRequest = (char*)"give map";
  120. char bufferMap[4096] = {0};
  121. send(sock , mapRequest , strlen(mapRequest) , 0 );
  122. int getmap = read( sock , bufferMap, 4096);
  123. map += ("%s\n",bufferMap );
  124. }
  125. /*
  126. map += "################";
  127. map += "#..............#";
  128. map += "#####......#####";
  129. map += "#..............#";
  130. map += "#..........#####";
  131. map += "#..............#";
  132. map += "#####......#####";
  133. map += "#####......#####";
  134. map += "#####......#####";
  135. map += "#####......#####";
  136. map += "#####......#####";
  137. map += "#..............#";
  138. map += "#..............#";
  139. map += "#####......#####";
  140. map += "#..............#";
  141. map += "################"; */
  142. system("kbdrate -d 250 -r 10");
  143. using clock = steady_clock;
  144. auto tp1 = clock::now();
  145. auto tp2 = clock::now();
  146. fputs("\e[?25l", stdout); //remove cursor*/
  147. float fSpeedFactor = 20.0f;
  148. ///////////////////////////////////////////////////////////
  149. ///////////////////////////////////////////////////////////
  150. ///////////////////////////////////////////////////////////
  151. ////////BEGINDRAW/////
  152. ///////////////////////////////////////////////////////////
  153. ///////////////////////////////////////////////////////////
  154. ///////////////////////////////////////////////////////////
  155. while(bGameLoop){
  156. tp2 = clock::now();
  157. duration<float> elapsedTime = tp2 - tp1;
  158. tp1 = tp2;
  159. fElapsedTime = elapsedTime.count();
  160. //dynamic terminal window size (on Window Resize)
  161. ioctl(STDOUT_FILENO,TIOCGWINSZ,&size);
  162. nScreenWidth = size.ws_col;
  163. nScreenHeight = size.ws_row;
  164. screen.clear();
  165. screen.resize(nScreenWidth*nScreenHeight);
  166. cout << "\x1B[0;0H"; //reset cursor to 0,0
  167. //fun part
  168. char *locxRequest = (char*)"give locx";
  169. char *locyRequest = (char*)"give locy";
  170. char *aRequest = (char*)"give a";
  171. char buffer[32] = {0};
  172. send(sock , locxRequest , strlen(locxRequest) , 0 );
  173. int getlocx = read( sock , buffer, 32);
  174. string s_xPos = ("%s\n",buffer );
  175. buffer[32] = {0};
  176. send(sock , locyRequest , strlen(locyRequest) , 0 );
  177. int getlocy = read( sock , buffer, 32);
  178. string s_yPos = ("%s\n",buffer );
  179. buffer[32] = {0};
  180. send(sock , aRequest , strlen(aRequest) , 0 );
  181. int geta = read( sock , buffer, 32);
  182. string s_angle = ("%s\n",buffer );
  183. fPlayerA = stof(s_angle)+3.14159*0.5;
  184. fPlayerX = stof(s_xPos);
  185. fPlayerY = stof(s_yPos);
  186. //this would be much better as class
  187. if(bMoveForward){
  188. fPlayerX += fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime;
  189. fPlayerY += fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime;
  190. if(map[(int)fPlayerY * nMapWidth + (int)fPlayerX] == '#')
  191. {
  192. fPlayerX -= fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime;
  193. fPlayerY -= fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime;
  194. }
  195. bMoveForward = false;
  196. }
  197. if(bMoveBackwards){
  198. fPlayerX -= fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime;
  199. fPlayerY -= fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime;
  200. if(map[(int)fPlayerY * nMapWidth + (int)fPlayerX] == '#') {
  201. fPlayerX += fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime;
  202. fPlayerY += fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime;
  203. }
  204. bMoveBackwards = false;
  205. }
  206. if(bTurnLeft){
  207. fPlayerA -= 0.15f;
  208. bTurnLeft = false;
  209. }
  210. if(bTurnRight){
  211. fPlayerA += 0.15f;
  212. bTurnRight = false;
  213. }
  214. //shading part
  215. for (int x = 0; x < nScreenWidth; x++){
  216. float fRayAngle = (fPlayerA - fFOV / 2.0f) + ((float)x / (float)nScreenWidth) * fFOV;
  217. float fDistanceToWall = 0;
  218. bool bHitWall = false;
  219. bool bBoundary = false;
  220. float fEyeX = -sinf(fRayAngle);
  221. float fEyeY = cosf(fRayAngle);
  222. while(!bHitWall && fDistanceToWall < fDepth){
  223. fDistanceToWall += 0.1f;
  224. int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall);
  225. int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall);
  226. if(nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight){
  227. bHitWall = true;
  228. fDistanceToWall = fDepth;
  229. } else {
  230. if(map[nTestY * nMapWidth + nTestX] == '#')
  231. {
  232. bHitWall = true;
  233. vector<pair<float, float>> p; //distance, dot
  234. for (int tx = 0; tx < 2; tx++)
  235. for (int ty = 0; ty < 2; ty++)
  236. {
  237. float vy = (float)nTestY + ty - fPlayerY;
  238. float vx = (float)nTestX + tx - fPlayerX;
  239. float d = sqrt(vx*vx + vy*vy);
  240. float dot = (fEyeX * vx / d) + (fEyeY * vy / d);
  241. p.push_back(make_pair(d,dot));
  242. }
  243. sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) { return left.first < right.first; });
  244. float fBound = 0.005;
  245. if (acos(p.at(0).second) < fBound) bBoundary = true;
  246. if (acos(p.at(1).second) < fBound) bBoundary = true;
  247. if (acos(p.at(2).second) < fBound) bBoundary = true;
  248. }
  249. }
  250. }
  251. int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall);
  252. int nFloor = nScreenHeight - nCeiling;
  253. short nShade = 32;
  254. for(int y = 0; y < nScreenHeight; y++){
  255. if(y < nCeiling)
  256. screen[y*nScreenWidth+x] = ' ';
  257. if(y > nCeiling && y <= nFloor){
  258. if (fDistanceToWall <= fDepth / 4.0f) nShade = 77; //very close
  259. else if (fDistanceToWall < fDepth / 3.5f) nShade = 72;
  260. else if (fDistanceToWall < fDepth / 3.0f) nShade = 84;
  261. else if (fDistanceToWall < fDepth / 2.5f) nShade = 73;
  262. else if (fDistanceToWall < fDepth / 2.0f) nShade = 105;
  263. else if (fDistanceToWall < fDepth / 1.5f) nShade = 58;
  264. else if (fDistanceToWall < fDepth) nShade = 46;
  265. else nShade = 32; // too far
  266. if(bBoundary) nShade = '-';
  267. screen[y*nScreenWidth+x] = nShade;
  268. }
  269. else
  270. {
  271. float b = 1.0f - (((float)y - nScreenHeight / 2.0f) / ((float)nScreenHeight / 2.0f));
  272. if (b < 0.3) nShade = 32; //32 //very close
  273. else if (b < 0.55) nShade = 96; //96
  274. else if (b < 0.8) nShade = 94; //94
  275. else if (b < 0.9) nShade = 42; //42
  276. else nShade = 32; //64 too far
  277. screen[y*nScreenWidth+x] = nShade;
  278. }
  279. }
  280. }
  281. writeStringToScreen(0, nScreenHeight-3,"Received from server: " + s_xPos+ " "+s_yPos+ " "+s_angle + " " + to_string(nMapWidth)+ " " + to_string(nMapHeight) + " ");
  282. //writeStringToScreen(0, 0, "Key pressed: " + to_string(123) + " Key code: " + to_string(cInput));
  283. //writeStringToScreen(0, nScreenHeight-3, debugMsg);
  284. writeStringToScreen(0, nScreenHeight-2, "Frame rate: " + to_string(1.0f / fElapsedTime) + " ");
  285. writeStringToScreen(0, nScreenHeight-1, "Key pressed: " + debugMsg + " Angle: " + to_string(fPlayerA) + " X: " + to_string(fPlayerX) + " Y: " + to_string(fPlayerY) + " ");
  286. //string sInput(1, cInput[0]);
  287. cout << screen; //this is the renderer
  288. //cout << ;
  289. tp1 += milliseconds(1000 / nFrameRate);
  290. this_thread::sleep_until(tp1);
  291. }
  292. return 0;
  293. }