#include #include #include #include "../src/NeuronNetwork/Learning/QLearning.h" #include int learningGames=6000; int ball_x = 320; int ball_y = 240; int ball_tempX = 320; int ball_tempY = 240; int p1_x = 20; int p1_y = 210; int p1_tempX = 20; int p1_tempY = 210; int p2_x = 620; int p2_y = 210; int p2_tempX = 620; int p2_tempY = 210; int i=0; long game=0; int q=0; int speed=1; bool randomLearner=0; int dir; //This will keep track of the circles direction //1= up and left, 2 = down and left, 3= up and right, 4 = down and right BITMAP *buffer; //This will be our temporary bitmap for double buffering class X: public Shin::NeuronNetwork::Problem { public: X(int p1,int ballX,int ballY,int p2)//, int ballY) { data.push_back((float)p1/480.0); data.push_back((float)ballX/640.0); data.push_back((float)ballY/480.0); } }; Shin::NeuronNetwork::Learning::QLearning l(3,15,3); std::vector > p1x; void propagateOKtoP1(double quality=10) { l.learnDelayed(p1x,quality); p1x.clear(); } void moveBall(){ ball_tempX = ball_x; ball_tempY = ball_y; if (dir == 1 && ball_x > 5 && ball_y > 5){ if( ball_x == p1_x + 15 && ball_y >= p1_y && ball_y <= p1_y + 60){ dir = rand()% 2 + 3; propagateOKtoP1(100); }else{ --ball_x; --ball_y; } } else if (dir == 2 && ball_x > 5 && ball_y < 475){ if( ball_x == p1_x + 15 && ball_y >= p1_y && ball_y <= p1_y + 60){ dir = rand()% 2 + 3; propagateOKtoP1(100); }else{ --ball_x; ++ball_y; } } else if (dir == 3 && ball_x < 635 && ball_y > 5){ if( ball_x + 5 == p2_x && ball_y >= p2_y && ball_y <= p2_y + 60){ dir = rand()% 2 + 1; }else{ ++ball_x; --ball_y; } } else if (dir == 4 && ball_x < 635 && ball_y < 475){ if( ball_x + 5 == p2_x && ball_y >= p2_y && ball_y <= p2_y + 60){ dir = rand()% 2 + 1; }else{ ++ball_x; ++ball_y; } } else { if (dir == 1 || dir == 3) ++dir; else if (dir == 2 || dir == 4) --dir; } } char p1Move(){ X p=X(p1_y,ball_x,ball_y,p2_y); if(game (p,2));//,ball_tempX,ball_tempY)); return 1; }else if(tmp==0) { p1x.push_back(std::pair(p,0));//,ball_tempX,ball_tempY)); return -1; }else { p1x.push_back(std::pair(p,1));//,ball_tempX,ball_tempY)); return 0; } }else { if( p1_tempY > ball_y && p1_y > 0){ p1x.push_back(std::pair(p,0));//,ball_tempX,ball_tempY)); return -1; } else if( p1_tempY < ball_y && p1_y < 420){ p1x.push_back(std::pair(p,2));//,ball_tempX,ball_tempY)); return 1; }else { p1x.push_back(std::pair(p,1));//,ball_tempX,ball_tempY)); return 0; } } } int j=l.getChoice(p); p1x.push_back(std::pair(p,j));//,ball_tempX,ball_tempY)); return j-1; } char p2Move(){ if(game >= learningGames) { if(key[KEY_UP]) return 1; else if( key[KEY_DOWN]) return -1; else return 0; }else { if(rand()%10==0) { return (rand()%3)-1; } if( p2_tempY > ball_y){ return -1; } else if( p2_tempY < ball_y){ return 1; } return 0; } } void startNew(){ clear_keybuf(); if(game==learningGames) textout_ex( screen, font, "Player 1 learned! Push a button to start a game.", 160, 240, makecol( 255, 0, 0), makecol( 0, 0, 0)); if(game >= learningGames) readkey(); clear_to_color( buffer, makecol( 0, 0, 0)); ball_x = 350; ball_y = rand()%481; p1_x = 20; p1_y = 210; p2_x = 620; p2_y = 210; } void checkWin(){ int won=0; if ( ball_x < p1_x){ won=1; game++; textout_ex( screen, font, "Player 2 Wins!", 320, 240, makecol( 255, 0, 0), makecol( 0, 0, 0)); propagateOKtoP1(-100); startNew(); } else if ( ball_x > p2_x){ game++; won=1; textout_ex( screen, font, "Player 1 Wins!", 320, 240, makecol( 255, 0, 0), makecol( 0, 0, 0)); propagateOKtoP1(100); startNew(); } } void setupGame(){ acquire_screen(); rectfill( buffer, p1_x, p1_y, p1_x + 10, p1_y + 60, makecol ( 0, 0, 255)); rectfill( buffer, p2_x, p2_y, p2_x + 10, p2_y + 60, makecol ( 0, 0, 255)); circlefill ( buffer, ball_x, ball_y, 5, makecol( 128, 255, 0)); draw_sprite( screen, buffer, 0, 0); release_screen(); srand( time(NULL)); dir = rand() % 4 + 1; } int main(int argc, char**argv) { allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); l.setLearningCoeficient(0.01,0.01); if(argc>=4 && argv[3][0]=='o') { std::cerr << "USING Optical Backpropagation\n"; l.opticalBackPropagation(); } if(argc>=3) { std::cerr << "Setting learning coefficients to:" << atof(argv[1]) << "," << atof(argv[2]) << "\n"; l.setLearningCoeficient(atof(argv[1]),atof(argv[2])); } if(argc >=5) { std::cerr << "Setting learning games to:" << atof(argv[4]) << "\n"; learningGames=atof(argv[4]); } if(argc >=6 && argv[5][0]=='r') { std::cerr << "Setting random learning\n"; randomLearner=1; } buffer = create_bitmap( 640, 480); setupGame(); speed=51; int sleepTime=1000; while(!key[KEY_ESC]) { q++; if(key[KEY_T]) { std::cout << "ADDING next 500 learning games\n"; usleep(500000); learningGames+=500; } if(game < learningGames) { if( key[KEY_UP] && speed < 200){ speed+=5; }else if( key[KEY_DOWN] && speed >1 ){ speed-=5; } if(speed <= 0) { speed=1; } }else { speed=1; } register char p1dir=p1Move(); register char p2dir=p2Move(); p1_tempY = p1_y; p2_tempY = p2_y; if(p1dir < 0 && p1_y > 0){ --p1_y; } else if( p1dir > 0 && p1_y < 420){ ++p1_y; } if(p2dir > 0 && p2_y > 0){ --p2_y; } else if( p2dir < 0 && p2_y < 420){ ++p2_y; } moveBall(); if(key[KEY_PLUS_PAD] && sleepTime >=10) sleepTime-=50; else if(key[KEY_MINUS_PAD] && sleepTime <=15000) sleepTime+=50; if(i%speed==0) { acquire_screen(); rectfill( buffer, p1_tempX, p1_tempY, p1_tempX + 10, p1_tempY + 60, makecol ( 0, 0, 0)); rectfill( buffer, p1_x, p1_y, p1_x + 10, p1_y + 60, makecol ( 0, 0, 255)); rectfill( buffer, p2_tempX, p2_tempY, p2_tempX + 10, p2_tempY + 60, makecol ( 0, 0, 0)); rectfill( buffer, p2_x, p2_y, p2_x + 10, p2_y + 60, makecol ( 0, 0, 255)); circlefill ( buffer, ball_tempX, ball_tempY, 5, makecol( 0, 0, 0)); circlefill ( buffer, ball_x, ball_y, 5, makecol( 128, 255, 0)); draw_sprite( screen, buffer, 0, 0); release_screen(); usleep(sleepTime); } checkWin(); i++; } return 0; } END_OF_MAIN()